@rimori/client 1.4.5 → 1.4.8

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.
Files changed (64) hide show
  1. package/README.md +116 -0
  2. package/dist/cli/scripts/release/detect-translation-languages.d.ts +5 -0
  3. package/dist/cli/scripts/release/detect-translation-languages.js +43 -0
  4. package/dist/cli/scripts/release/release-config-upload.js +4 -0
  5. package/dist/cli/scripts/release/release-translation-upload.d.ts +6 -0
  6. package/dist/cli/scripts/release/release-translation-upload.js +87 -0
  7. package/dist/cli/scripts/release/release.d.ts +1 -1
  8. package/dist/cli/scripts/release/release.js +14 -5
  9. package/dist/components/ai/EmbeddedAssistent/TTS/MessageSender.js +2 -2
  10. package/dist/core/controller/EnhancedUserInfo.d.ts +0 -0
  11. package/dist/core/controller/EnhancedUserInfo.js +1 -0
  12. package/dist/core/controller/SettingsController.d.ts +7 -1
  13. package/dist/core/core.d.ts +1 -2
  14. package/dist/core/core.js +0 -1
  15. package/dist/fromRimori/EventBus.js +23 -23
  16. package/dist/fromRimori/PluginTypes.d.ts +4 -4
  17. package/dist/hooks/I18nHooks.d.ts +11 -0
  18. package/dist/hooks/I18nHooks.js +25 -0
  19. package/dist/i18n/I18nHooks.d.ts +11 -0
  20. package/dist/i18n/I18nHooks.js +25 -0
  21. package/dist/i18n/Translator.d.ts +43 -0
  22. package/dist/i18n/Translator.js +118 -0
  23. package/dist/i18n/config.d.ts +7 -0
  24. package/dist/i18n/config.js +20 -0
  25. package/dist/i18n/createI18nInstance.d.ts +7 -0
  26. package/dist/i18n/createI18nInstance.js +31 -0
  27. package/dist/i18n/hooks.d.ts +11 -0
  28. package/dist/i18n/hooks.js +25 -0
  29. package/dist/i18n/index.d.ts +4 -0
  30. package/dist/i18n/index.js +4 -0
  31. package/dist/i18n/types.d.ts +7 -0
  32. package/dist/i18n/types.js +1 -0
  33. package/dist/i18n/useRimoriI18n.d.ts +11 -0
  34. package/dist/i18n/useRimoriI18n.js +41 -0
  35. package/dist/index.d.ts +1 -1
  36. package/dist/index.js +1 -1
  37. package/dist/plugin/RimoriClient.d.ts +3 -0
  38. package/dist/plugin/RimoriClient.js +6 -0
  39. package/dist/plugin/TranslationController.d.ts +38 -0
  40. package/dist/plugin/TranslationController.js +105 -0
  41. package/dist/plugin/Translator.d.ts +38 -0
  42. package/dist/plugin/Translator.js +101 -0
  43. package/dist/utils/LanguageClass.d.ts +36 -0
  44. package/dist/utils/LanguageClass.example.d.ts +0 -0
  45. package/dist/utils/LanguageClass.example.js +1 -0
  46. package/dist/utils/LanguageClass.js +50 -0
  47. package/dist/utils/LanguageClass.test.d.ts +0 -0
  48. package/dist/utils/LanguageClass.test.js +1 -0
  49. package/package.json +12 -14
  50. package/prettier.config.js +1 -1
  51. package/src/cli/scripts/release/detect-translation-languages.ts +37 -0
  52. package/src/cli/scripts/release/release-config-upload.ts +5 -0
  53. package/src/cli/scripts/release/release.ts +20 -4
  54. package/src/cli/types/DatabaseTypes.ts +10 -2
  55. package/src/components/ai/EmbeddedAssistent/TTS/MessageSender.ts +2 -2
  56. package/src/core/controller/SettingsController.ts +8 -1
  57. package/src/core/core.ts +1 -2
  58. package/src/fromRimori/EventBus.ts +47 -76
  59. package/src/fromRimori/PluginTypes.ts +17 -26
  60. package/src/hooks/I18nHooks.ts +33 -0
  61. package/src/index.ts +1 -1
  62. package/src/plugin/RimoriClient.ts +9 -1
  63. package/src/plugin/TranslationController.ts +105 -0
  64. package/src/utils/Language.ts +0 -72
