@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.
- package/dist/domain/entities/Language.entity.d.ts +14 -0
- package/dist/domain/entities/Language.entity.d.ts.map +1 -0
- package/dist/domain/entities/Translation.entity.d.ts +31 -0
- package/dist/domain/entities/Translation.entity.d.ts.map +1 -0
- package/dist/domain/entities/index.d.ts +7 -0
- package/dist/domain/entities/index.d.ts.map +1 -0
- package/dist/domain/index.d.ts +9 -0
- package/dist/domain/index.d.ts.map +1 -0
- package/dist/domain/interfaces/ITranslationService.interface.d.ts +19 -0
- package/dist/domain/interfaces/ITranslationService.interface.d.ts.map +1 -0
- package/dist/domain/interfaces/index.d.ts +6 -0
- package/dist/domain/interfaces/index.d.ts.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/infrastructure/constants/api.constants.d.ts +9 -0
- package/dist/infrastructure/constants/api.constants.d.ts.map +1 -0
- package/dist/infrastructure/constants/index.d.ts +7 -0
- package/dist/infrastructure/constants/index.d.ts.map +1 -0
- package/dist/infrastructure/constants/languages.constants.d.ts +9 -0
- package/dist/infrastructure/constants/languages.constants.d.ts.map +1 -0
- package/dist/infrastructure/index.d.ts +10 -0
- package/dist/infrastructure/index.d.ts.map +1 -0
- package/dist/infrastructure/services/GoogleTranslate.service.d.ts +20 -0
- package/dist/infrastructure/services/GoogleTranslate.service.d.ts.map +1 -0
- package/dist/infrastructure/services/GoogleTranslate.service.js +114 -27
- package/dist/infrastructure/services/index.d.ts +8 -0
- package/dist/infrastructure/services/index.d.ts.map +1 -0
- package/dist/infrastructure/utils/index.d.ts +7 -0
- package/dist/infrastructure/utils/index.d.ts.map +1 -0
- package/dist/infrastructure/utils/rateLimit.util.d.ts +12 -0
- package/dist/infrastructure/utils/rateLimit.util.d.ts.map +1 -0
- package/dist/infrastructure/utils/textValidator.util.d.ts +11 -0
- package/dist/infrastructure/utils/textValidator.util.d.ts.map +1 -0
- package/dist/presentation/hooks/index.d.ts +9 -0
- package/dist/presentation/hooks/index.d.ts.map +1 -0
- package/dist/presentation/hooks/index.js +11 -0
- package/dist/presentation/hooks/useBatchTranslation.hook.d.ts +20 -0
- package/dist/presentation/hooks/useBatchTranslation.hook.d.ts.map +1 -0
- package/dist/presentation/hooks/useBatchTranslation.hook.js +105 -0
- package/dist/presentation/hooks/useTranslation.hook.d.ts +16 -0
- package/dist/presentation/hooks/useTranslation.hook.d.ts.map +1 -0
- package/dist/presentation/hooks/useTranslation.hook.js +67 -0
- package/dist/presentation/index.d.ts +8 -0
- package/dist/presentation/index.d.ts.map +1 -0
- package/dist/presentation/index.js +23 -0
- package/dist/scripts/index.d.ts +9 -0
- package/dist/scripts/index.d.ts.map +1 -0
- package/dist/scripts/setup.d.ts +13 -0
- package/dist/scripts/setup.d.ts.map +1 -0
- package/dist/scripts/sync.d.ts +21 -0
- package/dist/scripts/sync.d.ts.map +1 -0
- package/dist/scripts/translate.d.ts +13 -0
- package/dist/scripts/translate.d.ts.map +1 -0
- package/dist/scripts/utils/file-parser.d.ts +8 -0
- package/dist/scripts/utils/file-parser.d.ts.map +1 -0
- package/dist/scripts/utils/index.d.ts +10 -0
- package/dist/scripts/utils/index.d.ts.map +1 -0
- package/dist/scripts/utils/key-detector.d.ts +11 -0
- package/dist/scripts/utils/key-detector.d.ts.map +1 -0
- package/dist/scripts/utils/key-extractor.d.ts +2 -0
- package/dist/scripts/utils/key-extractor.d.ts.map +1 -0
- package/dist/scripts/utils/object-helper.d.ts +14 -0
- package/dist/scripts/utils/object-helper.d.ts.map +1 -0
- package/dist/scripts/utils/sync-helper.d.ts +13 -0
- package/dist/scripts/utils/sync-helper.d.ts.map +1 -0
- package/package.json +13 -12
- 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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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.
|
|
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": "./
|
|
6
|
-
"types": "./
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
7
|
"sideEffects": false,
|
|
8
8
|
"exports": {
|
|
9
|
-
".": "./
|
|
10
|
-
"./core": "./
|
|
11
|
-
"./services": "./
|
|
12
|
-
"./constants": "./
|
|
13
|
-
"./hooks": "./
|
|
14
|
-
"./scripts": "./
|
|
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:
|
|
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 (
|
|
129
|
-
const
|
|
130
|
+
for (let i = 0; i < requests.length; i += batchSize) {
|
|
131
|
+
const batch = requests.slice(i, i + batchSize);
|
|
130
132
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
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
|
-
|
|
201
|
-
|
|
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
|
-
|
|
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 (
|
|
208
|
-
targetObject[key] =
|
|
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:
|
|
265
|
+
to: translatedKey.to,
|
|
214
266
|
});
|
|
215
|
-
} else if (!
|
|
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();
|