@eventra_dev/eventra-cli 0.1.20 → 0.1.21
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/engine/resolver.js +15 -13
- package/dist/engine/scanner.js +12 -8
- package/dist/utils/parsers/router.js +3 -16
- package/dist/utils/parsers/universal.js +155 -0
- package/dist/utils/processFile.js +11 -9
- package/package.json +1 -1
- package/src/engine/resolver.ts +19 -12
- package/src/engine/scanner.ts +10 -6
- package/src/utils/parsers/router.ts +3 -16
- package/src/utils/parsers/universal.ts +186 -0
- package/src/utils/processFile.ts +8 -9
- package/dist/utils/parsers/astro.js +0 -49
- package/dist/utils/parsers/svelte.js +0 -30
- package/dist/utils/parsers/vue.js +0 -59
- package/src/utils/parsers/astro.ts +0 -53
- package/src/utils/parsers/svelte.ts +0 -36
- package/src/utils/parsers/vue.ts +0 -67
package/dist/engine/resolver.js
CHANGED
|
@@ -7,10 +7,10 @@ exports.resolveNodeValue = resolveNodeValue;
|
|
|
7
7
|
const typescript_1 = __importDefault(require("typescript"));
|
|
8
8
|
const exportResolver_1 = require("./exportResolver");
|
|
9
9
|
function resolveNodeValue(node, checker, paramMap, seen = new Set()) {
|
|
10
|
-
if (seen.has(node))
|
|
11
|
-
return
|
|
10
|
+
if (seen.has(node)) {
|
|
11
|
+
return { values: [], dynamic: true };
|
|
12
|
+
}
|
|
12
13
|
seen.add(node);
|
|
13
|
-
// param mapping
|
|
14
14
|
if (typescript_1.default.isIdentifier(node) && paramMap?.has(node.text)) {
|
|
15
15
|
return resolveNodeValue(paramMap.get(node.text), checker, paramMap, seen);
|
|
16
16
|
}
|
|
@@ -29,15 +29,14 @@ function resolveNodeValue(node, checker, paramMap, seen = new Set()) {
|
|
|
29
29
|
const a = resolveNodeValue(node.whenTrue, checker, paramMap, seen);
|
|
30
30
|
const b = resolveNodeValue(node.whenFalse, checker, paramMap, seen);
|
|
31
31
|
return {
|
|
32
|
-
values: [...new Set([...(a
|
|
32
|
+
values: [...new Set([...(a.values ?? []), ...(b.values ?? [])])],
|
|
33
33
|
dynamic: true,
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
if (typescript_1.default.isIdentifier(node)) {
|
|
37
37
|
let symbol = checker.getSymbolAtLocation(node);
|
|
38
38
|
if (!symbol)
|
|
39
|
-
return
|
|
40
|
-
// variable inline resolve FIRST
|
|
39
|
+
return { values: [], dynamic: true };
|
|
41
40
|
for (const decl of symbol.getDeclarations() ?? []) {
|
|
42
41
|
if (typescript_1.default.isVariableDeclaration(decl) && decl.initializer) {
|
|
43
42
|
return resolveNodeValue(decl.initializer, checker, paramMap, seen);
|
|
@@ -45,7 +44,6 @@ function resolveNodeValue(node, checker, paramMap, seen = new Set()) {
|
|
|
45
44
|
}
|
|
46
45
|
const original = symbol;
|
|
47
46
|
symbol = (0, exportResolver_1.resolveExportedSymbol)(symbol, checker) ?? symbol;
|
|
48
|
-
// avoid alias loop
|
|
49
47
|
if (symbol !== original && (symbol.flags & typescript_1.default.SymbolFlags.Alias)) {
|
|
50
48
|
symbol = checker.getAliasedSymbol(symbol);
|
|
51
49
|
}
|
|
@@ -62,6 +60,7 @@ function resolveNodeValue(node, checker, paramMap, seen = new Set()) {
|
|
|
62
60
|
}
|
|
63
61
|
}
|
|
64
62
|
}
|
|
63
|
+
return { values: [], dynamic: true };
|
|
65
64
|
}
|
|
66
65
|
if (typescript_1.default.isPropertyAccessExpression(node)) {
|
|
67
66
|
const symbol = checker.getSymbolAtLocation(node);
|
|
@@ -70,7 +69,6 @@ function resolveNodeValue(node, checker, paramMap, seen = new Set()) {
|
|
|
70
69
|
if (s.flags & typescript_1.default.SymbolFlags.Alias) {
|
|
71
70
|
s = checker.getAliasedSymbol(s);
|
|
72
71
|
}
|
|
73
|
-
// ENUM support
|
|
74
72
|
for (const decl of s.getDeclarations() ?? []) {
|
|
75
73
|
if (typescript_1.default.isEnumMember(decl) && decl.initializer) {
|
|
76
74
|
if (typescript_1.default.isStringLiteral(decl.initializer)) {
|
|
@@ -82,7 +80,6 @@ function resolveNodeValue(node, checker, paramMap, seen = new Set()) {
|
|
|
82
80
|
}
|
|
83
81
|
}
|
|
84
82
|
}
|
|
85
|
-
// OBJECT support
|
|
86
83
|
if (typescript_1.default.isIdentifier(node.expression)) {
|
|
87
84
|
const objSymbol = checker.getSymbolAtLocation(node.expression);
|
|
88
85
|
if (objSymbol) {
|
|
@@ -102,6 +99,7 @@ function resolveNodeValue(node, checker, paramMap, seen = new Set()) {
|
|
|
102
99
|
}
|
|
103
100
|
}
|
|
104
101
|
}
|
|
102
|
+
return { values: [], dynamic: true };
|
|
105
103
|
}
|
|
106
104
|
if (typescript_1.default.isObjectLiteralExpression(node)) {
|
|
107
105
|
const values = [];
|
|
@@ -111,8 +109,7 @@ function resolveNodeValue(node, checker, paramMap, seen = new Set()) {
|
|
|
111
109
|
const name = prop.name.getText();
|
|
112
110
|
if (name === "event") {
|
|
113
111
|
const res = resolveNodeValue(prop.initializer, checker, paramMap, seen);
|
|
114
|
-
|
|
115
|
-
values.push(...res.values);
|
|
112
|
+
values.push(...res.values);
|
|
116
113
|
}
|
|
117
114
|
}
|
|
118
115
|
return { values, dynamic: true };
|
|
@@ -123,11 +120,16 @@ function resolveNodeValue(node, checker, paramMap, seen = new Set()) {
|
|
|
123
120
|
const right = resolveNodeValue(node.right, checker, paramMap, seen);
|
|
124
121
|
if (left && right) {
|
|
125
122
|
return {
|
|
126
|
-
values: left.values.flatMap(l => right.values.
|
|
123
|
+
values: left.values.flatMap(l => right.values.length
|
|
124
|
+
? right.values.map(r => l + r)
|
|
125
|
+
: [l + "*"]),
|
|
127
126
|
dynamic: true,
|
|
128
127
|
};
|
|
129
128
|
}
|
|
130
129
|
}
|
|
131
130
|
}
|
|
132
|
-
|
|
131
|
+
if (typescript_1.default.isCallExpression(node)) {
|
|
132
|
+
return { values: [], dynamic: true };
|
|
133
|
+
}
|
|
134
|
+
return { values: [], dynamic: true };
|
|
133
135
|
}
|
package/dist/engine/scanner.js
CHANGED
|
@@ -115,10 +115,12 @@ function scanSource(source, checker, config, visited = new Set(), depth = 0, inh
|
|
|
115
115
|
const idx = (0, functionAnalyzer_1.findTrackParamIndex)(resolvedFn);
|
|
116
116
|
if (idx !== null && node.arguments[idx]) {
|
|
117
117
|
const res = (0, resolver_1.resolveNodeValue)(node.arguments[idx], checker, paramMap);
|
|
118
|
-
res
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
118
|
+
if (res && res.values.length) {
|
|
119
|
+
res.values.forEach(v => {
|
|
120
|
+
if (isValidEvent(v))
|
|
121
|
+
events.add(v);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
122
124
|
handled = true;
|
|
123
125
|
}
|
|
124
126
|
}
|
|
@@ -126,10 +128,12 @@ function scanSource(source, checker, config, visited = new Set(), depth = 0, inh
|
|
|
126
128
|
if (!handled) {
|
|
127
129
|
for (const arg of node.arguments) {
|
|
128
130
|
const res = (0, resolver_1.resolveNodeValue)(arg, checker, paramMap);
|
|
129
|
-
res
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
131
|
+
if (res && res.values.length) {
|
|
132
|
+
res.values.forEach(v => {
|
|
133
|
+
if (isValidEvent(v))
|
|
134
|
+
events.add(v);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
133
137
|
}
|
|
134
138
|
}
|
|
135
139
|
// CROSS FILE
|
|
@@ -1,20 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.detectParser = detectParser;
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const fallback = (content) => ({
|
|
8
|
-
code: content,
|
|
9
|
-
deps: [],
|
|
10
|
-
});
|
|
11
|
-
function detectParser(file) {
|
|
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;
|
|
4
|
+
const universal_1 = require("./universal");
|
|
5
|
+
function detectParser() {
|
|
6
|
+
return universal_1.parseUniversal;
|
|
20
7
|
}
|
|
@@ -0,0 +1,155 @@
|
|
|
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.parseUniversal = parseUniversal;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
function extractJS(input) {
|
|
9
|
+
const result = [];
|
|
10
|
+
let i = 0;
|
|
11
|
+
const len = input.length;
|
|
12
|
+
let inString = null;
|
|
13
|
+
let escape = false;
|
|
14
|
+
while (i < len) {
|
|
15
|
+
const ch = input[i];
|
|
16
|
+
// STRING
|
|
17
|
+
if (inString) {
|
|
18
|
+
if (escape)
|
|
19
|
+
escape = false;
|
|
20
|
+
else if (ch === "\\")
|
|
21
|
+
escape = true;
|
|
22
|
+
else if (ch === inString)
|
|
23
|
+
inString = null;
|
|
24
|
+
i++;
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (ch === '"' || ch === "'" || ch === "`") {
|
|
28
|
+
inString = ch;
|
|
29
|
+
i++;
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
// { ... }
|
|
33
|
+
if (ch === "{") {
|
|
34
|
+
let depth = 1;
|
|
35
|
+
let j = i + 1;
|
|
36
|
+
let innerStr = null;
|
|
37
|
+
let innerEsc = false;
|
|
38
|
+
while (j < len && depth > 0) {
|
|
39
|
+
const c = input[j];
|
|
40
|
+
if (innerStr) {
|
|
41
|
+
if (innerEsc)
|
|
42
|
+
innerEsc = false;
|
|
43
|
+
else if (c === "\\")
|
|
44
|
+
innerEsc = true;
|
|
45
|
+
else if (c === innerStr)
|
|
46
|
+
innerStr = null;
|
|
47
|
+
j++;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
51
|
+
innerStr = c;
|
|
52
|
+
j++;
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (c === "{")
|
|
56
|
+
depth++;
|
|
57
|
+
else if (c === "}")
|
|
58
|
+
depth--;
|
|
59
|
+
j++;
|
|
60
|
+
}
|
|
61
|
+
if (depth === 0) {
|
|
62
|
+
const expr = input.slice(i + 1, j - 1).trim();
|
|
63
|
+
if (expr)
|
|
64
|
+
result.push(expr);
|
|
65
|
+
i = j;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// attr="..."
|
|
70
|
+
if (ch === "=" && (input[i + 1] === '"' || input[i + 1] === "'")) {
|
|
71
|
+
const quote = input[i + 1];
|
|
72
|
+
let j = i + 2;
|
|
73
|
+
let val = "";
|
|
74
|
+
while (j < len) {
|
|
75
|
+
const c = input[j];
|
|
76
|
+
if (c === "\\" && input[j + 1]) {
|
|
77
|
+
val += c + input[j + 1];
|
|
78
|
+
j += 2;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (c === quote)
|
|
82
|
+
break;
|
|
83
|
+
val += c;
|
|
84
|
+
j++;
|
|
85
|
+
}
|
|
86
|
+
if (val.trim())
|
|
87
|
+
result.push(val.trim());
|
|
88
|
+
i = j + 1;
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
i++;
|
|
92
|
+
}
|
|
93
|
+
// Vue / Svelte handlers
|
|
94
|
+
const extra = [
|
|
95
|
+
/@[\w-]+\s*=\s*["']([\s\S]*?)["']/g,
|
|
96
|
+
/v-on:[\w-]+\s*=\s*["']([\s\S]*?)["']/g,
|
|
97
|
+
/on:[\w-]+\s*=\s*{([\s\S]*?)}/g,
|
|
98
|
+
/on\w+\s*=\s*{([\s\S]*?)}/g,
|
|
99
|
+
];
|
|
100
|
+
for (const r of extra) {
|
|
101
|
+
const m = input.matchAll(r);
|
|
102
|
+
for (const x of m) {
|
|
103
|
+
const v = x[1]?.trim();
|
|
104
|
+
if (v)
|
|
105
|
+
result.push(v);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return result;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* - Astro
|
|
112
|
+
* - Vue
|
|
113
|
+
* - Svelte
|
|
114
|
+
* - HTML + JS
|
|
115
|
+
* - SSR / mixed files
|
|
116
|
+
*/
|
|
117
|
+
function parseUniversal(content, file) {
|
|
118
|
+
const parts = [];
|
|
119
|
+
const deps = [];
|
|
120
|
+
// Astro frontmatter
|
|
121
|
+
const fm = content.match(/^---([\s\S]*?)---/);
|
|
122
|
+
if (fm?.[1])
|
|
123
|
+
parts.push(fm[1]);
|
|
124
|
+
// <script src="">
|
|
125
|
+
const scriptSrc = content.matchAll(/<script\b[^>]*?\bsrc=["'](.+?)["'][^>]*>/g);
|
|
126
|
+
for (const s of scriptSrc) {
|
|
127
|
+
const src = s[1];
|
|
128
|
+
const resolved = src.startsWith("/")
|
|
129
|
+
? path_1.default.resolve(process.cwd(), "." + src)
|
|
130
|
+
: path_1.default.resolve(path_1.default.dirname(file), src);
|
|
131
|
+
deps.push(resolved);
|
|
132
|
+
}
|
|
133
|
+
// inline <script>
|
|
134
|
+
const scripts = content.matchAll(/<script\b[^>]*>([\s\S]*?)<\/script>/g);
|
|
135
|
+
for (const m of scripts) {
|
|
136
|
+
if (m[1].trim())
|
|
137
|
+
parts.push(m[1]);
|
|
138
|
+
}
|
|
139
|
+
// JS <script>
|
|
140
|
+
const noScripts = content.replace(/<script[\s\S]*?<\/script>/g, "");
|
|
141
|
+
const noHtml = noScripts
|
|
142
|
+
.replace(/<[^>]+>/g, "\n")
|
|
143
|
+
.replace(/\n+/g, "\n");
|
|
144
|
+
if (noHtml.trim())
|
|
145
|
+
parts.push(noHtml);
|
|
146
|
+
// expressions
|
|
147
|
+
const extracted = extractJS(content);
|
|
148
|
+
for (const e of extracted) {
|
|
149
|
+
parts.push(e + ";");
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
code: [...new Set(parts)].join("\n"),
|
|
153
|
+
deps,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
@@ -1,18 +1,20 @@
|
|
|
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.processFile = processFile;
|
|
4
|
-
const
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const universal_1 = require("./parsers/universal");
|
|
5
9
|
function processFile(file, content) {
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const virtualFile =
|
|
9
|
-
file.
|
|
10
|
-
file.endsWith(".astro")
|
|
11
|
-
? file + ".tsx"
|
|
10
|
+
const { code, deps } = (0, universal_1.parseUniversal)(content, file);
|
|
11
|
+
const ext = path_1.default.extname(file);
|
|
12
|
+
const virtualFile = /\.(vue|svelte|astro|html)$/i.test(file)
|
|
13
|
+
? file.replace(ext, "") + ".tsx"
|
|
12
14
|
: file;
|
|
13
15
|
return {
|
|
14
|
-
content:
|
|
16
|
+
content: code || "",
|
|
15
17
|
virtualFile,
|
|
16
|
-
deps:
|
|
18
|
+
deps: [...new Set(deps.filter(Boolean))],
|
|
17
19
|
};
|
|
18
20
|
}
|
package/package.json
CHANGED
package/src/engine/resolver.ts
CHANGED
|
@@ -11,12 +11,13 @@ export function resolveNodeValue(
|
|
|
11
11
|
checker: ts.TypeChecker,
|
|
12
12
|
paramMap?: Map<string, ts.Expression>,
|
|
13
13
|
seen = new Set<ts.Node>()
|
|
14
|
-
): ResolveResult
|
|
14
|
+
): ResolveResult {
|
|
15
15
|
|
|
16
|
-
if (seen.has(node))
|
|
16
|
+
if (seen.has(node)) {
|
|
17
|
+
return { values: [], dynamic: true };
|
|
18
|
+
}
|
|
17
19
|
seen.add(node);
|
|
18
20
|
|
|
19
|
-
// param mapping
|
|
20
21
|
if (ts.isIdentifier(node) && paramMap?.has(node.text)) {
|
|
21
22
|
return resolveNodeValue(
|
|
22
23
|
paramMap.get(node.text)!,
|
|
@@ -46,16 +47,15 @@ export function resolveNodeValue(
|
|
|
46
47
|
const b = resolveNodeValue(node.whenFalse, checker, paramMap, seen);
|
|
47
48
|
|
|
48
49
|
return {
|
|
49
|
-
values: [...new Set([...(a
|
|
50
|
+
values: [...new Set([...(a.values ?? []), ...(b.values ?? [])])],
|
|
50
51
|
dynamic: true,
|
|
51
52
|
};
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
if (ts.isIdentifier(node)) {
|
|
55
56
|
let symbol = checker.getSymbolAtLocation(node);
|
|
56
|
-
if (!symbol) return
|
|
57
|
+
if (!symbol) return { values: [], dynamic: true };
|
|
57
58
|
|
|
58
|
-
// variable inline resolve FIRST
|
|
59
59
|
for (const decl of symbol.getDeclarations() ?? []) {
|
|
60
60
|
if (ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
61
61
|
return resolveNodeValue(
|
|
@@ -71,7 +71,6 @@ export function resolveNodeValue(
|
|
|
71
71
|
|
|
72
72
|
symbol = resolveExportedSymbol(symbol, checker) ?? symbol;
|
|
73
73
|
|
|
74
|
-
// avoid alias loop
|
|
75
74
|
if (symbol !== original && (symbol.flags & ts.SymbolFlags.Alias)) {
|
|
76
75
|
symbol = checker.getAliasedSymbol(symbol);
|
|
77
76
|
}
|
|
@@ -95,6 +94,8 @@ export function resolveNodeValue(
|
|
|
95
94
|
}
|
|
96
95
|
}
|
|
97
96
|
}
|
|
97
|
+
|
|
98
|
+
return { values: [], dynamic: true };
|
|
98
99
|
}
|
|
99
100
|
|
|
100
101
|
if (ts.isPropertyAccessExpression(node)) {
|
|
@@ -107,7 +108,6 @@ export function resolveNodeValue(
|
|
|
107
108
|
s = checker.getAliasedSymbol(s);
|
|
108
109
|
}
|
|
109
110
|
|
|
110
|
-
// ENUM support
|
|
111
111
|
for (const decl of s.getDeclarations() ?? []) {
|
|
112
112
|
if (ts.isEnumMember(decl) && decl.initializer) {
|
|
113
113
|
if (ts.isStringLiteral(decl.initializer)) {
|
|
@@ -120,7 +120,6 @@ export function resolveNodeValue(
|
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
// OBJECT support
|
|
124
123
|
if (ts.isIdentifier(node.expression)) {
|
|
125
124
|
const objSymbol = checker.getSymbolAtLocation(node.expression);
|
|
126
125
|
|
|
@@ -149,6 +148,8 @@ export function resolveNodeValue(
|
|
|
149
148
|
}
|
|
150
149
|
}
|
|
151
150
|
}
|
|
151
|
+
|
|
152
|
+
return { values: [], dynamic: true };
|
|
152
153
|
}
|
|
153
154
|
|
|
154
155
|
if (ts.isObjectLiteralExpression(node)) {
|
|
@@ -161,7 +162,7 @@ export function resolveNodeValue(
|
|
|
161
162
|
|
|
162
163
|
if (name === "event") {
|
|
163
164
|
const res = resolveNodeValue(prop.initializer, checker, paramMap, seen);
|
|
164
|
-
|
|
165
|
+
values.push(...res.values);
|
|
165
166
|
}
|
|
166
167
|
}
|
|
167
168
|
|
|
@@ -176,7 +177,9 @@ export function resolveNodeValue(
|
|
|
176
177
|
if (left && right) {
|
|
177
178
|
return {
|
|
178
179
|
values: left.values.flatMap(l =>
|
|
179
|
-
right.values.
|
|
180
|
+
right.values.length
|
|
181
|
+
? right.values.map(r => l + r)
|
|
182
|
+
: [l + "*"]
|
|
180
183
|
),
|
|
181
184
|
dynamic: true,
|
|
182
185
|
};
|
|
@@ -184,5 +187,9 @@ export function resolveNodeValue(
|
|
|
184
187
|
}
|
|
185
188
|
}
|
|
186
189
|
|
|
187
|
-
|
|
190
|
+
if (ts.isCallExpression(node)) {
|
|
191
|
+
return { values: [], dynamic: true };
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return { values: [], dynamic: true };
|
|
188
195
|
}
|
package/src/engine/scanner.ts
CHANGED
|
@@ -166,9 +166,11 @@ export function scanSource(
|
|
|
166
166
|
paramMap
|
|
167
167
|
);
|
|
168
168
|
|
|
169
|
-
res
|
|
170
|
-
|
|
171
|
-
|
|
169
|
+
if (res && res.values.length) {
|
|
170
|
+
res.values.forEach(v => {
|
|
171
|
+
if (isValidEvent(v)) events.add(v);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
172
174
|
|
|
173
175
|
handled = true;
|
|
174
176
|
}
|
|
@@ -179,9 +181,11 @@ export function scanSource(
|
|
|
179
181
|
for (const arg of node.arguments) {
|
|
180
182
|
const res = resolveNodeValue(arg, checker, paramMap);
|
|
181
183
|
|
|
182
|
-
res
|
|
183
|
-
|
|
184
|
-
|
|
184
|
+
if (res && res.values.length) {
|
|
185
|
+
res.values.forEach(v => {
|
|
186
|
+
if (isValidEvent(v)) events.add(v);
|
|
187
|
+
});
|
|
188
|
+
}
|
|
185
189
|
}
|
|
186
190
|
}
|
|
187
191
|
|
|
@@ -1,19 +1,6 @@
|
|
|
1
1
|
import { Parser } from "../../types";
|
|
2
|
-
import {
|
|
3
|
-
import { parseSvelte } from "./svelte";
|
|
4
|
-
import { parseAstro } from "./astro";
|
|
2
|
+
import { parseUniversal } from "./universal";
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
deps: [],
|
|
9
|
-
});
|
|
10
|
-
|
|
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;
|
|
4
|
+
export function detectParser(): Parser {
|
|
5
|
+
return parseUniversal;
|
|
19
6
|
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { ParseResult } from "../../types";
|
|
3
|
+
|
|
4
|
+
function extractJS(input: string): string[] {
|
|
5
|
+
const result: string[] = [];
|
|
6
|
+
|
|
7
|
+
let i = 0;
|
|
8
|
+
const len = input.length;
|
|
9
|
+
|
|
10
|
+
let inString: '"' | "'" | "`" | null = null;
|
|
11
|
+
let escape = false;
|
|
12
|
+
|
|
13
|
+
while (i < len) {
|
|
14
|
+
const ch = input[i];
|
|
15
|
+
|
|
16
|
+
// STRING
|
|
17
|
+
if (inString) {
|
|
18
|
+
if (escape) escape = false;
|
|
19
|
+
else if (ch === "\\") escape = true;
|
|
20
|
+
else if (ch === inString) inString = null;
|
|
21
|
+
|
|
22
|
+
i++;
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (ch === '"' || ch === "'" || ch === "`") {
|
|
27
|
+
inString = ch;
|
|
28
|
+
i++;
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// { ... }
|
|
33
|
+
if (ch === "{") {
|
|
34
|
+
let depth = 1;
|
|
35
|
+
let j = i + 1;
|
|
36
|
+
|
|
37
|
+
let innerStr: '"' | "'" | "`" | null = null;
|
|
38
|
+
let innerEsc = false;
|
|
39
|
+
|
|
40
|
+
while (j < len && depth > 0) {
|
|
41
|
+
const c = input[j];
|
|
42
|
+
|
|
43
|
+
if (innerStr) {
|
|
44
|
+
if (innerEsc) innerEsc = false;
|
|
45
|
+
else if (c === "\\") innerEsc = true;
|
|
46
|
+
else if (c === innerStr) innerStr = null;
|
|
47
|
+
j++;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
52
|
+
innerStr = c;
|
|
53
|
+
j++;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (c === "{") depth++;
|
|
58
|
+
else if (c === "}") depth--;
|
|
59
|
+
|
|
60
|
+
j++;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (depth === 0) {
|
|
64
|
+
const expr = input.slice(i + 1, j - 1).trim();
|
|
65
|
+
if (expr) result.push(expr);
|
|
66
|
+
i = j;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// attr="..."
|
|
72
|
+
if (ch === "=" && (input[i + 1] === '"' || input[i + 1] === "'")) {
|
|
73
|
+
const quote = input[i + 1];
|
|
74
|
+
let j = i + 2;
|
|
75
|
+
let val = "";
|
|
76
|
+
|
|
77
|
+
while (j < len) {
|
|
78
|
+
const c = input[j];
|
|
79
|
+
|
|
80
|
+
if (c === "\\" && input[j + 1]) {
|
|
81
|
+
val += c + input[j + 1];
|
|
82
|
+
j += 2;
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (c === quote) break;
|
|
87
|
+
|
|
88
|
+
val += c;
|
|
89
|
+
j++;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (val.trim()) result.push(val.trim());
|
|
93
|
+
|
|
94
|
+
i = j + 1;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
i++;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Vue / Svelte handlers
|
|
102
|
+
const extra = [
|
|
103
|
+
/@[\w-]+\s*=\s*["']([\s\S]*?)["']/g,
|
|
104
|
+
/v-on:[\w-]+\s*=\s*["']([\s\S]*?)["']/g,
|
|
105
|
+
/on:[\w-]+\s*=\s*{([\s\S]*?)}/g,
|
|
106
|
+
/on\w+\s*=\s*{([\s\S]*?)}/g,
|
|
107
|
+
];
|
|
108
|
+
|
|
109
|
+
for (const r of extra) {
|
|
110
|
+
const m = input.matchAll(r);
|
|
111
|
+
for (const x of m) {
|
|
112
|
+
const v = x[1]?.trim();
|
|
113
|
+
if (v) result.push(v);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* - Astro
|
|
122
|
+
* - Vue
|
|
123
|
+
* - Svelte
|
|
124
|
+
* - HTML + JS
|
|
125
|
+
* - SSR / mixed files
|
|
126
|
+
*/
|
|
127
|
+
|
|
128
|
+
export function parseUniversal(
|
|
129
|
+
content: string,
|
|
130
|
+
file: string
|
|
131
|
+
): ParseResult {
|
|
132
|
+
const parts: string[] = [];
|
|
133
|
+
const deps: string[] = [];
|
|
134
|
+
|
|
135
|
+
// Astro frontmatter
|
|
136
|
+
const fm = content.match(/^---([\s\S]*?)---/);
|
|
137
|
+
if (fm?.[1]) parts.push(fm[1]);
|
|
138
|
+
|
|
139
|
+
// <script src="">
|
|
140
|
+
const scriptSrc = content.matchAll(
|
|
141
|
+
/<script\b[^>]*?\bsrc=["'](.+?)["'][^>]*>/g
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
for (const s of scriptSrc) {
|
|
145
|
+
const src = s[1];
|
|
146
|
+
|
|
147
|
+
const resolved = src.startsWith("/")
|
|
148
|
+
? path.resolve(process.cwd(), "." + src)
|
|
149
|
+
: path.resolve(path.dirname(file), src);
|
|
150
|
+
|
|
151
|
+
deps.push(resolved);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// inline <script>
|
|
155
|
+
const scripts = content.matchAll(
|
|
156
|
+
/<script\b[^>]*>([\s\S]*?)<\/script>/g
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
for (const m of scripts) {
|
|
160
|
+
if (m[1].trim()) parts.push(m[1]);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// JS <script>
|
|
164
|
+
const noScripts = content.replace(
|
|
165
|
+
/<script[\s\S]*?<\/script>/g,
|
|
166
|
+
""
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
const noHtml = noScripts
|
|
170
|
+
.replace(/<[^>]+>/g, "\n")
|
|
171
|
+
.replace(/\n+/g, "\n");
|
|
172
|
+
|
|
173
|
+
if (noHtml.trim()) parts.push(noHtml);
|
|
174
|
+
|
|
175
|
+
// expressions
|
|
176
|
+
const extracted = extractJS(content);
|
|
177
|
+
|
|
178
|
+
for (const e of extracted) {
|
|
179
|
+
parts.push(e + ";");
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return {
|
|
183
|
+
code: [...new Set(parts)].join("\n"),
|
|
184
|
+
deps,
|
|
185
|
+
};
|
|
186
|
+
}
|
package/src/utils/processFile.ts
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { parseUniversal } from "./parsers/universal";
|
|
2
3
|
|
|
3
4
|
export function processFile(file: string, content: string) {
|
|
4
|
-
const
|
|
5
|
+
const { code, deps } = parseUniversal(content, file);
|
|
5
6
|
|
|
6
|
-
const
|
|
7
|
+
const ext = path.extname(file);
|
|
7
8
|
|
|
8
9
|
const virtualFile =
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
file.endsWith(".astro")
|
|
12
|
-
? file + ".tsx"
|
|
10
|
+
/\.(vue|svelte|astro|html)$/i.test(file)
|
|
11
|
+
? file.replace(ext, "") + ".tsx"
|
|
13
12
|
: file;
|
|
14
13
|
|
|
15
14
|
return {
|
|
16
|
-
content:
|
|
15
|
+
content: code || "",
|
|
17
16
|
virtualFile,
|
|
18
|
-
deps:
|
|
17
|
+
deps: [...new Set(deps.filter(Boolean))],
|
|
19
18
|
};
|
|
20
19
|
}
|
|
@@ -1,49 +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.parseAstro = parseAstro;
|
|
7
|
-
const path_1 = __importDefault(require("path"));
|
|
8
|
-
const utils_1 = require("./utils");
|
|
9
|
-
function parseAstro(content, file) {
|
|
10
|
-
const parts = [];
|
|
11
|
-
const deps = [];
|
|
12
|
-
// frontmatter
|
|
13
|
-
const frontmatter = content.match(/^---([\s\S]*?)---/);
|
|
14
|
-
if (frontmatter?.[1]) {
|
|
15
|
-
parts.push(frontmatter[1]);
|
|
16
|
-
}
|
|
17
|
-
// scripts
|
|
18
|
-
const scripts = content.matchAll(/<script([^>]*)>([\s\S]*?)<\/script>/g);
|
|
19
|
-
for (const m of scripts) {
|
|
20
|
-
const attrs = m[1];
|
|
21
|
-
const body = m[2];
|
|
22
|
-
// external script
|
|
23
|
-
if (attrs.includes("src")) {
|
|
24
|
-
const src = attrs.match(/src=["'](.+?)["']/)?.[1];
|
|
25
|
-
if (!src)
|
|
26
|
-
continue;
|
|
27
|
-
let resolved;
|
|
28
|
-
if (src.startsWith("/")) {
|
|
29
|
-
resolved = path_1.default.join(process.cwd(), src); // FIX
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
resolved = path_1.default.resolve(path_1.default.dirname(file), src);
|
|
33
|
-
}
|
|
34
|
-
deps.push(resolved);
|
|
35
|
-
continue;
|
|
36
|
-
}
|
|
37
|
-
parts.push(body);
|
|
38
|
-
const imports = body.matchAll(/import\s+.*?from\s+["'](.+?)["']/g);
|
|
39
|
-
for (const im of imports) {
|
|
40
|
-
const resolved = (0, utils_1.resolveImport)(file, im[1]);
|
|
41
|
-
if (resolved)
|
|
42
|
-
deps.push(resolved);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return {
|
|
46
|
-
code: parts.join("\n"),
|
|
47
|
-
deps,
|
|
48
|
-
};
|
|
49
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.parseSvelte = parseSvelte;
|
|
4
|
-
const utils_1 = require("./utils");
|
|
5
|
-
function parseSvelte(content, file) {
|
|
6
|
-
const parts = [];
|
|
7
|
-
const deps = [];
|
|
8
|
-
// script
|
|
9
|
-
const scripts = content.matchAll(/<script[^>]*>([\s\S]*?)<\/script>/g);
|
|
10
|
-
for (const m of scripts) {
|
|
11
|
-
const code = m[1];
|
|
12
|
-
parts.push(code);
|
|
13
|
-
// imports
|
|
14
|
-
const imports = code.matchAll(/import\s+.*?from\s+["'](.+?)["']/g);
|
|
15
|
-
for (const im of imports) {
|
|
16
|
-
const resolved = (0, utils_1.resolveImport)(file, im[1]);
|
|
17
|
-
if (resolved)
|
|
18
|
-
deps.push(resolved);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
// handlers
|
|
22
|
-
const handlers = content.matchAll(/on:\w+=\{([^}]+)\}/g);
|
|
23
|
-
for (const h of handlers) {
|
|
24
|
-
parts.push(h[1] + ";");
|
|
25
|
-
}
|
|
26
|
-
return {
|
|
27
|
-
code: parts.join("\n"),
|
|
28
|
-
deps,
|
|
29
|
-
};
|
|
30
|
-
}
|
|
@@ -1,59 +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.parseVue = parseVue;
|
|
7
|
-
const path_1 = __importDefault(require("path"));
|
|
8
|
-
const utils_1 = require("./utils");
|
|
9
|
-
function parseVue(content, file) {
|
|
10
|
-
const parts = [];
|
|
11
|
-
const deps = [];
|
|
12
|
-
// SCRIPT
|
|
13
|
-
const scripts = content.matchAll(/<script([^>]*)>([\s\S]*?)<\/script>/g);
|
|
14
|
-
for (const m of scripts) {
|
|
15
|
-
const attrs = m[1];
|
|
16
|
-
const body = m[2];
|
|
17
|
-
if (attrs.includes("src")) {
|
|
18
|
-
const src = attrs.match(/src=["'](.+?)["']/)?.[1];
|
|
19
|
-
if (!src)
|
|
20
|
-
continue;
|
|
21
|
-
const resolved = src.startsWith("/")
|
|
22
|
-
? path_1.default.join(process.cwd(), src)
|
|
23
|
-
: path_1.default.resolve(path_1.default.dirname(file), src);
|
|
24
|
-
deps.push(resolved);
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
parts.push(body);
|
|
28
|
-
// imports
|
|
29
|
-
const imports = body.matchAll(/import\s+.*?from\s+["'](.+?)["']/g);
|
|
30
|
-
for (const im of imports) {
|
|
31
|
-
const resolved = (0, utils_1.resolveImport)(file, im[1]);
|
|
32
|
-
if (resolved)
|
|
33
|
-
deps.push(resolved);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
// TEMPLATE
|
|
37
|
-
const templateMatch = content.match(/<template[^>]*>([\s\S]*?)<\/template>/);
|
|
38
|
-
let template = templateMatch?.[1] ?? "";
|
|
39
|
-
template = template.replace(/<!--[\s\S]*?-->/g, "");
|
|
40
|
-
// @click
|
|
41
|
-
const handlers = template.matchAll(/@[\w-]+="([^"]+)"/g);
|
|
42
|
-
for (const h of handlers) {
|
|
43
|
-
parts.push(h[1] + ";");
|
|
44
|
-
}
|
|
45
|
-
// v-on
|
|
46
|
-
const vOn = template.matchAll(/v-on:[\w-]+="([^"]+)"/g);
|
|
47
|
-
for (const v of vOn) {
|
|
48
|
-
parts.push(v[1] + ";");
|
|
49
|
-
}
|
|
50
|
-
// :bind
|
|
51
|
-
const binds = template.matchAll(/:[\w-]+="([^"]+)"/g);
|
|
52
|
-
for (const b of binds) {
|
|
53
|
-
parts.push(b[1] + ";");
|
|
54
|
-
}
|
|
55
|
-
return {
|
|
56
|
-
code: parts.join("\n"),
|
|
57
|
-
deps,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import path from "path";
|
|
2
|
-
import { ParseResult } from "../../types";
|
|
3
|
-
import { resolveImport } from "./utils";
|
|
4
|
-
|
|
5
|
-
export function parseAstro(content: string, file: string): ParseResult {
|
|
6
|
-
const parts: string[] = [];
|
|
7
|
-
const deps: string[] = [];
|
|
8
|
-
|
|
9
|
-
// frontmatter
|
|
10
|
-
const frontmatter = content.match(/^---([\s\S]*?)---/);
|
|
11
|
-
if (frontmatter?.[1]) {
|
|
12
|
-
parts.push(frontmatter[1]);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// scripts
|
|
16
|
-
const scripts = content.matchAll(/<script([^>]*)>([\s\S]*?)<\/script>/g);
|
|
17
|
-
|
|
18
|
-
for (const m of scripts) {
|
|
19
|
-
const attrs = m[1];
|
|
20
|
-
const body = m[2];
|
|
21
|
-
|
|
22
|
-
// external script
|
|
23
|
-
if (attrs.includes("src")) {
|
|
24
|
-
const src = attrs.match(/src=["'](.+?)["']/)?.[1];
|
|
25
|
-
if (!src) continue;
|
|
26
|
-
|
|
27
|
-
let resolved: string;
|
|
28
|
-
|
|
29
|
-
if (src.startsWith("/")) {
|
|
30
|
-
resolved = path.join(process.cwd(), src); // FIX
|
|
31
|
-
} else {
|
|
32
|
-
resolved = path.resolve(path.dirname(file), src);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
deps.push(resolved);
|
|
36
|
-
continue;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
parts.push(body);
|
|
40
|
-
|
|
41
|
-
const imports = body.matchAll(/import\s+.*?from\s+["'](.+?)["']/g);
|
|
42
|
-
|
|
43
|
-
for (const im of imports) {
|
|
44
|
-
const resolved = resolveImport(file, im[1]);
|
|
45
|
-
if (resolved) deps.push(resolved);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return {
|
|
50
|
-
code: parts.join("\n"),
|
|
51
|
-
deps,
|
|
52
|
-
};
|
|
53
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { ParseResult } from "../../types";
|
|
2
|
-
import { resolveImport } from "./utils";
|
|
3
|
-
|
|
4
|
-
export function parseSvelte(content: string, file: string): ParseResult {
|
|
5
|
-
const parts: string[] = [];
|
|
6
|
-
const deps: string[] = [];
|
|
7
|
-
|
|
8
|
-
// script
|
|
9
|
-
const scripts = content.matchAll(/<script[^>]*>([\s\S]*?)<\/script>/g);
|
|
10
|
-
|
|
11
|
-
for (const m of scripts) {
|
|
12
|
-
const code = m[1];
|
|
13
|
-
|
|
14
|
-
parts.push(code);
|
|
15
|
-
|
|
16
|
-
// imports
|
|
17
|
-
const imports = code.matchAll(/import\s+.*?from\s+["'](.+?)["']/g);
|
|
18
|
-
|
|
19
|
-
for (const im of imports) {
|
|
20
|
-
const resolved = resolveImport(file, im[1]);
|
|
21
|
-
if (resolved) deps.push(resolved);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// handlers
|
|
26
|
-
const handlers = content.matchAll(/on:\w+=\{([^}]+)\}/g);
|
|
27
|
-
|
|
28
|
-
for (const h of handlers) {
|
|
29
|
-
parts.push(h[1] + ";");
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return {
|
|
33
|
-
code: parts.join("\n"),
|
|
34
|
-
deps,
|
|
35
|
-
};
|
|
36
|
-
}
|
package/src/utils/parsers/vue.ts
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import path from "path";
|
|
2
|
-
import { ParseResult } from "../../types";
|
|
3
|
-
import { resolveImport } from "./utils";
|
|
4
|
-
|
|
5
|
-
export function parseVue(content: string, file: string): ParseResult {
|
|
6
|
-
const parts: string[] = [];
|
|
7
|
-
const deps: string[] = [];
|
|
8
|
-
|
|
9
|
-
// SCRIPT
|
|
10
|
-
const scripts = content.matchAll(/<script([^>]*)>([\s\S]*?)<\/script>/g);
|
|
11
|
-
|
|
12
|
-
for (const m of scripts) {
|
|
13
|
-
const attrs = m[1];
|
|
14
|
-
const body = m[2];
|
|
15
|
-
|
|
16
|
-
if (attrs.includes("src")) {
|
|
17
|
-
const src = attrs.match(/src=["'](.+?)["']/)?.[1];
|
|
18
|
-
if (!src) continue;
|
|
19
|
-
|
|
20
|
-
const resolved = src.startsWith("/")
|
|
21
|
-
? path.join(process.cwd(), src)
|
|
22
|
-
: path.resolve(path.dirname(file), src);
|
|
23
|
-
|
|
24
|
-
deps.push(resolved);
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
parts.push(body);
|
|
29
|
-
|
|
30
|
-
// imports
|
|
31
|
-
const imports = body.matchAll(/import\s+.*?from\s+["'](.+?)["']/g);
|
|
32
|
-
|
|
33
|
-
for (const im of imports) {
|
|
34
|
-
const resolved = resolveImport(file, im[1]);
|
|
35
|
-
if (resolved) deps.push(resolved);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// TEMPLATE
|
|
40
|
-
const templateMatch = content.match(/<template[^>]*>([\s\S]*?)<\/template>/);
|
|
41
|
-
let template = templateMatch?.[1] ?? "";
|
|
42
|
-
|
|
43
|
-
template = template.replace(/<!--[\s\S]*?-->/g, "");
|
|
44
|
-
|
|
45
|
-
// @click
|
|
46
|
-
const handlers = template.matchAll(/@[\w-]+="([^"]+)"/g);
|
|
47
|
-
for (const h of handlers) {
|
|
48
|
-
parts.push(h[1] + ";");
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// v-on
|
|
52
|
-
const vOn = template.matchAll(/v-on:[\w-]+="([^"]+)"/g);
|
|
53
|
-
for (const v of vOn) {
|
|
54
|
-
parts.push(v[1] + ";");
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// :bind
|
|
58
|
-
const binds = template.matchAll(/:[\w-]+="([^"]+)"/g);
|
|
59
|
-
for (const b of binds) {
|
|
60
|
-
parts.push(b[1] + ";");
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return {
|
|
64
|
-
code: parts.join("\n"),
|
|
65
|
-
deps,
|
|
66
|
-
};
|
|
67
|
-
}
|