@eventra_dev/eventra-cli 0.3.2 → 0.3.4
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 +2 -2
- package/dist/analysis/cache/evaluationCache.js +1 -3
- package/dist/analysis/cache/resolvedCallCache.js +1 -3
- package/dist/analysis/cache/resolvedExportCache.js +1 -3
- package/dist/analysis/cache/returnPropagationCache.js +19 -0
- package/dist/analysis/cache/symbolInvalidation.js +8 -2
- package/dist/analysis/extractor/extractor.js +5 -13
- package/dist/analysis/extractor/propagationExtractor.js +55 -14
- package/dist/analysis/resolver/callResolver.js +10 -52
- package/dist/analysis/resolver/exportResolver.js +4 -19
- package/dist/analysis/resolver/resolver.js +148 -29
- package/dist/analysis/scanner/analyzer/propagationAnalyzer.js +19 -48
- package/dist/analysis/scanner/analyzer/returnPropagationAnalyzer.js +2 -13
- package/dist/analysis/scanner/scanner.js +16 -44
- package/dist/analysis/scanner/sinkDetector.js +10 -44
- package/dist/analysis/shared/evaluationContext.js +0 -1
- package/dist/analysis/symbols/symbolUtils.js +6 -29
- package/dist/analysis/symbols/wrapperRegistry.js +25 -25
- package/dist/cli/check.js +8 -10
- package/dist/cli/init.js +18 -82
- package/dist/cli/send.js +7 -5
- package/dist/cli/sync.js +4 -39
- package/dist/cli/watch.js +42 -40
- package/dist/compiler/compilerContext.js +18 -41
- package/dist/compiler/documentRegistry.js +5 -15
- package/dist/compiler/importGraph.js +4 -8
- package/dist/compiler/scheduler.js +1 -3
- package/dist/config/config.js +9 -19
- package/dist/core/EventraEngine.js +37 -101
- package/dist/core/projectScanner.js +7 -6
- package/dist/filesystem/processFile.js +1 -4
- package/dist/shared/buildSyntheticTsx.js +1 -2
- package/package.json +1 -1
- package/dist/analysis/cache/semanticDependencyGraph.js +0 -25
- package/dist/analysis/pipeline/semanticPass.js +0 -2
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// src/analysis/scanner/sinkDetector.ts
|
|
3
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
4
|
};
|
|
@@ -7,69 +6,39 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
6
|
exports.detectTrackSink = detectTrackSink;
|
|
8
7
|
const typescript_1 = __importDefault(require("typescript"));
|
|
9
8
|
function isElementTrackProperty(expr) {
|
|
10
|
-
return (typescript_1.default.isElementAccessExpression(expr)
|
|
11
|
-
&& expr.argumentExpression
|
|
12
|
-
&& typescript_1.default.isStringLiteral(expr.argumentExpression)
|
|
13
|
-
&& expr.argumentExpression.text
|
|
14
|
-
=== "track");
|
|
9
|
+
return (typescript_1.default.isElementAccessExpression(expr) && expr.argumentExpression && typescript_1.default.isStringLiteral(expr.argumentExpression) && expr.argumentExpression.text === "track");
|
|
15
10
|
}
|
|
16
11
|
function isTrackIdentifier(expr) {
|
|
17
|
-
return (typescript_1.default.isIdentifier(expr)
|
|
18
|
-
&& expr.text === "track");
|
|
12
|
+
return (typescript_1.default.isIdentifier(expr) && expr.text === "track");
|
|
19
13
|
}
|
|
20
14
|
function isTrackProperty(expr) {
|
|
21
|
-
return (typescript_1.default.isPropertyAccessExpression(expr)
|
|
22
|
-
&& expr.name.text
|
|
23
|
-
=== "track");
|
|
15
|
+
return (typescript_1.default.isPropertyAccessExpression(expr) && expr.name.text === "track");
|
|
24
16
|
}
|
|
25
17
|
function isOptionalTrackProperty(expr) {
|
|
26
|
-
return (typescript_1.default.isPropertyAccessChain(expr)
|
|
27
|
-
&& expr.name.text
|
|
28
|
-
=== "track");
|
|
18
|
+
return (typescript_1.default.isPropertyAccessChain(expr) && expr.name.text === "track");
|
|
29
19
|
}
|
|
30
20
|
function extractTrackedArguments(call) {
|
|
31
21
|
const result = [];
|
|
32
|
-
if (call.arguments.length
|
|
33
|
-
=== 0) {
|
|
22
|
+
if (call.arguments.length === 0) {
|
|
34
23
|
return result;
|
|
35
24
|
}
|
|
36
|
-
//
|
|
37
|
-
// ONLY FIRST ARGUMENT
|
|
38
|
-
// IS EVENT SINK
|
|
39
|
-
//
|
|
40
|
-
// track(name, payload)
|
|
41
|
-
// ^^^^
|
|
42
|
-
//
|
|
43
25
|
const first = call.arguments[0];
|
|
44
|
-
//
|
|
45
|
-
// track({
|
|
46
|
-
// event: "signup"
|
|
47
|
-
// })
|
|
48
|
-
//
|
|
49
26
|
if (typescript_1.default.isObjectLiteralExpression(first)) {
|
|
50
27
|
for (const property of first.properties) {
|
|
51
|
-
if (!typescript_1.default.isPropertyAssignment(property)) {
|
|
28
|
+
if (!typescript_1.default.isPropertyAssignment(property) && !typescript_1.default.isShorthandPropertyAssignment(property)) {
|
|
52
29
|
continue;
|
|
53
30
|
}
|
|
54
|
-
const name = property.name
|
|
55
|
-
|
|
56
|
-
if (name !== "event"
|
|
57
|
-
&& name !== "name"
|
|
58
|
-
&& name !== "type") {
|
|
31
|
+
const name = property.name.getText();
|
|
32
|
+
if (name !== "event" && name !== "name" && name !== "type") {
|
|
59
33
|
continue;
|
|
60
34
|
}
|
|
61
35
|
result.push({
|
|
62
36
|
index: 0,
|
|
63
|
-
propertyPath: [
|
|
64
|
-
name,
|
|
65
|
-
],
|
|
37
|
+
propertyPath: [name],
|
|
66
38
|
});
|
|
67
39
|
}
|
|
68
40
|
return result;
|
|
69
41
|
}
|
|
70
|
-
//
|
|
71
|
-
// track(name)
|
|
72
|
-
//
|
|
73
42
|
result.push({
|
|
74
43
|
index: 0,
|
|
75
44
|
propertyPath: [],
|
|
@@ -78,10 +47,7 @@ function extractTrackedArguments(call) {
|
|
|
78
47
|
}
|
|
79
48
|
function detectTrackSink(call) {
|
|
80
49
|
const expression = call.expression;
|
|
81
|
-
if (!isTrackIdentifier(expression)
|
|
82
|
-
&& !isTrackProperty(expression)
|
|
83
|
-
&& !isOptionalTrackProperty(expression)
|
|
84
|
-
&& !isElementTrackProperty(expression)) {
|
|
50
|
+
if (!isTrackIdentifier(expression) && !isTrackProperty(expression) && !isOptionalTrackProperty(expression) && !isElementTrackProperty(expression)) {
|
|
85
51
|
return null;
|
|
86
52
|
}
|
|
87
53
|
return {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// src/analysis/symbols/symbolUtils.ts
|
|
3
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
4
|
};
|
|
@@ -7,60 +6,38 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
6
|
exports.getFunctionSymbol = getFunctionSymbol;
|
|
8
7
|
const typescript_1 = __importDefault(require("typescript"));
|
|
9
8
|
function getFunctionSymbol(node, checker) {
|
|
10
|
-
//
|
|
11
9
|
// function foo() {}
|
|
12
|
-
|
|
13
|
-
if (typescript_1.default.isFunctionDeclaration(node)
|
|
14
|
-
&& node.name) {
|
|
10
|
+
if (typescript_1.default.isFunctionDeclaration(node) && node.name) {
|
|
15
11
|
return checker.getSymbolAtLocation(node.name);
|
|
16
12
|
}
|
|
17
|
-
//
|
|
18
13
|
// class method() {}
|
|
19
|
-
|
|
20
|
-
if (typescript_1.default.isMethodDeclaration(node)
|
|
21
|
-
&& typescript_1.default.isIdentifier(node.name)) {
|
|
14
|
+
if (typescript_1.default.isMethodDeclaration(node) && typescript_1.default.isIdentifier(node.name)) {
|
|
22
15
|
return checker.getSymbolAtLocation(node.name);
|
|
23
16
|
}
|
|
24
|
-
//
|
|
25
17
|
// object literal method
|
|
26
|
-
//
|
|
27
18
|
// const obj = {
|
|
28
19
|
// foo() {}
|
|
29
20
|
// }
|
|
30
|
-
|
|
31
|
-
if (typescript_1.default.isMethodDeclaration(node)
|
|
32
|
-
&& typescript_1.default.isComputedPropertyName(node.name)) {
|
|
21
|
+
if (typescript_1.default.isMethodDeclaration(node) && typescript_1.default.isComputedPropertyName(node.name)) {
|
|
33
22
|
return checker.getSymbolAtLocation(node.name.expression);
|
|
34
23
|
}
|
|
35
|
-
//
|
|
36
24
|
// const foo = () => {}
|
|
37
|
-
//
|
|
38
25
|
const parent = node.parent;
|
|
39
|
-
if (typescript_1.default.isVariableDeclaration(parent)
|
|
40
|
-
&& typescript_1.default.isIdentifier(parent.name)) {
|
|
26
|
+
if (typescript_1.default.isVariableDeclaration(parent) && typescript_1.default.isIdentifier(parent.name)) {
|
|
41
27
|
return checker.getSymbolAtLocation(parent.name);
|
|
42
28
|
}
|
|
43
|
-
//
|
|
44
29
|
// class field = () => {}
|
|
45
|
-
|
|
46
|
-
if (typescript_1.default.isPropertyDeclaration(parent)
|
|
47
|
-
&& typescript_1.default.isIdentifier(parent.name)) {
|
|
30
|
+
if (typescript_1.default.isPropertyDeclaration(parent) && typescript_1.default.isIdentifier(parent.name)) {
|
|
48
31
|
return checker.getSymbolAtLocation(parent.name);
|
|
49
32
|
}
|
|
50
|
-
//
|
|
51
33
|
// object property
|
|
52
|
-
//
|
|
53
34
|
// const x = {
|
|
54
35
|
// foo: () => {}
|
|
55
36
|
// }
|
|
56
|
-
|
|
57
|
-
if (typescript_1.default.isPropertyAssignment(parent)
|
|
58
|
-
&& typescript_1.default.isIdentifier(parent.name)) {
|
|
37
|
+
if (typescript_1.default.isPropertyAssignment(parent) && typescript_1.default.isIdentifier(parent.name)) {
|
|
59
38
|
return checker.getSymbolAtLocation(parent.name);
|
|
60
39
|
}
|
|
61
|
-
//
|
|
62
40
|
// export default function() {}
|
|
63
|
-
//
|
|
64
41
|
if (typescript_1.default.isExportAssignment(parent)) {
|
|
65
42
|
return checker.getSymbolAtLocation(node);
|
|
66
43
|
}
|
|
@@ -10,46 +10,46 @@ function isSymbol(value) {
|
|
|
10
10
|
return "flags" in value;
|
|
11
11
|
}
|
|
12
12
|
class WrapperRegistry {
|
|
13
|
+
checker;
|
|
14
|
+
exportCache;
|
|
13
15
|
wrappers = new WeakMap();
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
constructor(checker, exportCache) {
|
|
17
|
+
this.checker = checker;
|
|
18
|
+
this.exportCache = exportCache;
|
|
17
19
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
normalize(symbol) {
|
|
21
|
+
return ((0, exportResolver_1.resolveExportedSymbol)(symbol, this.checker, this.exportCache) ?? symbol);
|
|
20
22
|
}
|
|
21
|
-
|
|
23
|
+
set(semantic) {
|
|
24
|
+
this.wrappers.set(this.normalize(semantic.symbol), semantic);
|
|
25
|
+
}
|
|
26
|
+
get(target) {
|
|
22
27
|
if (isSymbol(target)) {
|
|
23
|
-
return this.wrappers.get(this.normalize(target
|
|
28
|
+
return this.wrappers.get(this.normalize(target));
|
|
24
29
|
}
|
|
25
30
|
let symbol;
|
|
26
|
-
if (typescript_1.default.isFunctionDeclaration(target)
|
|
27
|
-
|
|
28
|
-
symbol =
|
|
29
|
-
checker.getSymbolAtLocation(target.name);
|
|
31
|
+
if (typescript_1.default.isFunctionDeclaration(target) && target.name) {
|
|
32
|
+
symbol = this.checker.getSymbolAtLocation(target.name);
|
|
30
33
|
}
|
|
31
|
-
else if (typescript_1.default.isMethodDeclaration(target)
|
|
32
|
-
|
|
33
|
-
symbol =
|
|
34
|
-
checker.getSymbolAtLocation(target.name);
|
|
34
|
+
else if (typescript_1.default.isMethodDeclaration(target) && typescript_1.default.isIdentifier(target.name)) {
|
|
35
|
+
symbol = this.checker.getSymbolAtLocation(target.name);
|
|
35
36
|
}
|
|
36
|
-
else if (target.parent
|
|
37
|
-
|
|
38
|
-
&& typescript_1.default.isIdentifier(target.parent.name)) {
|
|
39
|
-
symbol =
|
|
40
|
-
checker.getSymbolAtLocation(target.parent.name);
|
|
37
|
+
else if (target.parent && typescript_1.default.isVariableDeclaration(target.parent) && typescript_1.default.isIdentifier(target.parent.name)) {
|
|
38
|
+
symbol = this.checker.getSymbolAtLocation(target.parent.name);
|
|
41
39
|
}
|
|
42
40
|
if (!symbol) {
|
|
43
41
|
return undefined;
|
|
44
42
|
}
|
|
45
|
-
return this.wrappers.get(this.normalize(symbol
|
|
43
|
+
return this.wrappers.get(this.normalize(symbol));
|
|
44
|
+
}
|
|
45
|
+
has(symbol) {
|
|
46
|
+
return this.wrappers.has(this.normalize(symbol));
|
|
46
47
|
}
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
delete(symbol) {
|
|
49
|
+
this.wrappers.delete(this.normalize(symbol));
|
|
49
50
|
}
|
|
50
51
|
clear() {
|
|
51
|
-
this.wrappers =
|
|
52
|
-
new WeakMap();
|
|
52
|
+
this.wrappers = new WeakMap();
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
exports.WrapperRegistry = WrapperRegistry;
|
package/dist/cli/check.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// src/commands/check.ts
|
|
3
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
3
|
if (k2 === undefined) k2 = k;
|
|
5
4
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -51,20 +50,19 @@ async function check({ fix = false }) {
|
|
|
51
50
|
const { engine } = await (0, projectScanner_1.scanProject)(config);
|
|
52
51
|
const found = new Set(engine.getAllEvents());
|
|
53
52
|
const known = new Set(config.events ?? []);
|
|
54
|
-
const added = [...found]
|
|
55
|
-
|
|
56
|
-
const removed = [...known]
|
|
57
|
-
.filter(e => !found.has(e));
|
|
53
|
+
const added = [...found].filter(e => !known.has(e));
|
|
54
|
+
const removed = [...known].filter(e => !found.has(e));
|
|
58
55
|
if (fix) {
|
|
59
|
-
|
|
60
|
-
|
|
56
|
+
const nextConfig = {
|
|
57
|
+
...config,
|
|
58
|
+
events: [...found].sort(),
|
|
59
|
+
};
|
|
61
60
|
const { saveConfig } = await Promise.resolve().then(() => __importStar(require("../config/config")));
|
|
62
|
-
await saveConfig(
|
|
61
|
+
await saveConfig(nextConfig);
|
|
63
62
|
console.log(chalk_1.default.green("Synced"));
|
|
64
63
|
return;
|
|
65
64
|
}
|
|
66
|
-
if (added.length
|
|
67
|
-
|| removed.length) {
|
|
65
|
+
if (added.length || removed.length) {
|
|
68
66
|
added.forEach(e => console.log(chalk_1.default.red(`+ ${e}`)));
|
|
69
67
|
removed.forEach(e => console.log(chalk_1.default.yellow(`- ${e}`)));
|
|
70
68
|
process.exit(1);
|
package/dist/cli/init.js
CHANGED
|
@@ -9,109 +9,45 @@ const inquirer_1 = __importDefault(require("inquirer"));
|
|
|
9
9
|
const config_1 = require("../config/config");
|
|
10
10
|
async function init() {
|
|
11
11
|
console.log(chalk_1.default.blue("Initializing Eventra..."));
|
|
12
|
-
|
|
13
|
-
const { apiKey, endpoint } = await inquirer_1.default.prompt([
|
|
12
|
+
const { apiKey, endpoint, } = await inquirer_1.default.prompt([
|
|
14
13
|
{
|
|
15
14
|
type: "input",
|
|
16
15
|
name: "apiKey",
|
|
17
|
-
message: "API Key (optional):"
|
|
16
|
+
message: "API Key (optional):",
|
|
18
17
|
},
|
|
19
18
|
{
|
|
20
19
|
type: "input",
|
|
21
20
|
name: "endpoint",
|
|
22
21
|
message: "Custom endpoint (optional):",
|
|
23
|
-
default: "https://api.eventra.dev/api/v1/cli/events"
|
|
24
|
-
}
|
|
22
|
+
default: "https://api.eventra.dev/api/v1/cli/events",
|
|
23
|
+
},
|
|
25
24
|
]);
|
|
26
|
-
console.log(
|
|
25
|
+
console.log("");
|
|
26
|
+
console.log(chalk_1.default.gray("Eventra automatically detects:"));
|
|
27
27
|
console.log(chalk_1.default.gray("• track('event')"));
|
|
28
|
-
console.log(chalk_1.default.gray("•
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
console.log(
|
|
33
|
-
let addComponent = true;
|
|
34
|
-
while (addComponent) {
|
|
35
|
-
const { useWrapper } = await inquirer_1.default.prompt([
|
|
36
|
-
{
|
|
37
|
-
type: "confirm",
|
|
38
|
-
name: "useWrapper",
|
|
39
|
-
message: "Add component wrapper?",
|
|
40
|
-
default: false
|
|
41
|
-
}
|
|
42
|
-
]);
|
|
43
|
-
if (!useWrapper)
|
|
44
|
-
break;
|
|
45
|
-
const { name, prop } = await inquirer_1.default.prompt([
|
|
46
|
-
{
|
|
47
|
-
type: "input",
|
|
48
|
-
name: "name",
|
|
49
|
-
message: "Component name:",
|
|
50
|
-
validate: (v) => v ? true : "Required"
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
type: "input",
|
|
54
|
-
name: "prop",
|
|
55
|
-
message: "Event prop:",
|
|
56
|
-
default: "event"
|
|
57
|
-
}
|
|
58
|
-
]);
|
|
59
|
-
wrappers.push({
|
|
60
|
-
name,
|
|
61
|
-
prop
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
// FUNCTION WRAPPERS
|
|
65
|
-
console.log(chalk_1.default.blue("\nFunction wrappers"));
|
|
66
|
-
let addFunction = true;
|
|
67
|
-
while (addFunction) {
|
|
68
|
-
const { useWrapper } = await inquirer_1.default.prompt([
|
|
69
|
-
{
|
|
70
|
-
type: "confirm",
|
|
71
|
-
name: "useWrapper",
|
|
72
|
-
message: "Add function wrapper?",
|
|
73
|
-
default: false
|
|
74
|
-
}
|
|
75
|
-
]);
|
|
76
|
-
if (!useWrapper)
|
|
77
|
-
break;
|
|
78
|
-
const { name, event } = await inquirer_1.default.prompt([
|
|
79
|
-
{
|
|
80
|
-
type: "input",
|
|
81
|
-
name: "name",
|
|
82
|
-
message: "Function name:"
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
type: "input",
|
|
86
|
-
name: "event",
|
|
87
|
-
message: "Event field (leave empty if string argument):",
|
|
88
|
-
default: ""
|
|
89
|
-
}
|
|
90
|
-
]);
|
|
91
|
-
functionWrappers.push({
|
|
92
|
-
name,
|
|
93
|
-
event: event || undefined
|
|
94
|
-
});
|
|
95
|
-
}
|
|
28
|
+
console.log(chalk_1.default.gray("• analytics.track('event')"));
|
|
29
|
+
console.log(chalk_1.default.gray("• semantic parameter propagation"));
|
|
30
|
+
console.log(chalk_1.default.gray("• cross-file wrappers"));
|
|
31
|
+
console.log(chalk_1.default.gray("• parameter propagation"));
|
|
32
|
+
console.log("");
|
|
96
33
|
const config = {
|
|
97
34
|
apiKey,
|
|
98
35
|
endpoint,
|
|
99
36
|
events: [],
|
|
100
|
-
wrappers,
|
|
101
|
-
functionWrappers,
|
|
102
37
|
sync: {
|
|
103
38
|
include: [
|
|
104
|
-
"**/*.{ts,tsx,js,jsx
|
|
39
|
+
"**/*.{ts,tsx,js,jsx}",
|
|
105
40
|
],
|
|
106
41
|
exclude: [
|
|
107
42
|
"node_modules",
|
|
108
43
|
"dist",
|
|
109
44
|
".next",
|
|
110
|
-
".git"
|
|
111
|
-
]
|
|
112
|
-
}
|
|
45
|
+
".git",
|
|
46
|
+
],
|
|
47
|
+
},
|
|
113
48
|
};
|
|
114
49
|
await (0, config_1.saveConfig)(config);
|
|
115
|
-
console.log(chalk_1.default.green("
|
|
116
|
-
console.log(
|
|
50
|
+
console.log(chalk_1.default.green("eventra.json created"));
|
|
51
|
+
console.log("");
|
|
52
|
+
console.log(chalk_1.default.gray("Run `eventra sync`"));
|
|
117
53
|
}
|
package/dist/cli/send.js
CHANGED
|
@@ -11,8 +11,7 @@ const package_json_1 = __importDefault(require("../../package.json"));
|
|
|
11
11
|
const CLI_VERSION = package_json_1.default.version;
|
|
12
12
|
async function send() {
|
|
13
13
|
const config = await (0, config_1.loadConfig)();
|
|
14
|
-
const endpoint = config?.endpoint ||
|
|
15
|
-
process.env.EVENTRA_ENDPOINT;
|
|
14
|
+
const endpoint = config?.endpoint || process.env.EVENTRA_ENDPOINT;
|
|
16
15
|
if (!config) {
|
|
17
16
|
console.log(chalk_1.default.red("eventra.json not found. Run 'eventra init'"));
|
|
18
17
|
return;
|
|
@@ -28,8 +27,10 @@ async function send() {
|
|
|
28
27
|
}
|
|
29
28
|
]);
|
|
30
29
|
apiKey = answers.apiKey;
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
await (0, config_1.saveConfig)({
|
|
31
|
+
...config,
|
|
32
|
+
apiKey,
|
|
33
|
+
});
|
|
33
34
|
console.log(chalk_1.default.green("API key saved"));
|
|
34
35
|
}
|
|
35
36
|
// no events
|
|
@@ -72,7 +73,8 @@ async function send() {
|
|
|
72
73
|
const text = await res.text();
|
|
73
74
|
console.log(chalk_1.default.gray(text));
|
|
74
75
|
}
|
|
75
|
-
catch {
|
|
76
|
+
catch {
|
|
77
|
+
}
|
|
76
78
|
return;
|
|
77
79
|
}
|
|
78
80
|
const data = await res.json();
|
package/dist/cli/sync.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// src/commands/sync.ts
|
|
3
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
4
|
};
|
|
@@ -11,46 +10,12 @@ const projectScanner_1 = require("../core/projectScanner");
|
|
|
11
10
|
async function sync() {
|
|
12
11
|
const config = await (0, config_1.loadConfig)();
|
|
13
12
|
if (!config) {
|
|
13
|
+
console.log(chalk_1.default.red("eventra.json not found"));
|
|
14
14
|
return;
|
|
15
15
|
}
|
|
16
16
|
console.log(chalk_1.default.blue("Scanning..."));
|
|
17
|
-
const { engine
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
for (const result of results.values()) {
|
|
21
|
-
result
|
|
22
|
-
.detectedFunctionWrappers
|
|
23
|
-
.forEach(w => detectedFn.add(w));
|
|
24
|
-
result
|
|
25
|
-
.detectedComponentWrappers
|
|
26
|
-
.forEach((v, k) => detectedCmp.set(k, v));
|
|
27
|
-
}
|
|
28
|
-
const events = engine
|
|
29
|
-
.getAllEvents()
|
|
30
|
-
.sort();
|
|
31
|
-
config.events =
|
|
32
|
-
events;
|
|
33
|
-
config.functionWrappers =
|
|
34
|
-
mergeUnique(config.functionWrappers
|
|
35
|
-
?? [], [...detectedFn]
|
|
36
|
-
.map(name => ({
|
|
37
|
-
name
|
|
38
|
-
})), w => w.name);
|
|
39
|
-
config.wrappers =
|
|
40
|
-
mergeUnique(config.wrappers
|
|
41
|
-
?? [], [...detectedCmp.entries()]
|
|
42
|
-
.map(([name, prop]) => ({
|
|
43
|
-
name,
|
|
44
|
-
prop,
|
|
45
|
-
})), w => `${w.name}:${w.prop}`);
|
|
46
|
-
await (0, config_1.saveConfig)(config);
|
|
17
|
+
const { engine } = await (0, projectScanner_1.scanProject)(config);
|
|
18
|
+
const events = engine.getAllEvents().sort();
|
|
19
|
+
await (0, config_1.saveConfig)({ ...config, events });
|
|
47
20
|
console.log(chalk_1.default.green(`Found ${events.length} events`));
|
|
48
21
|
}
|
|
49
|
-
function mergeUnique(a, b, key) {
|
|
50
|
-
const map = new Map();
|
|
51
|
-
[...b, ...a]
|
|
52
|
-
.forEach(item => map.set(key(item), item));
|
|
53
|
-
return [
|
|
54
|
-
...map.values()
|
|
55
|
-
];
|
|
56
|
-
}
|
package/dist/cli/watch.js
CHANGED
|
@@ -16,6 +16,7 @@ const getVirtualFile_1 = require("../filesystem/getVirtualFile");
|
|
|
16
16
|
async function watch() {
|
|
17
17
|
const config = await (0, config_1.loadConfig)();
|
|
18
18
|
if (!config) {
|
|
19
|
+
console.log(chalk_1.default.red("eventra.json not found"));
|
|
19
20
|
return;
|
|
20
21
|
}
|
|
21
22
|
console.log(chalk_1.default.blue("Watching...\n"));
|
|
@@ -23,13 +24,15 @@ async function watch() {
|
|
|
23
24
|
const fileDeps = new Map();
|
|
24
25
|
const cache = new Map();
|
|
25
26
|
const watchedDeps = new Set();
|
|
26
|
-
const normalize = (
|
|
27
|
-
.replace(/\\/g, "/");
|
|
27
|
+
const normalize = (file) => {
|
|
28
|
+
return path_1.default.resolve(file).replace(/\\/g, "/");
|
|
29
|
+
};
|
|
28
30
|
// INITIAL LOAD
|
|
29
31
|
const files = await (0, fast_glob_1.default)(config.sync.include, {
|
|
30
32
|
ignore: config.sync.exclude,
|
|
31
33
|
absolute: true,
|
|
32
34
|
});
|
|
35
|
+
engine.beginPreload();
|
|
33
36
|
for (const file of files) {
|
|
34
37
|
try {
|
|
35
38
|
const abs = normalize(file);
|
|
@@ -38,22 +41,21 @@ async function watch() {
|
|
|
38
41
|
cache.set(abs, parsed);
|
|
39
42
|
await engine.preloadFile((0, getVirtualFile_1.getVirtualFile)(abs), parsed.content);
|
|
40
43
|
await engine.updateFile((0, getVirtualFile_1.getVirtualFile)(abs), parsed.content, config);
|
|
41
|
-
fileDeps.set(abs, new Set(parsed.dependencies.map(
|
|
44
|
+
fileDeps.set(abs, new Set(parsed.dependencies.map(dep => normalize(dep))));
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// ignore invalid files
|
|
42
48
|
}
|
|
43
|
-
catch { }
|
|
44
49
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
// WATCHER
|
|
51
|
-
const watcher = chokidar_1.default.watch([
|
|
52
|
-
...files.map(normalize),
|
|
53
|
-
...watchedDeps,
|
|
54
|
-
], {
|
|
55
|
-
ignoreInitial: true
|
|
50
|
+
engine.endPreload();
|
|
51
|
+
const initialEvents = engine.getAllEvents().sort();
|
|
52
|
+
await (0, config_1.saveConfig)({
|
|
53
|
+
...config,
|
|
54
|
+
events: initialEvents,
|
|
56
55
|
});
|
|
56
|
+
console.log(chalk_1.default.gray(`Initial: ${initialEvents.length}\n`));
|
|
57
|
+
// WATCHER
|
|
58
|
+
const watcher = chokidar_1.default.watch([...files.map(normalize), ...watchedDeps], { ignoreInitial: true });
|
|
57
59
|
const queue = new Map();
|
|
58
60
|
let timer = null;
|
|
59
61
|
const run = async () => {
|
|
@@ -67,22 +69,23 @@ async function watch() {
|
|
|
67
69
|
await engine.updateFile((0, getVirtualFile_1.getVirtualFile)(file), parsed.content, config);
|
|
68
70
|
// dependency diff
|
|
69
71
|
const abs = normalize(file);
|
|
70
|
-
const prevDeps = fileDeps.get(abs)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
// add new deps
|
|
72
|
+
const prevDeps = fileDeps.get(abs) ?? new Set();
|
|
73
|
+
const nextDeps = new Set(parsed.dependencies.map(dep => normalize(dep)));
|
|
74
|
+
// add deps
|
|
74
75
|
for (const dep of nextDeps) {
|
|
75
|
-
if (
|
|
76
|
-
|
|
77
|
-
watchedDeps.add(dep);
|
|
76
|
+
if (prevDeps.has(dep)) {
|
|
77
|
+
continue;
|
|
78
78
|
}
|
|
79
|
+
watcher.add(dep);
|
|
80
|
+
watchedDeps.add(dep);
|
|
79
81
|
}
|
|
80
|
-
// remove
|
|
82
|
+
// remove deps
|
|
81
83
|
for (const dep of prevDeps) {
|
|
82
|
-
if (
|
|
83
|
-
|
|
84
|
-
watchedDeps.delete(dep);
|
|
84
|
+
if (nextDeps.has(dep)) {
|
|
85
|
+
continue;
|
|
85
86
|
}
|
|
87
|
+
watcher.unwatch(dep);
|
|
88
|
+
watchedDeps.delete(dep);
|
|
86
89
|
}
|
|
87
90
|
fileDeps.set(abs, nextDeps);
|
|
88
91
|
}
|
|
@@ -90,12 +93,12 @@ async function watch() {
|
|
|
90
93
|
console.log(chalk_1.default.gray(`skip: ${file}`));
|
|
91
94
|
}
|
|
92
95
|
}
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
console.log(chalk_1.default.green(`Updated: ${
|
|
96
|
+
const nextEvents = engine.getAllEvents().sort();
|
|
97
|
+
await (0, config_1.saveConfig)({
|
|
98
|
+
...config,
|
|
99
|
+
events: nextEvents,
|
|
100
|
+
});
|
|
101
|
+
console.log(chalk_1.default.green(`Updated: ${nextEvents.length}`));
|
|
99
102
|
};
|
|
100
103
|
const schedule = (file) => {
|
|
101
104
|
const abs = normalize(file);
|
|
@@ -103,8 +106,7 @@ async function watch() {
|
|
|
103
106
|
if (timer) {
|
|
104
107
|
clearTimeout(timer);
|
|
105
108
|
}
|
|
106
|
-
timer =
|
|
107
|
-
setTimeout(run, 200);
|
|
109
|
+
timer = setTimeout(run, 200);
|
|
108
110
|
};
|
|
109
111
|
watcher
|
|
110
112
|
.on("change", schedule)
|
|
@@ -112,12 +114,12 @@ async function watch() {
|
|
|
112
114
|
.on("unlink", async (file) => {
|
|
113
115
|
const abs = normalize(file);
|
|
114
116
|
await engine.removeFile((0, getVirtualFile_1.getVirtualFile)(abs), config);
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
console.log(chalk_1.default.red(`Removed → ${
|
|
117
|
+
const nextEvents = engine.getAllEvents().sort();
|
|
118
|
+
await (0, config_1.saveConfig)({
|
|
119
|
+
...config,
|
|
120
|
+
events: nextEvents,
|
|
121
|
+
});
|
|
122
|
+
console.log(chalk_1.default.red(`Removed → ${nextEvents.length}`));
|
|
121
123
|
});
|
|
122
124
|
process.on("SIGINT", async () => {
|
|
123
125
|
await watcher.close();
|