@umituz/react-native-google-translate 1.0.4 → 1.0.6
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.js +6 -0
- package/dist/domain/entities/Translation.entity.js +6 -0
- package/dist/domain/entities/index.js +6 -0
- package/dist/domain/index.js +24 -0
- package/dist/domain/interfaces/ITranslationService.interface.js +6 -0
- package/dist/domain/interfaces/index.js +6 -0
- package/dist/infrastructure/constants/api.constants.js +11 -0
- package/dist/infrastructure/constants/index.js +16 -0
- package/dist/infrastructure/constants/languages.constants.js +99 -0
- package/dist/infrastructure/index.js +25 -0
- package/dist/infrastructure/services/GoogleTranslate.service.js +203 -0
- package/dist/infrastructure/services/index.js +20 -0
- package/dist/infrastructure/utils/index.js +16 -0
- package/dist/infrastructure/utils/rateLimit.util.js +27 -0
- package/dist/infrastructure/utils/textValidator.util.js +58 -0
- package/dist/scripts/index.js +24 -0
- package/dist/scripts/setup.js +83 -0
- package/dist/scripts/sync.js +115 -0
- package/dist/scripts/translate.js +94 -0
- package/dist/scripts/utils/file-parser.js +98 -0
- package/dist/scripts/utils/index.js +25 -0
- package/dist/scripts/utils/key-detector.js +43 -0
- package/dist/scripts/utils/key-extractor.js +101 -0
- package/dist/scripts/utils/object-helper.js +47 -0
- package/dist/scripts/utils/sync-helper.js +51 -0
- package/package.json +8 -5
- package/src/scripts/setup.ts +4 -3
- package/src/scripts/sync.ts +2 -1
- package/src/scripts/translate.ts +2 -1
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Domain Layer
|
|
4
|
+
* @description Subpath: @umituz/react-native-google-translate/core
|
|
5
|
+
*
|
|
6
|
+
* Exports all domain entities and interfaces
|
|
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("./entities"), exports);
|
|
24
|
+
__exportStar(require("./interfaces"), exports);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* API Constants
|
|
4
|
+
* @description Google Translate API configuration
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.DEFAULT_MAX_RETRIES = exports.DEFAULT_MIN_DELAY = exports.DEFAULT_TIMEOUT = exports.GOOGLE_TRANSLATE_API_URL = void 0;
|
|
8
|
+
exports.GOOGLE_TRANSLATE_API_URL = "https://translate.googleapis.com/translate_a/single";
|
|
9
|
+
exports.DEFAULT_TIMEOUT = 10000;
|
|
10
|
+
exports.DEFAULT_MIN_DELAY = 100;
|
|
11
|
+
exports.DEFAULT_MAX_RETRIES = 3;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Infrastructure Constants
|
|
4
|
+
* @description Exports all constant definitions
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.DEFAULT_MAX_RETRIES = exports.DEFAULT_MIN_DELAY = exports.DEFAULT_TIMEOUT = exports.GOOGLE_TRANSLATE_API_URL = exports.LANGUAGE_NAMES = exports.SKIP_WORDS = exports.LANGUAGE_MAP = void 0;
|
|
8
|
+
var languages_constants_1 = require("./languages.constants");
|
|
9
|
+
Object.defineProperty(exports, "LANGUAGE_MAP", { enumerable: true, get: function () { return languages_constants_1.LANGUAGE_MAP; } });
|
|
10
|
+
Object.defineProperty(exports, "SKIP_WORDS", { enumerable: true, get: function () { return languages_constants_1.SKIP_WORDS; } });
|
|
11
|
+
Object.defineProperty(exports, "LANGUAGE_NAMES", { enumerable: true, get: function () { return languages_constants_1.LANGUAGE_NAMES; } });
|
|
12
|
+
var api_constants_1 = require("./api.constants");
|
|
13
|
+
Object.defineProperty(exports, "GOOGLE_TRANSLATE_API_URL", { enumerable: true, get: function () { return api_constants_1.GOOGLE_TRANSLATE_API_URL; } });
|
|
14
|
+
Object.defineProperty(exports, "DEFAULT_TIMEOUT", { enumerable: true, get: function () { return api_constants_1.DEFAULT_TIMEOUT; } });
|
|
15
|
+
Object.defineProperty(exports, "DEFAULT_MIN_DELAY", { enumerable: true, get: function () { return api_constants_1.DEFAULT_MIN_DELAY; } });
|
|
16
|
+
Object.defineProperty(exports, "DEFAULT_MAX_RETRIES", { enumerable: true, get: function () { return api_constants_1.DEFAULT_MAX_RETRIES; } });
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Language Constants
|
|
4
|
+
* @description Language mappings and metadata
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.LANGUAGE_NAMES = exports.SKIP_WORDS = exports.LANGUAGE_MAP = void 0;
|
|
8
|
+
exports.LANGUAGE_MAP = {
|
|
9
|
+
"ar-SA": "ar",
|
|
10
|
+
"bg-BG": "bg",
|
|
11
|
+
"cs-CZ": "cs",
|
|
12
|
+
"da-DK": "da",
|
|
13
|
+
"de-DE": "de",
|
|
14
|
+
"el-GR": "el",
|
|
15
|
+
"en-AU": "en",
|
|
16
|
+
"en-CA": "en",
|
|
17
|
+
"en-GB": "en",
|
|
18
|
+
"es-ES": "es",
|
|
19
|
+
"es-MX": "es",
|
|
20
|
+
"fi-FI": "fi",
|
|
21
|
+
"fr-CA": "fr",
|
|
22
|
+
"fr-FR": "fr",
|
|
23
|
+
"hi-IN": "hi",
|
|
24
|
+
"hr-HR": "hr",
|
|
25
|
+
"hu-HU": "hu",
|
|
26
|
+
"id-ID": "id",
|
|
27
|
+
"it-IT": "it",
|
|
28
|
+
"ja-JP": "ja",
|
|
29
|
+
"ko-KR": "ko",
|
|
30
|
+
"ms-MY": "ms",
|
|
31
|
+
"nl-NL": "nl",
|
|
32
|
+
"no-NO": "no",
|
|
33
|
+
"pl-PL": "pl",
|
|
34
|
+
"pt-BR": "pt",
|
|
35
|
+
"pt-PT": "pt",
|
|
36
|
+
"ro-RO": "ro",
|
|
37
|
+
"ru-RU": "ru",
|
|
38
|
+
"sk-SK": "sk",
|
|
39
|
+
"sl-SI": "sl",
|
|
40
|
+
"sv-SE": "sv",
|
|
41
|
+
"th-TH": "th",
|
|
42
|
+
"tl-PH": "tl",
|
|
43
|
+
"tr-TR": "tr",
|
|
44
|
+
"uk-UA": "uk",
|
|
45
|
+
"vi-VN": "vi",
|
|
46
|
+
"zh-CN": "zh-CN",
|
|
47
|
+
"zh-TW": "zh-TW",
|
|
48
|
+
};
|
|
49
|
+
exports.SKIP_WORDS = new Set([
|
|
50
|
+
"Google",
|
|
51
|
+
"Apple",
|
|
52
|
+
"Facebook",
|
|
53
|
+
"Instagram",
|
|
54
|
+
"Twitter",
|
|
55
|
+
"YouTube",
|
|
56
|
+
"WhatsApp",
|
|
57
|
+
]);
|
|
58
|
+
exports.LANGUAGE_NAMES = {
|
|
59
|
+
"ar-SA": "Arabic (Saudi Arabia)",
|
|
60
|
+
"bg-BG": "Bulgarian",
|
|
61
|
+
"cs-CZ": "Czech",
|
|
62
|
+
"da-DK": "Danish",
|
|
63
|
+
"de-DE": "German",
|
|
64
|
+
"el-GR": "Greek",
|
|
65
|
+
"en-AU": "English (Australia)",
|
|
66
|
+
"en-CA": "English (Canada)",
|
|
67
|
+
"en-GB": "English (UK)",
|
|
68
|
+
"en-US": "English (US)",
|
|
69
|
+
"es-ES": "Spanish (Spain)",
|
|
70
|
+
"es-MX": "Spanish (Mexico)",
|
|
71
|
+
"fi-FI": "Finnish",
|
|
72
|
+
"fr-CA": "French (Canada)",
|
|
73
|
+
"fr-FR": "French (France)",
|
|
74
|
+
"hi-IN": "Hindi",
|
|
75
|
+
"hr-HR": "Croatian",
|
|
76
|
+
"hu-HU": "Hungarian",
|
|
77
|
+
"id-ID": "Indonesian",
|
|
78
|
+
"it-IT": "Italian",
|
|
79
|
+
"ja-JP": "Japanese",
|
|
80
|
+
"ko-KR": "Korean",
|
|
81
|
+
"ms-MY": "Malay",
|
|
82
|
+
"nl-NL": "Dutch",
|
|
83
|
+
"no-NO": "Norwegian",
|
|
84
|
+
"pl-PL": "Polish",
|
|
85
|
+
"pt-BR": "Portuguese (Brazil)",
|
|
86
|
+
"pt-PT": "Portuguese (Portugal)",
|
|
87
|
+
"ro-RO": "Romanian",
|
|
88
|
+
"ru-RU": "Russian",
|
|
89
|
+
"sk-SK": "Slovak",
|
|
90
|
+
"sl-SI": "Slovenian",
|
|
91
|
+
"sv-SE": "Swedish",
|
|
92
|
+
"th-TH": "Thai",
|
|
93
|
+
"tl-PH": "Tagalog",
|
|
94
|
+
"tr-TR": "Turkish",
|
|
95
|
+
"uk-UA": "Ukrainian",
|
|
96
|
+
"vi-VN": "Vietnamese",
|
|
97
|
+
"zh-CN": "Chinese (Simplified)",
|
|
98
|
+
"zh-TW": "Chinese (Traditional)",
|
|
99
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Infrastructure Layer
|
|
4
|
+
* @description Subpath: @umituz/react-native-google-translate/infrastructure
|
|
5
|
+
*
|
|
6
|
+
* Exports all infrastructure services, utils, and constants
|
|
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("./services"), exports);
|
|
24
|
+
__exportStar(require("./utils"), exports);
|
|
25
|
+
__exportStar(require("./constants"), exports);
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Google Translate Service
|
|
4
|
+
* @description Main translation service using Google Translate API
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.googleTranslateService = void 0;
|
|
8
|
+
const rateLimit_util_1 = require("../utils/rateLimit.util");
|
|
9
|
+
const textValidator_util_1 = require("../utils/textValidator.util");
|
|
10
|
+
const constants_1 = require("../constants");
|
|
11
|
+
class GoogleTranslateService {
|
|
12
|
+
config = null;
|
|
13
|
+
rateLimiter = null;
|
|
14
|
+
initialize(config) {
|
|
15
|
+
this.config = {
|
|
16
|
+
minDelay: constants_1.DEFAULT_MIN_DELAY,
|
|
17
|
+
maxRetries: constants_1.DEFAULT_MAX_RETRIES,
|
|
18
|
+
timeout: constants_1.DEFAULT_TIMEOUT,
|
|
19
|
+
...config,
|
|
20
|
+
};
|
|
21
|
+
this.rateLimiter = new rateLimit_util_1.RateLimiter(this.config.minDelay);
|
|
22
|
+
}
|
|
23
|
+
isInitialized() {
|
|
24
|
+
return this.config !== null && this.rateLimiter !== null;
|
|
25
|
+
}
|
|
26
|
+
ensureInitialized() {
|
|
27
|
+
if (!this.isInitialized()) {
|
|
28
|
+
throw new Error("GoogleTranslateService is not initialized. Call initialize() first.");
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async translate(request) {
|
|
32
|
+
this.ensureInitialized();
|
|
33
|
+
const { text, targetLanguage, sourceLanguage = "en" } = request;
|
|
34
|
+
if (!(0, textValidator_util_1.isValidText)(text) || (0, textValidator_util_1.shouldSkipWord)(text)) {
|
|
35
|
+
return {
|
|
36
|
+
originalText: text,
|
|
37
|
+
translatedText: text,
|
|
38
|
+
sourceLanguage,
|
|
39
|
+
targetLanguage,
|
|
40
|
+
success: true,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
if (!targetLanguage || targetLanguage.trim().length === 0) {
|
|
44
|
+
return {
|
|
45
|
+
originalText: text,
|
|
46
|
+
translatedText: text,
|
|
47
|
+
sourceLanguage,
|
|
48
|
+
targetLanguage,
|
|
49
|
+
success: false,
|
|
50
|
+
error: "Invalid target language",
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// After ensureInitialized(), rateLimiter is guaranteed to be non-null
|
|
54
|
+
await this.rateLimiter.waitForSlot();
|
|
55
|
+
try {
|
|
56
|
+
const translatedText = await this.callTranslateAPI(text, targetLanguage, sourceLanguage);
|
|
57
|
+
return {
|
|
58
|
+
originalText: text,
|
|
59
|
+
translatedText,
|
|
60
|
+
sourceLanguage,
|
|
61
|
+
targetLanguage,
|
|
62
|
+
success: true,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
return {
|
|
67
|
+
originalText: text,
|
|
68
|
+
translatedText: text,
|
|
69
|
+
sourceLanguage,
|
|
70
|
+
targetLanguage,
|
|
71
|
+
success: false,
|
|
72
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async translateBatch(requests) {
|
|
77
|
+
this.ensureInitialized();
|
|
78
|
+
if (!Array.isArray(requests) || requests.length === 0) {
|
|
79
|
+
return {
|
|
80
|
+
totalCount: 0,
|
|
81
|
+
successCount: 0,
|
|
82
|
+
failureCount: 0,
|
|
83
|
+
skippedCount: 0,
|
|
84
|
+
translatedKeys: [],
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const stats = {
|
|
88
|
+
totalCount: requests.length,
|
|
89
|
+
successCount: 0,
|
|
90
|
+
failureCount: 0,
|
|
91
|
+
skippedCount: 0,
|
|
92
|
+
translatedKeys: [],
|
|
93
|
+
};
|
|
94
|
+
for (const request of requests) {
|
|
95
|
+
const result = await this.translate(request);
|
|
96
|
+
if (result.success) {
|
|
97
|
+
if (result.translatedText === result.originalText) {
|
|
98
|
+
stats.skippedCount++;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
stats.successCount++;
|
|
102
|
+
stats.translatedKeys.push({
|
|
103
|
+
key: request.text,
|
|
104
|
+
from: result.originalText,
|
|
105
|
+
to: result.translatedText,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
stats.failureCount++;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return stats;
|
|
114
|
+
}
|
|
115
|
+
async translateObject(sourceObject, targetObject, targetLanguage, path = "", stats = {
|
|
116
|
+
totalCount: 0,
|
|
117
|
+
successCount: 0,
|
|
118
|
+
failureCount: 0,
|
|
119
|
+
skippedCount: 0,
|
|
120
|
+
translatedKeys: [],
|
|
121
|
+
}) {
|
|
122
|
+
if (!sourceObject || typeof sourceObject !== "object") {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (!targetObject || typeof targetObject !== "object") {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (!targetLanguage || targetLanguage.trim().length === 0) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const keys = Object.keys(sourceObject);
|
|
132
|
+
for (const key of keys) {
|
|
133
|
+
const enValue = sourceObject[key];
|
|
134
|
+
const targetValue = targetObject[key];
|
|
135
|
+
const currentPath = path ? `${path}.${key}` : key;
|
|
136
|
+
if (typeof enValue === "object" && enValue !== null) {
|
|
137
|
+
if (!targetObject[key] ||
|
|
138
|
+
typeof targetObject[key] !== "object") {
|
|
139
|
+
targetObject[key] = {};
|
|
140
|
+
}
|
|
141
|
+
await this.translateObject(enValue, targetObject[key], targetLanguage, currentPath, stats);
|
|
142
|
+
}
|
|
143
|
+
else if (typeof enValue === "string") {
|
|
144
|
+
stats.totalCount++;
|
|
145
|
+
if ((0, textValidator_util_1.needsTranslation)(targetValue, enValue)) {
|
|
146
|
+
const request = {
|
|
147
|
+
text: enValue,
|
|
148
|
+
targetLanguage,
|
|
149
|
+
};
|
|
150
|
+
const result = await this.translate(request);
|
|
151
|
+
if (result.success && result.translatedText !== enValue) {
|
|
152
|
+
targetObject[key] = result.translatedText;
|
|
153
|
+
stats.successCount++;
|
|
154
|
+
stats.translatedKeys.push({
|
|
155
|
+
key: currentPath,
|
|
156
|
+
from: enValue,
|
|
157
|
+
to: result.translatedText,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
else if (!result.success) {
|
|
161
|
+
stats.failureCount++;
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
stats.skippedCount++;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
stats.skippedCount++;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
async callTranslateAPI(text, targetLanguage, sourceLanguage) {
|
|
174
|
+
const timeout = this.config?.timeout || constants_1.DEFAULT_TIMEOUT;
|
|
175
|
+
const encodedText = encodeURIComponent(text);
|
|
176
|
+
const url = `${constants_1.GOOGLE_TRANSLATE_API_URL}?client=gtx&sl=${sourceLanguage}&tl=${targetLanguage}&dt=t&q=${encodedText}`;
|
|
177
|
+
const controller = new AbortController();
|
|
178
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
179
|
+
try {
|
|
180
|
+
const response = await fetch(url, {
|
|
181
|
+
signal: controller.signal,
|
|
182
|
+
});
|
|
183
|
+
if (!response.ok) {
|
|
184
|
+
throw new Error(`API request failed: ${response.status}`);
|
|
185
|
+
}
|
|
186
|
+
const data = await response.json();
|
|
187
|
+
// Type guard for Google Translate API response structure
|
|
188
|
+
if (Array.isArray(data) &&
|
|
189
|
+
data.length > 0 &&
|
|
190
|
+
Array.isArray(data[0]) &&
|
|
191
|
+
data[0].length > 0 &&
|
|
192
|
+
Array.isArray(data[0][0]) &&
|
|
193
|
+
typeof data[0][0][0] === "string") {
|
|
194
|
+
return data[0][0][0];
|
|
195
|
+
}
|
|
196
|
+
return text;
|
|
197
|
+
}
|
|
198
|
+
finally {
|
|
199
|
+
clearTimeout(timeoutId);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
exports.googleTranslateService = new GoogleTranslateService();
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Infrastructure Services
|
|
4
|
+
* @description Exports all services and utilities
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.LANGUAGE_NAMES = exports.SKIP_WORDS = exports.LANGUAGE_MAP = exports.getLanguageDisplayName = exports.isEnglishVariant = exports.getTargetLanguage = exports.isValidText = exports.needsTranslation = exports.shouldSkipWord = exports.googleTranslateService = void 0;
|
|
8
|
+
var GoogleTranslate_service_1 = require("./GoogleTranslate.service");
|
|
9
|
+
Object.defineProperty(exports, "googleTranslateService", { enumerable: true, get: function () { return GoogleTranslate_service_1.googleTranslateService; } });
|
|
10
|
+
var textValidator_util_1 = require("../utils/textValidator.util");
|
|
11
|
+
Object.defineProperty(exports, "shouldSkipWord", { enumerable: true, get: function () { return textValidator_util_1.shouldSkipWord; } });
|
|
12
|
+
Object.defineProperty(exports, "needsTranslation", { enumerable: true, get: function () { return textValidator_util_1.needsTranslation; } });
|
|
13
|
+
Object.defineProperty(exports, "isValidText", { enumerable: true, get: function () { return textValidator_util_1.isValidText; } });
|
|
14
|
+
Object.defineProperty(exports, "getTargetLanguage", { enumerable: true, get: function () { return textValidator_util_1.getTargetLanguage; } });
|
|
15
|
+
Object.defineProperty(exports, "isEnglishVariant", { enumerable: true, get: function () { return textValidator_util_1.isEnglishVariant; } });
|
|
16
|
+
Object.defineProperty(exports, "getLanguageDisplayName", { enumerable: true, get: function () { return textValidator_util_1.getLanguageDisplayName; } });
|
|
17
|
+
var languages_constants_1 = require("../constants/languages.constants");
|
|
18
|
+
Object.defineProperty(exports, "LANGUAGE_MAP", { enumerable: true, get: function () { return languages_constants_1.LANGUAGE_MAP; } });
|
|
19
|
+
Object.defineProperty(exports, "SKIP_WORDS", { enumerable: true, get: function () { return languages_constants_1.SKIP_WORDS; } });
|
|
20
|
+
Object.defineProperty(exports, "LANGUAGE_NAMES", { enumerable: true, get: function () { return languages_constants_1.LANGUAGE_NAMES; } });
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Infrastructure Utils
|
|
4
|
+
* @description Exports all utility functions
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.getLanguageDisplayName = exports.isEnglishVariant = exports.getTargetLanguage = exports.isValidText = exports.needsTranslation = exports.shouldSkipWord = exports.RateLimiter = void 0;
|
|
8
|
+
var rateLimit_util_1 = require("./rateLimit.util");
|
|
9
|
+
Object.defineProperty(exports, "RateLimiter", { enumerable: true, get: function () { return rateLimit_util_1.RateLimiter; } });
|
|
10
|
+
var textValidator_util_1 = require("./textValidator.util");
|
|
11
|
+
Object.defineProperty(exports, "shouldSkipWord", { enumerable: true, get: function () { return textValidator_util_1.shouldSkipWord; } });
|
|
12
|
+
Object.defineProperty(exports, "needsTranslation", { enumerable: true, get: function () { return textValidator_util_1.needsTranslation; } });
|
|
13
|
+
Object.defineProperty(exports, "isValidText", { enumerable: true, get: function () { return textValidator_util_1.isValidText; } });
|
|
14
|
+
Object.defineProperty(exports, "getTargetLanguage", { enumerable: true, get: function () { return textValidator_util_1.getTargetLanguage; } });
|
|
15
|
+
Object.defineProperty(exports, "isEnglishVariant", { enumerable: true, get: function () { return textValidator_util_1.isEnglishVariant; } });
|
|
16
|
+
Object.defineProperty(exports, "getLanguageDisplayName", { enumerable: true, get: function () { return textValidator_util_1.getLanguageDisplayName; } });
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Rate Limit Utility
|
|
4
|
+
* @description Handles rate limiting for API requests
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.RateLimiter = void 0;
|
|
8
|
+
class RateLimiter {
|
|
9
|
+
lastCallTime = 0;
|
|
10
|
+
minDelay;
|
|
11
|
+
constructor(minDelay = 100) {
|
|
12
|
+
this.minDelay = minDelay;
|
|
13
|
+
}
|
|
14
|
+
async waitForSlot() {
|
|
15
|
+
const now = Date.now();
|
|
16
|
+
const elapsed = now - this.lastCallTime;
|
|
17
|
+
const waitTime = Math.max(0, this.minDelay - elapsed);
|
|
18
|
+
if (waitTime > 0) {
|
|
19
|
+
await new Promise((resolve) => setTimeout(resolve, waitTime));
|
|
20
|
+
}
|
|
21
|
+
this.lastCallTime = Date.now();
|
|
22
|
+
}
|
|
23
|
+
reset() {
|
|
24
|
+
this.lastCallTime = 0;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.RateLimiter = RateLimiter;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Text Validator Utility
|
|
4
|
+
* @description Validates text for translation eligibility
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.shouldSkipWord = shouldSkipWord;
|
|
8
|
+
exports.needsTranslation = needsTranslation;
|
|
9
|
+
exports.isValidText = isValidText;
|
|
10
|
+
exports.getTargetLanguage = getTargetLanguage;
|
|
11
|
+
exports.isEnglishVariant = isEnglishVariant;
|
|
12
|
+
exports.getLanguageDisplayName = getLanguageDisplayName;
|
|
13
|
+
const constants_1 = require("../constants");
|
|
14
|
+
function shouldSkipWord(word) {
|
|
15
|
+
return constants_1.SKIP_WORDS.has(word);
|
|
16
|
+
}
|
|
17
|
+
function needsTranslation(value, enValue) {
|
|
18
|
+
if (typeof enValue !== "string" || !enValue.trim()) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
if (shouldSkipWord(enValue)) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
// Skip technical keys (e.g., "scenario.xxx.title")
|
|
25
|
+
const isTechnicalKey = enValue.includes(".") && !enValue.includes(" ");
|
|
26
|
+
if (isTechnicalKey) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
// If value is missing or same as English, it needs translation
|
|
30
|
+
if (!value || typeof value !== "string") {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
if (value === enValue) {
|
|
34
|
+
const isSingleWord = !enValue.includes(" ") && enValue.length < 20;
|
|
35
|
+
return !isSingleWord;
|
|
36
|
+
}
|
|
37
|
+
// Detect outdated template patterns (e.g., {{appName}}, {{variable}})
|
|
38
|
+
if (typeof value === "string") {
|
|
39
|
+
const hasTemplatePattern = value.includes("{{") && value.includes("}}");
|
|
40
|
+
if (hasTemplatePattern && !enValue.includes("{{")) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
function isValidText(text) {
|
|
47
|
+
return typeof text === "string" && text.length > 0;
|
|
48
|
+
}
|
|
49
|
+
function getTargetLanguage(langCode) {
|
|
50
|
+
return constants_1.LANGUAGE_MAP[langCode];
|
|
51
|
+
}
|
|
52
|
+
function isEnglishVariant(langCode) {
|
|
53
|
+
const targetLang = getTargetLanguage(langCode);
|
|
54
|
+
return targetLang === "en";
|
|
55
|
+
}
|
|
56
|
+
function getLanguageDisplayName(code) {
|
|
57
|
+
return constants_1.LANGUAGE_NAMES[code] || code;
|
|
58
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Translation Scripts
|
|
4
|
+
* Scripts for translating and synchronizing localization files
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
18
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
__exportStar(require("./translate"), exports);
|
|
22
|
+
__exportStar(require("./sync"), exports);
|
|
23
|
+
__exportStar(require("./setup"), exports);
|
|
24
|
+
__exportStar(require("./utils"), exports);
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Setup Languages Script
|
|
5
|
+
* Creates stub files for all supported languages (if not exist),
|
|
6
|
+
* then generates index.ts from all available translation files.
|
|
7
|
+
* Usage: node setup.ts [locales-dir]
|
|
8
|
+
*/
|
|
9
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.setupLanguages = setupLanguages;
|
|
14
|
+
exports.runSetupLanguages = runSetupLanguages;
|
|
15
|
+
const fs_1 = __importDefault(require("fs"));
|
|
16
|
+
const path_1 = __importDefault(require("path"));
|
|
17
|
+
const services_1 = require("../infrastructure/services");
|
|
18
|
+
function setupLanguages(options) {
|
|
19
|
+
const { targetDir } = options;
|
|
20
|
+
const localesDir = path_1.default.resolve(process.cwd(), targetDir);
|
|
21
|
+
if (!fs_1.default.existsSync(localesDir)) {
|
|
22
|
+
console.error(`❌ Locales directory not found: ${localesDir}`);
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
// Create stub files for all supported languages that don't exist yet
|
|
26
|
+
let created = 0;
|
|
27
|
+
for (const langCode of Object.keys(services_1.LANGUAGE_MAP)) {
|
|
28
|
+
// Skip English variants — en-US is the base, others (en-AU, en-GB) are redundant
|
|
29
|
+
if (langCode.startsWith('en-') && langCode !== 'en-US')
|
|
30
|
+
continue;
|
|
31
|
+
const filePath = path_1.default.join(localesDir, `${langCode}.ts`);
|
|
32
|
+
if (!fs_1.default.existsSync(filePath)) {
|
|
33
|
+
const langName = (0, services_1.getLanguageDisplayName)(langCode);
|
|
34
|
+
fs_1.default.writeFileSync(filePath, `/**\n * ${langName} Translations\n * Auto-synced from en-US.ts\n */\n\nexport default {};\n`);
|
|
35
|
+
console.log(` ✅ Created ${langCode}.ts (${langName})`);
|
|
36
|
+
created++;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (created > 0) {
|
|
40
|
+
console.log(`\n📦 Created ${created} new language stubs.\n`);
|
|
41
|
+
}
|
|
42
|
+
// Generate index.ts from all language files
|
|
43
|
+
const files = fs_1.default.readdirSync(localesDir)
|
|
44
|
+
.filter(f => f.match(/^[a-z]{2}-[A-Z]{2}\.ts$/))
|
|
45
|
+
.sort();
|
|
46
|
+
const imports = [];
|
|
47
|
+
const exports = [];
|
|
48
|
+
files.forEach(file => {
|
|
49
|
+
const code = file.replace('.ts', '');
|
|
50
|
+
const varName = code.replace(/-([a-z0-9])/g, (g) => g[1].toUpperCase()).replace('-', '');
|
|
51
|
+
imports.push(`import ${varName} from "./${code}";`);
|
|
52
|
+
exports.push(` "${code}": ${varName},`);
|
|
53
|
+
});
|
|
54
|
+
const content = `/**
|
|
55
|
+
* Localization Index
|
|
56
|
+
* Exports all available translation files
|
|
57
|
+
* Auto-generated by scripts/setup.ts
|
|
58
|
+
*/
|
|
59
|
+
|
|
60
|
+
${imports.join('\n')}
|
|
61
|
+
|
|
62
|
+
export const translations = {
|
|
63
|
+
${exports.join('\n')}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export type TranslationKey = keyof typeof translations;
|
|
67
|
+
|
|
68
|
+
export default translations;
|
|
69
|
+
`;
|
|
70
|
+
fs_1.default.writeFileSync(path_1.default.join(localesDir, 'index.ts'), content);
|
|
71
|
+
console.log(`✅ Generated index.ts with ${files.length} languages`);
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
// CLI interface
|
|
75
|
+
function runSetupLanguages() {
|
|
76
|
+
const targetDir = process.argv[2] || 'src/infrastructure/locales';
|
|
77
|
+
console.log('🚀 Setting up language files...\n');
|
|
78
|
+
setupLanguages({ targetDir });
|
|
79
|
+
}
|
|
80
|
+
// Check if this file is being run directly
|
|
81
|
+
if (require.main === module || process.argv[1].endsWith('/setup.js') || process.argv[1].endsWith('\\setup.js')) {
|
|
82
|
+
runSetupLanguages();
|
|
83
|
+
}
|