@manybot/manybot 5.0.0 → 5.2.0

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.
@@ -1,129 +0,0 @@
1
- /**
2
- * src/utils/pluginI18n.js
3
- *
4
- * Independent i18n system for plugins.
5
- * Plugins load their own translations from locale/ folder.
6
- * Completely separate from bot core i18n.
7
- *
8
- * Usage in plugin:
9
- * import { createPluginI18n } from "../utils/pluginI18n.js";
10
- * const { t } = createPluginI18n(import.meta.url);
11
- *
12
- * Folder structure:
13
- * myPlugin/
14
- * index.js
15
- * locale/
16
- * en.json (required - fallback)
17
- * pt.json
18
- * es.json
19
- */
20
-
21
- import fs from "fs";
22
- import path from "path";
23
- import { fileURLToPath } from "url";
24
- import { LANGUAGE } from "#config";
25
-
26
- // Default/fallback language
27
- const DEFAULT_LANG = "en";
28
-
29
- /**
30
- * Gets a nested value from an object using dot path
31
- * @param {object} obj
32
- * @param {string} key - path like "error.notFound"
33
- * @returns {string|undefined}
34
- */
35
- function getNestedValue(obj, key) {
36
- const parts = key.split(".");
37
- let current = obj;
38
-
39
- for (const part of parts) {
40
- if (current === null || current === undefined || typeof current !== "object") {
41
- return undefined;
42
- }
43
- current = current[part];
44
- }
45
-
46
- return current;
47
- }
48
-
49
- /**
50
- * Replaces placeholders {{key}} with values from context
51
- * @param {string} str
52
- * @param {object} context
53
- * @returns {string}
54
- */
55
- function interpolate(str, context = {}) {
56
- return str.replace(/\{\{(\w+)\}\}/g, (match, key) => {
57
- return context[key] !== undefined ? String(context[key]) : match;
58
- });
59
- }
60
-
61
- /**
62
- * Load translations for a plugin
63
- * @param {string} localeDir - path to plugin's locale folder
64
- * @param {string} lang - target language
65
- * @returns {{ translations: object, fallback: object }}
66
- */
67
- function loadTranslations(localeDir, lang) {
68
- let translations = {};
69
- let fallback = {};
70
-
71
- try {
72
- const targetPath = path.join(localeDir, `${lang}.json`);
73
- if (fs.existsSync(targetPath)) {
74
- translations = JSON.parse(fs.readFileSync(targetPath, "utf8"));
75
- }
76
-
77
- const fallbackPath = path.join(localeDir, `${DEFAULT_LANG}.json`);
78
- if (fs.existsSync(fallbackPath)) {
79
- fallback = JSON.parse(fs.readFileSync(fallbackPath, "utf8"));
80
- }
81
- } catch {
82
- // Silent fail - plugin may not have translations
83
- }
84
-
85
- return { translations, fallback };
86
- }
87
-
88
- /**
89
- * Creates an isolated translation function for a plugin.
90
- * Language priority: PLUGIN_LANG env var > manybot.conf LANGUAGE > en
91
- *
92
- * @param {string} pluginMetaUrl - import.meta.url from the plugin
93
- * @returns {{ t: Function, lang: string }}
94
- */
95
- export function createPluginI18n(pluginMetaUrl) {
96
- const pluginDir = path.dirname(fileURLToPath(pluginMetaUrl));
97
- const localeDir = path.join(pluginDir, "locale");
98
-
99
- const targetLang =
100
- process.env.PLUGIN_LANG?.trim().toLowerCase() ||
101
- LANGUAGE?.trim().toLowerCase() ||
102
- DEFAULT_LANG;
103
-
104
- const { translations, fallback } = loadTranslations(localeDir, targetLang);
105
-
106
- /**
107
- * Translation function
108
- * @param {string} key - translation key (e.g., "error.notFound")
109
- * @param {object} context - values to interpolate {{key}}
110
- * @returns {string}
111
- */
112
- function t(key, context = {}) {
113
- let value = getNestedValue(translations, key);
114
-
115
- if (value === undefined) {
116
- value = getNestedValue(fallback, key);
117
- }
118
-
119
- if (value === undefined) return key;
120
-
121
- if (typeof value !== "string") return String(value);
122
-
123
- return interpolate(value, context);
124
- }
125
-
126
- return { t, lang: targetLang };
127
- }
128
-
129
- export default { createPluginI18n };