@umituz/react-native-google-translate 1.0.6 → 1.0.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 (68) hide show
  1. package/dist/domain/entities/Language.entity.d.ts +14 -0
  2. package/dist/domain/entities/Language.entity.d.ts.map +1 -0
  3. package/dist/domain/entities/Translation.entity.d.ts +31 -0
  4. package/dist/domain/entities/Translation.entity.d.ts.map +1 -0
  5. package/dist/domain/entities/index.d.ts +7 -0
  6. package/dist/domain/entities/index.d.ts.map +1 -0
  7. package/dist/domain/index.d.ts +9 -0
  8. package/dist/domain/index.d.ts.map +1 -0
  9. package/dist/domain/interfaces/ITranslationService.interface.d.ts +19 -0
  10. package/dist/domain/interfaces/ITranslationService.interface.d.ts.map +1 -0
  11. package/dist/domain/interfaces/index.d.ts +6 -0
  12. package/dist/domain/interfaces/index.d.ts.map +1 -0
  13. package/dist/index.d.ts +25 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +40 -0
  16. package/dist/infrastructure/constants/api.constants.d.ts +9 -0
  17. package/dist/infrastructure/constants/api.constants.d.ts.map +1 -0
  18. package/dist/infrastructure/constants/index.d.ts +7 -0
  19. package/dist/infrastructure/constants/index.d.ts.map +1 -0
  20. package/dist/infrastructure/constants/languages.constants.d.ts +9 -0
  21. package/dist/infrastructure/constants/languages.constants.d.ts.map +1 -0
  22. package/dist/infrastructure/index.d.ts +10 -0
  23. package/dist/infrastructure/index.d.ts.map +1 -0
  24. package/dist/infrastructure/services/GoogleTranslate.service.d.ts +20 -0
  25. package/dist/infrastructure/services/GoogleTranslate.service.d.ts.map +1 -0
  26. package/dist/infrastructure/services/GoogleTranslate.service.js +114 -27
  27. package/dist/infrastructure/services/index.d.ts +8 -0
  28. package/dist/infrastructure/services/index.d.ts.map +1 -0
  29. package/dist/infrastructure/utils/index.d.ts +7 -0
  30. package/dist/infrastructure/utils/index.d.ts.map +1 -0
  31. package/dist/infrastructure/utils/rateLimit.util.d.ts +12 -0
  32. package/dist/infrastructure/utils/rateLimit.util.d.ts.map +1 -0
  33. package/dist/infrastructure/utils/textValidator.util.d.ts +11 -0
  34. package/dist/infrastructure/utils/textValidator.util.d.ts.map +1 -0
  35. package/dist/presentation/hooks/index.d.ts +9 -0
  36. package/dist/presentation/hooks/index.d.ts.map +1 -0
  37. package/dist/presentation/hooks/index.js +11 -0
  38. package/dist/presentation/hooks/useBatchTranslation.hook.d.ts +20 -0
  39. package/dist/presentation/hooks/useBatchTranslation.hook.d.ts.map +1 -0
  40. package/dist/presentation/hooks/useBatchTranslation.hook.js +105 -0
  41. package/dist/presentation/hooks/useTranslation.hook.d.ts +16 -0
  42. package/dist/presentation/hooks/useTranslation.hook.d.ts.map +1 -0
  43. package/dist/presentation/hooks/useTranslation.hook.js +67 -0
  44. package/dist/presentation/index.d.ts +8 -0
  45. package/dist/presentation/index.d.ts.map +1 -0
  46. package/dist/presentation/index.js +23 -0
  47. package/dist/scripts/index.d.ts +9 -0
  48. package/dist/scripts/index.d.ts.map +1 -0
  49. package/dist/scripts/setup.d.ts +13 -0
  50. package/dist/scripts/setup.d.ts.map +1 -0
  51. package/dist/scripts/sync.d.ts +21 -0
  52. package/dist/scripts/sync.d.ts.map +1 -0
  53. package/dist/scripts/translate.d.ts +13 -0
  54. package/dist/scripts/translate.d.ts.map +1 -0
  55. package/dist/scripts/utils/file-parser.d.ts +8 -0
  56. package/dist/scripts/utils/file-parser.d.ts.map +1 -0
  57. package/dist/scripts/utils/index.d.ts +10 -0
  58. package/dist/scripts/utils/index.d.ts.map +1 -0
  59. package/dist/scripts/utils/key-detector.d.ts +11 -0
  60. package/dist/scripts/utils/key-detector.d.ts.map +1 -0
  61. package/dist/scripts/utils/key-extractor.d.ts +2 -0
  62. package/dist/scripts/utils/key-extractor.d.ts.map +1 -0
  63. package/dist/scripts/utils/object-helper.d.ts +14 -0
  64. package/dist/scripts/utils/object-helper.d.ts.map +1 -0
  65. package/dist/scripts/utils/sync-helper.d.ts +13 -0
  66. package/dist/scripts/utils/sync-helper.d.ts.map +1 -0
  67. package/package.json +13 -12
  68. package/src/infrastructure/services/GoogleTranslate.service.ts +130 -24
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ /**
3
+ * useBatchTranslation Hook
4
+ * @description React hook for batch translation of multiple texts
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.useBatchTranslation = useBatchTranslation;
8
+ const react_1 = require("react");
9
+ const services_1 = require("../../infrastructure/services");
10
+ function useBatchTranslation(options) {
11
+ const [isLoading, setIsLoading] = (0, react_1.useState)(false);
12
+ const [error, setError] = (0, react_1.useState)(null);
13
+ const [progress, setProgress] = (0, react_1.useState)(0);
14
+ const [total, setTotal] = (0, react_1.useState)(0);
15
+ const translateBatch = (0, react_1.useCallback)(async (requests) => {
16
+ if (!Array.isArray(requests) || requests.length === 0) {
17
+ return {
18
+ totalCount: 0,
19
+ successCount: 0,
20
+ failureCount: 0,
21
+ skippedCount: 0,
22
+ translatedKeys: [],
23
+ };
24
+ }
25
+ setIsLoading(true);
26
+ setError(null);
27
+ setTotal(requests.length);
28
+ setProgress(0);
29
+ try {
30
+ const stats = await services_1.googleTranslateService.translateBatch(requests);
31
+ // Progress is completed
32
+ setProgress(stats.totalCount);
33
+ options?.onProgress?.(stats.totalCount, stats.totalCount);
34
+ if (stats.failureCount > 0) {
35
+ const error = new Error(`${stats.failureCount} of ${stats.totalCount} translations failed`);
36
+ setError(error);
37
+ options?.onError?.(error);
38
+ }
39
+ else {
40
+ options?.onSuccess?.(stats);
41
+ }
42
+ return stats;
43
+ }
44
+ catch (err) {
45
+ const error = err instanceof Error ? err : new Error("Unknown error occurred");
46
+ setError(error);
47
+ options?.onError?.(error);
48
+ throw error;
49
+ }
50
+ finally {
51
+ setIsLoading(false);
52
+ }
53
+ }, [options]);
54
+ const translateObject = (0, react_1.useCallback)(async (sourceObject, targetObject, targetLanguage) => {
55
+ if (!sourceObject || typeof sourceObject !== "object") {
56
+ throw new Error("Source object is invalid");
57
+ }
58
+ if (!targetObject || typeof targetObject !== "object") {
59
+ throw new Error("Target object is invalid");
60
+ }
61
+ if (!targetLanguage || targetLanguage.trim().length === 0) {
62
+ throw new Error("Target language is required");
63
+ }
64
+ setIsLoading(true);
65
+ setError(null);
66
+ try {
67
+ const stats = {
68
+ totalCount: 0,
69
+ successCount: 0,
70
+ failureCount: 0,
71
+ skippedCount: 0,
72
+ translatedKeys: [],
73
+ };
74
+ await services_1.googleTranslateService.translateObject(sourceObject, targetObject, targetLanguage, "", stats);
75
+ setTotal(stats.totalCount);
76
+ setProgress(stats.totalCount);
77
+ if (stats.failureCount > 0) {
78
+ const error = new Error(`${stats.failureCount} of ${stats.totalCount} translations failed`);
79
+ setError(error);
80
+ options?.onError?.(error);
81
+ }
82
+ else {
83
+ options?.onSuccess?.(stats);
84
+ }
85
+ return stats;
86
+ }
87
+ catch (err) {
88
+ const error = err instanceof Error ? err : new Error("Unknown error occurred");
89
+ setError(error);
90
+ options?.onError?.(error);
91
+ throw error;
92
+ }
93
+ finally {
94
+ setIsLoading(false);
95
+ }
96
+ }, [options]);
97
+ return {
98
+ translateBatch,
99
+ translateObject,
100
+ isLoading,
101
+ progress,
102
+ total,
103
+ error,
104
+ };
105
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * useTranslation Hook
3
+ * @description React hook for single text translation
4
+ */
5
+ import type { TranslationResponse } from "../../domain";
6
+ export interface UseTranslationOptions {
7
+ readonly onSuccess?: (result: TranslationResponse) => void;
8
+ readonly onError?: (error: Error) => void;
9
+ }
10
+ export interface UseTranslationReturn {
11
+ readonly translate: (text: string, targetLanguage: string) => Promise<TranslationResponse>;
12
+ readonly isLoading: boolean;
13
+ readonly error: Error | null;
14
+ }
15
+ export declare function useTranslation(options?: UseTranslationOptions): UseTranslationReturn;
16
+ //# sourceMappingURL=useTranslation.hook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTranslation.hook.d.ts","sourceRoot":"","sources":["../../../src/presentation/hooks/useTranslation.hook.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAsB,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAG5E,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAC3D,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC3C;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC3F,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CAC9B;AAED,wBAAgB,cAAc,CAC5B,OAAO,CAAC,EAAE,qBAAqB,GAC9B,oBAAoB,CAkEtB"}
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ /**
3
+ * useTranslation Hook
4
+ * @description React hook for single text translation
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.useTranslation = useTranslation;
8
+ const react_1 = require("react");
9
+ const services_1 = require("../../infrastructure/services");
10
+ function useTranslation(options) {
11
+ const [isLoading, setIsLoading] = (0, react_1.useState)(false);
12
+ const [error, setError] = (0, react_1.useState)(null);
13
+ const translate = (0, react_1.useCallback)(async (text, targetLanguage) => {
14
+ if (!text || text.trim().length === 0) {
15
+ return {
16
+ originalText: text,
17
+ translatedText: text,
18
+ sourceLanguage: "en",
19
+ targetLanguage,
20
+ success: false,
21
+ error: "Text is empty",
22
+ };
23
+ }
24
+ if (!targetLanguage || targetLanguage.trim().length === 0) {
25
+ return {
26
+ originalText: text,
27
+ translatedText: text,
28
+ sourceLanguage: "en",
29
+ targetLanguage,
30
+ success: false,
31
+ error: "Target language is empty",
32
+ };
33
+ }
34
+ setIsLoading(true);
35
+ setError(null);
36
+ try {
37
+ const request = {
38
+ text,
39
+ targetLanguage,
40
+ };
41
+ const result = await services_1.googleTranslateService.translate(request);
42
+ if (result.success) {
43
+ options?.onSuccess?.(result);
44
+ }
45
+ else {
46
+ const error = new Error(result.error || "Translation failed");
47
+ setError(error);
48
+ options?.onError?.(error);
49
+ }
50
+ return result;
51
+ }
52
+ catch (err) {
53
+ const error = err instanceof Error ? err : new Error("Unknown error occurred");
54
+ setError(error);
55
+ options?.onError?.(error);
56
+ throw error;
57
+ }
58
+ finally {
59
+ setIsLoading(false);
60
+ }
61
+ }, [options]);
62
+ return {
63
+ translate,
64
+ isLoading,
65
+ error,
66
+ };
67
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Presentation Layer
3
+ * @description Subpath: @umituz/react-native-google-translate/hooks
4
+ *
5
+ * Exports all React hooks and presentation layer components
6
+ */
7
+ export * from "./hooks";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/presentation/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,SAAS,CAAC"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ /**
3
+ * Presentation Layer
4
+ * @description Subpath: @umituz/react-native-google-translate/hooks
5
+ *
6
+ * Exports all React hooks and presentation layer components
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
20
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
21
+ };
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ __exportStar(require("./hooks"), exports);
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Translation Scripts
3
+ * Scripts for translating and synchronizing localization files
4
+ */
5
+ export * from './translate';
6
+ export * from './sync';
7
+ export * from './setup';
8
+ export * from './utils';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scripts/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Setup Languages Script
4
+ * Creates stub files for all supported languages (if not exist),
5
+ * then generates index.ts from all available translation files.
6
+ * Usage: node setup.ts [locales-dir]
7
+ */
8
+ export interface SetupLanguagesOptions {
9
+ targetDir: string;
10
+ }
11
+ export declare function setupLanguages(options: SetupLanguagesOptions): boolean;
12
+ export declare function runSetupLanguages(): void;
13
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/scripts/setup.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAMH,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAkEtE;AAGD,wBAAgB,iBAAiB,IAAI,IAAI,CAIxC"}
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Sync Translations Script
4
+ * Synchronizes translation keys from en-US.ts to all other language files
5
+ */
6
+ export interface SyncTranslationsOptions {
7
+ targetDir: string;
8
+ srcDir?: string;
9
+ }
10
+ export interface SyncLanguageFileResult {
11
+ added?: number;
12
+ newKeys?: string[];
13
+ removed?: number;
14
+ removedKeys?: string[];
15
+ changed: boolean;
16
+ detectedNewKeys: unknown[];
17
+ }
18
+ export declare function syncLanguageFile(enUSPath: string, targetPath: string, langCode: string): SyncLanguageFileResult;
19
+ export declare function syncTranslations(options: SyncTranslationsOptions): boolean;
20
+ export declare function runSyncTranslations(): void;
21
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/scripts/sync.ts"],"names":[],"mappings":";AAEA;;;GAGG;AAiBH,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,OAAO,EAAE,CAAC;CAC5B;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,sBAAsB,CAgCxB;AAwCD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CA4B1E;AAGD,wBAAgB,mBAAmB,IAAI,IAAI,CAK1C"}
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Translate Missing Script
4
+ * Automatically translates missing strings using Google Translate
5
+ */
6
+ export interface TranslateMissingOptions {
7
+ targetDir: string;
8
+ srcDir?: string;
9
+ skipSync?: boolean;
10
+ }
11
+ export declare function translateMissing(options: TranslateMissingOptions): Promise<void>;
12
+ export declare function runTranslateMissing(): void;
13
+ //# sourceMappingURL=translate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translate.d.ts","sourceRoot":"","sources":["../../src/scripts/translate.ts"],"names":[],"mappings":";AAEA;;;GAGG;AAcH,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkFtF;AAGD,wBAAgB,mBAAmB,IAAI,IAAI,CAW1C"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * File Parser
3
+ * Parse and generate TypeScript translation files
4
+ */
5
+ export declare function parseTypeScriptFile(filePath: string): Record<string, unknown>;
6
+ export declare function stringifyValue(value: unknown, indent?: number): string;
7
+ export declare function generateTypeScriptContent(obj: Record<string, unknown>, langCode: string): string;
8
+ //# sourceMappingURL=file-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-parser.d.ts","sourceRoot":"","sources":["../../../src/scripts/utils/file-parser.ts"],"names":[],"mappings":"AAIA;;;GAGG;AAEH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA0C7E;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,SAAI,GAAG,MAAM,CAmCjE;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAYhG"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Scripts Utils
3
+ * Utility functions for translation scripts
4
+ */
5
+ export * from './file-parser';
6
+ export * from './key-detector';
7
+ export * from './key-extractor';
8
+ export * from './object-helper';
9
+ export * from './sync-helper';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/scripts/utils/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Key Detector
3
+ * Detects new, missing, and removed keys between source and target objects
4
+ */
5
+ export interface NewKey {
6
+ path: string;
7
+ value: unknown;
8
+ }
9
+ export declare function detectNewKeys(sourceObj: Record<string, unknown>, targetObj: Record<string, unknown>, path?: string, newKeys?: NewKey[]): NewKey[];
10
+ export declare function detectMissingKeys(sourceObj: Record<string, unknown>, targetObj: Record<string, unknown>, path?: string, missingKeys?: string[]): string[];
11
+ //# sourceMappingURL=key-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-detector.d.ts","sourceRoot":"","sources":["../../../src/scripts/utils/key-detector.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,IAAI,SAAK,EACT,OAAO,GAAE,MAAM,EAAO,GACrB,MAAM,EAAE,CAwBV;AAED,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,IAAI,SAAK,EACT,WAAW,GAAE,MAAM,EAAO,GACzB,MAAM,EAAE,CAuBV"}
@@ -0,0 +1,2 @@
1
+ export declare function extractUsedKeys(srcDir: string): Map<string, string>;
2
+ //# sourceMappingURL=key-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-extractor.d.ts","sourceRoot":"","sources":["../../../src/scripts/utils/key-extractor.ts"],"names":[],"mappings":"AA0FA,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAiBnE"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Object Helper
3
+ * Utilities for deep object manipulation
4
+ */
5
+ /**
6
+ * Set a value in a nested object, creating intermediate objects if necessary
7
+ * Returns true if the key was newly added, false if it already existed
8
+ */
9
+ export declare function setDeep(obj: Record<string, unknown>, path: string, value: unknown): boolean;
10
+ /**
11
+ * Count all leaf keys in a nested object
12
+ */
13
+ export declare function countKeys(obj: Record<string, unknown>): number;
14
+ //# sourceMappingURL=object-helper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"object-helper.d.ts","sourceRoot":"","sources":["../../../src/scripts/utils/object-helper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAmB3F;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAe9D"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Sync Helper
3
+ * Helper functions for synchronizing translation keys
4
+ */
5
+ export interface SyncStats {
6
+ added?: number;
7
+ newKeys?: string[];
8
+ removed?: number;
9
+ removedKeys?: string[];
10
+ }
11
+ export declare function addMissingKeys(sourceObj: Record<string, unknown>, targetObj: Record<string, unknown>, stats?: SyncStats): SyncStats;
12
+ export declare function removeExtraKeys(sourceObj: Record<string, unknown>, targetObj: Record<string, unknown>, stats?: SyncStats): SyncStats;
13
+ //# sourceMappingURL=sync-helper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-helper.d.ts","sourceRoot":"","sources":["../../../src/scripts/utils/sync-helper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,KAAK,GAAE,SAAc,GACpB,SAAS,CA4BX;AAED,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,KAAK,GAAE,SAAc,GACpB,SAAS,CA2BX"}
package/package.json CHANGED
@@ -1,27 +1,28 @@
1
1
  {
2
2
  "name": "@umituz/react-native-google-translate",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "Google Translate integration for React Native apps with rate limiting, batch translation, and TypeScript support",
5
- "main": "./src/index.ts",
6
- "types": "./src/index.ts",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
7
  "sideEffects": false,
8
8
  "exports": {
9
- ".": "./src/index.ts",
10
- "./core": "./src/domain/index.ts",
11
- "./services": "./src/infrastructure/services/index.ts",
12
- "./constants": "./src/infrastructure/constants/index.ts",
13
- "./hooks": "./src/presentation/hooks/index.ts",
14
- "./scripts": "./src/scripts/index.ts",
15
- "./package.json": "./package.json",
16
- "./*": "./src/*/index.ts"
9
+ ".": "./dist/index.js",
10
+ "./core": "./dist/domain/index.js",
11
+ "./services": "./dist/infrastructure/services/index.js",
12
+ "./constants": "./dist/infrastructure/constants/index.js",
13
+ "./hooks": "./dist/presentation/hooks/index.js",
14
+ "./scripts": "./dist/scripts/index.js",
15
+ "./package.json": "./package.json"
17
16
  },
18
17
  "scripts": {
18
+ "build": "tsc -p tsconfig.build.json",
19
19
  "build:scripts": "tsc -p tsconfig.scripts.json",
20
+ "build:all": "npm run build && npm run build:scripts",
20
21
  "setup": "node dist/scripts/setup.js",
21
22
  "translate": "node dist/scripts/translate.js",
22
23
  "sync": "node dist/scripts/sync.js",
23
24
  "i18n:setup": "node dist/scripts/setup.js",
24
- "prepublishOnly": "npm run build:scripts",
25
+ "prepublishOnly": "npm run build:all",
25
26
  "typecheck": "tsc --noEmit",
26
27
  "lint": "echo 'Lint passed'",
27
28
  "version:patch": "npm version patch -m 'chore: release v%s'",
@@ -117,6 +117,8 @@ class GoogleTranslateService implements ITranslationService {
117
117
  };
118
118
  }
119
119
 
120
+ // Use batch API call for better performance
121
+ const batchSize = 50;
120
122
  const stats: TranslationStats = {
121
123
  totalCount: requests.length,
122
124
  successCount: 0,
@@ -125,22 +127,52 @@ class GoogleTranslateService implements ITranslationService {
125
127
  translatedKeys: [],
126
128
  };
127
129
 
128
- for (const request of requests) {
129
- const result = await this.translate(request);
130
+ for (let i = 0; i < requests.length; i += batchSize) {
131
+ const batch = requests.slice(i, i + batchSize);
130
132
 
131
- if (result.success) {
132
- if (result.translatedText === result.originalText) {
133
- stats.skippedCount++;
134
- } else {
135
- stats.successCount++;
136
- stats.translatedKeys.push({
137
- key: request.text,
138
- from: result.originalText,
139
- to: result.translatedText,
140
- });
133
+ // Wait for rate limiter once per batch instead of once per request
134
+ await this.rateLimiter!.waitForSlot();
135
+
136
+ try {
137
+ const translations = await this.callTranslateAPIBatch(batch, requests[0].targetLanguage);
138
+
139
+ for (let j = 0; j < batch.length; j++) {
140
+ const request = batch[j];
141
+ const translatedText = translations[j];
142
+
143
+ if (translatedText && translatedText !== request.text) {
144
+ stats.successCount++;
145
+ stats.translatedKeys.push({
146
+ key: request.text,
147
+ from: request.text,
148
+ to: translatedText,
149
+ });
150
+ } else if (!translatedText) {
151
+ stats.failureCount++;
152
+ } else {
153
+ stats.skippedCount++;
154
+ }
155
+ }
156
+ } catch (error) {
157
+ // Fallback to individual requests on batch failure
158
+ for (const request of batch) {
159
+ const result = await this.translate(request);
160
+
161
+ if (result.success) {
162
+ if (result.translatedText === result.originalText) {
163
+ stats.skippedCount++;
164
+ } else {
165
+ stats.successCount++;
166
+ stats.translatedKeys.push({
167
+ key: request.text,
168
+ from: result.originalText,
169
+ to: result.translatedText,
170
+ });
171
+ }
172
+ } else {
173
+ stats.failureCount++;
174
+ }
141
175
  }
142
- } else {
143
- stats.failureCount++;
144
176
  }
145
177
  }
146
178
 
@@ -174,6 +206,9 @@ class GoogleTranslateService implements ITranslationService {
174
206
 
175
207
  const keys = Object.keys(sourceObject);
176
208
 
209
+ // Collect all texts to translate first
210
+ const textsToTranslate: Array<{key: string; enValue: string; currentPath: string}> = [];
211
+
177
212
  for (const key of keys) {
178
213
  const enValue = sourceObject[key];
179
214
  const targetValue = targetObject[key];
@@ -197,28 +232,43 @@ class GoogleTranslateService implements ITranslationService {
197
232
  stats.totalCount++;
198
233
 
199
234
  if (needsTranslation(targetValue, enValue)) {
200
- const request: TranslationRequest = {
201
- text: enValue,
235
+ textsToTranslate.push({key, enValue, currentPath});
236
+ } else {
237
+ stats.skippedCount++;
238
+ }
239
+ }
240
+ }
241
+
242
+ // Batch translate all texts at once
243
+ if (textsToTranslate.length > 0) {
244
+ const batchSize = 50; // Google Translate API can handle ~50 texts at once
245
+ for (let i = 0; i < textsToTranslate.length; i += batchSize) {
246
+ const batch = textsToTranslate.slice(i, i + batchSize);
247
+ const results = await this.translateBatch(
248
+ batch.map(item => ({
249
+ text: item.enValue,
202
250
  targetLanguage,
203
- };
251
+ }))
252
+ );
204
253
 
205
- const result = await this.translate(request);
254
+ // Apply translations
255
+ for (let j = 0; j < batch.length; j++) {
256
+ const {key, enValue, currentPath} = batch[j];
257
+ const translatedKey = results.translatedKeys[j];
206
258
 
207
- if (result.success && result.translatedText !== enValue) {
208
- targetObject[key] = result.translatedText;
259
+ if (translatedKey && translatedKey.from !== enValue) {
260
+ targetObject[key] = translatedKey.to;
209
261
  stats.successCount++;
210
262
  stats.translatedKeys.push({
211
263
  key: currentPath,
212
264
  from: enValue,
213
- to: result.translatedText,
265
+ to: translatedKey.to,
214
266
  });
215
- } else if (!result.success) {
267
+ } else if (!translatedKey) {
216
268
  stats.failureCount++;
217
269
  } else {
218
270
  stats.skippedCount++;
219
271
  }
220
- } else {
221
- stats.skippedCount++;
222
272
  }
223
273
  }
224
274
  }
@@ -264,6 +314,62 @@ class GoogleTranslateService implements ITranslationService {
264
314
  clearTimeout(timeoutId);
265
315
  }
266
316
  }
317
+
318
+ private async callTranslateAPIBatch(
319
+ requests: TranslationRequest[],
320
+ targetLanguage: string,
321
+ sourceLanguage: string = "en"
322
+ ): Promise<string[]> {
323
+ const timeout = this.config?.timeout || DEFAULT_TIMEOUT;
324
+
325
+ // Build batch request URL - Google Translate accepts multiple q parameters
326
+ const queryParams = requests.map(req => `q=${encodeURIComponent(req.text)}`).join('&');
327
+ const url = `${GOOGLE_TRANSLATE_API_URL}?client=gtx&sl=${sourceLanguage}&tl=${targetLanguage}&dt=t&${queryParams}`;
328
+
329
+ const controller = new AbortController();
330
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
331
+
332
+ try {
333
+ const response = await fetch(url, {
334
+ signal: controller.signal,
335
+ });
336
+
337
+ if (!response.ok) {
338
+ throw new Error(`Batch API request failed: ${response.status}`);
339
+ }
340
+
341
+ const data = await response.json();
342
+
343
+ // Google Translate batch response format:
344
+ // [[["translated1", ...]], [["translated2", ...]], ...]
345
+ const translations: string[] = [];
346
+
347
+ if (Array.isArray(data)) {
348
+ for (let i = 0; i < Math.min(requests.length, data.length); i++) {
349
+ const item = data[i];
350
+ if (
351
+ Array.isArray(item) &&
352
+ item.length > 0 &&
353
+ Array.isArray(item[0]) &&
354
+ typeof item[0][0] === "string"
355
+ ) {
356
+ translations.push(item[0][0]);
357
+ } else {
358
+ translations.push(requests[i].text); // Fallback to original
359
+ }
360
+ }
361
+ }
362
+
363
+ // Fill missing translations with original text
364
+ while (translations.length < requests.length) {
365
+ translations.push(requests[translations.length].text);
366
+ }
367
+
368
+ return translations;
369
+ } finally {
370
+ clearTimeout(timeoutId);
371
+ }
372
+ }
267
373
  }
268
374
 
269
375
  export const googleTranslateService = new GoogleTranslateService();