@easyoref/shared 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/config.d.ts +128 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +158 -0
- package/dist/config.js.map +1 -0
- package/dist/helpers.d.ts +6 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +15 -0
- package/dist/helpers.js.map +1 -0
- package/dist/i18n.d.ts +51 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/i18n.js +248 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/redis.d.ts +6 -0
- package/dist/redis.d.ts.map +1 -0
- package/dist/redis.js +21 -0
- package/dist/redis.js.map +1 -0
- package/dist/schemas.d.ts +1496 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +556 -0
- package/dist/schemas.js.map +1 -0
- package/dist/store.d.ts +55 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +162 -0
- package/dist/store.js.map +1 -0
- package/package.json +22 -0
- package/src/config.ts +248 -0
- package/src/helpers.ts +17 -0
- package/src/i18n.ts +306 -0
- package/src/index.ts +6 -0
- package/src/redis.ts +23 -0
- package/src/schemas.ts +712 -0
- package/src/store.ts +232 -0
- package/tsconfig.json +9 -0
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EasyOref — Centralized Configuration
|
|
3
|
+
*
|
|
4
|
+
* Primary: config.yaml (searched in cwd, /app, /etc/easyoref)
|
|
5
|
+
* Fallback: environment variables + Docker secrets (for backward compat)
|
|
6
|
+
*
|
|
7
|
+
* See config.yaml.example for all available options.
|
|
8
|
+
*/
|
|
9
|
+
import { type Language } from "./i18n.js";
|
|
10
|
+
import { type AlertTypeConfig } from "./schemas.js";
|
|
11
|
+
/** Raw YAML schema */
|
|
12
|
+
interface ConfigYaml {
|
|
13
|
+
alert_types?: AlertTypeConfig[];
|
|
14
|
+
city_ids?: number[];
|
|
15
|
+
language?: string;
|
|
16
|
+
gif_mode?: string;
|
|
17
|
+
emoji_override?: Partial<Record<AlertTypeConfig, string>>;
|
|
18
|
+
title_override?: Partial<Record<AlertTypeConfig, string>>;
|
|
19
|
+
description_override?: Partial<Record<AlertTypeConfig, string>>;
|
|
20
|
+
observability?: {
|
|
21
|
+
betterstack_token?: string;
|
|
22
|
+
};
|
|
23
|
+
telegram?: {
|
|
24
|
+
bot_token?: string;
|
|
25
|
+
chat_id?: string | string[];
|
|
26
|
+
};
|
|
27
|
+
health_port?: number;
|
|
28
|
+
poll_interval_ms?: number;
|
|
29
|
+
data_dir?: string;
|
|
30
|
+
oref_api_url?: string;
|
|
31
|
+
oref_history_url?: string;
|
|
32
|
+
ai?: ConfigYamlAi;
|
|
33
|
+
}
|
|
34
|
+
interface ConfigYamlAi {
|
|
35
|
+
enabled?: boolean;
|
|
36
|
+
openrouter_api_key?: string;
|
|
37
|
+
openrouter_filter_model?: string;
|
|
38
|
+
openrouter_extract_model?: string;
|
|
39
|
+
redis_url?: string;
|
|
40
|
+
socks5_proxy?: string;
|
|
41
|
+
enrich_delay_ms?: number;
|
|
42
|
+
confidence_threshold?: number;
|
|
43
|
+
window_minutes?: number;
|
|
44
|
+
timeout_minutes?: number;
|
|
45
|
+
/** Enable MCP tool calling for low-confidence clarification */
|
|
46
|
+
mcp_tools?: boolean;
|
|
47
|
+
/** Number of recent posts to fetch per channel during clarify (1-4) */
|
|
48
|
+
clarify_fetch_count?: number;
|
|
49
|
+
mtproto?: {
|
|
50
|
+
api_id?: number;
|
|
51
|
+
api_hash?: string;
|
|
52
|
+
session_string?: string;
|
|
53
|
+
};
|
|
54
|
+
channels?: string[];
|
|
55
|
+
/** Map monitored area prefix → human-readable region label */
|
|
56
|
+
area_labels?: Record<string, string>;
|
|
57
|
+
}
|
|
58
|
+
/** Config dir in user home — ~/.easyoref/ */
|
|
59
|
+
export declare const CONFIG_DIR: string;
|
|
60
|
+
export declare const HOME_CONFIG_PATH: string;
|
|
61
|
+
declare function loadYaml(): ConfigYaml;
|
|
62
|
+
declare function parseAlertTypes(raw?: AlertTypeConfig[]): AlertTypeConfig[];
|
|
63
|
+
export declare const config: {
|
|
64
|
+
/** Telegram bot token */
|
|
65
|
+
botToken: string;
|
|
66
|
+
/** All Telegram chat IDs to broadcast to */
|
|
67
|
+
chatIds: string[];
|
|
68
|
+
/** Primary Telegram chat ID (first in the list) */
|
|
69
|
+
chatId: string;
|
|
70
|
+
/** City IDs to monitor (resolved to Hebrew names at startup via cities.json) */
|
|
71
|
+
cityIds: number[];
|
|
72
|
+
/**
|
|
73
|
+
* Hebrew area names — legacy fallback for AREAS env var.
|
|
74
|
+
* Populated at startup from cityIds OR from AREAS env if no cityIds.
|
|
75
|
+
*/
|
|
76
|
+
areas: string[];
|
|
77
|
+
/** Which alert types to send */
|
|
78
|
+
alertTypes: AlertTypeConfig[];
|
|
79
|
+
/** Message language */
|
|
80
|
+
language: Language;
|
|
81
|
+
/** Emoji overrides per alert type */
|
|
82
|
+
emojiOverride: Partial<Record<AlertTypeConfig, string>>;
|
|
83
|
+
/** Title overrides per alert type */
|
|
84
|
+
titleOverride: Partial<Record<AlertTypeConfig, string>>;
|
|
85
|
+
/** Description overrides per alert type */
|
|
86
|
+
descriptionOverride: Partial<Record<AlertTypeConfig, string>>;
|
|
87
|
+
/** Oref API polling interval (ms) */
|
|
88
|
+
pollIntervalMs: number;
|
|
89
|
+
/** Health endpoint port */
|
|
90
|
+
healthPort: number;
|
|
91
|
+
/** Oref API URL */
|
|
92
|
+
orefApiUrl: string;
|
|
93
|
+
/** Oref alert history URL (base, without date params) */
|
|
94
|
+
orefHistoryUrl: string;
|
|
95
|
+
/** Better Stack Logtail token */
|
|
96
|
+
logtailToken: string;
|
|
97
|
+
/** GIF mode */
|
|
98
|
+
gifMode: "none" | "funny_cats";
|
|
99
|
+
/** Path for persistent data */
|
|
100
|
+
dataDir: string;
|
|
101
|
+
/** AI enrichment config (YAML key: `ai`) */
|
|
102
|
+
agent: {
|
|
103
|
+
enabled: boolean;
|
|
104
|
+
apiKey: string;
|
|
105
|
+
filterModel: string;
|
|
106
|
+
extractModel: string;
|
|
107
|
+
redisUrl: string;
|
|
108
|
+
socks5Proxy: string;
|
|
109
|
+
enrichDelayMs: number;
|
|
110
|
+
confidenceThreshold: number;
|
|
111
|
+
windowMinutes: number;
|
|
112
|
+
timeoutMinutes: number;
|
|
113
|
+
mtproto: {
|
|
114
|
+
apiId: number;
|
|
115
|
+
apiHash: string;
|
|
116
|
+
sessionString: string;
|
|
117
|
+
};
|
|
118
|
+
channels: string[];
|
|
119
|
+
areaLabels: Record<string, string>;
|
|
120
|
+
/** Enable MCP tool calling — deterministic fan-out on low confidence */
|
|
121
|
+
mcpTools: boolean;
|
|
122
|
+
/** Posts per channel to fetch during clarify (1-4, default 3) */
|
|
123
|
+
clarifyFetchCount: number;
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
/** Exported for testing */
|
|
127
|
+
export { loadYaml as _loadYaml, parseAlertTypes as _parseAlertTypes, type ConfigYaml, };
|
|
128
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EasyOref — Centralized Configuration
|
|
3
|
+
*
|
|
4
|
+
* Primary: config.yaml (searched in cwd, /app, /etc/easyoref)
|
|
5
|
+
* Fallback: environment variables + Docker secrets (for backward compat)
|
|
6
|
+
*
|
|
7
|
+
* See config.yaml.example for all available options.
|
|
8
|
+
*/
|
|
9
|
+
import yaml from "js-yaml";
|
|
10
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
11
|
+
import { homedir } from "node:os";
|
|
12
|
+
import { join, resolve } from "node:path";
|
|
13
|
+
import { isValidLanguage } from "./i18n.js";
|
|
14
|
+
// ── Types ────────────────────────────────────────────────
|
|
15
|
+
const VALID_GIF_MODES = ["funny_cats", "none"];
|
|
16
|
+
const ALL_ALERT_TYPES = ["early", "red_alert", "resolved"];
|
|
17
|
+
// ── YAML Loader ──────────────────────────────────────────
|
|
18
|
+
/** Config dir in user home — ~/.easyoref/ */
|
|
19
|
+
export const CONFIG_DIR = join(homedir(), ".easyoref");
|
|
20
|
+
export const HOME_CONFIG_PATH = join(CONFIG_DIR, "config.yaml");
|
|
21
|
+
const CONFIG_SEARCH_PATHS = [
|
|
22
|
+
HOME_CONFIG_PATH,
|
|
23
|
+
"config.yaml",
|
|
24
|
+
"config.yml",
|
|
25
|
+
"/app/config.yaml",
|
|
26
|
+
"/etc/easyoref/config.yaml",
|
|
27
|
+
];
|
|
28
|
+
function findConfigFile() {
|
|
29
|
+
const envPath = process.env.EASYOREF_CONFIG;
|
|
30
|
+
if (envPath && existsSync(envPath))
|
|
31
|
+
return envPath;
|
|
32
|
+
for (const p of CONFIG_SEARCH_PATHS) {
|
|
33
|
+
const abs = resolve(p);
|
|
34
|
+
if (existsSync(abs))
|
|
35
|
+
return abs;
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
function loadYaml() {
|
|
40
|
+
const path = findConfigFile();
|
|
41
|
+
if (path) {
|
|
42
|
+
try {
|
|
43
|
+
const raw = readFileSync(path, "utf-8");
|
|
44
|
+
const parsed = yaml.load(raw);
|
|
45
|
+
// eslint-disable-next-line no-console
|
|
46
|
+
console.log(`[config] Loaded from ${path}`);
|
|
47
|
+
return parsed ?? {};
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
// eslint-disable-next-line no-console
|
|
51
|
+
console.error(`[config] Failed to parse ${path}:`, err);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return {};
|
|
55
|
+
}
|
|
56
|
+
// ── Helpers ──────────────────────────────────────────────
|
|
57
|
+
function readSecret(envKey, secretPaths) {
|
|
58
|
+
for (const p of secretPaths) {
|
|
59
|
+
if (existsSync(p))
|
|
60
|
+
return readFileSync(p, "utf-8").trim();
|
|
61
|
+
}
|
|
62
|
+
return process.env[envKey] ?? "";
|
|
63
|
+
}
|
|
64
|
+
function parseGifMode(raw) {
|
|
65
|
+
const lower = raw.toLowerCase();
|
|
66
|
+
return VALID_GIF_MODES.includes(lower) ? lower : "none";
|
|
67
|
+
}
|
|
68
|
+
function parseAlertTypes(raw) {
|
|
69
|
+
if (!raw || !Array.isArray(raw))
|
|
70
|
+
return ALL_ALERT_TYPES;
|
|
71
|
+
return raw.filter((t) => ALL_ALERT_TYPES.includes(t));
|
|
72
|
+
}
|
|
73
|
+
// ── Build Config ─────────────────────────────────────────
|
|
74
|
+
const yml = loadYaml();
|
|
75
|
+
const parsedChatIds = (() => {
|
|
76
|
+
const raw = yml.telegram?.chat_id ?? process.env.CHAT_ID ?? "";
|
|
77
|
+
if (Array.isArray(raw))
|
|
78
|
+
return raw.map(String).filter(Boolean);
|
|
79
|
+
return String(raw)
|
|
80
|
+
.split(",")
|
|
81
|
+
.map((s) => s.trim())
|
|
82
|
+
.filter(Boolean);
|
|
83
|
+
})();
|
|
84
|
+
export const config = {
|
|
85
|
+
/** Telegram bot token */
|
|
86
|
+
botToken: yml.telegram?.bot_token ??
|
|
87
|
+
readSecret("BOT_TOKEN", ["/run/secrets/bot_token", "secrets/bot_token"]),
|
|
88
|
+
/** All Telegram chat IDs to broadcast to */
|
|
89
|
+
chatIds: parsedChatIds,
|
|
90
|
+
/** Primary Telegram chat ID (first in the list) */
|
|
91
|
+
chatId: parsedChatIds[0] ?? "",
|
|
92
|
+
/** City IDs to monitor (resolved to Hebrew names at startup via cities.json) */
|
|
93
|
+
cityIds: yml.city_ids ?? [],
|
|
94
|
+
/**
|
|
95
|
+
* Hebrew area names — legacy fallback for AREAS env var.
|
|
96
|
+
* Populated at startup from cityIds OR from AREAS env if no cityIds.
|
|
97
|
+
*/
|
|
98
|
+
areas: [],
|
|
99
|
+
/** Which alert types to send */
|
|
100
|
+
alertTypes: parseAlertTypes(yml.alert_types),
|
|
101
|
+
/** Message language */
|
|
102
|
+
language: (() => {
|
|
103
|
+
const raw = (yml.language ?? process.env.LANGUAGE ?? "ru").toLowerCase();
|
|
104
|
+
return isValidLanguage(raw) ? raw : "ru";
|
|
105
|
+
})(),
|
|
106
|
+
/** Emoji overrides per alert type */
|
|
107
|
+
emojiOverride: yml.emoji_override ?? {},
|
|
108
|
+
/** Title overrides per alert type */
|
|
109
|
+
titleOverride: yml.title_override ?? {},
|
|
110
|
+
/** Description overrides per alert type */
|
|
111
|
+
descriptionOverride: yml.description_override ?? {},
|
|
112
|
+
/** Oref API polling interval (ms) */
|
|
113
|
+
pollIntervalMs: yml.poll_interval_ms ?? Number(process.env.OREF_POLL_INTERVAL_MS ?? "2000"),
|
|
114
|
+
/** Health endpoint port */
|
|
115
|
+
healthPort: yml.health_port ?? Number(process.env.HEALTH_PORT ?? "3100"),
|
|
116
|
+
/** Oref API URL */
|
|
117
|
+
orefApiUrl: yml.oref_api_url ??
|
|
118
|
+
process.env.OREF_API_URL ??
|
|
119
|
+
"https://www.oref.org.il/WarningMessages/alert/alerts.json",
|
|
120
|
+
/** Oref alert history URL (base, without date params) */
|
|
121
|
+
orefHistoryUrl: yml.oref_history_url ?? process.env.OREF_HISTORY_URL ?? "",
|
|
122
|
+
/** Better Stack Logtail token */
|
|
123
|
+
logtailToken: yml.observability?.betterstack_token ?? process.env.LOGTAIL_TOKEN ?? "",
|
|
124
|
+
/** GIF mode */
|
|
125
|
+
gifMode: parseGifMode(yml.gif_mode ?? process.env.GIF_MODE ?? "none"),
|
|
126
|
+
/** Path for persistent data */
|
|
127
|
+
dataDir: yml.data_dir ?? process.env.DATA_DIR ?? join(CONFIG_DIR, "data"),
|
|
128
|
+
/** AI enrichment config (YAML key: `ai`) */
|
|
129
|
+
agent: (() => {
|
|
130
|
+
const ai = yml.ai;
|
|
131
|
+
return {
|
|
132
|
+
enabled: ai?.enabled ?? false,
|
|
133
|
+
apiKey: ai?.openrouter_api_key ?? process.env.OPENROUTER_API_KEY ?? "",
|
|
134
|
+
filterModel: ai?.openrouter_filter_model ?? "google/gemini-2.5-flash-lite",
|
|
135
|
+
extractModel: ai?.openrouter_extract_model ?? "google/gemini-3.1-flash-lite-preview",
|
|
136
|
+
redisUrl: ai?.redis_url ?? process.env.REDIS_URL ?? "redis://localhost:6379",
|
|
137
|
+
socks5Proxy: ai?.socks5_proxy ?? process.env.SOCKS5_PROXY ?? "",
|
|
138
|
+
enrichDelayMs: ai?.enrich_delay_ms ?? 20_000,
|
|
139
|
+
confidenceThreshold: ai?.confidence_threshold ?? 0.7,
|
|
140
|
+
windowMinutes: ai?.window_minutes ?? 2,
|
|
141
|
+
timeoutMinutes: ai?.timeout_minutes ?? 15,
|
|
142
|
+
mtproto: {
|
|
143
|
+
apiId: ai?.mtproto?.api_id ?? Number(process.env.TG_API_ID ?? "0"),
|
|
144
|
+
apiHash: ai?.mtproto?.api_hash ?? process.env.TG_API_HASH ?? "",
|
|
145
|
+
sessionString: ai?.mtproto?.session_string ?? process.env.TG_SESSION ?? "",
|
|
146
|
+
},
|
|
147
|
+
channels: ai?.channels ?? [],
|
|
148
|
+
areaLabels: ai?.area_labels ?? {},
|
|
149
|
+
/** Enable MCP tool calling — deterministic fan-out on low confidence */
|
|
150
|
+
mcpTools: ai?.mcp_tools ?? false,
|
|
151
|
+
/** Posts per channel to fetch during clarify (1-4, default 3) */
|
|
152
|
+
clarifyFetchCount: Math.min(4, Math.max(1, ai?.clarify_fetch_count ?? 3)),
|
|
153
|
+
};
|
|
154
|
+
})(),
|
|
155
|
+
};
|
|
156
|
+
/** Exported for testing */
|
|
157
|
+
export { loadYaml as _loadYaml, parseAlertTypes as _parseAlertTypes, };
|
|
158
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Shared utility functions for the agent subsystem. */
|
|
2
|
+
/** Format timestamp as HH:MM Israel time */
|
|
3
|
+
export declare function toIsraelTime(ts: number): string;
|
|
4
|
+
/** MD5 hash for dedup */
|
|
5
|
+
export declare function textHash(text: string): string;
|
|
6
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,wDAAwD;AAIxD,4CAA4C;AAC5C,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAM/C;AAED,yBAAyB;AACzB,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C"}
|
package/dist/helpers.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Shared utility functions for the agent subsystem. */
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
/** Format timestamp as HH:MM Israel time */
|
|
4
|
+
export function toIsraelTime(ts) {
|
|
5
|
+
return new Date(ts).toLocaleTimeString("he-IL", {
|
|
6
|
+
hour: "2-digit",
|
|
7
|
+
minute: "2-digit",
|
|
8
|
+
timeZone: "Asia/Jerusalem",
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
/** MD5 hash for dedup */
|
|
12
|
+
export function textHash(text) {
|
|
13
|
+
return createHash("md5").update(text).digest("hex");
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,wDAAwD;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,4CAA4C;AAC5C,MAAM,UAAU,YAAY,CAAC,EAAU;IACrC,OAAO,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,kBAAkB,CAAC,OAAO,EAAE;QAC9C,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,SAAS;QACjB,QAAQ,EAAE,gBAAgB;KAC3B,CAAC,CAAC;AACL,CAAC;AAED,yBAAyB;AACzB,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACtD,CAAC"}
|
package/dist/i18n.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EasyOref — Internationalization (i18n)
|
|
3
|
+
*
|
|
4
|
+
* Supported languages: Russian (ru), English (en), Hebrew (he), Arabic (ar)
|
|
5
|
+
* Default: ru (built for diaspora families)
|
|
6
|
+
*
|
|
7
|
+
* Message format:
|
|
8
|
+
* <b>⚠️ Title</b>
|
|
9
|
+
* Description
|
|
10
|
+
* <blockquote>
|
|
11
|
+
* <b>Key:</b> Value
|
|
12
|
+
* ...
|
|
13
|
+
* </blockquote>
|
|
14
|
+
*/
|
|
15
|
+
export type Language = "ru" | "en" | "he" | "ar";
|
|
16
|
+
export type AlertKind = "early" | "red_alert" | "resolved";
|
|
17
|
+
export interface AlertLocales {
|
|
18
|
+
emoji: string;
|
|
19
|
+
title: string;
|
|
20
|
+
description: string;
|
|
21
|
+
}
|
|
22
|
+
export interface I18nLabels {
|
|
23
|
+
area: string;
|
|
24
|
+
timeToImpact: string;
|
|
25
|
+
earlyEta: string;
|
|
26
|
+
redAlertEta: string;
|
|
27
|
+
monitoring: string;
|
|
28
|
+
}
|
|
29
|
+
export interface LanguagePack {
|
|
30
|
+
alerts: Record<AlertKind, AlertLocales>;
|
|
31
|
+
labels: I18nLabels;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Load and cache translations from pikud-haoref-api.
|
|
35
|
+
* Must be called once at startup (before first alert).
|
|
36
|
+
* Falls back silently to Hebrew names on fetch failure.
|
|
37
|
+
*/
|
|
38
|
+
export declare function initTranslations(): Promise<void>;
|
|
39
|
+
/** Translate comma-separated Hebrew area names to target language */
|
|
40
|
+
export declare function translateAreas(areas: string, lang: Language): string;
|
|
41
|
+
/** Translate country name from English (LLM extraction result) to target language */
|
|
42
|
+
export declare function translateCountry(name: string, lang: Language): string;
|
|
43
|
+
/**
|
|
44
|
+
* Resolve numeric city IDs to Hebrew area names.
|
|
45
|
+
* Call AFTER initTranslations().
|
|
46
|
+
* Unknown IDs are logged as warnings and skipped.
|
|
47
|
+
*/
|
|
48
|
+
export declare function resolveCityIds(ids: number[]): string[];
|
|
49
|
+
export declare function getLanguagePack(lang: Language): LanguagePack;
|
|
50
|
+
export declare function isValidLanguage(s: string): s is Language;
|
|
51
|
+
//# sourceMappingURL=i18n.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,MAAM,QAAQ,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAIjD,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,WAAW,GAAG,UAAU,CAAC;AAE3D,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IACxC,MAAM,EAAE,UAAU,CAAC;CACpB;AA+KD;;;;GAIG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAoCtD;AAED,qEAAqE;AACrE,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,CAapE;AAED,qFAAqF;AACrF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,CAKrE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAYtD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,GAAG,YAAY,CAE5D;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,IAAI,QAAQ,CAExD"}
|
package/dist/i18n.js
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EasyOref — Internationalization (i18n)
|
|
3
|
+
*
|
|
4
|
+
* Supported languages: Russian (ru), English (en), Hebrew (he), Arabic (ar)
|
|
5
|
+
* Default: ru (built for diaspora families)
|
|
6
|
+
*
|
|
7
|
+
* Message format:
|
|
8
|
+
* <b>⚠️ Title</b>
|
|
9
|
+
* Description
|
|
10
|
+
* <blockquote>
|
|
11
|
+
* <b>Key:</b> Value
|
|
12
|
+
* ...
|
|
13
|
+
* </blockquote>
|
|
14
|
+
*/
|
|
15
|
+
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
16
|
+
// Language Packs — structured alert metadata + labels
|
|
17
|
+
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
18
|
+
const ruPack = {
|
|
19
|
+
alerts: {
|
|
20
|
+
early: {
|
|
21
|
+
emoji: "⚠️",
|
|
22
|
+
title: "Раннее предупреждение",
|
|
23
|
+
description: "Обнаружены запуски ракет по Израилю.",
|
|
24
|
+
},
|
|
25
|
+
red_alert: {
|
|
26
|
+
emoji: "🚨",
|
|
27
|
+
title: "Цева Адом",
|
|
28
|
+
description: "",
|
|
29
|
+
},
|
|
30
|
+
resolved: {
|
|
31
|
+
emoji: "😮💨",
|
|
32
|
+
title: "Инцидент завершён",
|
|
33
|
+
description: "Можно покинуть защищённое помещение.",
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
labels: {
|
|
37
|
+
area: "Район",
|
|
38
|
+
timeToImpact: "Подлёт",
|
|
39
|
+
earlyEta: "~5–12 мин",
|
|
40
|
+
redAlertEta: "1.5 мин",
|
|
41
|
+
monitoring: '<tg-emoji emoji-id="5258052328455424397">⏳</tg-emoji> Сообщение обновляется...',
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
const enPack = {
|
|
45
|
+
alerts: {
|
|
46
|
+
early: {
|
|
47
|
+
emoji: "⚠️",
|
|
48
|
+
title: "Early Warning",
|
|
49
|
+
description: "Rocket launches detected. Stay near a protected space.",
|
|
50
|
+
},
|
|
51
|
+
red_alert: {
|
|
52
|
+
emoji: "🚨",
|
|
53
|
+
title: "Siren Alert",
|
|
54
|
+
description: "Enter a protected space immediately.",
|
|
55
|
+
},
|
|
56
|
+
resolved: {
|
|
57
|
+
emoji: "😮💨",
|
|
58
|
+
title: "Incident Over",
|
|
59
|
+
description: "You may leave the protected space.",
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
labels: {
|
|
63
|
+
area: "Area",
|
|
64
|
+
timeToImpact: "Time to impact",
|
|
65
|
+
earlyEta: "~5–12 min",
|
|
66
|
+
redAlertEta: "1.5 min",
|
|
67
|
+
monitoring: '<tg-emoji emoji-id="5258052328455424397">⏳</tg-emoji> Message updating...',
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
const hePack = {
|
|
71
|
+
alerts: {
|
|
72
|
+
early: {
|
|
73
|
+
emoji: "⚠️",
|
|
74
|
+
title: "התרעה מוקדמת",
|
|
75
|
+
description: "זוהו שיגורים. הישארו בקרבת מרחב מוגן.",
|
|
76
|
+
},
|
|
77
|
+
red_alert: {
|
|
78
|
+
emoji: "🚨",
|
|
79
|
+
title: "צבע אדום",
|
|
80
|
+
description: "היכנסו למרחב מוגן.",
|
|
81
|
+
},
|
|
82
|
+
resolved: {
|
|
83
|
+
emoji: "😮💨",
|
|
84
|
+
title: "האירוע הסתיים",
|
|
85
|
+
description: "ניתן לצאת מהמרחב המוגן.",
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
labels: {
|
|
89
|
+
area: "אזור",
|
|
90
|
+
timeToImpact: "זמן מעוף",
|
|
91
|
+
earlyEta: "~5–12 דקות",
|
|
92
|
+
redAlertEta: "1.5 דקות",
|
|
93
|
+
monitoring: '<tg-emoji emoji-id="5258052328455424397">⏳</tg-emoji> ההודעה מתעדכנת...',
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
const arPack = {
|
|
97
|
+
alerts: {
|
|
98
|
+
early: {
|
|
99
|
+
emoji: "⚠️",
|
|
100
|
+
title: "إنذار مبكر",
|
|
101
|
+
description: "تم رصد إطلاق صواريخ. ابقوا بالقرب من الملجأ.",
|
|
102
|
+
},
|
|
103
|
+
red_alert: {
|
|
104
|
+
emoji: "🚨",
|
|
105
|
+
title: "صفارة إنذار",
|
|
106
|
+
description: "ادخلوا إلى الملجأ فوراً.",
|
|
107
|
+
},
|
|
108
|
+
resolved: {
|
|
109
|
+
emoji: "😮💨",
|
|
110
|
+
title: "انتهى الحادث",
|
|
111
|
+
description: "يمكنكم مغادرة الملجأ.",
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
labels: {
|
|
115
|
+
area: "المنطقة",
|
|
116
|
+
timeToImpact: "وقت الوصول",
|
|
117
|
+
earlyEta: "~5–12 دقيقة",
|
|
118
|
+
redAlertEta: "1.5 دقيقة",
|
|
119
|
+
monitoring: '<tg-emoji emoji-id="5258052328455424397">⏳</tg-emoji> الرسالة قيد التحديث...',
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
const packs = {
|
|
123
|
+
ru: ruPack,
|
|
124
|
+
en: enPack,
|
|
125
|
+
he: hePack,
|
|
126
|
+
ar: arPack,
|
|
127
|
+
};
|
|
128
|
+
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
129
|
+
// Area Name Translation — loaded from pikud-haoref-api/cities.json
|
|
130
|
+
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
131
|
+
const CITIES_JSON_URL = "https://raw.githubusercontent.com/eladnava/pikud-haoref-api/master/cities.json";
|
|
132
|
+
/** Hebrew city name → { en, ru, ar } */
|
|
133
|
+
const cityMap = new Map();
|
|
134
|
+
/** Hebrew zone name → { en, ru, ar } */
|
|
135
|
+
const zoneMap = new Map();
|
|
136
|
+
/** City ID → Hebrew name (for YAML city_ids resolution) */
|
|
137
|
+
const idToNameMap = new Map();
|
|
138
|
+
/** Country name translation map (Source: agent extraction names) */
|
|
139
|
+
const COUNTRY_NAMES = {
|
|
140
|
+
Iran: { ru: "Иран", en: "Iran", ar: "إيران" },
|
|
141
|
+
Yemen: { ru: "Йемен", en: "Yemen", ar: "اليمن" },
|
|
142
|
+
Lebanon: { ru: "Ливан", en: "Lebanon", ar: "لبنان" },
|
|
143
|
+
Gaza: { ru: "Газа", en: "Gaza", ar: "غزة" },
|
|
144
|
+
Iraq: { ru: "Ирак", en: "Iraq", ar: "العراق" },
|
|
145
|
+
Syria: { ru: "Сирия", en: "Syria", ar: "سوريا" },
|
|
146
|
+
Hezbollah: { ru: "Хезболла", en: "Hezbollah", ar: "حزب الله" },
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* Known bad translations in upstream cities.json.
|
|
150
|
+
* Applied as post-processing corrections after loading.
|
|
151
|
+
* Key: Hebrew name, Value: { lang: corrected_name }
|
|
152
|
+
*/
|
|
153
|
+
const TRANSLATION_FIXES = {
|
|
154
|
+
"תל אביב - דרום העיר ויפו": {
|
|
155
|
+
ru: "Тель-Авив — Южный район и Яффо",
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
/**
|
|
159
|
+
* Load and cache translations from pikud-haoref-api.
|
|
160
|
+
* Must be called once at startup (before first alert).
|
|
161
|
+
* Falls back silently to Hebrew names on fetch failure.
|
|
162
|
+
*/
|
|
163
|
+
export async function initTranslations() {
|
|
164
|
+
try {
|
|
165
|
+
const res = await fetch(CITIES_JSON_URL);
|
|
166
|
+
if (!res.ok)
|
|
167
|
+
throw new Error(`HTTP ${res.status}`);
|
|
168
|
+
const data = (await res.json());
|
|
169
|
+
for (const c of data) {
|
|
170
|
+
if (!c.name || c.name === "בחר הכל")
|
|
171
|
+
continue;
|
|
172
|
+
cityMap.set(c.name, { en: c.name_en, ru: c.name_ru, ar: c.name_ar });
|
|
173
|
+
if (c.id)
|
|
174
|
+
idToNameMap.set(c.id, c.name);
|
|
175
|
+
if (c.zone && !zoneMap.has(c.zone)) {
|
|
176
|
+
zoneMap.set(c.zone, { en: c.zone_en, ru: c.zone_ru, ar: c.zone_ar });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// Apply known corrections over upstream data
|
|
180
|
+
for (const [heName, fixes] of Object.entries(TRANSLATION_FIXES)) {
|
|
181
|
+
const existing = cityMap.get(heName);
|
|
182
|
+
if (existing) {
|
|
183
|
+
for (const [lang, corrected] of Object.entries(fixes)) {
|
|
184
|
+
existing[lang] = corrected;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// eslint-disable-next-line no-console
|
|
189
|
+
console.log(`[i18n] Loaded ${cityMap.size} city + ${zoneMap.size} zone translations`);
|
|
190
|
+
}
|
|
191
|
+
catch (err) {
|
|
192
|
+
// eslint-disable-next-line no-console
|
|
193
|
+
console.warn("[i18n] Failed to load cities.json — area names will stay in Hebrew", err);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/** Translate comma-separated Hebrew area names to target language */
|
|
197
|
+
export function translateAreas(areas, lang) {
|
|
198
|
+
if (lang === "he")
|
|
199
|
+
return areas;
|
|
200
|
+
const key = lang;
|
|
201
|
+
return areas
|
|
202
|
+
.split(", ")
|
|
203
|
+
.map((a) => {
|
|
204
|
+
const city = cityMap.get(a);
|
|
205
|
+
if (city?.[key])
|
|
206
|
+
return city[key];
|
|
207
|
+
const zone = zoneMap.get(a);
|
|
208
|
+
if (zone?.[key])
|
|
209
|
+
return zone[key];
|
|
210
|
+
return a; // fallback: Hebrew as-is
|
|
211
|
+
})
|
|
212
|
+
.join(", ");
|
|
213
|
+
}
|
|
214
|
+
/** Translate country name from English (LLM extraction result) to target language */
|
|
215
|
+
export function translateCountry(name, lang) {
|
|
216
|
+
if (lang === "he")
|
|
217
|
+
return name; // Fallback: no Hebrew country map yet
|
|
218
|
+
const entry = COUNTRY_NAMES[name];
|
|
219
|
+
if (entry)
|
|
220
|
+
return entry[lang];
|
|
221
|
+
return name;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Resolve numeric city IDs to Hebrew area names.
|
|
225
|
+
* Call AFTER initTranslations().
|
|
226
|
+
* Unknown IDs are logged as warnings and skipped.
|
|
227
|
+
*/
|
|
228
|
+
export function resolveCityIds(ids) {
|
|
229
|
+
const names = [];
|
|
230
|
+
for (const id of ids) {
|
|
231
|
+
const name = idToNameMap.get(id);
|
|
232
|
+
if (name) {
|
|
233
|
+
names.push(name);
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
// eslint-disable-next-line no-console
|
|
237
|
+
console.warn(`[i18n] Unknown city ID: ${id} — skipping`);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return names;
|
|
241
|
+
}
|
|
242
|
+
export function getLanguagePack(lang) {
|
|
243
|
+
return packs[lang] ?? packs.ru;
|
|
244
|
+
}
|
|
245
|
+
export function isValidLanguage(s) {
|
|
246
|
+
return s === "ru" || s === "en" || s === "he" || s === "ar";
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=i18n.js.map
|
package/dist/i18n.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n.js","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
|