@easyoref/cli 1.21.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/dist/commands/init.d.ts +11 -0
- package/dist/commands/init.js +132 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list-areas.d.ts +4 -0
- package/dist/commands/list-areas.js +16 -0
- package/dist/commands/list-areas.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +78 -0
- package/dist/index.js.map +1 -0
- package/package.json +39 -0
- package/src/commands/init.ts +147 -0
- package/src/commands/list-areas.ts +24 -0
- package/src/index.ts +89 -0
- package/tsconfig.json +21 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `easyoref init` — Interactive setup wizard
|
|
3
|
+
*
|
|
4
|
+
* Walks user through:
|
|
5
|
+
* 1. Language selection (ru/en/he)
|
|
6
|
+
* 2. Bot token input + validation
|
|
7
|
+
* 3. Chat ID input
|
|
8
|
+
* 4. Area selection (checkbox)
|
|
9
|
+
* 5. Generates .env file
|
|
10
|
+
*/
|
|
11
|
+
export declare function init(): Promise<void>;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `easyoref init` — Interactive setup wizard
|
|
3
|
+
*
|
|
4
|
+
* Walks user through:
|
|
5
|
+
* 1. Language selection (ru/en/he)
|
|
6
|
+
* 2. Bot token input + validation
|
|
7
|
+
* 3. Chat ID input
|
|
8
|
+
* 4. Area selection (checkbox)
|
|
9
|
+
* 5. Generates .env file
|
|
10
|
+
*/
|
|
11
|
+
import { checkbox, input, password, select } from "@inquirer/prompts";
|
|
12
|
+
import chalk from "chalk";
|
|
13
|
+
import { Bot } from "grammy";
|
|
14
|
+
import { writeFileSync } from "node:fs";
|
|
15
|
+
import { AREA_CHOICES } from "../data/areas.js";
|
|
16
|
+
export async function init() {
|
|
17
|
+
// ── Step 0: Language ───────────────────────────────────
|
|
18
|
+
const language = await select({
|
|
19
|
+
message: "🌍 Message language / Язык сообщений / שפת ההודעות:",
|
|
20
|
+
choices: [
|
|
21
|
+
{ name: "Русский", value: "ru" },
|
|
22
|
+
{ name: "English", value: "en" },
|
|
23
|
+
{ name: "עברית", value: "he" },
|
|
24
|
+
],
|
|
25
|
+
});
|
|
26
|
+
const t = translations[language];
|
|
27
|
+
// ── Step 1: Bot Token ──────────────────────────────────
|
|
28
|
+
const botToken = await password({
|
|
29
|
+
message: t.botTokenPrompt,
|
|
30
|
+
validate: (val) => {
|
|
31
|
+
if (!val || val.length < 10)
|
|
32
|
+
return t.botTokenRequired;
|
|
33
|
+
if (!val.includes(":"))
|
|
34
|
+
return t.botTokenFormat;
|
|
35
|
+
return true;
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
// Validate token by calling Telegram API
|
|
39
|
+
console.log(chalk.dim(t.validating));
|
|
40
|
+
try {
|
|
41
|
+
const bot = new Bot(botToken);
|
|
42
|
+
const me = await bot.api.getMe();
|
|
43
|
+
console.log(chalk.green(` ✅ ${t.botVerified}: @${me.username}`));
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
console.log(chalk.yellow(` ⚠️ ${t.botVerifyFailed}`));
|
|
47
|
+
}
|
|
48
|
+
// ── Step 2: Chat ID ────────────────────────────────────
|
|
49
|
+
const chatId = await input({
|
|
50
|
+
message: t.chatIdPrompt,
|
|
51
|
+
validate: (val) => {
|
|
52
|
+
if (!val)
|
|
53
|
+
return t.chatIdRequired;
|
|
54
|
+
// Allow negative numbers (groups) and positive (DMs)
|
|
55
|
+
if (!/^-?\d+$/.test(val))
|
|
56
|
+
return t.chatIdFormat;
|
|
57
|
+
return true;
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
// ── Step 3: Areas ──────────────────────────────────────
|
|
61
|
+
const areas = await checkbox({
|
|
62
|
+
message: t.areasPrompt,
|
|
63
|
+
choices: AREA_CHOICES,
|
|
64
|
+
required: true,
|
|
65
|
+
});
|
|
66
|
+
// ── Step 4: Write .env ─────────────────────────────────
|
|
67
|
+
const envContent = [
|
|
68
|
+
"# EasyOref Configuration",
|
|
69
|
+
`# Generated by @easyoref/cli on ${new Date().toISOString().split("T")[0]}`,
|
|
70
|
+
"",
|
|
71
|
+
`BOT_TOKEN=${botToken}`,
|
|
72
|
+
`CHAT_ID=${chatId}`,
|
|
73
|
+
`AREAS=${areas.join(",")}`,
|
|
74
|
+
`LANGUAGE=${language}`,
|
|
75
|
+
"HEALTH_PORT=3100",
|
|
76
|
+
"",
|
|
77
|
+
].join("\n");
|
|
78
|
+
writeFileSync(".env", envContent, "utf-8");
|
|
79
|
+
console.log("");
|
|
80
|
+
console.log(chalk.green.bold(`✅ ${t.configSaved}`));
|
|
81
|
+
console.log("");
|
|
82
|
+
console.log(chalk.dim(t.nextSteps));
|
|
83
|
+
console.log(` ${chalk.cyan("docker compose up -d")} ${chalk.dim("(Docker)")}`);
|
|
84
|
+
console.log(` ${chalk.cyan("npm start")} ${chalk.dim("(Node.js)")}`);
|
|
85
|
+
console.log("");
|
|
86
|
+
}
|
|
87
|
+
// ── i18n for the wizard itself ───────────────────────────
|
|
88
|
+
const translations = {
|
|
89
|
+
ru: {
|
|
90
|
+
botTokenPrompt: "🤖 Токен бота (от @BotFather):",
|
|
91
|
+
botTokenRequired: "Токен обязателен",
|
|
92
|
+
botTokenFormat: "Формат: 123456:ABC-DEF...",
|
|
93
|
+
validating: " Проверяем токен...",
|
|
94
|
+
botVerified: "Бот найден",
|
|
95
|
+
botVerifyFailed: "Не удалось проверить токен (продолжаем)",
|
|
96
|
+
chatIdPrompt: "💬 Chat ID группы (отрицательное число):",
|
|
97
|
+
chatIdRequired: "Chat ID обязателен",
|
|
98
|
+
chatIdFormat: "Chat ID — число (отрицательное для групп)",
|
|
99
|
+
areasPrompt: "📍 Выберите районы для мониторинга (пробел = выбрать):",
|
|
100
|
+
configSaved: "Конфигурация сохранена в .env",
|
|
101
|
+
nextSteps: "Следующий шаг — запустите бота:",
|
|
102
|
+
},
|
|
103
|
+
en: {
|
|
104
|
+
botTokenPrompt: "🤖 Bot Token (from @BotFather):",
|
|
105
|
+
botTokenRequired: "Token is required",
|
|
106
|
+
botTokenFormat: "Format: 123456:ABC-DEF...",
|
|
107
|
+
validating: " Validating token...",
|
|
108
|
+
botVerified: "Bot found",
|
|
109
|
+
botVerifyFailed: "Could not verify token (continuing anyway)",
|
|
110
|
+
chatIdPrompt: "💬 Chat ID (negative number for groups):",
|
|
111
|
+
chatIdRequired: "Chat ID is required",
|
|
112
|
+
chatIdFormat: "Chat ID must be a number (negative for groups)",
|
|
113
|
+
areasPrompt: "📍 Select areas to monitor (space = toggle):",
|
|
114
|
+
configSaved: "Config saved to .env",
|
|
115
|
+
nextSteps: "Next step — start the bot:",
|
|
116
|
+
},
|
|
117
|
+
he: {
|
|
118
|
+
botTokenPrompt: "🤖 טוקן בוט (מ-@BotFather):",
|
|
119
|
+
botTokenRequired: "טוקן נדרש",
|
|
120
|
+
botTokenFormat: "פורמט: 123456:ABC-DEF...",
|
|
121
|
+
validating: " מאמת טוקן...",
|
|
122
|
+
botVerified: "בוט נמצא",
|
|
123
|
+
botVerifyFailed: "לא ניתן לאמת את הטוקן (ממשיכים)",
|
|
124
|
+
chatIdPrompt: "💬 Chat ID (מספר שלילי לקבוצות):",
|
|
125
|
+
chatIdRequired: "Chat ID נדרש",
|
|
126
|
+
chatIdFormat: "Chat ID חייב להיות מספר (שלילי לקבוצות)",
|
|
127
|
+
areasPrompt: "📍 בחר אזורים לניטור (רווח = בחירה):",
|
|
128
|
+
configSaved: "הגדרות נשמרו ל-.env",
|
|
129
|
+
nextSteps: "שלב הבא — הפעל את הבוט:",
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `easyoref list-areas` — Print all available Oref area names
|
|
3
|
+
*/
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import { AREA_CHOICES } from "../data/areas.js";
|
|
6
|
+
export function listAreas() {
|
|
7
|
+
console.log(chalk.bold("Available Oref areas for AREAS env var:\n"));
|
|
8
|
+
console.log(chalk.dim("Copy the Hebrew name (right column) into your .env AREAS field.\n"));
|
|
9
|
+
const maxName = Math.max(...AREA_CHOICES.map((c) => c.name.length));
|
|
10
|
+
for (const choice of AREA_CHOICES) {
|
|
11
|
+
const padded = choice.name.padEnd(maxName + 2);
|
|
12
|
+
console.log(` ${padded} ${chalk.cyan(choice.value)}`);
|
|
13
|
+
}
|
|
14
|
+
console.log(chalk.dim("\nExample: AREAS=תל אביב - דרום העיר ויפו,גוש דן"));
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=list-areas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-areas.js","sourceRoot":"","sources":["../../src/commands/list-areas.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,MAAM,UAAU,SAAS;IACvB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,GAAG,CACP,mEAAmE,CACpE,CACF,CAAC;IAEF,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAEpE,KAAK,MAAM,MAAM,IAAI,YAAY,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC,CAAC;AAC7E,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#! /usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @easyoref/cli — Interactive setup wizard
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* npx @easyoref/cli init — interactive setup
|
|
7
|
+
* npx @easyoref/cli list-areas — show all Oref area names
|
|
8
|
+
* npx @easyoref/cli update — update RPi deployment
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#! /usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @easyoref/cli — Interactive setup wizard
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* npx @easyoref/cli init — interactive setup
|
|
7
|
+
* npx @easyoref/cli list-areas — show all Oref area names
|
|
8
|
+
* npx @easyoref/cli update — update RPi deployment
|
|
9
|
+
*/
|
|
10
|
+
import chalk from "chalk";
|
|
11
|
+
import { execSync } from "node:child_process";
|
|
12
|
+
import { existsSync } from "node:fs";
|
|
13
|
+
import { resolve } from "node:path";
|
|
14
|
+
import { init } from "./commands/init.js";
|
|
15
|
+
import { listAreas } from "./commands/list-areas.js";
|
|
16
|
+
const command = process.argv[2];
|
|
17
|
+
const args = process.argv.slice(3);
|
|
18
|
+
async function main() {
|
|
19
|
+
console.log(chalk.bold("\n🚨 EasyOref — Setup Wizard\n"));
|
|
20
|
+
switch (command) {
|
|
21
|
+
case "init":
|
|
22
|
+
case undefined:
|
|
23
|
+
await init();
|
|
24
|
+
break;
|
|
25
|
+
case "list-areas":
|
|
26
|
+
listAreas();
|
|
27
|
+
break;
|
|
28
|
+
case "update":
|
|
29
|
+
update(args[0]);
|
|
30
|
+
break;
|
|
31
|
+
case "--help":
|
|
32
|
+
case "-h":
|
|
33
|
+
printHelp();
|
|
34
|
+
break;
|
|
35
|
+
default:
|
|
36
|
+
console.log(chalk.red(`Unknown command: ${command}`));
|
|
37
|
+
printHelp();
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function printHelp() {
|
|
42
|
+
console.log(`${chalk.bold("Commands:")}
|
|
43
|
+
${chalk.cyan("init")} Interactive setup wizard (default)
|
|
44
|
+
${chalk.cyan("list-areas")} Show all Oref area names with translations
|
|
45
|
+
${chalk.cyan("update")} Update RPi deployment
|
|
46
|
+
${chalk.cyan("update /path/to/deploy")} Update in specific directory
|
|
47
|
+
${chalk.cyan("--help")} Show this help message
|
|
48
|
+
`);
|
|
49
|
+
}
|
|
50
|
+
function update(path) {
|
|
51
|
+
const targetPath = path
|
|
52
|
+
? resolve(path)
|
|
53
|
+
: process.cwd();
|
|
54
|
+
const composePath = resolve(targetPath, "docker-compose.yml");
|
|
55
|
+
const envPath = resolve(targetPath, ".env");
|
|
56
|
+
if (!existsSync(composePath)) {
|
|
57
|
+
console.log(chalk.yellow(`No docker-compose.yml found in: ${targetPath}`));
|
|
58
|
+
console.log(chalk.gray("Usage: easyoref update /path/to/deployment"));
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
console.log(chalk.cyan(`Updating EasyOref in: ${targetPath}...\n`));
|
|
62
|
+
try {
|
|
63
|
+
console.log(chalk.gray(" → docker compose down"));
|
|
64
|
+
execSync("docker compose down", { cwd: targetPath, stdio: "inherit" });
|
|
65
|
+
console.log(chalk.gray("\n → docker compose up --build -d"));
|
|
66
|
+
execSync("docker compose up --build -d", { cwd: targetPath, stdio: "inherit" });
|
|
67
|
+
console.log(chalk.green("\n✅ EasyOref updated successfully!"));
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
console.error(chalk.red("\n❌ Update failed:"), err);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
main().catch((err) => {
|
|
75
|
+
console.error(chalk.red("Fatal error:"), err);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
});
|
|
78
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@easyoref/cli",
|
|
3
|
+
"version": "1.21.1",
|
|
4
|
+
"description": "Interactive setup wizard for EasyOref",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"easyoref": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "dist/index.js",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"dev": "tsx src/index.ts",
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"start": "node dist/index.js",
|
|
14
|
+
"typecheck": "tsc --noEmit"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"easyoref",
|
|
18
|
+
"oref",
|
|
19
|
+
"telegram",
|
|
20
|
+
"cli",
|
|
21
|
+
"setup-wizard"
|
|
22
|
+
],
|
|
23
|
+
"author": "Mikhail Kogan <kogan.mikhail@gmail.com>",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@inquirer/prompts": "^7.0.0",
|
|
27
|
+
"chalk": "^5.3.0",
|
|
28
|
+
"grammy": "^1.35.0",
|
|
29
|
+
"@easyoref/shared": "*"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/node": "^22.0.0",
|
|
33
|
+
"tsx": "^4.19.0",
|
|
34
|
+
"typescript": "^5.7.0"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=22"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `easyoref init` — Interactive setup wizard
|
|
3
|
+
*
|
|
4
|
+
* Walks user through:
|
|
5
|
+
* 1. Language selection (ru/en/he)
|
|
6
|
+
* 2. Bot token input + validation
|
|
7
|
+
* 3. Chat ID input
|
|
8
|
+
* 4. Area selection (checkbox)
|
|
9
|
+
* 5. Generates .env file
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { checkbox, input, password, select } from "@inquirer/prompts";
|
|
13
|
+
import chalk from "chalk";
|
|
14
|
+
import { Bot } from "grammy";
|
|
15
|
+
import { writeFileSync } from "node:fs";
|
|
16
|
+
import { AREA_CHOICES } from "../data/areas.js";
|
|
17
|
+
|
|
18
|
+
export async function init(): Promise<void> {
|
|
19
|
+
// ── Step 0: Language ───────────────────────────────────
|
|
20
|
+
|
|
21
|
+
const language = await select({
|
|
22
|
+
message: "🌍 Message language / Язык сообщений / שפת ההודעות:",
|
|
23
|
+
choices: [
|
|
24
|
+
{ name: "Русский", value: "ru" },
|
|
25
|
+
{ name: "English", value: "en" },
|
|
26
|
+
{ name: "עברית", value: "he" },
|
|
27
|
+
],
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const t = translations[language as keyof typeof translations];
|
|
31
|
+
|
|
32
|
+
// ── Step 1: Bot Token ──────────────────────────────────
|
|
33
|
+
|
|
34
|
+
const botToken = await password({
|
|
35
|
+
message: t.botTokenPrompt,
|
|
36
|
+
validate: (val) => {
|
|
37
|
+
if (!val || val.length < 10) return t.botTokenRequired;
|
|
38
|
+
if (!val.includes(":")) return t.botTokenFormat;
|
|
39
|
+
return true;
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Validate token by calling Telegram API
|
|
44
|
+
console.log(chalk.dim(t.validating));
|
|
45
|
+
try {
|
|
46
|
+
const bot = new Bot(botToken);
|
|
47
|
+
const me = await bot.api.getMe();
|
|
48
|
+
console.log(chalk.green(` ✅ ${t.botVerified}: @${me.username}`));
|
|
49
|
+
} catch {
|
|
50
|
+
console.log(chalk.yellow(` ⚠️ ${t.botVerifyFailed}`));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// ── Step 2: Chat ID ────────────────────────────────────
|
|
54
|
+
|
|
55
|
+
const chatId = await input({
|
|
56
|
+
message: t.chatIdPrompt,
|
|
57
|
+
validate: (val) => {
|
|
58
|
+
if (!val) return t.chatIdRequired;
|
|
59
|
+
// Allow negative numbers (groups) and positive (DMs)
|
|
60
|
+
if (!/^-?\d+$/.test(val)) return t.chatIdFormat;
|
|
61
|
+
return true;
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// ── Step 3: Areas ──────────────────────────────────────
|
|
66
|
+
|
|
67
|
+
const areas = await checkbox({
|
|
68
|
+
message: t.areasPrompt,
|
|
69
|
+
choices: AREA_CHOICES,
|
|
70
|
+
required: true,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// ── Step 4: Write .env ─────────────────────────────────
|
|
74
|
+
|
|
75
|
+
const envContent = [
|
|
76
|
+
"# EasyOref Configuration",
|
|
77
|
+
`# Generated by @easyoref/cli on ${new Date().toISOString().split("T")[0]}`,
|
|
78
|
+
"",
|
|
79
|
+
`BOT_TOKEN=${botToken}`,
|
|
80
|
+
`CHAT_ID=${chatId}`,
|
|
81
|
+
`AREAS=${areas.join(",")}`,
|
|
82
|
+
`LANGUAGE=${language}`,
|
|
83
|
+
"HEALTH_PORT=3100",
|
|
84
|
+
"",
|
|
85
|
+
].join("\n");
|
|
86
|
+
|
|
87
|
+
writeFileSync(".env", envContent, "utf-8");
|
|
88
|
+
|
|
89
|
+
console.log("");
|
|
90
|
+
console.log(chalk.green.bold(`✅ ${t.configSaved}`));
|
|
91
|
+
console.log("");
|
|
92
|
+
console.log(chalk.dim(t.nextSteps));
|
|
93
|
+
console.log(
|
|
94
|
+
` ${chalk.cyan("docker compose up -d")} ${chalk.dim("(Docker)")}`,
|
|
95
|
+
);
|
|
96
|
+
console.log(
|
|
97
|
+
` ${chalk.cyan("npm start")} ${chalk.dim("(Node.js)")}`,
|
|
98
|
+
);
|
|
99
|
+
console.log("");
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// ── i18n for the wizard itself ───────────────────────────
|
|
103
|
+
|
|
104
|
+
const translations = {
|
|
105
|
+
ru: {
|
|
106
|
+
botTokenPrompt: "🤖 Токен бота (от @BotFather):",
|
|
107
|
+
botTokenRequired: "Токен обязателен",
|
|
108
|
+
botTokenFormat: "Формат: 123456:ABC-DEF...",
|
|
109
|
+
validating: " Проверяем токен...",
|
|
110
|
+
botVerified: "Бот найден",
|
|
111
|
+
botVerifyFailed: "Не удалось проверить токен (продолжаем)",
|
|
112
|
+
chatIdPrompt: "💬 Chat ID группы (отрицательное число):",
|
|
113
|
+
chatIdRequired: "Chat ID обязателен",
|
|
114
|
+
chatIdFormat: "Chat ID — число (отрицательное для групп)",
|
|
115
|
+
areasPrompt: "📍 Выберите районы для мониторинга (пробел = выбрать):",
|
|
116
|
+
configSaved: "Конфигурация сохранена в .env",
|
|
117
|
+
nextSteps: "Следующий шаг — запустите бота:",
|
|
118
|
+
},
|
|
119
|
+
en: {
|
|
120
|
+
botTokenPrompt: "🤖 Bot Token (from @BotFather):",
|
|
121
|
+
botTokenRequired: "Token is required",
|
|
122
|
+
botTokenFormat: "Format: 123456:ABC-DEF...",
|
|
123
|
+
validating: " Validating token...",
|
|
124
|
+
botVerified: "Bot found",
|
|
125
|
+
botVerifyFailed: "Could not verify token (continuing anyway)",
|
|
126
|
+
chatIdPrompt: "💬 Chat ID (negative number for groups):",
|
|
127
|
+
chatIdRequired: "Chat ID is required",
|
|
128
|
+
chatIdFormat: "Chat ID must be a number (negative for groups)",
|
|
129
|
+
areasPrompt: "📍 Select areas to monitor (space = toggle):",
|
|
130
|
+
configSaved: "Config saved to .env",
|
|
131
|
+
nextSteps: "Next step — start the bot:",
|
|
132
|
+
},
|
|
133
|
+
he: {
|
|
134
|
+
botTokenPrompt: "🤖 טוקן בוט (מ-@BotFather):",
|
|
135
|
+
botTokenRequired: "טוקן נדרש",
|
|
136
|
+
botTokenFormat: "פורמט: 123456:ABC-DEF...",
|
|
137
|
+
validating: " מאמת טוקן...",
|
|
138
|
+
botVerified: "בוט נמצא",
|
|
139
|
+
botVerifyFailed: "לא ניתן לאמת את הטוקן (ממשיכים)",
|
|
140
|
+
chatIdPrompt: "💬 Chat ID (מספר שלילי לקבוצות):",
|
|
141
|
+
chatIdRequired: "Chat ID נדרש",
|
|
142
|
+
chatIdFormat: "Chat ID חייב להיות מספר (שלילי לקבוצות)",
|
|
143
|
+
areasPrompt: "📍 בחר אזורים לניטור (רווח = בחירה):",
|
|
144
|
+
configSaved: "הגדרות נשמרו ל-.env",
|
|
145
|
+
nextSteps: "שלב הבא — הפעל את הבוט:",
|
|
146
|
+
},
|
|
147
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `easyoref list-areas` — Print all available Oref area names
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import chalk from "chalk";
|
|
6
|
+
import { AREA_CHOICES } from "../data/areas.js";
|
|
7
|
+
|
|
8
|
+
export function listAreas(): void {
|
|
9
|
+
console.log(chalk.bold("Available Oref areas for AREAS env var:\n"));
|
|
10
|
+
console.log(
|
|
11
|
+
chalk.dim(
|
|
12
|
+
"Copy the Hebrew name (right column) into your .env AREAS field.\n",
|
|
13
|
+
),
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const maxName = Math.max(...AREA_CHOICES.map((c) => c.name.length));
|
|
17
|
+
|
|
18
|
+
for (const choice of AREA_CHOICES) {
|
|
19
|
+
const padded = choice.name.padEnd(maxName + 2);
|
|
20
|
+
console.log(` ${padded} ${chalk.cyan(choice.value)}`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
console.log(chalk.dim("\nExample: AREAS=תל אביב - דרום העיר ויפו,גוש דן"));
|
|
24
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#! /usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @easyoref/cli — Interactive setup wizard
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* npx @easyoref/cli init — interactive setup
|
|
7
|
+
* npx @easyoref/cli list-areas — show all Oref area names
|
|
8
|
+
* npx @easyoref/cli update — update RPi deployment
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import chalk from "chalk";
|
|
12
|
+
import { execSync } from "node:child_process";
|
|
13
|
+
import { existsSync } from "node:fs";
|
|
14
|
+
import { resolve } from "node:path";
|
|
15
|
+
import { init } from "./commands/init.js";
|
|
16
|
+
import { listAreas } from "./commands/list-areas.js";
|
|
17
|
+
|
|
18
|
+
const command = process.argv[2];
|
|
19
|
+
const args = process.argv.slice(3);
|
|
20
|
+
|
|
21
|
+
async function main(): Promise<void> {
|
|
22
|
+
console.log(chalk.bold("\n🚨 EasyOref — Setup Wizard\n"));
|
|
23
|
+
|
|
24
|
+
switch (command) {
|
|
25
|
+
case "init":
|
|
26
|
+
case undefined:
|
|
27
|
+
await init();
|
|
28
|
+
break;
|
|
29
|
+
case "list-areas":
|
|
30
|
+
listAreas();
|
|
31
|
+
break;
|
|
32
|
+
case "update":
|
|
33
|
+
update(args[0]);
|
|
34
|
+
break;
|
|
35
|
+
case "--help":
|
|
36
|
+
case "-h":
|
|
37
|
+
printHelp();
|
|
38
|
+
break;
|
|
39
|
+
default:
|
|
40
|
+
console.log(chalk.red(`Unknown command: ${command}`));
|
|
41
|
+
printHelp();
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function printHelp(): void {
|
|
47
|
+
console.log(`${chalk.bold("Commands:")}
|
|
48
|
+
${chalk.cyan("init")} Interactive setup wizard (default)
|
|
49
|
+
${chalk.cyan("list-areas")} Show all Oref area names with translations
|
|
50
|
+
${chalk.cyan("update")} Update RPi deployment
|
|
51
|
+
${chalk.cyan("update /path/to/deploy")} Update in specific directory
|
|
52
|
+
${chalk.cyan("--help")} Show this help message
|
|
53
|
+
`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function update(path?: string): void {
|
|
57
|
+
const targetPath = path
|
|
58
|
+
? resolve(path)
|
|
59
|
+
: process.cwd();
|
|
60
|
+
|
|
61
|
+
const composePath = resolve(targetPath, "docker-compose.yml");
|
|
62
|
+
const envPath = resolve(targetPath, ".env");
|
|
63
|
+
|
|
64
|
+
if (!existsSync(composePath)) {
|
|
65
|
+
console.log(chalk.yellow(`No docker-compose.yml found in: ${targetPath}`));
|
|
66
|
+
console.log(chalk.gray("Usage: easyoref update /path/to/deployment"));
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
console.log(chalk.cyan(`Updating EasyOref in: ${targetPath}...\n`));
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
console.log(chalk.gray(" → docker compose down"));
|
|
74
|
+
execSync("docker compose down", { cwd: targetPath, stdio: "inherit" });
|
|
75
|
+
|
|
76
|
+
console.log(chalk.gray("\n → docker compose up --build -d"));
|
|
77
|
+
execSync("docker compose up --build -d", { cwd: targetPath, stdio: "inherit" });
|
|
78
|
+
|
|
79
|
+
console.log(chalk.green("\n✅ EasyOref updated successfully!"));
|
|
80
|
+
} catch (err) {
|
|
81
|
+
console.error(chalk.red("\n❌ Update failed:"), err);
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
main().catch((err) => {
|
|
87
|
+
console.error(chalk.red("Fatal error:"), err);
|
|
88
|
+
process.exit(1);
|
|
89
|
+
});
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"outDir": "dist",
|
|
8
|
+
"rootDir": "src",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"resolveJsonModule": true,
|
|
14
|
+
"declaration": true,
|
|
15
|
+
"sourceMap": true,
|
|
16
|
+
"composite": true
|
|
17
|
+
},
|
|
18
|
+
"references": [{ "path": "../shared" }, { "path": "../monitoring" }],
|
|
19
|
+
"include": ["src/**/*"],
|
|
20
|
+
"exclude": ["node_modules", "dist"]
|
|
21
|
+
}
|