@eventra_dev/eventra-cli 0.2.3 → 0.3.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.
- package/README.md +154 -32
- package/dist/analysis/cache/evaluationCache.js +21 -0
- package/dist/analysis/cache/resolvedCallCache.js +21 -0
- package/dist/analysis/cache/resolvedExportCache.js +21 -0
- package/dist/analysis/cache/semanticDependencyGraph.js +25 -0
- package/dist/analysis/cache/symbolInvalidation.js +20 -0
- package/dist/analysis/extractor/extractor.js +47 -0
- package/dist/analysis/extractor/propagationExtractor.js +52 -0
- package/dist/analysis/pipeline/semanticPass.js +2 -0
- package/dist/analysis/resolver/callResolver.js +125 -0
- package/dist/analysis/resolver/exportResolver.js +75 -0
- package/dist/analysis/resolver/resolver.js +133 -0
- package/dist/analysis/scanner/analyzer/propagationAnalyzer.js +193 -0
- package/dist/analysis/scanner/analyzer/returnPropagationAnalyzer.js +105 -0
- package/dist/analysis/scanner/scanner.js +117 -0
- package/dist/analysis/scanner/sinkDetector.js +91 -0
- package/dist/analysis/shared/evaluationContext.js +9 -0
- package/dist/analysis/shared/propagation.js +3 -0
- package/dist/analysis/shared/returnPropagation.js +2 -0
- package/dist/analysis/shared/types.js +2 -0
- package/dist/analysis/shared/utils.js +62 -0
- package/dist/analysis/symbols/symbolUtils.js +68 -0
- package/dist/analysis/symbols/wrapperRegistry.js +55 -0
- package/dist/cli/check.js +73 -0
- package/dist/{commands → cli}/init.js +1 -1
- package/dist/{commands → cli}/send.js +1 -1
- package/dist/cli/sync.js +56 -0
- package/dist/{commands → cli}/watch.js +41 -25
- package/dist/compiler/compilerContext.js +204 -0
- package/dist/compiler/documentRegistry.js +78 -0
- package/dist/compiler/importGraph.js +83 -0
- package/dist/compiler/scheduler.js +29 -0
- package/dist/core/EventraEngine.js +234 -0
- package/dist/core/projectScanner.js +73 -0
- package/dist/{utils → filesystem}/getVirtualFile.js +1 -3
- package/dist/filesystem/processFile.js +38 -0
- package/dist/index.js +5 -5
- package/dist/shared/buildSyntheticTsx.js +20 -0
- package/dist/shared/templateExpressionExtractor.js +22 -0
- package/package.json +32 -9
- package/.github/workflows/release.yml +0 -43
- package/ARCHITECTURE.md +0 -88
- package/assets/eventra-icon-animated.svg +0 -19
- package/dist/commands/check.js +0 -78
- package/dist/commands/sync.js +0 -79
- package/dist/engine/boundary.js +0 -14
- package/dist/engine/callResolver.js +0 -58
- package/dist/engine/engine.js +0 -154
- package/dist/engine/exportResolver.js +0 -46
- package/dist/engine/functionAnalyzer.js +0 -71
- package/dist/engine/graph.js +0 -168
- package/dist/engine/languageService.js +0 -162
- package/dist/engine/resolver.js +0 -149
- package/dist/engine/scanner.js +0 -230
- package/dist/utils/processFile.js +0 -28
- package/dist/utils/universal.js +0 -190
- package/src/commands/check.ts +0 -91
- package/src/commands/init.ts +0 -174
- package/src/commands/send.ts +0 -213
- package/src/commands/sync.ts +0 -106
- package/src/commands/watch.ts +0 -144
- package/src/engine/boundary.ts +0 -12
- package/src/engine/callResolver.ts +0 -65
- package/src/engine/engine.ts +0 -227
- package/src/engine/exportResolver.ts +0 -56
- package/src/engine/functionAnalyzer.ts +0 -81
- package/src/engine/graph.ts +0 -193
- package/src/engine/hash.ts +0 -5
- package/src/engine/languageService.ts +0 -209
- package/src/engine/resolver.ts +0 -177
- package/src/engine/scanner.ts +0 -298
- package/src/index.ts +0 -49
- package/src/types.ts +0 -35
- package/src/utils/config.ts +0 -53
- package/src/utils/getVirtualFile.ts +0 -5
- package/src/utils/processFile.ts +0 -29
- package/src/utils/universal.ts +0 -249
- package/tests/fixtures/backend/express/app.ts +0 -233
- package/tests/fixtures/backend/nest/service.ts +0 -70
- package/tests/fixtures/backend/node/index.ts +0 -63
- package/tests/fixtures/frontend/next/page.tsx +0 -101
- package/tests/fixtures/frontend/react/App.tsx +0 -104
- package/tests/fixtures/frontend/vue/App.vue +0 -83
- package/tests/fixtures/wrappers/component/test.tsx +0 -62
- package/tests/fixtures/wrappers/function/test.ts +0 -60
- package/tests/run.ts +0 -106
- package/tsconfig.json +0 -14
- /package/dist/{utils → config}/config.js +0 -0
- /package/dist/{engine → shared}/hash.js +0 -0
package/src/index.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { Command } from "commander";
|
|
4
|
-
|
|
5
|
-
const program = new Command();
|
|
6
|
-
|
|
7
|
-
program
|
|
8
|
-
.name("eventra")
|
|
9
|
-
.description("Eventra CLI")
|
|
10
|
-
.version("0.0.1");
|
|
11
|
-
|
|
12
|
-
program
|
|
13
|
-
.command("init")
|
|
14
|
-
.action(async () => {
|
|
15
|
-
const { init } = await import("./commands/init");
|
|
16
|
-
await init();
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
program
|
|
20
|
-
.command("sync")
|
|
21
|
-
.action(async () => {
|
|
22
|
-
const { sync } = await import("./commands/sync");
|
|
23
|
-
await sync();
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
program
|
|
27
|
-
.command("check")
|
|
28
|
-
.option("--fix", "auto fix issues")
|
|
29
|
-
.action(async (opts) => {
|
|
30
|
-
const { check } = await import("./commands/check");
|
|
31
|
-
await check({ fix: opts.fix });
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
program
|
|
35
|
-
.command("watch")
|
|
36
|
-
.description("Watch files and detect events in real-time")
|
|
37
|
-
.action(async () => {
|
|
38
|
-
const { watch } = await import("./commands/watch");
|
|
39
|
-
await watch();
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
program
|
|
43
|
-
.command("send")
|
|
44
|
-
.action(async () => {
|
|
45
|
-
const { send } = await import("./commands/send");
|
|
46
|
-
await send();
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
program.parse();
|
package/src/types.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
export type ScanMode = "strict" | "hybrid" | "discovery";
|
|
2
|
-
|
|
3
|
-
export type ScanResult = {
|
|
4
|
-
events: Set<string>;
|
|
5
|
-
detectedFunctionWrappers: Set<string>;
|
|
6
|
-
detectedComponentWrappers: Map<string, string>;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export type ParseResult = {
|
|
10
|
-
code: string;
|
|
11
|
-
deps: string[];
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export type ComponentWrapper = {
|
|
15
|
-
name: string;
|
|
16
|
-
prop: string;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export type FunctionWrapper = {
|
|
20
|
-
name: string;
|
|
21
|
-
event?: string;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export type EventraConfig = {
|
|
25
|
-
apiKey?: string;
|
|
26
|
-
endpoint?: string;
|
|
27
|
-
events: string[];
|
|
28
|
-
mode?: ScanMode;
|
|
29
|
-
wrappers: ComponentWrapper[];
|
|
30
|
-
functionWrappers: FunctionWrapper[];
|
|
31
|
-
sync: {
|
|
32
|
-
include: string[];
|
|
33
|
-
exclude: string[];
|
|
34
|
-
};
|
|
35
|
-
};
|
package/src/utils/config.ts
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import fs from "fs-extra";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import { EventraConfig } from "../types";
|
|
4
|
-
|
|
5
|
-
export const CONFIG_NAME = "eventra.json";
|
|
6
|
-
|
|
7
|
-
export function normalizeConfig(
|
|
8
|
-
config: Partial<EventraConfig>
|
|
9
|
-
): EventraConfig {
|
|
10
|
-
return {
|
|
11
|
-
apiKey: config.apiKey ?? "",
|
|
12
|
-
events: config.events ?? [],
|
|
13
|
-
endpoint: config.endpoint ?? "",
|
|
14
|
-
wrappers: config.wrappers ?? [],
|
|
15
|
-
functionWrappers: config.functionWrappers ?? [],
|
|
16
|
-
sync: config.sync ?? {
|
|
17
|
-
include: [
|
|
18
|
-
"**/*.{ts,tsx,js,jsx,vue,svelte,astro}"
|
|
19
|
-
],
|
|
20
|
-
exclude: [
|
|
21
|
-
"node_modules",
|
|
22
|
-
"dist",
|
|
23
|
-
".next",
|
|
24
|
-
".git"
|
|
25
|
-
]
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export async function loadConfig(): Promise<EventraConfig | null> {
|
|
31
|
-
const configPath = path.join(process.cwd(), CONFIG_NAME);
|
|
32
|
-
|
|
33
|
-
if (!(await fs.pathExists(configPath))) {
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
try {
|
|
38
|
-
const config = await fs.readJSON(configPath);
|
|
39
|
-
return normalizeConfig(config);
|
|
40
|
-
} catch {
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export async function saveConfig(config: EventraConfig) {
|
|
46
|
-
const configPath = path.join(process.cwd(), CONFIG_NAME);
|
|
47
|
-
|
|
48
|
-
const normalized = normalizeConfig(config);
|
|
49
|
-
|
|
50
|
-
await fs.writeJSON(configPath, normalized, {
|
|
51
|
-
spaces: 2
|
|
52
|
-
});
|
|
53
|
-
}
|
package/src/utils/processFile.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import path from "path";
|
|
2
|
-
import { parseUniversal } from "./universal";
|
|
3
|
-
|
|
4
|
-
function extractImports(content: string, file: string) {
|
|
5
|
-
return parseUniversal(content, file).deps;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function processFile(file: string, content: string) {
|
|
9
|
-
const ext = path.extname(file);
|
|
10
|
-
|
|
11
|
-
if (
|
|
12
|
-
ext === ".ts" ||
|
|
13
|
-
ext === ".tsx" ||
|
|
14
|
-
ext === ".js" ||
|
|
15
|
-
ext === ".jsx"
|
|
16
|
-
) {
|
|
17
|
-
return {
|
|
18
|
-
content,
|
|
19
|
-
deps: extractImports(content, file),
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const parsed = parseUniversal(content, file);
|
|
24
|
-
|
|
25
|
-
return {
|
|
26
|
-
content: parsed.code || "",
|
|
27
|
-
deps: [...new Set(parsed.deps.filter(Boolean))],
|
|
28
|
-
};
|
|
29
|
-
}
|
package/src/utils/universal.ts
DELETED
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
import path from "path";
|
|
2
|
-
import { ParseResult } from "../types";
|
|
3
|
-
|
|
4
|
-
/* ---------------------------------- */
|
|
5
|
-
/* COMMENT STRIP (SAFE) */
|
|
6
|
-
/* ---------------------------------- */
|
|
7
|
-
function stripComments(input: string): string {
|
|
8
|
-
return input
|
|
9
|
-
.replace(/<!--[\s\S]*?-->/g, "")
|
|
10
|
-
.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/* ---------------------------------- */
|
|
14
|
-
/* TRACK DETECTOR */
|
|
15
|
-
/* ---------------------------------- */
|
|
16
|
-
function looksLikeTracking(code: string) {
|
|
17
|
-
return /\btrack\s*\(|\.track\s*\(/.test(code);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/* ---------------------------------- */
|
|
21
|
-
/* SAFE {} PARSER (JSX / TEMPLATES) */
|
|
22
|
-
/* ---------------------------------- */
|
|
23
|
-
function extractBracedExpressions(input: string): string[] {
|
|
24
|
-
const result: string[] = [];
|
|
25
|
-
|
|
26
|
-
let depth = 0;
|
|
27
|
-
let start = -1;
|
|
28
|
-
let inString: string | null = null;
|
|
29
|
-
|
|
30
|
-
for (let i = 0; i < input.length; i++) {
|
|
31
|
-
const char = input[i];
|
|
32
|
-
|
|
33
|
-
// handle strings
|
|
34
|
-
if (inString) {
|
|
35
|
-
if (char === inString && input[i - 1] !== "\\") {
|
|
36
|
-
inString = null;
|
|
37
|
-
}
|
|
38
|
-
continue;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (char === '"' || char === "'" || char === "`") {
|
|
42
|
-
inString = char;
|
|
43
|
-
continue;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (char === "{") {
|
|
47
|
-
if (depth === 0) start = i + 1;
|
|
48
|
-
depth++;
|
|
49
|
-
} else if (char === "}") {
|
|
50
|
-
depth--;
|
|
51
|
-
if (depth === 0 && start !== -1) {
|
|
52
|
-
const expr = input.slice(start, i);
|
|
53
|
-
|
|
54
|
-
if (looksLikeTracking(expr)) {
|
|
55
|
-
result.push(expr);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
start = -1;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return result;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/* ---------------------------------- */
|
|
67
|
-
/* HTML HANDLERS */
|
|
68
|
-
/* ---------------------------------- */
|
|
69
|
-
function extractHTMLHandlers(input: string): string[] {
|
|
70
|
-
const result: string[] = [];
|
|
71
|
-
|
|
72
|
-
const regex = /\bon\w+\s*=\s*["']([^"']+)["']/g;
|
|
73
|
-
|
|
74
|
-
for (const m of input.matchAll(regex)) {
|
|
75
|
-
if (looksLikeTracking(m[1])) {
|
|
76
|
-
result.push(m[1]);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return result;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/* ---------------------------------- */
|
|
84
|
-
/* VUE HANDLERS */
|
|
85
|
-
/* ---------------------------------- */
|
|
86
|
-
function extractVueHandlers(input: string): string[] {
|
|
87
|
-
const result: string[] = [];
|
|
88
|
-
|
|
89
|
-
const regex = /(?:@|v-on:)[\w:-]+\s*=\s*["']([^"']+)["']/g;
|
|
90
|
-
|
|
91
|
-
for (const m of input.matchAll(regex)) {
|
|
92
|
-
if (looksLikeTracking(m[1])) {
|
|
93
|
-
result.push(m[1]);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return result;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/* ---------------------------------- */
|
|
101
|
-
/* SVELTE HANDLERS */
|
|
102
|
-
/* ---------------------------------- */
|
|
103
|
-
function extractSvelteHandlers(input: string): string[] {
|
|
104
|
-
const result: string[] = [];
|
|
105
|
-
|
|
106
|
-
const regex = /\bon:[\w]+\s*=\s*{([\s\S]*?)}/g;
|
|
107
|
-
|
|
108
|
-
for (const m of input.matchAll(regex)) {
|
|
109
|
-
const expr = m[1];
|
|
110
|
-
|
|
111
|
-
const nested = extractBracedExpressions(`{${expr}}`);
|
|
112
|
-
result.push(...nested);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
return result;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/* ---------------------------------- */
|
|
119
|
-
/* SCRIPT EXTRACTION */
|
|
120
|
-
/* ---------------------------------- */
|
|
121
|
-
function extractScripts(input: string, file: string) {
|
|
122
|
-
const scripts: string[] = [];
|
|
123
|
-
const deps: string[] = [];
|
|
124
|
-
|
|
125
|
-
// <script src="">
|
|
126
|
-
const srcRegex =
|
|
127
|
-
/<script\b[^>]*?\bsrc=["'](.+?)["'][^>]*>/gi;
|
|
128
|
-
|
|
129
|
-
for (const m of input.matchAll(srcRegex)) {
|
|
130
|
-
const src = m[1];
|
|
131
|
-
|
|
132
|
-
const resolved = src.startsWith("/")
|
|
133
|
-
? path.resolve(process.cwd(), "." + src)
|
|
134
|
-
: path.resolve(path.dirname(file), src);
|
|
135
|
-
|
|
136
|
-
deps.push(resolved);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// inline <script>
|
|
140
|
-
const scriptRegex =
|
|
141
|
-
/<script\b[^>]*>([\s\S]*?)<\/script>/gi;
|
|
142
|
-
|
|
143
|
-
for (const m of input.matchAll(scriptRegex)) {
|
|
144
|
-
if (m[1]?.trim()) {
|
|
145
|
-
scripts.push(m[1]);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
const noScripts = input.replace(scriptRegex, "");
|
|
150
|
-
|
|
151
|
-
return { scripts, deps, noScripts };
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/* ---------------------------------- */
|
|
155
|
-
/* STATIC IMPORTS */
|
|
156
|
-
/* ---------------------------------- */
|
|
157
|
-
function extractStaticImports(input: string, file: string) {
|
|
158
|
-
const deps: string[] = [];
|
|
159
|
-
|
|
160
|
-
const regex =
|
|
161
|
-
/import\s+(?:.+?\s+from\s+)?["'](.+?)["']/g;
|
|
162
|
-
|
|
163
|
-
for (const m of input.matchAll(regex)) {
|
|
164
|
-
const mod = m[1];
|
|
165
|
-
|
|
166
|
-
if (!mod.startsWith(".") && !mod.startsWith("/")) continue;
|
|
167
|
-
|
|
168
|
-
const resolved = path.resolve(
|
|
169
|
-
path.dirname(file),
|
|
170
|
-
mod
|
|
171
|
-
);
|
|
172
|
-
|
|
173
|
-
deps.push(resolved);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
return deps;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/* ---------------------------------- */
|
|
180
|
-
/* DYNAMIC IMPORTS */
|
|
181
|
-
/* ---------------------------------- */
|
|
182
|
-
function extractDynamicImports(input: string, file: string) {
|
|
183
|
-
const deps: string[] = [];
|
|
184
|
-
const calls: string[] = [];
|
|
185
|
-
|
|
186
|
-
const regex = /import\(\s*["'](.+?)["']\s*\)/g;
|
|
187
|
-
|
|
188
|
-
for (const m of input.matchAll(regex)) {
|
|
189
|
-
const mod = m[1];
|
|
190
|
-
|
|
191
|
-
const resolved = mod.startsWith("/")
|
|
192
|
-
? path.resolve(process.cwd(), "." + mod)
|
|
193
|
-
: path.resolve(path.dirname(file), mod);
|
|
194
|
-
|
|
195
|
-
deps.push(resolved);
|
|
196
|
-
|
|
197
|
-
if (looksLikeTracking(mod)) {
|
|
198
|
-
calls.push(`import("${mod}")`);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
return { deps, calls };
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/* ---------------------------------- */
|
|
206
|
-
/* MAIN */
|
|
207
|
-
/* ---------------------------------- */
|
|
208
|
-
export function parseUniversal(
|
|
209
|
-
content: string,
|
|
210
|
-
file: string
|
|
211
|
-
): ParseResult {
|
|
212
|
-
const parts: string[] = [];
|
|
213
|
-
const deps: string[] = [];
|
|
214
|
-
|
|
215
|
-
const clean = stripComments(content);
|
|
216
|
-
|
|
217
|
-
/* ---------- ASTRO FRONTMATTER ---------- */
|
|
218
|
-
const fm = clean.match(/^\s*---([\s\S]*?)---/);
|
|
219
|
-
if (fm?.[1]) {
|
|
220
|
-
parts.push(fm[1]);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/* ---------- SCRIPTS ---------- */
|
|
224
|
-
const { scripts, deps: scriptDeps, noScripts } =
|
|
225
|
-
extractScripts(clean, file);
|
|
226
|
-
|
|
227
|
-
parts.push(...scripts);
|
|
228
|
-
deps.push(...scriptDeps);
|
|
229
|
-
|
|
230
|
-
/* ---------- HANDLERS ---------- */
|
|
231
|
-
parts.push(...extractHTMLHandlers(noScripts));
|
|
232
|
-
parts.push(...extractVueHandlers(noScripts));
|
|
233
|
-
parts.push(...extractSvelteHandlers(noScripts));
|
|
234
|
-
|
|
235
|
-
/* ---------- JSX / TEMPLATE ---------- */
|
|
236
|
-
parts.push(...extractBracedExpressions(clean));
|
|
237
|
-
|
|
238
|
-
/* ---------- IMPORTS ---------- */
|
|
239
|
-
deps.push(...extractStaticImports(clean, file));
|
|
240
|
-
|
|
241
|
-
const dyn = extractDynamicImports(clean, file);
|
|
242
|
-
deps.push(...dyn.deps);
|
|
243
|
-
parts.push(...dyn.calls);
|
|
244
|
-
|
|
245
|
-
return {
|
|
246
|
-
code: parts.length ? parts.join("\n") : content,
|
|
247
|
-
deps: [...new Set(deps.filter(Boolean))],
|
|
248
|
-
};
|
|
249
|
-
}
|
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
|
-
|
|
3
|
-
declare function track(event: string): void;
|
|
4
|
-
|
|
5
|
-
const express = (...args: any[]) => ({
|
|
6
|
-
get: (...args: any[]) => {},
|
|
7
|
-
post: (...args: any[]) => {},
|
|
8
|
-
put: (...args: any[]) => {},
|
|
9
|
-
delete: (...args: any[]) => {},
|
|
10
|
-
use: (...args: any[]) => {},
|
|
11
|
-
listen: (...args: any[]) => {}
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
const app = express();
|
|
15
|
-
|
|
16
|
-
// =========================
|
|
17
|
-
// BASIC
|
|
18
|
-
// =========================
|
|
19
|
-
|
|
20
|
-
track("express_event");
|
|
21
|
-
|
|
22
|
-
// =========================
|
|
23
|
-
// VARIABLES
|
|
24
|
-
// =========================
|
|
25
|
-
|
|
26
|
-
const eventName = "variable_event";
|
|
27
|
-
track(eventName);
|
|
28
|
-
|
|
29
|
-
let anotherEvent;
|
|
30
|
-
anotherEvent = "assigned_event";
|
|
31
|
-
track(anotherEvent);
|
|
32
|
-
|
|
33
|
-
// =========================
|
|
34
|
-
// TEMPLATE
|
|
35
|
-
// =========================
|
|
36
|
-
|
|
37
|
-
track(`template_event`);
|
|
38
|
-
|
|
39
|
-
const id = "123";
|
|
40
|
-
track(`template_${id}`); // dynamic
|
|
41
|
-
|
|
42
|
-
// =========================
|
|
43
|
-
// MIDDLEWARE
|
|
44
|
-
// =========================
|
|
45
|
-
|
|
46
|
-
app.use(() => {
|
|
47
|
-
track("middleware_event");
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
// =========================
|
|
51
|
-
// ROUTES
|
|
52
|
-
// =========================
|
|
53
|
-
|
|
54
|
-
app.get("/", () => {
|
|
55
|
-
track("get_event");
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
app.post("/users", () => {
|
|
59
|
-
track("post_event");
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
app.put("/users", () => {
|
|
63
|
-
track("put_event");
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
app.delete("/users", () => {
|
|
67
|
-
track("delete_event");
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
// =========================
|
|
71
|
-
// NESTED
|
|
72
|
-
// =========================
|
|
73
|
-
|
|
74
|
-
app.get("/nested", () => {
|
|
75
|
-
if (true) {
|
|
76
|
-
track("nested_event");
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
// =========================
|
|
81
|
-
// ASYNC
|
|
82
|
-
// =========================
|
|
83
|
-
|
|
84
|
-
app.get("/async", async () => {
|
|
85
|
-
track("async_event");
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
// =========================
|
|
89
|
-
// ARROW HANDLER
|
|
90
|
-
// =========================
|
|
91
|
-
|
|
92
|
-
const handler = () => {
|
|
93
|
-
track("arrow_event");
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
app.get("/arrow", handler);
|
|
97
|
-
|
|
98
|
-
// =========================
|
|
99
|
-
// FUNCTION DECLARATION
|
|
100
|
-
// =========================
|
|
101
|
-
|
|
102
|
-
function service() {
|
|
103
|
-
track("function_event");
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// =========================
|
|
107
|
-
// CLASS
|
|
108
|
-
// =========================
|
|
109
|
-
|
|
110
|
-
class Service {
|
|
111
|
-
run() {
|
|
112
|
-
track("class_event");
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// =========================
|
|
117
|
-
// LISTEN
|
|
118
|
-
// =========================
|
|
119
|
-
|
|
120
|
-
app.listen(3000, () => {
|
|
121
|
-
track("listen_event");
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
// =========================
|
|
125
|
-
// OBJECT WRAPPER
|
|
126
|
-
// =========================
|
|
127
|
-
|
|
128
|
-
const analytics = {
|
|
129
|
-
track
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
analytics.track("object_event");
|
|
133
|
-
|
|
134
|
-
// nested object
|
|
135
|
-
const analyticsDeep = {
|
|
136
|
-
events: {
|
|
137
|
-
track
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
analyticsDeep.events.track("nested_object_event");
|
|
142
|
-
|
|
143
|
-
// =========================
|
|
144
|
-
// CONDITIONALS
|
|
145
|
-
// =========================
|
|
146
|
-
|
|
147
|
-
if (true) {
|
|
148
|
-
track("if_event");
|
|
149
|
-
} else {
|
|
150
|
-
track("else_event");
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// ternary
|
|
154
|
-
true
|
|
155
|
-
? track("ternary_true")
|
|
156
|
-
: track("ternary_false");
|
|
157
|
-
|
|
158
|
-
// =========================
|
|
159
|
-
// ARRAYS
|
|
160
|
-
// =========================
|
|
161
|
-
|
|
162
|
-
[
|
|
163
|
-
() => track("array_1"),
|
|
164
|
-
() => track("array_2")
|
|
165
|
-
];
|
|
166
|
-
|
|
167
|
-
// =========================
|
|
168
|
-
// LOOP
|
|
169
|
-
// =========================
|
|
170
|
-
|
|
171
|
-
for (let i = 0; i < 1; i++) {
|
|
172
|
-
track("loop_event");
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// =========================
|
|
176
|
-
// TRY / CATCH
|
|
177
|
-
// =========================
|
|
178
|
-
|
|
179
|
-
try {
|
|
180
|
-
track("try_event");
|
|
181
|
-
} catch {
|
|
182
|
-
track("catch_event");
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// =========================
|
|
186
|
-
// RETURN
|
|
187
|
-
// =========================
|
|
188
|
-
|
|
189
|
-
function returnTest() {
|
|
190
|
-
return track("return_event");
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// =========================
|
|
194
|
-
// PARAM DEFAULT
|
|
195
|
-
// =========================
|
|
196
|
-
|
|
197
|
-
function withDefault(e = "default_event") {
|
|
198
|
-
track(e);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// =========================
|
|
202
|
-
// INLINE OBJECT
|
|
203
|
-
// =========================
|
|
204
|
-
|
|
205
|
-
track({
|
|
206
|
-
name: "object_payload_event"
|
|
207
|
-
} as any);
|
|
208
|
-
|
|
209
|
-
// =========================
|
|
210
|
-
// OPTIONAL CHAINING
|
|
211
|
-
// =========================
|
|
212
|
-
|
|
213
|
-
analytics?.track?.("optional_chain_event");
|
|
214
|
-
|
|
215
|
-
// =========================
|
|
216
|
-
// EDGE CASES
|
|
217
|
-
// =========================
|
|
218
|
-
|
|
219
|
-
// not first argument (should be ignored usually)
|
|
220
|
-
// @ts-ignore
|
|
221
|
-
track("real_event", "extra");
|
|
222
|
-
|
|
223
|
-
// no args
|
|
224
|
-
// @ts-ignore
|
|
225
|
-
track();
|
|
226
|
-
|
|
227
|
-
// dynamic identifier (should be dynamic)
|
|
228
|
-
const dynamicEvent = Math.random() > 0.5 ? "a" : "b";
|
|
229
|
-
track(dynamicEvent);
|
|
230
|
-
|
|
231
|
-
// =========================
|
|
232
|
-
// END
|
|
233
|
-
// =========================
|