@@ -0,0 +1,25 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { useRimori } from '../providers/PluginProvider';
3
+ /**
4
+ * Custom useTranslation hook that provides a translation function and indicates readiness
5
+ * @returns An object containing the translation function (`t`) and a boolean (`ready`) indicating if the translator is initialized.
6
+ */
7
+ export function useTranslation() {
8
+ const { plugin } = useRimori();
9
+ const [translatorInstance, setTranslatorInstance] = useState(null);
10
+ useEffect(() => {
11
+ void plugin.getTranslator().then(setTranslatorInstance);
12
+ }, [plugin]);
13
+ const safeT = (key, options) => {
14
+ if (!translatorInstance)
15
+ return '\u200B'; // zero-width space
16
+ try {
17
+ return translatorInstance.t(key, options);
18
+ }
19
+ catch (error) {
20
+ console.error('Translation error:', error);
21
+ return key;
22
+ }
23
+ };
24
+ return { t: safeT, ready: translatorInstance !== null };
25
+ }
@@ -0,0 +1,43 @@
1
+ import { ThirdPartyModule, TOptions } from 'i18next';
2
+ /**
3
+ * Translator class for handling internationalization
4
+ */
5
+ export declare class Translator {
6
+ private currentLanguage;
7
+ private isInitialized;
8
+ private i18n;
9
+ constructor(initialLanguage: string);
10
+ /**
11
+ * Initialize translator with user's language
12
+ * @param userLanguage - Language code from user info
13
+ */
14
+ initialize(): Promise<void>;
15
+ private getTranslationUrl;
16
+ /**
17
+ * Initialize i18n with or without React support
18
+ * @param isReact - Whether to use React-specific features
19
+ */
20
+ private getI18n;
21
+ usePlugin(plugin: ThirdPartyModule): void;
22
+ /**
23
+ * Fetch translations manually from the current domain
24
+ * @param language - Language code to fetch
25
+ * @returns Promise with translation data
26
+ */
27
+ private fetchTranslations;
28
+ /**
29
+ * Get translation for a key
30
+ * @param key - Translation key
31
+ * @param options - Translation options
32
+ * @returns Translated string
33
+ */
34
+ t(key: string, options?: TOptions): string;
35
+ /**
36
+ * Get current language
37
+ */
38
+ getCurrentLanguage(): string;
39
+ /**
40
+ * Check if translator is initialized
41
+ */
42
+ isReady(): boolean;
43
+ }
@@ -0,0 +1,118 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import i18n from './config';
11
+ import { createInstance } from 'i18next';
12
+ /**
13
+ * Translator class for handling internationalization
14
+ */
15
+ export class Translator {
16
+ constructor(initialLanguage) {
17
+ this.currentLanguage = initialLanguage;
18
+ this.isInitialized = false;
19
+ this.i18n = this.getI18n();
20
+ }
21
+ /**
22
+ * Initialize translator with user's language
23
+ * @param userLanguage - Language code from user info
24
+ */
25
+ initialize() {
26
+ return __awaiter(this, void 0, void 0, function* () {
27
+ if (this.isInitialized) {
28
+ return;
29
+ }
30
+ try {
31
+ // Fetch translations manually
32
+ const translations = yield this.fetchTranslations(this.currentLanguage);
33
+ // Add translations to i18n
34
+ i18n.addResourceBundle(this.currentLanguage, 'translation', translations);
35
+ // Change language
36
+ yield i18n.changeLanguage(this.currentLanguage);
37
+ this.isInitialized = true;
38
+ }
39
+ catch (error) {
40
+ console.warn('Failed to initialize translator:', error);
41
+ // Ensure we have at least English fallback
42
+ if (!this.isInitialized) {
43
+ this.currentLanguage = 'en';
44
+ yield this.initialize();
45
+ }
46
+ }
47
+ });
48
+ }
49
+ getTranslationUrl(language) {
50
+ return `${window.location.origin}/locales/${language}/translation.json`;
51
+ }
52
+ /**
53
+ * Initialize i18n with or without React support
54
+ * @param isReact - Whether to use React-specific features
55
+ */
56
+ getI18n(isReact = false) {
57
+ return createInstance({
58
+ fallbackLng: 'en',
59
+ debug: window.location.hostname === 'localhost',
60
+ interpolation: {
61
+ escapeValue: !isReact,
62
+ },
63
+ });
64
+ }
65
+ usePlugin(plugin) {
66
+ this.i18n.use(plugin);
67
+ }
68
+ /**
69
+ * Fetch translations manually from the current domain
70
+ * @param language - Language code to fetch
71
+ * @returns Promise with translation data
72
+ */
73
+ fetchTranslations(language) {
74
+ return __awaiter(this, void 0, void 0, function* () {
75
+ try {
76
+ const response = yield fetch(this.getTranslationUrl(language));
77
+ if (!response.ok) {
78
+ throw new Error(`Failed to fetch translations for ${language}`);
79
+ }
80
+ return yield response.json();
81
+ }
82
+ catch (error) {
83
+ console.warn(`Failed to fetch translations for ${language}:`, error);
84
+ // Fallback to English if available
85
+ if (language !== 'en') {
86
+ try {
87
+ return yield this.fetchTranslations('en');
88
+ }
89
+ catch (error) {
90
+ console.warn('Failed to fetch fallback translations:', error);
91
+ }
92
+ }
93
+ return {};
94
+ }
95
+ });
96
+ }
97
+ /**
98
+ * Get translation for a key
99
+ * @param key - Translation key
100
+ * @param options - Translation options
101
+ * @returns Translated string
102
+ */
103
+ t(key, options) {
104
+ return i18n.t(key, options);
105
+ }
106
+ /**
107
+ * Get current language
108
+ */
109
+ getCurrentLanguage() {
110
+ return this.currentLanguage;
111
+ }
112
+ /**
113
+ * Check if translator is initialized
114
+ */
115
+ isReady() {
116
+ return this.isInitialized;
117
+ }
118
+ }
@@ -0,0 +1,7 @@
1
+ import i18n from 'i18next';
2
+ /**
3
+ * Initialize i18n with or without React support
4
+ * @param isReact - Whether to use React-specific features
5
+ */
6
+ export declare function getI18n(isReact?: boolean): import("i18next").i18n;
7
+ export default i18n;
@@ -0,0 +1,20 @@
1
+ import i18n, { createInstance } from 'i18next';
2
+ import { initReactI18next } from 'react-i18next';
3
+ /**
4
+ * Initialize i18n with or without React support
5
+ * @param isReact - Whether to use React-specific features
6
+ */
7
+ export function getI18n(isReact = false) {
8
+ const i18n = createInstance({
9
+ fallbackLng: 'en',
10
+ debug: window.location.hostname === 'localhost',
11
+ interpolation: {
12
+ escapeValue: !isReact,
13
+ },
14
+ });
15
+ if (isReact) {
16
+ i18n.use(initReactI18next);
17
+ }
18
+ return i18n;
19
+ }
20
+ export default i18n;
@@ -0,0 +1,7 @@
1
+ import { I18nConfig } from './types';
2
+ /**
3
+ * Creates a configured i18next instance for Rimori plugins
4
+ * @param config - Configuration options for i18n
5
+ * @returns Configured i18next instance
6
+ */
7
+ export declare const createI18nInstance: (config?: I18nConfig) => import("i18next").i18n;
@@ -0,0 +1,31 @@
1
+ import i18n from 'i18next';
2
+ import { initReactI18next } from 'react-i18next';
3
+ import HttpBackend from 'i18next-http-backend';
4
+ /**
5
+ * Creates a configured i18next instance for Rimori plugins
6
+ * @param config - Configuration options for i18n
7
+ * @returns Configured i18next instance
8
+ */
9
+ export const createI18nInstance = (config = {}) => {
10
+ const { fallbackLng = 'en', debug = false, loadPath = './locales/{{lng}}/translation.json', supportedLanguages = ['en', 'es', 'zh', 'hi', 'ar'], namespace = 'translation', } = config;
11
+ i18n
12
+ .use(HttpBackend)
13
+ .use(initReactI18next)
14
+ .init({
15
+ fallbackLng,
16
+ debug,
17
+ supportedLngs: supportedLanguages,
18
+ ns: [namespace],
19
+ defaultNS: namespace,
20
+ backend: {
21
+ loadPath,
22
+ },
23
+ interpolation: {
24
+ escapeValue: false, // React already escapes by default
25
+ },
26
+ react: {
27
+ useSuspense: true,
28
+ },
29
+ });
30
+ return i18n;
31
+ };
@@ -0,0 +1,11 @@
1
+ import { TOptions } from 'i18next';
2
+ type TranslatorFn = (key: string, options?: TOptions) => string;
3
+ /**
4
+ * Custom useTranslation hook that provides a translation function and indicates readiness
5
+ * @returns An object containing the translation function (`t`) and a boolean (`ready`) indicating if the translator is initialized.
6
+ */
7
+ export declare function useTranslation(): {
8
+ t: TranslatorFn;
9
+ ready: boolean;
10
+ };
11
+ export {};
@@ -0,0 +1,25 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { useRimori } from '../providers/PluginProvider';
3
+ /**
4
+ * Custom useTranslation hook that provides a translation function and indicates readiness
5
+ * @returns An object containing the translation function (`t`) and a boolean (`ready`) indicating if the translator is initialized.
6
+ */
7
+ export function useTranslation() {
8
+ const { plugin } = useRimori();
9
+ const [translatorInstance, setTranslatorInstance] = useState(null);
10
+ useEffect(() => {
11
+ void plugin.getTranslator().then(setTranslatorInstance);
12
+ }, [plugin]);
13
+ const safeT = (key, options) => {
14
+ if (!translatorInstance)
15
+ return '\u200B'; // zero-width space
16
+ try {
17
+ return translatorInstance.t(key, options);
18
+ }
19
+ catch (error) {
20
+ console.error('Translation error:', error);
21
+ return key;
22
+ }
23
+ };
24
+ return { t: safeT, ready: translatorInstance !== null };
25
+ }
@@ -0,0 +1,4 @@
1
+ export { useTranslation } from './hooks';
2
+ export { default as i18n, initializeI18n } from './config';
3
+ export { useTranslation as useI18nTranslation } from 'react-i18next';
4
+ export { Translator } from './Translator';
@@ -0,0 +1,4 @@
1
+ export { useTranslation } from './hooks';
2
+ export { default as i18n, initializeI18n } from './config';
3
+ export { useTranslation as useI18nTranslation } from 'react-i18next';
4
+ export { Translator } from './Translator';
@@ -0,0 +1,7 @@
1
+ export interface I18nConfig {
2
+ fallbackLng?: string;
3
+ debug?: boolean;
4
+ loadPath?: string;
5
+ supportedLanguages?: string[];
6
+ namespace?: string;
7
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Custom hook that automatically initializes i18n with user's language
3
+ * and provides the useTranslation hook functionality
4
+ * @param namespace - Optional namespace for translations
5
+ * @returns useTranslation hook result
6
+ */
7
+ export declare const useRimoriI18n: (namespace?: string) => {
8
+ t: import("i18next").TFunction<string, undefined>;
9
+ i18n: import("i18next").i18n;
10
+ ready: boolean;
11
+ };
@@ -0,0 +1,41 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { useEffect } from 'react';
11
+ import { useTranslation } from 'react-i18next';
12
+ import { useRimori } from '../providers/PluginProvider';
13
+ /**
14
+ * Custom hook that automatically initializes i18n with user's language
15
+ * and provides the useTranslation hook functionality
16
+ * @param namespace - Optional namespace for translations
17
+ * @returns useTranslation hook result
18
+ */
19
+ export const useRimoriI18n = (namespace) => {
20
+ const { t, i18n, ready } = useTranslation(namespace);
21
+ const rimoriClient = useRimori();
22
+ useEffect(() => {
23
+ const initializeLanguage = () => __awaiter(void 0, void 0, void 0, function* () {
24
+ try {
25
+ const userInfo = rimoriClient.plugin.getUserInfo();
26
+ const userLanguage = userInfo.mother_tongue.code.toLowerCase();
27
+ // Only change language if it's different from current
28
+ if (i18n.language !== userLanguage) {
29
+ yield i18n.changeLanguage(userLanguage);
30
+ }
31
+ }
32
+ catch (error) {
33
+ console.warn('Failed to initialize i18n with user language, using fallback:', error);
34
+ }
35
+ });
36
+ if (ready) {
37
+ initializeLanguage();
38
+ }
39
+ }, [i18n, rimoriClient, ready]);
40
+ return { t, i18n, ready };
41
+ };
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@ export * from './providers/PluginProvider';
5
5
  export * from './cli/types/DatabaseTypes';
6
6
  export * from './utils/difficultyConverter';
7
7
  export * from './utils/PluginUtils';
8
- export * from './utils/Language';
9
8
  export * from './fromRimori/PluginTypes';
10
9
  export { FirstMessages } from './components/ai/utils';
11
10
  export { AudioController } from './plugin/AudioController';
11
+ export { useTranslation } from './hooks/I18nHooks';
package/dist/index.js CHANGED
@@ -6,6 +6,6 @@ export * from './providers/PluginProvider';
6
6
  export * from './cli/types/DatabaseTypes';
7
7
  export * from './utils/difficultyConverter';
8
8
  export * from './utils/PluginUtils';
9
- export * from './utils/Language';
10
9
  export * from './fromRimori/PluginTypes';
11
10
  export { AudioController } from './plugin/AudioController';
11
+ export { useTranslation } from './hooks/I18nHooks';
@@ -9,6 +9,7 @@ import { EventBusMessage, EventHandler, EventPayload } from '../fromRimori/Event
9
9
  import { ActivePlugin, MainPanelAction, Plugin, Tool } from '../fromRimori/PluginTypes';
10
10
  import { AccomplishmentPayload } from './AccomplishmentHandler';
11
11
  import { PluginController } from './PluginController';
12
+ import { Translator } from './TranslationController';
12
13
  interface Db {
13
14
  from: {
14
15
  <TableName extends string & keyof GenericSchema['Tables'], Table extends GenericSchema['Tables'][TableName]>(relation: TableName): PostgrestQueryBuilder<GenericSchema, Table, TableName>;
@@ -57,6 +58,7 @@ interface PluginInterface {
57
58
  sidePanelPlugin?: ActivePlugin;
58
59
  };
59
60
  getUserInfo: () => UserInfo;
61
+ getTranslator: () => Promise<Translator>;
60
62
  }
61
63
  export declare class RimoriClient {
62
64
  private static instance;
@@ -67,6 +69,7 @@ export declare class RimoriClient {
67
69
  private exerciseController;
68
70
  private accomplishmentHandler;
69
71
  private rimoriInfo;
72
+ private translator;
70
73
  plugin: PluginInterface;
71
74
  db: Db;
72
75
  private constructor();
@@ -15,6 +15,7 @@ import { getSTTResponse, getTTSResponse } from '../core/controller/VoiceControll
15
15
  import { ExerciseController } from '../core/controller/ExerciseController';
16
16
  import { EventBus } from '../fromRimori/EventBus';
17
17
  import { AccomplishmentHandler } from './AccomplishmentHandler';
18
+ import { Translator } from './TranslationController';
18
19
  export class RimoriClient {
19
20
  constructor(supabase, info, pluginController) {
20
21
  this.event = {
@@ -250,6 +251,7 @@ export class RimoriClient {
250
251
  this.sharedContentController = new SharedContentController(this.superbase, this);
251
252
  this.exerciseController = new ExerciseController(supabase, pluginController);
252
253
  this.accomplishmentHandler = new AccomplishmentHandler(info.pluginId);
254
+ this.translator = new Translator(info.profile.mother_tongue.code);
253
255
  this.from = this.from.bind(this);
254
256
  this.getTableName = this.getTableName.bind(this);
255
257
  this.db = {
@@ -277,6 +279,10 @@ export class RimoriClient {
277
279
  sidePanelPlugin: this.rimoriInfo.sidePanelPlugin,
278
280
  };
279
281
  },
282
+ getTranslator: () => __awaiter(this, void 0, void 0, function* () {
283
+ yield this.translator.initialize();
284
+ return this.translator;
285
+ }),
280
286
  };
281
287
  }
282
288
  /**
@@ -0,0 +1,38 @@
1
+ import { ThirdPartyModule, TOptions } from 'i18next';
2
+ /**
3
+ * Translator class for handling internationalization
4
+ */
5
+ export declare class Translator {
6
+ private currentLanguage;
7
+ private isInitialized;
8
+ private i18n;
9
+ constructor(initialLanguage: string);
10
+ /**
11
+ * Initialize translator with user's language
12
+ * @param userLanguage - Language code from user info
13
+ */
14
+ initialize(): Promise<void>;
15
+ private getTranslationUrl;
16
+ usePlugin(plugin: ThirdPartyModule): void;
17
+ /**
18
+ * Fetch translations manually from the current domain
19
+ * @param language - Language code to fetch
20
+ * @returns Promise with translation data
21
+ */
22
+ private fetchTranslations;
23
+ /**
24
+ * Get translation for a key
25
+ * @param key - Translation key
26
+ * @param options - Translation options
27
+ * @returns Translated string
28
+ */
29
+ t(key: string, options?: TOptions): string;
30
+ /**
31
+ * Get current language
32
+ */
33
+ getCurrentLanguage(): string;
34
+ /**
35
+ * Check if translator is initialized
36
+ */
37
+ isReady(): boolean;
38
+ }
@@ -0,0 +1,105 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { createInstance } from 'i18next';
11
+ /**
12
+ * Translator class for handling internationalization
13
+ */
14
+ export class Translator {
15
+ constructor(initialLanguage) {
16
+ this.isInitialized = false;
17
+ this.currentLanguage = initialLanguage;
18
+ }
19
+ /**
20
+ * Initialize translator with user's language
21
+ * @param userLanguage - Language code from user info
22
+ */
23
+ initialize() {
24
+ return __awaiter(this, void 0, void 0, function* () {
25
+ if (this.isInitialized)
26
+ return;
27
+ const translations = yield this.fetchTranslations(this.currentLanguage);
28
+ const instance = createInstance({
29
+ lng: this.currentLanguage,
30
+ resources: {
31
+ [this.currentLanguage]: {
32
+ translation: translations,
33
+ },
34
+ },
35
+ debug: window.location.hostname === 'localhost',
36
+ });
37
+ yield instance.init();
38
+ this.i18n = instance;
39
+ this.isInitialized = true;
40
+ });
41
+ }
42
+ getTranslationUrl(language) {
43
+ // For localhost development, use local- prefix for non-English languages
44
+ const isLocalhost = window.location.hostname === 'localhost';
45
+ const isEnglish = language === 'en';
46
+ const filename = isLocalhost && !isEnglish ? `local-${language}` : language;
47
+ return `${window.location.origin}/locales/${filename}.json`;
48
+ }
49
+ usePlugin(plugin) {
50
+ if (!this.i18n) {
51
+ throw new Error('Translator is not initialized');
52
+ }
53
+ this.i18n.use(plugin);
54
+ }
55
+ /**
56
+ * Fetch translations manually from the current domain
57
+ * @param language - Language code to fetch
58
+ * @returns Promise with translation data
59
+ */
60
+ fetchTranslations(language) {
61
+ return __awaiter(this, void 0, void 0, function* () {
62
+ try {
63
+ const response = yield fetch(this.getTranslationUrl(language));
64
+ if (!response.ok) {
65
+ throw new Error(`Failed to fetch translations for ${language}`);
66
+ }
67
+ return (yield response.json());
68
+ }
69
+ catch (error) {
70
+ console.warn(`Failed to fetch translations for ${language}:`, error);
71
+ if (language === 'en')
72
+ return {};
73
+ // Fallback to English
74
+ return this.fetchTranslations('en').catch((error) => {
75
+ console.error('Failed to fetch fallback translations:', error);
76
+ return {};
77
+ });
78
+ }
79
+ });
80
+ }
81
+ /**
82
+ * Get translation for a key
83
+ * @param key - Translation key
84
+ * @param options - Translation options
85
+ * @returns Translated string
86
+ */
87
+ t(key, options) {
88
+ if (!this.i18n) {
89
+ throw new Error('Translator is not initialized');
90
+ }
91
+ return this.i18n.t(key, options);
92
+ }
93
+ /**
94
+ * Get current language
95
+ */
96
+ getCurrentLanguage() {
97
+ return this.currentLanguage;
98
+ }
99
+ /**
100
+ * Check if translator is initialized
101
+ */
102
+ isReady() {
103
+ return this.isInitialized;
104
+ }
105
+ }
@@ -0,0 +1,38 @@
1
+ import { ThirdPartyModule, TOptions } from 'i18next';
2
+ /**
3
+ * Translator class for handling internationalization
4
+ */
5
+ export declare class Translator {
6
+ private currentLanguage;
7
+ private isInitialized;
8
+ private i18n;
9
+ constructor(initialLanguage: string);
10
+ /**
11
+ * Initialize translator with user's language
12
+ * @param userLanguage - Language code from user info
13
+ */
14
+ initialize(): Promise<void>;
15
+ private getTranslationUrl;
16
+ usePlugin(plugin: ThirdPartyModule): void;
17
+ /**
18
+ * Fetch translations manually from the current domain
19
+ * @param language - Language code to fetch
20
+ * @returns Promise with translation data
21
+ */
22
+ private fetchTranslations;
23
+ /**
24
+ * Get translation for a key
25
+ * @param key - Translation key
26
+ * @param options - Translation options
27
+ * @returns Translated string
28
+ */
29
+ t(key: string, options?: TOptions): string;
30
+ /**
31
+ * Get current language
32
+ */
33
+ getCurrentLanguage(): string;
34
+ /**
35
+ * Check if translator is initialized
36
+ */
37
+ isReady(): boolean;
38
+ }