@eventra_dev/eventra-cli 0.0.18 → 0.1.1

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.
Files changed (44) hide show
  1. package/README.md +74 -166
  2. package/dist/commands/check.js +25 -88
  3. package/dist/commands/sync.js +22 -77
  4. package/dist/commands/watch.js +135 -0
  5. package/dist/engine/callResolver.js +31 -0
  6. package/dist/engine/engine.js +33 -0
  7. package/dist/engine/extract.js +53 -0
  8. package/dist/engine/flow.js +38 -0
  9. package/dist/engine/graph.js +22 -0
  10. package/dist/engine/project.js +74 -0
  11. package/dist/engine/resolver.js +38 -0
  12. package/dist/engine/scanner.js +78 -0
  13. package/dist/engine/symbol.js +31 -0
  14. package/dist/index.js +10 -6
  15. package/dist/utils/parsers/vue.js +16 -12
  16. package/dist/utils/processFile.js +20 -0
  17. package/package.json +2 -1
  18. package/src/commands/check.ts +29 -136
  19. package/src/commands/sync.ts +24 -135
  20. package/src/commands/watch.ts +166 -0
  21. package/src/engine/callResolver.ts +37 -0
  22. package/src/engine/engine.ts +39 -0
  23. package/src/engine/extract.ts +74 -0
  24. package/src/engine/flow.ts +54 -0
  25. package/src/engine/graph.ts +23 -0
  26. package/src/engine/project.ts +75 -0
  27. package/src/engine/resolver.ts +53 -0
  28. package/src/engine/scanner.ts +90 -0
  29. package/src/engine/symbol.ts +42 -0
  30. package/src/index.ts +11 -6
  31. package/src/types.ts +3 -5
  32. package/src/utils/parsers/vue.ts +19 -20
  33. package/src/utils/processFile.ts +18 -0
  34. package/tests/fixtures/backend/express/app.ts +167 -12
  35. package/tests/fixtures/wrappers/component/test.tsx +1 -1
  36. package/tests/run.ts +4 -17
  37. package/dist/utils/extract.js +0 -136
  38. package/dist/utils/scanners/component-wrappers.js +0 -70
  39. package/dist/utils/scanners/function-wrappers.js +0 -85
  40. package/dist/utils/scanners/track.js +0 -52
  41. package/src/utils/extract.ts +0 -185
  42. package/src/utils/scanners/component-wrappers.ts +0 -107
  43. package/src/utils/scanners/function-wrappers.ts +0 -180
  44. package/src/utils/scanners/track.ts +0 -84
