@eventra_dev/eventra-cli 0.0.17 → 0.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +91 -94
- package/dist/commands/check.js +153 -0
- package/dist/commands/sync.js +93 -53
- package/dist/commands/watch.js +97 -0
- package/dist/index.js +14 -3
- package/dist/utils/detect-aliases.js +39 -0
- package/dist/utils/detect-wrappers.js +84 -0
- package/dist/utils/extract.js +18 -98
- package/dist/utils/scanners/component-wrappers.js +23 -20
- package/dist/utils/scanners/function-wrappers.js +16 -18
- package/dist/utils/scanners/track.js +20 -8
- package/package.json +2 -1
- package/src/commands/check.ts +197 -0
- package/src/commands/sync.ts +170 -110
- package/src/commands/watch.ts +113 -0
- package/src/index.ts +16 -3
- package/src/types.ts +4 -0
- package/src/utils/detect-aliases.ts +46 -0
- package/src/utils/detect-wrappers.ts +119 -0
- package/src/utils/extract.ts +20 -133
- package/src/utils/scanners/component-wrappers.ts +27 -25
- package/src/utils/scanners/function-wrappers.ts +47 -90
- package/src/utils/scanners/track.ts +23 -8
|
@@ -0,0 +1,97 @@
|
|
|
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 ts_morph_1 = require("ts-morph");
|
|
10
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
11
|
+
const config_1 = require("../utils/config");
|
|
12
|
+
const router_1 = require("../utils/parsers/router");
|
|
13
|
+
const vue_1 = require("../utils/parsers/vue");
|
|
14
|
+
const svelte_1 = require("../utils/parsers/svelte");
|
|
15
|
+
const astro_1 = require("../utils/parsers/astro");
|
|
16
|
+
const track_1 = require("../utils/scanners/track");
|
|
17
|
+
const function_wrappers_1 = require("../utils/scanners/function-wrappers");
|
|
18
|
+
const component_wrappers_1 = require("../utils/scanners/component-wrappers");
|
|
19
|
+
async function watch() {
|
|
20
|
+
const config = await (0, config_1.loadConfig)();
|
|
21
|
+
if (!config) {
|
|
22
|
+
console.log(chalk_1.default.red("Run init first"));
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
console.log(chalk_1.default.blue("Watching...\n"));
|
|
26
|
+
const project = new ts_morph_1.Project();
|
|
27
|
+
const aliases = config.aliases ?? {};
|
|
28
|
+
// уже известные события
|
|
29
|
+
const seen = new Set(config.events);
|
|
30
|
+
const queue = new Set();
|
|
31
|
+
let timer;
|
|
32
|
+
const processQueue = async () => {
|
|
33
|
+
const files = [...queue];
|
|
34
|
+
queue.clear();
|
|
35
|
+
for (const file of files) {
|
|
36
|
+
await handle(file);
|
|
37
|
+
}
|
|
38
|
+
config.events = [...new Set(config.events)].sort();
|
|
39
|
+
await (0, config_1.saveConfig)(config);
|
|
40
|
+
};
|
|
41
|
+
const handle = async (file) => {
|
|
42
|
+
try {
|
|
43
|
+
let content = await promises_1.default.readFile(file, "utf-8");
|
|
44
|
+
const parser = (0, router_1.detectParser)(file);
|
|
45
|
+
if (parser === "vue")
|
|
46
|
+
content = (0, vue_1.parseVue)(content);
|
|
47
|
+
if (parser === "svelte")
|
|
48
|
+
content = (0, svelte_1.parseSvelte)(content);
|
|
49
|
+
if (parser === "astro")
|
|
50
|
+
content = (0, astro_1.parseAstro)(content);
|
|
51
|
+
const source = project.createSourceFile(file, content, {
|
|
52
|
+
overwrite: true
|
|
53
|
+
});
|
|
54
|
+
const found = [
|
|
55
|
+
...(0, track_1.scanTrack)(source, config, aliases),
|
|
56
|
+
...(0, function_wrappers_1.scanFunctionWrappers)(source, config.functionWrappers ?? [], aliases),
|
|
57
|
+
...(0, component_wrappers_1.scanComponentWrappers)(source, config.wrappers ?? [], aliases)
|
|
58
|
+
];
|
|
59
|
+
for (const e of found) {
|
|
60
|
+
if (!e.value)
|
|
61
|
+
continue;
|
|
62
|
+
if (aliases[e.value] === "__skip__")
|
|
63
|
+
continue;
|
|
64
|
+
if (e.value in aliases)
|
|
65
|
+
continue;
|
|
66
|
+
if (seen.has(e.value))
|
|
67
|
+
continue;
|
|
68
|
+
seen.add(e.value);
|
|
69
|
+
if (!e.dynamic) {
|
|
70
|
+
config.events.push(e.value);
|
|
71
|
+
console.log(chalk_1.default.green(`+ ${e.value}`));
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
console.log(chalk_1.default.yellow(`Dynamic: ${e.value}`));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
project.removeSourceFile(source);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
console.log(chalk_1.default.gray(`skip: ${file}`));
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
const watcher = chokidar_1.default.watch(config.sync.include, {
|
|
84
|
+
ignored: [
|
|
85
|
+
...config.sync.exclude,
|
|
86
|
+
"**/*.log",
|
|
87
|
+
"**/*.tmp",
|
|
88
|
+
"**/*.swp"
|
|
89
|
+
],
|
|
90
|
+
ignoreInitial: true
|
|
91
|
+
});
|
|
92
|
+
watcher.on("change", (file) => {
|
|
93
|
+
queue.add(file);
|
|
94
|
+
clearTimeout(timer);
|
|
95
|
+
timer = setTimeout(processQueue, 200);
|
|
96
|
+
});
|
|
97
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -42,21 +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
|
});
|
|
55
|
+
program
|
|
56
|
+
.command("check")
|
|
57
|
+
.option("--fix", "auto fix issues")
|
|
58
|
+
.action(async (opts) => {
|
|
59
|
+
const { check } = await Promise.resolve().then(() => __importStar(require("./commands/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();
|
|
68
|
+
});
|
|
57
69
|
program
|
|
58
70
|
.command("send")
|
|
59
|
-
.description("Send events")
|
|
60
71
|
.action(async () => {
|
|
61
72
|
const { send } = await Promise.resolve().then(() => __importStar(require("./commands/send")));
|
|
62
73
|
await send();
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.detectAliases = detectAliases;
|
|
4
|
+
const ts_morph_1 = require("ts-morph");
|
|
5
|
+
function detectAliases(source) {
|
|
6
|
+
const aliases = {};
|
|
7
|
+
const vars = source.getDescendantsOfKind(ts_morph_1.SyntaxKind.VariableDeclaration);
|
|
8
|
+
for (const v of vars) {
|
|
9
|
+
const name = v.getName();
|
|
10
|
+
const init = v.getInitializer();
|
|
11
|
+
if (!init)
|
|
12
|
+
continue;
|
|
13
|
+
// const A = "event"
|
|
14
|
+
if (ts_morph_1.Node.isStringLiteral(init)) {
|
|
15
|
+
aliases[name] = init.getLiteralText();
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
// const A = `event`
|
|
19
|
+
if (init.getKind() === ts_morph_1.SyntaxKind.NoSubstitutionTemplateLiteral) {
|
|
20
|
+
aliases[name] = init.getText().replace(/`/g, "");
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
// const EVENTS = { CLICK: "click" }
|
|
24
|
+
if (ts_morph_1.Node.isObjectLiteralExpression(init)) {
|
|
25
|
+
for (const p of init.getProperties()) {
|
|
26
|
+
if (!ts_morph_1.Node.isPropertyAssignment(p))
|
|
27
|
+
continue;
|
|
28
|
+
const key = p.getName();
|
|
29
|
+
const val = p.getInitializer();
|
|
30
|
+
if (!val)
|
|
31
|
+
continue;
|
|
32
|
+
if (ts_morph_1.Node.isStringLiteral(val)) {
|
|
33
|
+
aliases[`${name}.${key}`] = val.getLiteralText();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return aliases;
|
|
39
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.detectWrappers = detectWrappers;
|
|
4
|
+
const ts_morph_1 = require("ts-morph");
|
|
5
|
+
function detectWrappers(source) {
|
|
6
|
+
return {
|
|
7
|
+
functions: detectFunctionWrappers(source),
|
|
8
|
+
components: detectComponentWrappers(source)
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
// FUNCTIONS
|
|
12
|
+
function detectFunctionWrappers(source) {
|
|
13
|
+
const result = new Map();
|
|
14
|
+
const functions = [
|
|
15
|
+
...source.getDescendantsOfKind(ts_morph_1.SyntaxKind.FunctionDeclaration),
|
|
16
|
+
...source.getDescendantsOfKind(ts_morph_1.SyntaxKind.ArrowFunction),
|
|
17
|
+
...source.getDescendantsOfKind(ts_morph_1.SyntaxKind.FunctionExpression)
|
|
18
|
+
];
|
|
19
|
+
for (const fn of functions) {
|
|
20
|
+
const body = fn.getBody();
|
|
21
|
+
if (!body)
|
|
22
|
+
continue;
|
|
23
|
+
const calls = body.getDescendantsOfKind(ts_morph_1.SyntaxKind.CallExpression);
|
|
24
|
+
for (const call of calls) {
|
|
25
|
+
if (!isTrackCall(call))
|
|
26
|
+
continue;
|
|
27
|
+
const name = getFunctionName(fn);
|
|
28
|
+
if (!name)
|
|
29
|
+
continue;
|
|
30
|
+
const arg = call.getArguments()[0];
|
|
31
|
+
let eventField;
|
|
32
|
+
if (arg && ts_morph_1.Node.isObjectLiteralExpression(arg)) {
|
|
33
|
+
const prop = arg.getProperties()[0];
|
|
34
|
+
if (prop && ts_morph_1.Node.isPropertyAssignment(prop)) {
|
|
35
|
+
eventField = prop.getName();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
result.set(name, { name, event: eventField });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return [...result.values()];
|
|
42
|
+
}
|
|
43
|
+
function isTrackCall(call) {
|
|
44
|
+
const expr = call.getExpression();
|
|
45
|
+
if (ts_morph_1.Node.isIdentifier(expr)) {
|
|
46
|
+
return expr.getText() === "track";
|
|
47
|
+
}
|
|
48
|
+
if (ts_morph_1.Node.isPropertyAccessExpression(expr)) {
|
|
49
|
+
return expr.getName() === "track";
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
function getFunctionName(fn) {
|
|
54
|
+
if (ts_morph_1.Node.isFunctionDeclaration(fn)) {
|
|
55
|
+
return fn.getName() ?? null;
|
|
56
|
+
}
|
|
57
|
+
const varDecl = fn.getFirstAncestorByKind(ts_morph_1.SyntaxKind.VariableDeclaration);
|
|
58
|
+
return varDecl?.getName() ?? null;
|
|
59
|
+
}
|
|
60
|
+
// COMPONENTS
|
|
61
|
+
function detectComponentWrappers(source) {
|
|
62
|
+
const result = new Map();
|
|
63
|
+
const elements = [
|
|
64
|
+
...source.getDescendantsOfKind(ts_morph_1.SyntaxKind.JsxOpeningElement),
|
|
65
|
+
...source.getDescendantsOfKind(ts_morph_1.SyntaxKind.JsxSelfClosingElement)
|
|
66
|
+
];
|
|
67
|
+
for (const el of elements) {
|
|
68
|
+
const name = el.getTagNameNode().getText();
|
|
69
|
+
for (const attr of el.getAttributes()) {
|
|
70
|
+
const a = attr.asKind(ts_morph_1.SyntaxKind.JsxAttribute);
|
|
71
|
+
if (!a)
|
|
72
|
+
continue;
|
|
73
|
+
const prop = a.getNameNode().getText();
|
|
74
|
+
const val = a.getInitializer();
|
|
75
|
+
if (!val)
|
|
76
|
+
continue;
|
|
77
|
+
if (ts_morph_1.Node.isStringLiteral(val) ||
|
|
78
|
+
ts_morph_1.Node.isJsxExpression(val)) {
|
|
79
|
+
result.set(name, { name, prop });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return [...result.values()];
|
|
84
|
+
}
|
package/dist/utils/extract.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.extractExpression = extractExpression;
|
|
4
4
|
const ts_morph_1 = require("ts-morph");
|
|
5
|
-
function extractExpression(expr) {
|
|
5
|
+
function extractExpression(expr, aliases) {
|
|
6
6
|
// "event"
|
|
7
7
|
if (ts_morph_1.Node.isStringLiteral(expr)) {
|
|
8
8
|
return {
|
|
@@ -11,124 +11,44 @@ function extractExpression(expr) {
|
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
13
|
// `event`
|
|
14
|
-
if (expr.getKind() ===
|
|
15
|
-
ts_morph_1.SyntaxKind.NoSubstitutionTemplateLiteral) {
|
|
14
|
+
if (expr.getKind() === ts_morph_1.SyntaxKind.NoSubstitutionTemplateLiteral) {
|
|
16
15
|
return {
|
|
17
|
-
values: [
|
|
18
|
-
expr.getText().replace(/`/g, "")
|
|
19
|
-
],
|
|
16
|
+
values: [expr.getText().replace(/`/g, "")],
|
|
20
17
|
dynamic: false
|
|
21
18
|
};
|
|
22
19
|
}
|
|
23
|
-
//
|
|
20
|
+
// IDENTIFIER
|
|
24
21
|
if (ts_morph_1.Node.isIdentifier(expr)) {
|
|
25
22
|
const name = expr.getText();
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (decl && ts_morph_1.Node.isVariableDeclaration(decl)) {
|
|
32
|
-
const initializer = decl.getInitializer();
|
|
33
|
-
// const TEST = "event"
|
|
34
|
-
if (initializer &&
|
|
35
|
-
ts_morph_1.Node.isStringLiteral(initializer)) {
|
|
36
|
-
return {
|
|
37
|
-
values: [initializer.getLiteralText()],
|
|
38
|
-
dynamic: false
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
// const TEST = `event`
|
|
42
|
-
if (initializer &&
|
|
43
|
-
initializer.getKind() ===
|
|
44
|
-
ts_morph_1.SyntaxKind.NoSubstitutionTemplateLiteral) {
|
|
45
|
-
return {
|
|
46
|
-
values: [
|
|
47
|
-
initializer.getText().replace(/`/g, "")
|
|
48
|
-
],
|
|
49
|
-
dynamic: false
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
}
|
|
23
|
+
if (name in aliases) {
|
|
24
|
+
return {
|
|
25
|
+
values: [aliases[name]],
|
|
26
|
+
dynamic: false
|
|
27
|
+
};
|
|
53
28
|
}
|
|
54
29
|
return {
|
|
55
30
|
values: [name],
|
|
56
31
|
dynamic: true
|
|
57
32
|
};
|
|
58
33
|
}
|
|
59
|
-
//
|
|
34
|
+
// PROPERTY ACCESS
|
|
60
35
|
if (ts_morph_1.Node.isPropertyAccessExpression(expr)) {
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const decl = defs[0]?.getDeclarationNode();
|
|
68
|
-
// const EVENTS = { CLICK: "event" }
|
|
69
|
-
if (decl && ts_morph_1.Node.isVariableDeclaration(decl)) {
|
|
70
|
-
const init = decl.getInitializer();
|
|
71
|
-
if (init && ts_morph_1.Node.isObjectLiteralExpression(init)) {
|
|
72
|
-
const prop = init.getProperty(propName);
|
|
73
|
-
if (prop &&
|
|
74
|
-
ts_morph_1.Node.isPropertyAssignment(prop)) {
|
|
75
|
-
const value = prop.getInitializer();
|
|
76
|
-
if (value &&
|
|
77
|
-
ts_morph_1.Node.isStringLiteral(value)) {
|
|
78
|
-
return {
|
|
79
|
-
values: [value.getLiteralText()],
|
|
80
|
-
dynamic: false
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
// fallback
|
|
87
|
-
if (decl && ts_morph_1.Node.isPropertyAssignment(decl)) {
|
|
88
|
-
const initializer = decl.getInitializer();
|
|
89
|
-
if (initializer &&
|
|
90
|
-
ts_morph_1.Node.isStringLiteral(initializer)) {
|
|
91
|
-
return {
|
|
92
|
-
values: [initializer.getLiteralText()],
|
|
93
|
-
dynamic: false
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
}
|
|
36
|
+
const name = expr.getText();
|
|
37
|
+
if (name in aliases) {
|
|
38
|
+
return {
|
|
39
|
+
values: [aliases[name]],
|
|
40
|
+
dynamic: false
|
|
41
|
+
};
|
|
97
42
|
}
|
|
98
43
|
return {
|
|
99
|
-
values: [
|
|
100
|
-
dynamic: true
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
// ternary (a ? b : c)
|
|
104
|
-
if (ts_morph_1.Node.isConditionalExpression(expr)) {
|
|
105
|
-
const values = [];
|
|
106
|
-
const whenTrue = extractExpression(expr.getWhenTrue());
|
|
107
|
-
const whenFalse = extractExpression(expr.getWhenFalse());
|
|
108
|
-
if (whenTrue)
|
|
109
|
-
values.push(...whenTrue.values);
|
|
110
|
-
if (whenFalse)
|
|
111
|
-
values.push(...whenFalse.values);
|
|
112
|
-
return {
|
|
113
|
-
values,
|
|
44
|
+
values: [name],
|
|
114
45
|
dynamic: true
|
|
115
46
|
};
|
|
116
47
|
}
|
|
117
48
|
// template `${}`
|
|
118
49
|
if (ts_morph_1.Node.isTemplateExpression(expr)) {
|
|
119
50
|
return {
|
|
120
|
-
values: [
|
|
121
|
-
expr.getText().replace(/`/g, "")
|
|
122
|
-
],
|
|
123
|
-
dynamic: true
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
// call (fn())
|
|
127
|
-
if (ts_morph_1.Node.isCallExpression(expr)) {
|
|
128
|
-
return {
|
|
129
|
-
values: [
|
|
130
|
-
expr.getExpression().getText()
|
|
131
|
-
],
|
|
51
|
+
values: [expr.getText()],
|
|
132
52
|
dynamic: true
|
|
133
53
|
};
|
|
134
54
|
}
|
|
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.scanComponentWrappers = scanComponentWrappers;
|
|
4
4
|
const ts_morph_1 = require("ts-morph");
|
|
5
5
|
const extract_1 = require("../extract");
|
|
6
|
-
function scanComponentWrappers(source, wrappers) {
|
|
7
|
-
const events = new
|
|
6
|
+
function scanComponentWrappers(source, wrappers, aliases) {
|
|
7
|
+
const events = new Map();
|
|
8
8
|
const elements = [
|
|
9
9
|
...source.getDescendantsOfKind(ts_morph_1.SyntaxKind.JsxOpeningElement),
|
|
10
10
|
...source.getDescendantsOfKind(ts_morph_1.SyntaxKind.JsxSelfClosingElement)
|
|
@@ -17,12 +17,9 @@ function scanComponentWrappers(source, wrappers) {
|
|
|
17
17
|
for (const wrapper of wrappers) {
|
|
18
18
|
if (name !== wrapper.name.toLowerCase())
|
|
19
19
|
continue;
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
// ❗ NO spread props
|
|
23
|
-
if (ts_morph_1.Node.isJsxSpreadAttribute(attr)) {
|
|
20
|
+
for (const attr of el.getAttributes()) {
|
|
21
|
+
if (ts_morph_1.Node.isJsxSpreadAttribute(attr))
|
|
24
22
|
continue;
|
|
25
|
-
}
|
|
26
23
|
const attrNode = attr.asKind(ts_morph_1.SyntaxKind.JsxAttribute);
|
|
27
24
|
if (!attrNode)
|
|
28
25
|
continue;
|
|
@@ -35,36 +32,42 @@ function scanComponentWrappers(source, wrappers) {
|
|
|
35
32
|
const init = attrNode.getInitializer();
|
|
36
33
|
// <Button event />
|
|
37
34
|
if (!init) {
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
const value = key;
|
|
36
|
+
const k = `${value}:true`;
|
|
37
|
+
events.set(k, {
|
|
38
|
+
value,
|
|
40
39
|
dynamic: true
|
|
41
40
|
});
|
|
42
41
|
continue;
|
|
43
42
|
}
|
|
44
|
-
//
|
|
43
|
+
// <Button event="click" />
|
|
45
44
|
if (ts_morph_1.Node.isStringLiteral(init)) {
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
const value = init.getLiteralText();
|
|
46
|
+
const k = `${value}:false`;
|
|
47
|
+
events.set(k, {
|
|
48
|
+
value,
|
|
48
49
|
dynamic: false
|
|
49
50
|
});
|
|
50
51
|
continue;
|
|
51
52
|
}
|
|
52
|
-
//
|
|
53
|
+
// <Button event={...} />
|
|
53
54
|
if (ts_morph_1.Node.isJsxExpression(init)) {
|
|
54
55
|
const expr = init.getExpression();
|
|
55
56
|
if (!expr)
|
|
56
57
|
continue;
|
|
57
|
-
const result = (0, extract_1.extractExpression)(expr);
|
|
58
|
+
const result = (0, extract_1.extractExpression)(expr, aliases);
|
|
58
59
|
if (!result)
|
|
59
60
|
continue;
|
|
60
|
-
result.values
|
|
61
|
-
value
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
for (const value of result.values) {
|
|
62
|
+
const k = `${value}:${result.dynamic}`;
|
|
63
|
+
events.set(k, {
|
|
64
|
+
value,
|
|
65
|
+
dynamic: result.dynamic
|
|
66
|
+
});
|
|
67
|
+
}
|
|
65
68
|
}
|
|
66
69
|
}
|
|
67
70
|
}
|
|
68
71
|
}
|
|
69
|
-
return events;
|
|
72
|
+
return [...events.values()];
|
|
70
73
|
}
|
|
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.scanFunctionWrappers = scanFunctionWrappers;
|
|
4
4
|
const ts_morph_1 = require("ts-morph");
|
|
5
5
|
const extract_1 = require("../extract");
|
|
6
|
-
function scanFunctionWrappers(source, wrappers) {
|
|
7
|
-
const events = new
|
|
6
|
+
function scanFunctionWrappers(source, wrappers, aliases) {
|
|
7
|
+
const events = new Map();
|
|
8
8
|
const calls = source.getDescendantsOfKind(ts_morph_1.SyntaxKind.CallExpression);
|
|
9
9
|
for (const call of calls) {
|
|
10
10
|
const name = getFunctionName(call);
|
|
@@ -13,13 +13,16 @@ function scanFunctionWrappers(source, wrappers) {
|
|
|
13
13
|
for (const wrapper of wrappers) {
|
|
14
14
|
if (wrapper.name !== name)
|
|
15
15
|
continue;
|
|
16
|
-
const results = extractEventFromArgs(call, wrapper.event);
|
|
16
|
+
const results = extractEventFromArgs(call, wrapper.event, aliases);
|
|
17
17
|
if (!results)
|
|
18
18
|
continue;
|
|
19
|
-
|
|
19
|
+
for (const r of results) {
|
|
20
|
+
const key = `${r.value}:${r.dynamic}`;
|
|
21
|
+
events.set(key, r);
|
|
22
|
+
}
|
|
20
23
|
}
|
|
21
24
|
}
|
|
22
|
-
return events;
|
|
25
|
+
return [...events.values()];
|
|
23
26
|
}
|
|
24
27
|
function getFunctionName(call) {
|
|
25
28
|
const expression = call.getExpression();
|
|
@@ -35,21 +38,18 @@ function getDeepName(node) {
|
|
|
35
38
|
let current = node;
|
|
36
39
|
let name = "";
|
|
37
40
|
while (ts_morph_1.Node.isPropertyAccessExpression(current)) {
|
|
38
|
-
name =
|
|
39
|
-
|
|
40
|
-
current =
|
|
41
|
-
current.getExpression();
|
|
41
|
+
name = current.getName();
|
|
42
|
+
current = current.getExpression();
|
|
42
43
|
}
|
|
43
44
|
return name;
|
|
44
45
|
}
|
|
45
|
-
function extractEventFromArgs(call, event) {
|
|
46
|
+
function extractEventFromArgs(call, event, aliases) {
|
|
46
47
|
const args = call.getArguments();
|
|
47
48
|
const events = [];
|
|
48
|
-
for (
|
|
49
|
-
const arg = args[i];
|
|
49
|
+
for (const arg of args) {
|
|
50
50
|
// track("event")
|
|
51
51
|
if (!event) {
|
|
52
|
-
const result = (0, extract_1.extractExpression)(arg);
|
|
52
|
+
const result = (0, extract_1.extractExpression)(arg, aliases);
|
|
53
53
|
if (!result)
|
|
54
54
|
continue;
|
|
55
55
|
result.values.forEach((value) => events.push({
|
|
@@ -57,7 +57,7 @@ function extractEventFromArgs(call, event) {
|
|
|
57
57
|
dynamic: result.dynamic
|
|
58
58
|
}));
|
|
59
59
|
}
|
|
60
|
-
// track({event})
|
|
60
|
+
// track({ event })
|
|
61
61
|
if (event) {
|
|
62
62
|
const obj = arg.asKind(ts_morph_1.SyntaxKind.ObjectLiteralExpression);
|
|
63
63
|
if (!obj)
|
|
@@ -69,7 +69,7 @@ function extractEventFromArgs(call, event) {
|
|
|
69
69
|
const init = prop.getInitializer();
|
|
70
70
|
if (!init)
|
|
71
71
|
continue;
|
|
72
|
-
const result = (0, extract_1.extractExpression)(init);
|
|
72
|
+
const result = (0, extract_1.extractExpression)(init, aliases);
|
|
73
73
|
if (!result)
|
|
74
74
|
continue;
|
|
75
75
|
result.values.forEach((value) => events.push({
|
|
@@ -79,7 +79,5 @@ function extractEventFromArgs(call, event) {
|
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
-
return events.length
|
|
83
|
-
? events
|
|
84
|
-
: null;
|
|
82
|
+
return events.length ? events : null;
|
|
85
83
|
}
|
|
@@ -1,10 +1,14 @@
|
|
|
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.scanTrack = scanTrack;
|
|
4
7
|
const ts_morph_1 = require("ts-morph");
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
5
9
|
const extract_1 = require("../extract");
|
|
6
|
-
function scanTrack(source, config) {
|
|
7
|
-
const events = new
|
|
10
|
+
function scanTrack(source, config, aliases) {
|
|
11
|
+
const events = new Map();
|
|
8
12
|
const calls = source.getDescendantsOfKind(ts_morph_1.SyntaxKind.CallExpression);
|
|
9
13
|
for (const call of calls) {
|
|
10
14
|
const expr = call.getExpression();
|
|
@@ -19,6 +23,7 @@ function scanTrack(source, config) {
|
|
|
19
23
|
}
|
|
20
24
|
if (!isTrack)
|
|
21
25
|
continue;
|
|
26
|
+
// ❗ skip wrapper functions
|
|
22
27
|
const func = call.getFirstAncestorByKind(ts_morph_1.SyntaxKind.FunctionDeclaration) ||
|
|
23
28
|
call.getFirstAncestorByKind(ts_morph_1.SyntaxKind.ArrowFunction) ||
|
|
24
29
|
call.getFirstAncestorByKind(ts_morph_1.SyntaxKind.FunctionExpression);
|
|
@@ -40,13 +45,20 @@ function scanTrack(source, config) {
|
|
|
40
45
|
const arg = call.getArguments()[0];
|
|
41
46
|
if (!arg)
|
|
42
47
|
continue;
|
|
43
|
-
const result = (0, extract_1.extractExpression)(arg);
|
|
48
|
+
const result = (0, extract_1.extractExpression)(arg, aliases);
|
|
44
49
|
if (!result)
|
|
45
50
|
continue;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
const line = call.getStartLineNumber();
|
|
52
|
+
const file = path_1.default.relative(process.cwd(), source.getFilePath());
|
|
53
|
+
for (const value of result.values) {
|
|
54
|
+
const key = `${value}:${file}:${line}`;
|
|
55
|
+
events.set(key, {
|
|
56
|
+
value,
|
|
57
|
+
dynamic: result.dynamic,
|
|
58
|
+
file,
|
|
59
|
+
line
|
|
60
|
+
});
|
|
61
|
+
}
|
|
50
62
|
}
|
|
51
|
-
return events;
|
|
63
|
+
return [...events.values()];
|
|
52
64
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eventra_dev/eventra-cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.19",
|
|
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",
|