@eventra_dev/eventra-cli 0.0.4 → 0.0.6
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/.github/workflows/release.yml +3 -0
- package/README.md +125 -44
- package/dist/commands/init.js +4 -1
- package/dist/commands/send.js +41 -7
- package/dist/commands/sync.js +35 -194
- package/dist/index.js +0 -0
- package/dist/types.js +2 -0
- package/dist/utils/config.js +4 -1
- package/dist/utils/extract.js +44 -0
- package/dist/utils/parsers/astro.js +6 -0
- package/dist/utils/parsers/router.js +12 -0
- package/dist/utils/parsers/svelte.js +6 -0
- package/dist/utils/parsers/vue.js +18 -0
- package/dist/utils/scanners/component-wrappers.js +55 -0
- package/dist/utils/scanners/function-wrappers.js +45 -0
- package/dist/utils/scanners/track.js +42 -0
- package/package.json +6 -4
- package/src/commands/init.ts +4 -1
- package/src/commands/send.ts +101 -17
- package/src/commands/sync.ts +66 -345
- package/src/types.ts +20 -0
- package/src/utils/config.ts +24 -7
- package/src/utils/extract.ts +74 -0
- package/src/utils/parsers/astro.ts +5 -0
- package/src/utils/parsers/router.ts +14 -0
- package/src/utils/parsers/svelte.ts +5 -0
- package/src/utils/parsers/vue.ts +25 -0
- package/src/utils/scanners/component-wrappers.ts +108 -0
- package/src/utils/scanners/function-wrappers.ts +98 -0
- package/src/utils/scanners/track.ts +84 -0
- package/tests/fixtures/backend/express/app.ts +78 -0
- package/tests/fixtures/backend/nest/service.ts +70 -0
- package/tests/fixtures/backend/node/index.ts +63 -0
- package/tests/fixtures/frontend/next/page.tsx +101 -0
- package/tests/fixtures/frontend/react/App.tsx +104 -0
- package/tests/fixtures/frontend/vue/App.vue +83 -0
- package/tests/fixtures/wrappers/component/test.tsx +62 -0
- package/tests/fixtures/wrappers/function/test.ts +60 -0
- package/tests/run.ts +120 -0
- package/tsconfig.json +2 -0
package/src/commands/sync.ts
CHANGED
|
@@ -1,31 +1,39 @@
|
|
|
1
|
-
import { Project, SyntaxKind } from "ts-morph";
|
|
2
|
-
import fg from "fast-glob";
|
|
3
1
|
import chalk from "chalk";
|
|
4
|
-
import
|
|
2
|
+
import fg from "fast-glob";
|
|
3
|
+
import { Project } from "ts-morph";
|
|
4
|
+
import fs from "fs/promises";
|
|
5
|
+
|
|
5
6
|
import {
|
|
6
7
|
loadConfig,
|
|
7
8
|
saveConfig
|
|
8
9
|
} from "../utils/config";
|
|
9
10
|
|
|
11
|
+
import { detectParser } from "../utils/parsers/router";
|
|
12
|
+
import { parseVue } from "../utils/parsers/vue";
|
|
13
|
+
import { parseSvelte } from "../utils/parsers/svelte";
|
|
14
|
+
import { parseAstro } from "../utils/parsers/astro";
|
|
15
|
+
|
|
16
|
+
import { scanTrack } from "../utils/scanners/track";
|
|
17
|
+
import { scanFunctionWrappers } from "../utils/scanners/function-wrappers";
|
|
18
|
+
import { scanComponentWrappers } from "../utils/scanners/component-wrappers";
|
|
19
|
+
|
|
10
20
|
export async function sync() {
|
|
11
|
-
|
|
21
|
+
const config = await loadConfig();
|
|
12
22
|
|
|
13
23
|
if (!config) {
|
|
14
24
|
console.log(
|
|
15
|
-
chalk.red(
|
|
16
|
-
"Run 'eventra init' first"
|
|
17
|
-
)
|
|
25
|
+
chalk.red("Run 'eventra init'")
|
|
18
26
|
);
|
|
19
27
|
return;
|
|
20
28
|
}
|
|
21
29
|
|
|
22
|
-
const events = new Set<string>();
|
|
23
|
-
const project = new Project();
|
|
24
|
-
|
|
25
30
|
console.log(
|
|
26
31
|
chalk.blue("Scanning project...")
|
|
27
32
|
);
|
|
28
33
|
|
|
34
|
+
const project = new Project();
|
|
35
|
+
const events = new Set<string>();
|
|
36
|
+
|
|
29
37
|
const files = await fg(
|
|
30
38
|
config.sync.include,
|
|
31
39
|
{
|
|
@@ -33,365 +41,78 @@ export async function sync() {
|
|
|
33
41
|
}
|
|
34
42
|
);
|
|
35
43
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
sourceFile.getDescendantsOfKind(
|
|
43
|
-
SyntaxKind.CallExpression
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
for (const call of calls) {
|
|
47
|
-
const expression =
|
|
48
|
-
call.getExpression();
|
|
49
|
-
|
|
50
|
-
if (
|
|
51
|
-
expression.getKind() ===
|
|
52
|
-
SyntaxKind.PropertyAccessExpression
|
|
53
|
-
) {
|
|
54
|
-
const prop =
|
|
55
|
-
expression.asKind(
|
|
56
|
-
SyntaxKind.PropertyAccessExpression
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
if (!prop) continue;
|
|
60
|
-
|
|
61
|
-
if (prop.getName() !== "track")
|
|
62
|
-
continue;
|
|
63
|
-
|
|
64
|
-
const args =
|
|
65
|
-
call.getArguments();
|
|
66
|
-
|
|
67
|
-
const eventArg =
|
|
68
|
-
args[0];
|
|
69
|
-
|
|
70
|
-
if (!eventArg) continue;
|
|
71
|
-
|
|
72
|
-
let event: string | null = null;
|
|
73
|
-
|
|
74
|
-
// "event"
|
|
75
|
-
if (
|
|
76
|
-
eventArg.getKind() ===
|
|
77
|
-
SyntaxKind.StringLiteral
|
|
78
|
-
) {
|
|
79
|
-
event =
|
|
80
|
-
eventArg
|
|
81
|
-
.asKindOrThrow(
|
|
82
|
-
SyntaxKind.StringLiteral
|
|
83
|
-
)
|
|
84
|
-
.getLiteralText();
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// `event`
|
|
88
|
-
if (
|
|
89
|
-
eventArg.getKind() ===
|
|
90
|
-
SyntaxKind.NoSubstitutionTemplateLiteral
|
|
91
|
-
) {
|
|
92
|
-
event =
|
|
93
|
-
eventArg
|
|
94
|
-
.asKindOrThrow(
|
|
95
|
-
SyntaxKind.NoSubstitutionTemplateLiteral
|
|
96
|
-
)
|
|
97
|
-
.getLiteralText();
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (event) {
|
|
101
|
-
events.add(event);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
console.log(
|
|
108
|
-
chalk.green(
|
|
109
|
-
`Found ${events.size} track events`
|
|
110
|
-
)
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
// wrappers setup
|
|
114
|
-
if (!config.wrappers.length) {
|
|
115
|
-
const { useWrapper } =
|
|
116
|
-
await inquirer.prompt([
|
|
117
|
-
{
|
|
118
|
-
type: "confirm",
|
|
119
|
-
name: "useWrapper",
|
|
120
|
-
message:
|
|
121
|
-
"Use wrapper components?",
|
|
122
|
-
default: true
|
|
123
|
-
}
|
|
124
|
-
]);
|
|
125
|
-
|
|
126
|
-
if (useWrapper) {
|
|
127
|
-
const wrappers = [];
|
|
128
|
-
|
|
129
|
-
let addMore = true;
|
|
130
|
-
|
|
131
|
-
while (addMore) {
|
|
132
|
-
const answers =
|
|
133
|
-
await inquirer.prompt([
|
|
134
|
-
{
|
|
135
|
-
type: "input",
|
|
136
|
-
name: "name",
|
|
137
|
-
message:
|
|
138
|
-
"Wrapper component name:"
|
|
139
|
-
},
|
|
140
|
-
{
|
|
141
|
-
type: "input",
|
|
142
|
-
name: "prop",
|
|
143
|
-
message:
|
|
144
|
-
"Event prop name:"
|
|
145
|
-
}
|
|
146
|
-
]);
|
|
147
|
-
|
|
148
|
-
wrappers.push({
|
|
149
|
-
name: answers.name,
|
|
150
|
-
prop: answers.prop
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
const more =
|
|
154
|
-
await inquirer.prompt([
|
|
155
|
-
{
|
|
156
|
-
type: "confirm",
|
|
157
|
-
name: "more",
|
|
158
|
-
message:
|
|
159
|
-
"Add another wrapper?",
|
|
160
|
-
default: false
|
|
161
|
-
}
|
|
162
|
-
]);
|
|
163
|
-
|
|
164
|
-
addMore = more.more;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
config.wrappers = wrappers;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// scan wrappers
|
|
172
|
-
if (config.wrappers.length) {
|
|
173
|
-
console.log(
|
|
174
|
-
chalk.blue(
|
|
175
|
-
"Scanning wrappers..."
|
|
176
|
-
)
|
|
44
|
+
const functionWrappers =
|
|
45
|
+
(config.functionWrappers ?? []).map(
|
|
46
|
+
(w) => ({
|
|
47
|
+
...w,
|
|
48
|
+
path: w.path ?? "0"
|
|
49
|
+
})
|
|
177
50
|
);
|
|
178
51
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
project.addSourceFileAtPath(file);
|
|
182
|
-
|
|
183
|
-
const elements = [
|
|
184
|
-
...sourceFile.getDescendantsOfKind(
|
|
185
|
-
SyntaxKind.JsxOpeningElement
|
|
186
|
-
),
|
|
187
|
-
...sourceFile.getDescendantsOfKind(
|
|
188
|
-
SyntaxKind.JsxSelfClosingElement
|
|
189
|
-
)
|
|
190
|
-
];
|
|
191
|
-
|
|
192
|
-
for (const element of elements) {
|
|
193
|
-
const tagName =
|
|
194
|
-
element
|
|
195
|
-
.getTagNameNode()
|
|
196
|
-
.getText()
|
|
197
|
-
.toLowerCase();
|
|
198
|
-
|
|
199
|
-
for (const wrapper of config.wrappers) {
|
|
200
|
-
if (
|
|
201
|
-
tagName !==
|
|
202
|
-
wrapper.name.toLowerCase()
|
|
203
|
-
)
|
|
204
|
-
continue;
|
|
52
|
+
const componentWrappers =
|
|
53
|
+
config.wrappers ?? [];
|
|
205
54
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
for (const attr of attrs) {
|
|
210
|
-
if (
|
|
211
|
-
attr.getKind() !==
|
|
212
|
-
SyntaxKind.JsxAttribute
|
|
213
|
-
)
|
|
214
|
-
continue;
|
|
215
|
-
|
|
216
|
-
const attrNode =
|
|
217
|
-
attr.asKind(
|
|
218
|
-
SyntaxKind.JsxAttribute
|
|
219
|
-
);
|
|
220
|
-
|
|
221
|
-
if (!attrNode) continue;
|
|
222
|
-
|
|
223
|
-
const attrName =
|
|
224
|
-
attrNode
|
|
225
|
-
.getNameNode()
|
|
226
|
-
.getText()
|
|
227
|
-
.toLowerCase();
|
|
228
|
-
|
|
229
|
-
if (
|
|
230
|
-
attrName !==
|
|
231
|
-
wrapper.prop.toLowerCase()
|
|
232
|
-
)
|
|
233
|
-
continue;
|
|
234
|
-
|
|
235
|
-
const initializer =
|
|
236
|
-
attrNode.getInitializer();
|
|
237
|
-
|
|
238
|
-
if (!initializer) continue;
|
|
239
|
-
|
|
240
|
-
let value: string | null = null;
|
|
241
|
-
|
|
242
|
-
// event="signup"
|
|
243
|
-
if (
|
|
244
|
-
initializer.getKind() ===
|
|
245
|
-
SyntaxKind.StringLiteral
|
|
246
|
-
) {
|
|
247
|
-
value =
|
|
248
|
-
initializer
|
|
249
|
-
.asKindOrThrow(
|
|
250
|
-
SyntaxKind.StringLiteral
|
|
251
|
-
)
|
|
252
|
-
.getLiteralText();
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
// event={"signup"}
|
|
256
|
-
if (
|
|
257
|
-
initializer.getKind() ===
|
|
258
|
-
SyntaxKind.JsxExpression
|
|
259
|
-
) {
|
|
260
|
-
const expr =
|
|
261
|
-
initializer
|
|
262
|
-
.asKindOrThrow(
|
|
263
|
-
SyntaxKind.JsxExpression
|
|
264
|
-
)
|
|
265
|
-
.getExpression();
|
|
266
|
-
|
|
267
|
-
if (
|
|
268
|
-
expr?.getKind() ===
|
|
269
|
-
SyntaxKind.StringLiteral
|
|
270
|
-
) {
|
|
271
|
-
value =
|
|
272
|
-
expr
|
|
273
|
-
.asKindOrThrow(
|
|
274
|
-
SyntaxKind.StringLiteral
|
|
275
|
-
)
|
|
276
|
-
.getLiteralText();
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
if (value) {
|
|
281
|
-
events.add(value);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
// results
|
|
290
|
-
const list =
|
|
291
|
-
[...events].sort();
|
|
292
|
-
|
|
293
|
-
console.log("");
|
|
294
|
-
|
|
295
|
-
console.log(
|
|
296
|
-
chalk.green("Found events:")
|
|
297
|
-
);
|
|
298
|
-
|
|
299
|
-
list.forEach((e) =>
|
|
300
|
-
console.log(
|
|
301
|
-
chalk.gray(`- ${e}`)
|
|
302
|
-
)
|
|
303
|
-
);
|
|
304
|
-
|
|
305
|
-
console.log("");
|
|
55
|
+
for (const file of files) {
|
|
56
|
+
const parser =
|
|
57
|
+
detectParser(file);
|
|
306
58
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
59
|
+
let content =
|
|
60
|
+
await fs.readFile(
|
|
61
|
+
file,
|
|
62
|
+
"utf-8"
|
|
63
|
+
);
|
|
310
64
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
);
|
|
65
|
+
if (parser === "vue")
|
|
66
|
+
content = parseVue(content);
|
|
314
67
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
(e: string) =>
|
|
318
|
-
!list.includes(e)
|
|
319
|
-
);
|
|
68
|
+
if (parser === "svelte")
|
|
69
|
+
content = parseSvelte(content);
|
|
320
70
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
chalk.blue("Changes:")
|
|
324
|
-
);
|
|
71
|
+
if (parser === "astro")
|
|
72
|
+
content = parseAstro(content);
|
|
325
73
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
)
|
|
331
|
-
);
|
|
74
|
+
const virtualFile =
|
|
75
|
+
parser === "ts"
|
|
76
|
+
? file
|
|
77
|
+
: file + ".tsx";
|
|
332
78
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
)
|
|
79
|
+
const source =
|
|
80
|
+
project.createSourceFile(
|
|
81
|
+
virtualFile,
|
|
82
|
+
content,
|
|
83
|
+
{ overwrite: true }
|
|
339
84
|
);
|
|
340
|
-
}
|
|
341
85
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
"Removed events:"
|
|
346
|
-
)
|
|
347
|
-
);
|
|
86
|
+
scanTrack(source).forEach(
|
|
87
|
+
(e) => events.add(e)
|
|
88
|
+
);
|
|
348
89
|
|
|
349
|
-
removed.forEach((e: unknown) =>
|
|
350
|
-
console.log(
|
|
351
|
-
chalk.red(
|
|
352
|
-
`- ${e}`
|
|
353
|
-
)
|
|
354
|
-
)
|
|
355
|
-
);
|
|
356
|
-
}
|
|
357
90
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
)
|
|
91
|
+
scanFunctionWrappers(
|
|
92
|
+
source,
|
|
93
|
+
functionWrappers
|
|
94
|
+
).forEach((e) =>
|
|
95
|
+
events.add(e)
|
|
364
96
|
);
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// confirm
|
|
368
|
-
const { confirm } =
|
|
369
|
-
await inquirer.prompt([
|
|
370
|
-
{
|
|
371
|
-
type: "confirm",
|
|
372
|
-
name: "confirm",
|
|
373
|
-
message:
|
|
374
|
-
"Sync these events?",
|
|
375
|
-
default: true
|
|
376
|
-
}
|
|
377
|
-
]);
|
|
378
97
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
)
|
|
98
|
+
scanComponentWrappers(
|
|
99
|
+
source,
|
|
100
|
+
componentWrappers
|
|
101
|
+
).forEach((e) =>
|
|
102
|
+
events.add(e)
|
|
384
103
|
);
|
|
385
|
-
return;
|
|
386
104
|
}
|
|
387
105
|
|
|
106
|
+
const list =
|
|
107
|
+
[...events].sort();
|
|
108
|
+
|
|
388
109
|
config.events = list;
|
|
389
110
|
|
|
390
111
|
await saveConfig(config);
|
|
391
112
|
|
|
392
113
|
console.log(
|
|
393
114
|
chalk.green(
|
|
394
|
-
|
|
115
|
+
`Found ${list.length} events`
|
|
395
116
|
)
|
|
396
117
|
);
|
|
397
118
|
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type ComponentWrapper = {
|
|
2
|
+
name: string;
|
|
3
|
+
prop: string;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
export type FunctionWrapper = {
|
|
7
|
+
name: string;
|
|
8
|
+
path?: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type EventraConfig = {
|
|
12
|
+
apiKey?: string;
|
|
13
|
+
events: string[];
|
|
14
|
+
wrappers: ComponentWrapper[];
|
|
15
|
+
functionWrappers: FunctionWrapper[];
|
|
16
|
+
sync: {
|
|
17
|
+
include: string[];
|
|
18
|
+
exclude: string[];
|
|
19
|
+
};
|
|
20
|
+
};
|
package/src/utils/config.ts
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
import fs from "fs-extra";
|
|
2
2
|
import path from "path";
|
|
3
|
+
import { EventraConfig } from "../types";
|
|
3
4
|
|
|
4
5
|
export const CONFIG_NAME = "eventra.json";
|
|
5
6
|
|
|
6
|
-
export function normalizeConfig(
|
|
7
|
+
export function normalizeConfig(
|
|
8
|
+
config: Partial<EventraConfig>
|
|
9
|
+
): EventraConfig {
|
|
7
10
|
return {
|
|
8
11
|
apiKey: config.apiKey ?? "",
|
|
9
12
|
events: config.events ?? [],
|
|
10
13
|
wrappers: config.wrappers ?? [],
|
|
14
|
+
functionWrappers:
|
|
15
|
+
config.functionWrappers ?? [],
|
|
11
16
|
sync: config.sync ?? {
|
|
12
|
-
include: [
|
|
17
|
+
include: [
|
|
18
|
+
"**/*.{ts,tsx,js,jsx,vue,svelte,astro}"
|
|
19
|
+
],
|
|
13
20
|
exclude: [
|
|
14
21
|
"node_modules",
|
|
15
22
|
"dist",
|
|
@@ -20,28 +27,38 @@ export function normalizeConfig(config: any) {
|
|
|
20
27
|
};
|
|
21
28
|
}
|
|
22
29
|
|
|
23
|
-
export async function loadConfig() {
|
|
30
|
+
export async function loadConfig(): Promise<EventraConfig | null> {
|
|
24
31
|
const configPath = path.join(
|
|
25
32
|
process.cwd(),
|
|
26
33
|
CONFIG_NAME
|
|
27
34
|
);
|
|
28
35
|
|
|
29
|
-
if (
|
|
36
|
+
if (
|
|
37
|
+
!(await fs.pathExists(
|
|
38
|
+
configPath
|
|
39
|
+
))
|
|
40
|
+
) {
|
|
30
41
|
return null;
|
|
31
42
|
}
|
|
32
43
|
|
|
33
|
-
const config =
|
|
44
|
+
const config =
|
|
45
|
+
await fs.readJSON(
|
|
46
|
+
configPath
|
|
47
|
+
);
|
|
34
48
|
|
|
35
49
|
return normalizeConfig(config);
|
|
36
50
|
}
|
|
37
51
|
|
|
38
|
-
export async function saveConfig(
|
|
52
|
+
export async function saveConfig(
|
|
53
|
+
config: EventraConfig
|
|
54
|
+
) {
|
|
39
55
|
const configPath = path.join(
|
|
40
56
|
process.cwd(),
|
|
41
57
|
CONFIG_NAME
|
|
42
58
|
);
|
|
43
59
|
|
|
44
|
-
const normalized =
|
|
60
|
+
const normalized =
|
|
61
|
+
normalizeConfig(config);
|
|
45
62
|
|
|
46
63
|
await fs.writeJSON(
|
|
47
64
|
configPath,
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CallExpression,
|
|
3
|
+
Node,
|
|
4
|
+
ObjectLiteralExpression,
|
|
5
|
+
SyntaxKind,
|
|
6
|
+
} from "ts-morph";
|
|
7
|
+
|
|
8
|
+
export function extractEvent(
|
|
9
|
+
call: CallExpression,
|
|
10
|
+
path: string
|
|
11
|
+
): string | null {
|
|
12
|
+
const parts = path.split(".");
|
|
13
|
+
|
|
14
|
+
let node: Node | undefined =
|
|
15
|
+
call.getArguments()[Number(parts[0])];
|
|
16
|
+
|
|
17
|
+
if (!node) return null;
|
|
18
|
+
|
|
19
|
+
node = unwrap(node);
|
|
20
|
+
|
|
21
|
+
for (let i = 1; i < parts.length; i++) {
|
|
22
|
+
if (!Node.isObjectLiteralExpression(node)) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const obj: ObjectLiteralExpression =
|
|
27
|
+
node;
|
|
28
|
+
|
|
29
|
+
const prop =
|
|
30
|
+
obj.getProperty(parts[i]);
|
|
31
|
+
|
|
32
|
+
if (!prop) return null;
|
|
33
|
+
|
|
34
|
+
if (!Node.isPropertyAssignment(prop)) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const initializer =
|
|
39
|
+
prop.getInitializer();
|
|
40
|
+
|
|
41
|
+
if (!initializer) return null;
|
|
42
|
+
|
|
43
|
+
node = unwrap(initializer);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (Node.isStringLiteral(node)) {
|
|
47
|
+
return node.getLiteralText();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (
|
|
51
|
+
node.getKind() ===
|
|
52
|
+
SyntaxKind.NoSubstitutionTemplateLiteral
|
|
53
|
+
) {
|
|
54
|
+
return node
|
|
55
|
+
.getText()
|
|
56
|
+
.replace(/`/g, "");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function unwrap(node: Node): Node {
|
|
63
|
+
let current = node;
|
|
64
|
+
|
|
65
|
+
while (
|
|
66
|
+
Node.isParenthesizedExpression(
|
|
67
|
+
current
|
|
68
|
+
)
|
|
69
|
+
) {
|
|
70
|
+
current = current.getExpression();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return current;
|
|
74
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export function parseVue(
|
|
2
|
+
content: string
|
|
3
|
+
) {
|
|
4
|
+
const template =
|
|
5
|
+
content.match(
|
|
6
|
+
/<template[\s\S]*?>([\s\S]*?)<\/template>/
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
const script =
|
|
10
|
+
content.match(
|
|
11
|
+
/<script[\s\S]*?>([\s\S]*?)<\/script>/
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
return `
|
|
15
|
+
${script?.[1] ?? ""}
|
|
16
|
+
|
|
17
|
+
function __vue_template__() {
|
|
18
|
+
return (
|
|
19
|
+
<>
|
|
20
|
+
${template?.[1] ?? ""}
|
|
21
|
+
</>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
`;
|
|
25
|
+
}
|