@eventra_dev/eventra-cli 0.0.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/.github/workflows/release.yml +40 -0
- package/LICENSE +9 -0
- package/README.md +310 -0
- package/dist/commands/init.js +42 -0
- package/dist/commands/send.js +67 -0
- package/dist/commands/sync.js +216 -0
- package/dist/index.js +64 -0
- package/dist/utils/config.js +43 -0
- package/package.json +30 -0
- package/src/commands/init.ts +60 -0
- package/src/commands/send.ts +124 -0
- package/src/commands/sync.ts +397 -0
- package/src/index.ts +36 -0
- package/src/utils/config.ts +53 -0
- package/tsconfig.json +12 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
const commander_1 = require("commander");
|
|
38
|
+
const program = new commander_1.Command();
|
|
39
|
+
program
|
|
40
|
+
.name("eventra")
|
|
41
|
+
.description("Eventra CLI")
|
|
42
|
+
.version("0.0.1");
|
|
43
|
+
program
|
|
44
|
+
.command("init")
|
|
45
|
+
.description("Initialize Eventra")
|
|
46
|
+
.action(async () => {
|
|
47
|
+
const { init } = await Promise.resolve().then(() => __importStar(require("./commands/init")));
|
|
48
|
+
await init();
|
|
49
|
+
});
|
|
50
|
+
program
|
|
51
|
+
.command("sync")
|
|
52
|
+
.description("Sync events")
|
|
53
|
+
.action(async () => {
|
|
54
|
+
const { sync } = await Promise.resolve().then(() => __importStar(require("./commands/sync")));
|
|
55
|
+
await sync();
|
|
56
|
+
});
|
|
57
|
+
program
|
|
58
|
+
.command("send")
|
|
59
|
+
.description("Send events")
|
|
60
|
+
.action(async () => {
|
|
61
|
+
const { send } = await Promise.resolve().then(() => __importStar(require("./commands/send")));
|
|
62
|
+
await send();
|
|
63
|
+
});
|
|
64
|
+
program.parse();
|
|
@@ -0,0 +1,43 @@
|
|
|
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.CONFIG_NAME = void 0;
|
|
7
|
+
exports.normalizeConfig = normalizeConfig;
|
|
8
|
+
exports.loadConfig = loadConfig;
|
|
9
|
+
exports.saveConfig = saveConfig;
|
|
10
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
exports.CONFIG_NAME = "eventra.json";
|
|
13
|
+
function normalizeConfig(config) {
|
|
14
|
+
return {
|
|
15
|
+
apiKey: config.apiKey ?? "",
|
|
16
|
+
events: config.events ?? [],
|
|
17
|
+
wrappers: config.wrappers ?? [],
|
|
18
|
+
sync: config.sync ?? {
|
|
19
|
+
include: ["**/*.{ts,tsx,js,jsx}"],
|
|
20
|
+
exclude: [
|
|
21
|
+
"node_modules",
|
|
22
|
+
"dist",
|
|
23
|
+
".next",
|
|
24
|
+
".git"
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
async function loadConfig() {
|
|
30
|
+
const configPath = path_1.default.join(process.cwd(), exports.CONFIG_NAME);
|
|
31
|
+
if (!(await fs_extra_1.default.pathExists(configPath))) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
const config = await fs_extra_1.default.readJSON(configPath);
|
|
35
|
+
return normalizeConfig(config);
|
|
36
|
+
}
|
|
37
|
+
async function saveConfig(config) {
|
|
38
|
+
const configPath = path_1.default.join(process.cwd(), exports.CONFIG_NAME);
|
|
39
|
+
const normalized = normalizeConfig(config);
|
|
40
|
+
await fs_extra_1.default.writeJSON(configPath, normalized, {
|
|
41
|
+
spaces: 2
|
|
42
|
+
});
|
|
43
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@eventra_dev/eventra-cli",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Eventra CLI",
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"bin": {
|
|
7
|
+
"eventra": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"access": "public",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc && chmod +x dist/index.js",
|
|
13
|
+
"dev": "tsx src/index.ts"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"chalk": "^4.1.2",
|
|
17
|
+
"commander": "^11.0.0",
|
|
18
|
+
"fast-glob": "^3.3.3",
|
|
19
|
+
"fs-extra": "^11.2.0",
|
|
20
|
+
"inquirer": "^8.2.7",
|
|
21
|
+
"ts-morph": "^27.0.2"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/fs-extra": "^11.0.4",
|
|
25
|
+
"@types/inquirer": "^9.0.9",
|
|
26
|
+
"@types/node": "^20.0.0",
|
|
27
|
+
"tsx": "^4.7.0",
|
|
28
|
+
"typescript": "^5.3.0"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import fs from "fs-extra";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import inquirer from "inquirer";
|
|
5
|
+
import {
|
|
6
|
+
CONFIG_NAME,
|
|
7
|
+
saveConfig
|
|
8
|
+
} from "../utils/config";
|
|
9
|
+
|
|
10
|
+
export async function init() {
|
|
11
|
+
console.log(
|
|
12
|
+
chalk.blue("Initializing Eventra...")
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
const configPath = path.join(
|
|
16
|
+
process.cwd(),
|
|
17
|
+
CONFIG_NAME
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
if (await fs.pathExists(configPath)) {
|
|
21
|
+
console.log(
|
|
22
|
+
chalk.yellow(
|
|
23
|
+
"eventra.json already exists"
|
|
24
|
+
)
|
|
25
|
+
);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const answers = await inquirer.prompt([
|
|
30
|
+
{
|
|
31
|
+
type: "input",
|
|
32
|
+
name: "apiKey",
|
|
33
|
+
message:
|
|
34
|
+
"API Key (optional):"
|
|
35
|
+
}
|
|
36
|
+
]);
|
|
37
|
+
|
|
38
|
+
const config = {
|
|
39
|
+
apiKey: answers.apiKey || "",
|
|
40
|
+
events: [],
|
|
41
|
+
wrappers: [],
|
|
42
|
+
sync: {
|
|
43
|
+
include: ["**/*.{ts,tsx,js,jsx}"],
|
|
44
|
+
exclude: [
|
|
45
|
+
"node_modules",
|
|
46
|
+
"dist",
|
|
47
|
+
".next",
|
|
48
|
+
".git"
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
await saveConfig(config);
|
|
54
|
+
|
|
55
|
+
console.log(
|
|
56
|
+
chalk.green(
|
|
57
|
+
"eventra.json created"
|
|
58
|
+
)
|
|
59
|
+
);
|
|
60
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import inquirer from "inquirer";
|
|
3
|
+
import {
|
|
4
|
+
loadConfig,
|
|
5
|
+
saveConfig
|
|
6
|
+
} from "../utils/config";
|
|
7
|
+
|
|
8
|
+
const EVENTRA_ENDPOINT = process.env.EVENTRA_ENDPOINT ?? "";
|
|
9
|
+
|
|
10
|
+
const CLI_VERSION = "0.0.1";
|
|
11
|
+
|
|
12
|
+
export async function send() {
|
|
13
|
+
let config = await loadConfig();
|
|
14
|
+
|
|
15
|
+
if (!config) {
|
|
16
|
+
console.log(
|
|
17
|
+
chalk.red(
|
|
18
|
+
"eventra.json not found. Run 'eventra init'"
|
|
19
|
+
)
|
|
20
|
+
);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let apiKey = config.apiKey;
|
|
25
|
+
|
|
26
|
+
if (!apiKey) {
|
|
27
|
+
const answers =
|
|
28
|
+
await inquirer.prompt([
|
|
29
|
+
{
|
|
30
|
+
type: "input",
|
|
31
|
+
name: "apiKey",
|
|
32
|
+
message:
|
|
33
|
+
"Enter your API key:"
|
|
34
|
+
}
|
|
35
|
+
]);
|
|
36
|
+
|
|
37
|
+
apiKey = answers.apiKey;
|
|
38
|
+
|
|
39
|
+
config.apiKey = apiKey;
|
|
40
|
+
|
|
41
|
+
await saveConfig(config);
|
|
42
|
+
|
|
43
|
+
console.log(
|
|
44
|
+
chalk.green(
|
|
45
|
+
"API key saved"
|
|
46
|
+
)
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (!config.events.length) {
|
|
51
|
+
console.log(
|
|
52
|
+
chalk.yellow(
|
|
53
|
+
"No events found. Run 'eventra sync'"
|
|
54
|
+
)
|
|
55
|
+
);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
console.log(
|
|
60
|
+
chalk.blue("Sending events...")
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
const res = await fetch(EVENTRA_ENDPOINT,
|
|
65
|
+
{
|
|
66
|
+
method: "POST",
|
|
67
|
+
headers: {
|
|
68
|
+
"Content-Type":
|
|
69
|
+
"application/json",
|
|
70
|
+
"x-api-key": apiKey
|
|
71
|
+
},
|
|
72
|
+
body: JSON.stringify({
|
|
73
|
+
events: config.events,
|
|
74
|
+
cli: {
|
|
75
|
+
name:
|
|
76
|
+
"@eventra_dev/eventra-cli",
|
|
77
|
+
version: CLI_VERSION,
|
|
78
|
+
runtime: "node"
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
if (res.status >= 400) {
|
|
85
|
+
console.log(
|
|
86
|
+
chalk.red(
|
|
87
|
+
`Failed (${res.status})`
|
|
88
|
+
)
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const data = await res.json();
|
|
95
|
+
|
|
96
|
+
console.log(
|
|
97
|
+
chalk.green(
|
|
98
|
+
"Events registered successfully"
|
|
99
|
+
)
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
if (data.created?.length) {
|
|
103
|
+
console.log(
|
|
104
|
+
chalk.green(
|
|
105
|
+
"\nNew events:"
|
|
106
|
+
)
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
data.created.forEach(
|
|
110
|
+
(e: string) =>
|
|
111
|
+
console.log(
|
|
112
|
+
chalk.green(
|
|
113
|
+
`+ ${e}`
|
|
114
|
+
)
|
|
115
|
+
)
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
} catch {
|
|
120
|
+
console.log(
|
|
121
|
+
chalk.red("Network error")
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
import { Project, SyntaxKind } from "ts-morph";
|
|
2
|
+
import fg from "fast-glob";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import inquirer from "inquirer";
|
|
5
|
+
import {
|
|
6
|
+
loadConfig,
|
|
7
|
+
saveConfig
|
|
8
|
+
} from "../utils/config";
|
|
9
|
+
|
|
10
|
+
export async function sync() {
|
|
11
|
+
let config = await loadConfig();
|
|
12
|
+
|
|
13
|
+
if (!config) {
|
|
14
|
+
console.log(
|
|
15
|
+
chalk.red(
|
|
16
|
+
"Run 'eventra init' first"
|
|
17
|
+
)
|
|
18
|
+
);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const events = new Set<string>();
|
|
23
|
+
const project = new Project();
|
|
24
|
+
|
|
25
|
+
console.log(
|
|
26
|
+
chalk.blue("Scanning project...")
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
const files = await fg(
|
|
30
|
+
config.sync.include,
|
|
31
|
+
{
|
|
32
|
+
ignore: config.sync.exclude
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
// track()
|
|
37
|
+
for (const file of files) {
|
|
38
|
+
const sourceFile =
|
|
39
|
+
project.addSourceFileAtPath(file);
|
|
40
|
+
|
|
41
|
+
const calls =
|
|
42
|
+
sourceFile.getDescendantsOfKind(
|
|
43
|
+
SyntaxKind.CallExpression
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
for (const call of calls) {
|
|
47
|
+
const expression =
|
|
48
|
+
call.getExpression();
|
|
49
|
+
|
|
50
|
+
if (
|
|
51
|
+
expression.getKind() ===
|
|
52
|
+
SyntaxKind.PropertyAccessExpression
|
|
53
|
+
) {
|
|
54
|
+
const prop =
|
|
55
|
+
expression.asKind(
|
|
56
|
+
SyntaxKind.PropertyAccessExpression
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
if (!prop) continue;
|
|
60
|
+
|
|
61
|
+
if (prop.getName() !== "track")
|
|
62
|
+
continue;
|
|
63
|
+
|
|
64
|
+
const args =
|
|
65
|
+
call.getArguments();
|
|
66
|
+
|
|
67
|
+
const eventArg =
|
|
68
|
+
args[0];
|
|
69
|
+
|
|
70
|
+
if (!eventArg) continue;
|
|
71
|
+
|
|
72
|
+
let event: string | null = null;
|
|
73
|
+
|
|
74
|
+
// "event"
|
|
75
|
+
if (
|
|
76
|
+
eventArg.getKind() ===
|
|
77
|
+
SyntaxKind.StringLiteral
|
|
78
|
+
) {
|
|
79
|
+
event =
|
|
80
|
+
eventArg
|
|
81
|
+
.asKindOrThrow(
|
|
82
|
+
SyntaxKind.StringLiteral
|
|
83
|
+
)
|
|
84
|
+
.getLiteralText();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// `event`
|
|
88
|
+
if (
|
|
89
|
+
eventArg.getKind() ===
|
|
90
|
+
SyntaxKind.NoSubstitutionTemplateLiteral
|
|
91
|
+
) {
|
|
92
|
+
event =
|
|
93
|
+
eventArg
|
|
94
|
+
.asKindOrThrow(
|
|
95
|
+
SyntaxKind.NoSubstitutionTemplateLiteral
|
|
96
|
+
)
|
|
97
|
+
.getLiteralText();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (event) {
|
|
101
|
+
events.add(event);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
console.log(
|
|
108
|
+
chalk.green(
|
|
109
|
+
`Found ${events.size} track events`
|
|
110
|
+
)
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
// wrappers setup
|
|
114
|
+
if (!config.wrappers.length) {
|
|
115
|
+
const { useWrapper } =
|
|
116
|
+
await inquirer.prompt([
|
|
117
|
+
{
|
|
118
|
+
type: "confirm",
|
|
119
|
+
name: "useWrapper",
|
|
120
|
+
message:
|
|
121
|
+
"Use wrapper components?",
|
|
122
|
+
default: true
|
|
123
|
+
}
|
|
124
|
+
]);
|
|
125
|
+
|
|
126
|
+
if (useWrapper) {
|
|
127
|
+
const wrappers = [];
|
|
128
|
+
|
|
129
|
+
let addMore = true;
|
|
130
|
+
|
|
131
|
+
while (addMore) {
|
|
132
|
+
const answers =
|
|
133
|
+
await inquirer.prompt([
|
|
134
|
+
{
|
|
135
|
+
type: "input",
|
|
136
|
+
name: "name",
|
|
137
|
+
message:
|
|
138
|
+
"Wrapper component name:"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
type: "input",
|
|
142
|
+
name: "prop",
|
|
143
|
+
message:
|
|
144
|
+
"Event prop name:"
|
|
145
|
+
}
|
|
146
|
+
]);
|
|
147
|
+
|
|
148
|
+
wrappers.push({
|
|
149
|
+
name: answers.name,
|
|
150
|
+
prop: answers.prop
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
const more =
|
|
154
|
+
await inquirer.prompt([
|
|
155
|
+
{
|
|
156
|
+
type: "confirm",
|
|
157
|
+
name: "more",
|
|
158
|
+
message:
|
|
159
|
+
"Add another wrapper?",
|
|
160
|
+
default: false
|
|
161
|
+
}
|
|
162
|
+
]);
|
|
163
|
+
|
|
164
|
+
addMore = more.more;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
config.wrappers = wrappers;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// scan wrappers
|
|
172
|
+
if (config.wrappers.length) {
|
|
173
|
+
console.log(
|
|
174
|
+
chalk.blue(
|
|
175
|
+
"Scanning wrappers..."
|
|
176
|
+
)
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
for (const file of files) {
|
|
180
|
+
const sourceFile =
|
|
181
|
+
project.addSourceFileAtPath(file);
|
|
182
|
+
|
|
183
|
+
const elements = [
|
|
184
|
+
...sourceFile.getDescendantsOfKind(
|
|
185
|
+
SyntaxKind.JsxOpeningElement
|
|
186
|
+
),
|
|
187
|
+
...sourceFile.getDescendantsOfKind(
|
|
188
|
+
SyntaxKind.JsxSelfClosingElement
|
|
189
|
+
)
|
|
190
|
+
];
|
|
191
|
+
|
|
192
|
+
for (const element of elements) {
|
|
193
|
+
const tagName =
|
|
194
|
+
element
|
|
195
|
+
.getTagNameNode()
|
|
196
|
+
.getText()
|
|
197
|
+
.toLowerCase();
|
|
198
|
+
|
|
199
|
+
for (const wrapper of config.wrappers) {
|
|
200
|
+
if (
|
|
201
|
+
tagName !==
|
|
202
|
+
wrapper.name.toLowerCase()
|
|
203
|
+
)
|
|
204
|
+
continue;
|
|
205
|
+
|
|
206
|
+
const attrs =
|
|
207
|
+
element.getAttributes();
|
|
208
|
+
|
|
209
|
+
for (const attr of attrs) {
|
|
210
|
+
if (
|
|
211
|
+
attr.getKind() !==
|
|
212
|
+
SyntaxKind.JsxAttribute
|
|
213
|
+
)
|
|
214
|
+
continue;
|
|
215
|
+
|
|
216
|
+
const attrNode =
|
|
217
|
+
attr.asKind(
|
|
218
|
+
SyntaxKind.JsxAttribute
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
if (!attrNode) continue;
|
|
222
|
+
|
|
223
|
+
const attrName =
|
|
224
|
+
attrNode
|
|
225
|
+
.getNameNode()
|
|
226
|
+
.getText()
|
|
227
|
+
.toLowerCase();
|
|
228
|
+
|
|
229
|
+
if (
|
|
230
|
+
attrName !==
|
|
231
|
+
wrapper.prop.toLowerCase()
|
|
232
|
+
)
|
|
233
|
+
continue;
|
|
234
|
+
|
|
235
|
+
const initializer =
|
|
236
|
+
attrNode.getInitializer();
|
|
237
|
+
|
|
238
|
+
if (!initializer) continue;
|
|
239
|
+
|
|
240
|
+
let value: string | null = null;
|
|
241
|
+
|
|
242
|
+
// event="signup"
|
|
243
|
+
if (
|
|
244
|
+
initializer.getKind() ===
|
|
245
|
+
SyntaxKind.StringLiteral
|
|
246
|
+
) {
|
|
247
|
+
value =
|
|
248
|
+
initializer
|
|
249
|
+
.asKindOrThrow(
|
|
250
|
+
SyntaxKind.StringLiteral
|
|
251
|
+
)
|
|
252
|
+
.getLiteralText();
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// event={"signup"}
|
|
256
|
+
if (
|
|
257
|
+
initializer.getKind() ===
|
|
258
|
+
SyntaxKind.JsxExpression
|
|
259
|
+
) {
|
|
260
|
+
const expr =
|
|
261
|
+
initializer
|
|
262
|
+
.asKindOrThrow(
|
|
263
|
+
SyntaxKind.JsxExpression
|
|
264
|
+
)
|
|
265
|
+
.getExpression();
|
|
266
|
+
|
|
267
|
+
if (
|
|
268
|
+
expr?.getKind() ===
|
|
269
|
+
SyntaxKind.StringLiteral
|
|
270
|
+
) {
|
|
271
|
+
value =
|
|
272
|
+
expr
|
|
273
|
+
.asKindOrThrow(
|
|
274
|
+
SyntaxKind.StringLiteral
|
|
275
|
+
)
|
|
276
|
+
.getLiteralText();
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (value) {
|
|
281
|
+
events.add(value);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// results
|
|
290
|
+
const list =
|
|
291
|
+
[...events].sort();
|
|
292
|
+
|
|
293
|
+
console.log("");
|
|
294
|
+
|
|
295
|
+
console.log(
|
|
296
|
+
chalk.green("Found events:")
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
list.forEach((e) =>
|
|
300
|
+
console.log(
|
|
301
|
+
chalk.gray(`- ${e}`)
|
|
302
|
+
)
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
console.log("");
|
|
306
|
+
|
|
307
|
+
// diff
|
|
308
|
+
const previous =
|
|
309
|
+
config.events ?? [];
|
|
310
|
+
|
|
311
|
+
const added = list.filter(
|
|
312
|
+
(e) => !previous.includes(e)
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
const removed =
|
|
316
|
+
previous.filter(
|
|
317
|
+
(e: string) =>
|
|
318
|
+
!list.includes(e)
|
|
319
|
+
);
|
|
320
|
+
|
|
321
|
+
if (added.length || removed.length) {
|
|
322
|
+
console.log(
|
|
323
|
+
chalk.blue("Changes:")
|
|
324
|
+
);
|
|
325
|
+
|
|
326
|
+
if (added.length) {
|
|
327
|
+
console.log(
|
|
328
|
+
chalk.green(
|
|
329
|
+
"New events:"
|
|
330
|
+
)
|
|
331
|
+
);
|
|
332
|
+
|
|
333
|
+
added.forEach((e) =>
|
|
334
|
+
console.log(
|
|
335
|
+
chalk.green(
|
|
336
|
+
`+ ${e}`
|
|
337
|
+
)
|
|
338
|
+
)
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
if (removed.length) {
|
|
343
|
+
console.log(
|
|
344
|
+
chalk.red(
|
|
345
|
+
"Removed events:"
|
|
346
|
+
)
|
|
347
|
+
);
|
|
348
|
+
|
|
349
|
+
removed.forEach((e: unknown) =>
|
|
350
|
+
console.log(
|
|
351
|
+
chalk.red(
|
|
352
|
+
`- ${e}`
|
|
353
|
+
)
|
|
354
|
+
)
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
console.log("");
|
|
359
|
+
} else {
|
|
360
|
+
console.log(
|
|
361
|
+
chalk.gray(
|
|
362
|
+
"No changes detected"
|
|
363
|
+
)
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// confirm
|
|
368
|
+
const { confirm } =
|
|
369
|
+
await inquirer.prompt([
|
|
370
|
+
{
|
|
371
|
+
type: "confirm",
|
|
372
|
+
name: "confirm",
|
|
373
|
+
message:
|
|
374
|
+
"Sync these events?",
|
|
375
|
+
default: true
|
|
376
|
+
}
|
|
377
|
+
]);
|
|
378
|
+
|
|
379
|
+
if (!confirm) {
|
|
380
|
+
console.log(
|
|
381
|
+
chalk.yellow(
|
|
382
|
+
"Sync cancelled"
|
|
383
|
+
)
|
|
384
|
+
);
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
config.events = list;
|
|
389
|
+
|
|
390
|
+
await saveConfig(config);
|
|
391
|
+
|
|
392
|
+
console.log(
|
|
393
|
+
chalk.green(
|
|
394
|
+
"eventra.json updated"
|
|
395
|
+
)
|
|
396
|
+
);
|
|
397
|
+
}
|