@@ -0,0 +1,135 @@
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.watch = watch;
7
+ const chokidar_1 = __importDefault(require("chokidar"));
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const promises_1 = __importDefault(require("fs/promises"));
10
+ const fast_glob_1 = __importDefault(require("fast-glob"));
11
+ const config_1 = require("../utils/config");
12
+ const engine_1 = require("../engine/engine");
13
+ const router_1 = require("../utils/parsers/router");
14
+ const vue_1 = require("../utils/parsers/vue");
15
+ const svelte_1 = require("../utils/parsers/svelte");
16
+ const astro_1 = require("../utils/parsers/astro");
17
+ // PREPROCESS (CONTENT)
18
+ function preprocess(file, content) {
19
+ const parser = (0, router_1.detectParser)(file);
20
+ if (parser === "vue")
21
+ return (0, vue_1.parseVue)(content);
22
+ if (parser === "svelte")
23
+ return (0, svelte_1.parseSvelte)(content);
24
+ if (parser === "astro")
25
+ return (0, astro_1.parseAstro)(content);
26
+ return content;
27
+ }
28
+ // VIRTUAL FILE (PATH)
29
+ function toVirtualFile(file) {
30
+ return file.endsWith(".vue")
31
+ ? file + ".tsx"
32
+ : file;
33
+ }
34
+ // WATCH
35
+ async function watch() {
36
+ const config = await (0, config_1.loadConfig)();
37
+ if (!config)
38
+ return;
39
+ console.log(chalk_1.default.blue("Watching...\n"));
40
+ const files = await (0, fast_glob_1.default)(config.sync.include, {
41
+ ignore: config.sync.exclude,
42
+ });
43
+ if (!files.length) {
44
+ console.log(chalk_1.default.yellow("No files found"));
45
+ return;
46
+ }
47
+ const engine = new engine_1.EventraEngine(process.cwd());
48
+ // INITIAL SCAN
49
+ for (const file of files) {
50
+ try {
51
+ const raw = await promises_1.default.readFile(file, "utf-8");
52
+ const content = preprocess(file, raw);
53
+ const virtualFile = toVirtualFile(file);
54
+ engine.scanFile(virtualFile, content);
55
+ }
56
+ catch {
57
+ console.log(chalk_1.default.gray(`skip: ${file}`));
58
+ }
59
+ }
60
+ config.events = engine.getAllEvents().sort();
61
+ await (0, config_1.saveConfig)(config);
62
+ console.log(chalk_1.default.gray(`Initial: ${config.events.length} events\n`));
63
+ // STATE
64
+ let locked = false;
65
+ let queued = new Set();
66
+ const run = async () => {
67
+ if (locked)
68
+ return;
69
+ locked = true;
70
+ const batch = [...queued];
71
+ queued.clear();
72
+ for (const file of batch) {
73
+ try {
74
+ const raw = await promises_1.default.readFile(file, "utf-8");
75
+ const content = preprocess(file, raw);
76
+ const virtualFile = toVirtualFile(file);
77
+ engine.updateFile(virtualFile, content);
78
+ }
79
+ catch {
80
+ console.log(chalk_1.default.gray(`skip: ${file}`));
81
+ }
82
+ }
83
+ const next = engine.getAllEvents();
84
+ const added = next.filter(e => !config.events.includes(e));
85
+ const removed = config.events.filter(e => !next.includes(e));
86
+ if (added.length || removed.length) {
87
+ added.forEach(e => console.log(chalk_1.default.green(`+ ${e}`)));
88
+ removed.forEach(e => console.log(chalk_1.default.red(`- ${e}`)));
89
+ config.events = next.sort();
90
+ await (0, config_1.saveConfig)(config);
91
+ console.log(chalk_1.default.gray(`Total: ${config.events.length} events\n`));
92
+ }
93
+ locked = false;
94
+ };
95
+ const schedule = (file) => {
96
+ queued.add(file);
97
+ setTimeout(run, 50);
98
+ };
99
+ // WATCHER
100
+ const watcher = chokidar_1.default.watch(config.sync.include, {
101
+ ignored: config.sync.exclude,
102
+ ignoreInitial: true,
103
+ awaitWriteFinish: {
104
+ stabilityThreshold: 50,
105
+ pollInterval: 10,
106
+ },
107
+ });
108
+ watcher
109
+ .on("add", (file) => {
110
+ console.log(chalk_1.default.gray(`add: ${file}`));
111
+ schedule(file);
112
+ })
113
+ .on("change", (file) => {
114
+ console.log(chalk_1.default.gray(`change: ${file}`));
115
+ schedule(file);
116
+ })
117
+ .on("unlink", async (file) => {
118
+ console.log(chalk_1.default.gray(`remove: ${file}`));
119
+ const virtualFile = toVirtualFile(file);
120
+ engine.removeFile?.(virtualFile);
121
+ const next = engine.getAllEvents();
122
+ const removed = config.events.filter(e => !next.includes(e));
123
+ if (removed.length) {
124
+ removed.forEach(e => console.log(chalk_1.default.red(`- ${e}`)));
125
+ config.events = next.sort();
126
+ await (0, config_1.saveConfig)(config);
127
+ }
128
+ });
129
+ // EXIT
130
+ process.on("SIGINT", async () => {
131
+ console.log(chalk_1.default.yellow("\nStopping watcher..."));
132
+ await watcher.close();
133
+ process.exit(0);
134
+ });
135
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveFunctionFromCall = resolveFunctionFromCall;
4
+ const ts_morph_1 = require("ts-morph");
5
+ function resolveFunctionFromCall(expr) {
6
+ let symbol = expr.getSymbol();
7
+ if (!symbol && ts_morph_1.Node.isPropertyAccessExpression(expr)) {
8
+ symbol = expr.getNameNode().getSymbol();
9
+ }
10
+ if (!symbol)
11
+ return null;
12
+ const decls = symbol.getDeclarations() ?? [];
13
+ for (const d of decls) {
14
+ if (ts_morph_1.Node.isFunctionDeclaration(d))
15
+ return d;
16
+ if (ts_morph_1.Node.isVariableDeclaration(d)) {
17
+ const init = d.getInitializer();
18
+ if (init &&
19
+ (ts_morph_1.Node.isArrowFunction(init) ||
20
+ ts_morph_1.Node.isFunctionExpression(init))) {
21
+ return init;
22
+ }
23
+ }
24
+ if (ts_morph_1.Node.isMethodDeclaration(d))
25
+ return d;
26
+ if (ts_morph_1.Node.isFunctionExpression(d) || ts_morph_1.Node.isArrowFunction(d)) {
27
+ return d;
28
+ }
29
+ }
30
+ return null;
31
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EventraEngine = void 0;
4
+ const project_1 = require("./project");
5
+ const scanner_1 = require("./scanner");
6
+ class EventraEngine {
7
+ project;
8
+ fileEvents = new Map();
9
+ constructor(entry) {
10
+ this.project = new project_1.ProjectGraph(entry);
11
+ }
12
+ scanFile(file, content) {
13
+ const source = this.project.getSource(file, content);
14
+ const checker = this.project.getChecker();
15
+ const events = (0, scanner_1.scanSource)(source, checker);
16
+ this.fileEvents.set(file, events);
17
+ return events;
18
+ }
19
+ updateFile(file, content) {
20
+ return this.scanFile(file, content);
21
+ }
22
+ getAllEvents() {
23
+ const all = new Set();
24
+ for (const set of this.fileEvents.values()) {
25
+ set.forEach(e => all.add(e));
26
+ }
27
+ return [...all];
28
+ }
29
+ removeFile(file) {
30
+ this.fileEvents.delete(file);
31
+ }
32
+ }
33
+ exports.EventraEngine = EventraEngine;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractEventsFromArgs = extractEventsFromArgs;
4
+ const ts_morph_1 = require("ts-morph");
5
+ const resolver_1 = require("./resolver");
6
+ function extractEventsFromArgs(args, checker) {
7
+ return args.flatMap(arg => extract(arg, checker));
8
+ }
9
+ function extract(node, checker) {
10
+ if (ts_morph_1.Node.isStringLiteral(node)) {
11
+ return [{ value: node.getLiteralText(), dynamic: false }];
12
+ }
13
+ if (ts_morph_1.Node.isNoSubstitutionTemplateLiteral(node)) {
14
+ return [{ value: node.getLiteralText(), dynamic: false }];
15
+ }
16
+ if (ts_morph_1.Node.isTemplateExpression(node)) {
17
+ let result = node.getHead().getLiteralText();
18
+ for (const span of node.getTemplateSpans()) {
19
+ result += "*";
20
+ result += span.getLiteral().getLiteralText();
21
+ }
22
+ return [{ value: result, dynamic: true }];
23
+ }
24
+ if (ts_morph_1.Node.isObjectLiteralExpression(node)) {
25
+ return extractObject(node, checker);
26
+ }
27
+ const resolved = (0, resolver_1.resolveNodeValue)(node, checker);
28
+ if (resolved) {
29
+ return resolved.values.map(v => ({
30
+ value: v,
31
+ dynamic: resolved.dynamic,
32
+ }));
33
+ }
34
+ return [];
35
+ }
36
+ function extractObject(obj, checker) {
37
+ const res = [];
38
+ for (const prop of obj.getProperties()) {
39
+ if (!ts_morph_1.Node.isPropertyAssignment(prop))
40
+ continue;
41
+ const name = prop.getName();
42
+ const init = prop.getInitializer();
43
+ if (!init)
44
+ continue;
45
+ if (["event", "name", "action", "type"].includes(name)) {
46
+ res.push(...extract(init, checker));
47
+ }
48
+ if (ts_morph_1.Node.isObjectLiteralExpression(init)) {
49
+ res.push(...extractObject(init, checker));
50
+ }
51
+ }
52
+ return res;
53
+ }
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getForwardedParamIndex = getForwardedParamIndex;
4
+ const ts_morph_1 = require("ts-morph");
5
+ function getBodyNodes(fn) {
6
+ const body = fn.getBody();
7
+ if (!body)
8
+ return [];
9
+ if (ts_morph_1.Node.isBlock(body))
10
+ return body.getStatements();
11
+ return [body];
12
+ }
13
+ function getForwardedParamIndex(fn) {
14
+ if (!ts_morph_1.Node.isFunctionDeclaration(fn) &&
15
+ !ts_morph_1.Node.isArrowFunction(fn) &&
16
+ !ts_morph_1.Node.isFunctionExpression(fn))
17
+ return null;
18
+ const f = fn;
19
+ const params = f.getParameters();
20
+ for (const node of getBodyNodes(f)) {
21
+ const calls = node.getDescendantsOfKind(ts_morph_1.SyntaxKind.CallExpression);
22
+ for (const call of calls) {
23
+ const name = call.getExpression().getText();
24
+ if (!/(track|event|log|analytics|capture|send)/i.test(name))
25
+ continue;
26
+ const args = call.getArguments();
27
+ for (let i = 0; i < args.length; i++) {
28
+ const arg = args[i];
29
+ if (ts_morph_1.Node.isIdentifier(arg)) {
30
+ const idx = params.findIndex(p => p.getName() === arg.getText());
31
+ if (idx !== -1)
32
+ return idx;
33
+ }
34
+ }
35
+ }
36
+ }
37
+ return null;
38
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DependencyGraph = void 0;
4
+ class DependencyGraph {
5
+ reverse = new Map();
6
+ update(file, source) {
7
+ const imports = source
8
+ .getImportDeclarations()
9
+ .map(i => i.getModuleSpecifierSourceFile()?.getFilePath())
10
+ .filter(Boolean);
11
+ for (const dep of imports) {
12
+ if (!this.reverse.has(dep)) {
13
+ this.reverse.set(dep, new Set());
14
+ }
15
+ this.reverse.get(dep).add(file);
16
+ }
17
+ }
18
+ getDependents(file) {
19
+ return [...(this.reverse.get(file) ?? [])];
20
+ }
21
+ }
22
+ exports.DependencyGraph = DependencyGraph;
@@ -0,0 +1,74 @@
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.ProjectGraph = void 0;
7
+ const ts_morph_1 = require("ts-morph");
8
+ const path_1 = __importDefault(require("path"));
9
+ const fs_1 = __importDefault(require("fs"));
10
+ function normalize(file) {
11
+ return path_1.default.resolve(file);
12
+ }
13
+ function findTsConfig(start) {
14
+ let dir = path_1.default.dirname(start);
15
+ while (true) {
16
+ const file = path_1.default.join(dir, "tsconfig.json");
17
+ if (fs_1.default.existsSync(file))
18
+ return file;
19
+ const parent = path_1.default.dirname(dir);
20
+ if (parent === dir)
21
+ break;
22
+ dir = parent;
23
+ }
24
+ return null;
25
+ }
26
+ function getScriptKind(file) {
27
+ if (file.endsWith(".tsx"))
28
+ return ts_morph_1.ts.ScriptKind.TSX;
29
+ if (file.endsWith(".jsx"))
30
+ return ts_morph_1.ts.ScriptKind.JSX;
31
+ if (file.endsWith(".js"))
32
+ return ts_morph_1.ts.ScriptKind.JS;
33
+ if (file.endsWith(".vue"))
34
+ return ts_morph_1.ts.ScriptKind.TSX;
35
+ return ts_morph_1.ts.ScriptKind.TS;
36
+ }
37
+ class ProjectGraph {
38
+ project;
39
+ constructor(entry) {
40
+ const tsconfig = findTsConfig(entry);
41
+ this.project = tsconfig
42
+ ? new ts_morph_1.Project({
43
+ tsConfigFilePath: tsconfig,
44
+ skipAddingFilesFromTsConfig: false,
45
+ })
46
+ : new ts_morph_1.Project({
47
+ useInMemoryFileSystem: true,
48
+ compilerOptions: {
49
+ allowJs: true,
50
+ jsx: ts_morph_1.ts.JsxEmit.Preserve,
51
+ moduleResolution: ts_morph_1.ts.ModuleResolutionKind.NodeJs,
52
+ target: ts_morph_1.ts.ScriptTarget.ESNext,
53
+ },
54
+ });
55
+ }
56
+ getSource(file, content) {
57
+ const filePath = normalize(file);
58
+ let source = this.project.getSourceFile(filePath);
59
+ if (!source) {
60
+ source = this.project.createSourceFile(filePath, content, {
61
+ overwrite: true,
62
+ scriptKind: getScriptKind(filePath),
63
+ });
64
+ }
65
+ else {
66
+ source.replaceWithText(content);
67
+ }
68
+ return source;
69
+ }
70
+ getChecker() {
71
+ return this.project.getTypeChecker().compilerObject;
72
+ }
73
+ }
74
+ exports.ProjectGraph = ProjectGraph;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveNodeValue = resolveNodeValue;
4
+ const ts_morph_1 = require("ts-morph");
5
+ function resolveNodeValue(node, checker) {
6
+ if (!ts_morph_1.Node.isIdentifier(node))
7
+ return null;
8
+ const symbol = checker.getSymbolAtLocation(node.compilerNode);
9
+ if (!symbol)
10
+ return null;
11
+ const decls = symbol.getDeclarations() ?? [];
12
+ for (const d of decls) {
13
+ if (ts_morph_1.ts.isVariableDeclaration(d) && d.initializer) {
14
+ const init = d.initializer;
15
+ if (ts_morph_1.ts.isStringLiteral(init)) {
16
+ return { values: [init.text], dynamic: false };
17
+ }
18
+ if (ts_morph_1.ts.isNoSubstitutionTemplateLiteral(init)) {
19
+ return { values: [init.text], dynamic: false };
20
+ }
21
+ if (ts_morph_1.ts.isTemplateExpression(init)) {
22
+ let result = init.head.text;
23
+ for (const span of init.templateSpans) {
24
+ result += "*";
25
+ result += span.literal.text;
26
+ }
27
+ return { values: [result], dynamic: true };
28
+ }
29
+ }
30
+ if (ts_morph_1.ts.isParameter(d) && d.initializer) {
31
+ const init = d.initializer;
32
+ if (ts_morph_1.ts.isStringLiteral(init)) {
33
+ return { values: [init.text], dynamic: false };
34
+ }
35
+ }
36
+ }
37
+ return null;
38
+ }
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.scanSource = scanSource;
4
+ const ts_morph_1 = require("ts-morph");
5
+ const extract_1 = require("./extract");
6
+ const callResolver_1 = require("./callResolver");
7
+ const flow_1 = require("./flow");
8
+ function getCallName(expr) {
9
+ if (ts_morph_1.Node.isIdentifier(expr))
10
+ return expr.getText();
11
+ if (ts_morph_1.Node.isPropertyAccessExpression(expr))
12
+ return expr.getName();
13
+ return expr.getText();
14
+ }
15
+ function isTrackLike(name) {
16
+ return /(track|trackFeature)/i.test(name);
17
+ }
18
+ function pickArg(args) {
19
+ return (args.find(ts_morph_1.Node.isStringLiteral) ??
20
+ args.find(ts_morph_1.Node.isTemplateExpression) ??
21
+ args.find(ts_morph_1.Node.isObjectLiteralExpression) ??
22
+ args[0]);
23
+ }
24
+ function scanSource(source, checker) {
25
+ const events = new Set();
26
+ // CALLS
27
+ for (const call of source.getDescendantsOfKind(ts_morph_1.SyntaxKind.CallExpression)) {
28
+ const expr = call.getExpression();
29
+ const name = getCallName(expr);
30
+ if (!isTrackLike(name))
31
+ continue;
32
+ const args = call.getArguments();
33
+ if (!args.length)
34
+ continue;
35
+ let target = pickArg(args);
36
+ const fn = (0, callResolver_1.resolveFunctionFromCall)(expr);
37
+ if (fn) {
38
+ const index = (0, flow_1.getForwardedParamIndex)(fn);
39
+ if (index !== null && args[index]) {
40
+ target = args[index];
41
+ }
42
+ }
43
+ (0, extract_1.extractEventsFromArgs)([target], checker).forEach(({ value }) => {
44
+ if (isValid(value))
45
+ events.add(value);
46
+ });
47
+ }
48
+ // JSX
49
+ const jsx = [
50
+ ...source.getDescendantsOfKind(ts_morph_1.SyntaxKind.JsxOpeningElement),
51
+ ...source.getDescendantsOfKind(ts_morph_1.SyntaxKind.JsxSelfClosingElement),
52
+ ];
53
+ for (const el of jsx) {
54
+ for (const attr of el.getAttributes()) {
55
+ if (!ts_morph_1.Node.isJsxAttribute(attr))
56
+ continue;
57
+ const name = attr.getNameNode().getText();
58
+ if (!/(event|name|action)/i.test(name))
59
+ continue;
60
+ const init = attr.getInitializer();
61
+ if (!init)
62
+ continue;
63
+ const expr = ts_morph_1.Node.isJsxExpression(init)
64
+ ? init.getExpression()
65
+ : init;
66
+ if (!expr)
67
+ continue;
68
+ (0, extract_1.extractEventsFromArgs)([expr], checker).forEach(({ value }) => {
69
+ if (isValid(value))
70
+ events.add(value);
71
+ });
72
+ }
73
+ }
74
+ return events;
75
+ }
76
+ function isValid(v) {
77
+ return !!v && v.length > 1 && !v.includes(" ");
78
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveNodeValue = resolveNodeValue;
4
+ const ts_morph_1 = require("ts-morph");
5
+ function resolveNodeValue(node, checker) {
6
+ if (ts_morph_1.Node.isIdentifier(node)) {
7
+ const symbol = checker.getSymbolAtLocation(node.compilerNode);
8
+ if (!symbol)
9
+ return null;
10
+ const decls = symbol.getDeclarations() ?? [];
11
+ for (const d of decls) {
12
+ if (ts_morph_1.ts.isVariableDeclaration(d) && d.initializer) {
13
+ if (ts_morph_1.Node.isStringLiteral(d.initializer)) {
14
+ return {
15
+ values: [d.initializer.text],
16
+ dynamic: false
17
+ };
18
+ }
19
+ }
20
+ if (ts_morph_1.ts.isParameter(d) && d.initializer) {
21
+ if (ts_morph_1.Node.isStringLiteral(d.initializer)) {
22
+ return {
23
+ values: [d.initializer.text],
24
+ dynamic: false
25
+ };
26
+ }
27
+ }
28
+ }
29
+ }
30
+ return null;
31
+ }
package/dist/index.js CHANGED
@@ -42,28 +42,32 @@ program
42
42
  .version("0.0.1");
43
43
  program
44
44
  .command("init")
45
- .description("Initialize Eventra")
46
45
  .action(async () => {
47
46
  const { init } = await Promise.resolve().then(() => __importStar(require("./commands/init")));
48
47
  await init();
49
48
  });
50
49
  program
51
50
  .command("sync")
52
- .description("Sync events")
53
51
  .action(async () => {
54
52
  const { sync } = await Promise.resolve().then(() => __importStar(require("./commands/sync")));
55
53
  await sync();
56
54
  });
57
55
  program
58
56
  .command("check")
59
- .description("Validate events (CI mode)")
60
- .action(async () => {
57
+ .option("--fix", "auto fix issues")
58
+ .action(async (opts) => {
61
59
  const { check } = await Promise.resolve().then(() => __importStar(require("./commands/check")));
62
- await check();
60
+ await check({ fix: opts.fix });
61
+ });
62
+ program
63
+ .command("watch")
64
+ .description("Watch files and detect events in real-time")
65
+ .action(async () => {
66
+ const { watch } = await Promise.resolve().then(() => __importStar(require("./commands/watch")));
67
+ await watch();
63
68
  });
64
69
  program
65
70
  .command("send")
66
- .description("Send events")
67
71
  .action(async () => {
68
72
  const { send } = await Promise.resolve().then(() => __importStar(require("./commands/send")));
69
73
  await send();
@@ -2,17 +2,21 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseVue = parseVue;
4
4
  function parseVue(content) {
5
- const template = content.match(/<template[\s\S]*?>([\s\S]*?)<\/template>/);
6
- const script = content.match(/<script[\s\S]*?>([\s\S]*?)<\/script>/);
7
- return `
8
- ${script?.[1] ?? ""}
9
-
10
- function __vue_template__() {
11
- return (
12
- <>
13
- ${template?.[1] ?? ""}
14
- </>
15
- );
16
- }
5
+ const scriptMatch = content.match(/<script[\s\S]*?>([\s\S]*?)<\/script>/);
6
+ const templateMatch = content.match(/<template>([\s\S]*?)<\/template>/);
7
+ const script = scriptMatch?.[1] ?? "";
8
+ let template = templateMatch?.[1] ?? "";
9
+ template = template.replace(/<!--[\s\S]*?-->/g, "");
10
+ template = template
11
+ .replace(/v-if="[^"]+"/g, "")
12
+ .replace(/v-for="[^"]+"/g, "")
13
+ .replace(/@click=/g, "onClick=");
14
+ const jsx = `
15
+ const __VUE_JSX__ = (
16
+ <>
17
+ ${template}
18
+ </>
19
+ );
17
20
  `;
21
+ return script + "\n" + jsx;
18
22
  }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.processFile = processFile;
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
+ function processFile(file, content) {
9
+ 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);
16
+ const virtualFile = file.endsWith(".vue")
17
+ ? file + ".tsx"
18
+ : file;
19
+ return { content, virtualFile };
20
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eventra_dev/eventra-cli",
3
- "version": "0.0.18",
3
+ "version": "0.1.1",
4
4
  "description": "Eventra CLI",
5
5
  "type": "commonjs",
6
6
  "bin": {
@@ -20,6 +20,7 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "chalk": "^4.1.2",
23
+ "chokidar": "^5.0.0",
23
24
  "commander": "^11.0.0",
24
25
  "fast-glob": "^3.3.3",
25
26
  "fs-extra": "^11.2.0",