generaltranslation 9.4.2 → 9.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/README.md +2 -1
- package/dist/{ApiError-BcjcnTAr.cjs → ApiError-BCjEo_CM.cjs} +1 -1
- package/dist/{ApiError-BcjcnTAr.cjs.map → ApiError-BCjEo_CM.cjs.map} +1 -1
- package/dist/{ApiError-CUKcz3YS.mjs → ApiError-DxWKM0Xt.mjs} +1 -1
- package/dist/{ApiError-CUKcz3YS.mjs.map → ApiError-DxWKM0Xt.mjs.map} +1 -1
- package/dist/adapter/createGtApi.d.ts +196 -27
- package/dist/adapter/createGtApi.js +561 -117
- package/dist/adapter/modelProvider.d.ts +4 -0
- package/dist/adapter/modelProvider.js +6 -0
- package/dist/derive-Cv5_y8Tf.mjs +656 -0
- package/dist/derive-Cv5_y8Tf.mjs.map +1 -0
- package/dist/{derive-DBCCXTmL.d.cts → derive-J2NQLqZm.d.cts} +1 -1
- package/dist/derive-t_E3ftJN.cjs +733 -0
- package/dist/derive-t_E3ftJN.cjs.map +1 -0
- package/dist/diagnostics-CqAHg_Vc.d.cts +34 -0
- package/dist/diagnostics-DKA2SkZB.mjs +45 -0
- package/dist/diagnostics-DKA2SkZB.mjs.map +1 -0
- package/dist/{unwrapApiResult-BzGfPw75.mjs → diagnostics-DKtiPUvo.cjs} +12 -31
- package/dist/diagnostics-DKtiPUvo.cjs.map +1 -0
- package/dist/diagnostics-DYtVjOm5.d.mts +34 -0
- package/dist/diagnostics.cjs +4 -0
- package/dist/diagnostics.d.cts +2 -0
- package/dist/diagnostics.d.mts +2 -0
- package/dist/diagnostics.d.ts +1 -0
- package/dist/diagnostics.js +1 -0
- package/dist/diagnostics.mjs +2 -0
- package/dist/errors.cjs +1 -1
- package/dist/errors.mjs +1 -1
- package/dist/file-B37WkCqM.cjs.map +1 -1
- package/dist/file-Dga6cyM8.mjs.map +1 -1
- package/dist/{id-X2zyx5Jk.mjs → id-B2wA7-S-.mjs} +19 -3
- package/dist/id-B2wA7-S-.mjs.map +1 -0
- package/dist/{id-pdr3R1xs.cjs → id-DJ_59q21.cjs} +25 -3
- package/dist/id-DJ_59q21.cjs.map +1 -0
- package/dist/id.cjs +1 -1
- package/dist/id.d.cts +1 -1
- package/dist/id.d.mts +1 -1
- package/dist/id.mjs +1 -1
- package/dist/index.cjs +94 -753
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -33
- package/dist/index.d.mts +13 -32
- package/dist/index.d.ts +20 -16
- package/dist/index.js +110 -98
- package/dist/index.mjs +88 -746
- package/dist/index.mjs.map +1 -1
- package/dist/internal.cjs +16 -186
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +200 -62
- package/dist/internal.d.mts +199 -61
- package/dist/internal.d.ts +3 -1
- package/dist/internal.js +2 -1
- package/dist/internal.mjs +6 -178
- package/dist/internal.mjs.map +1 -1
- package/dist/logging/errors.d.ts +0 -1
- package/dist/logging/errors.js +0 -6
- package/dist/logging/logger.js +6 -4
- package/dist/openapi.json +2344 -845
- package/dist/runtime.cjs +580 -2
- package/dist/runtime.cjs.map +1 -0
- package/dist/runtime.d.cts +12 -6
- package/dist/runtime.d.mts +12 -6
- package/dist/runtime.d.ts +10 -4
- package/dist/runtime.js +10 -65
- package/dist/runtime.mjs +579 -1
- package/dist/runtime.mjs.map +1 -0
- package/dist/runtimeTranslate-CVw143pQ.mjs +506 -0
- package/dist/runtimeTranslate-CVw143pQ.mjs.map +1 -0
- package/dist/runtimeTranslate-DJioRjb6.cjs +601 -0
- package/dist/runtimeTranslate-DJioRjb6.cjs.map +1 -0
- package/dist/translate/awaitJobs.d.ts +2 -2
- package/dist/translate/awaitJobs.js +1 -156
- package/dist/translate/checkJobStatus.d.ts +2 -1
- package/dist/translate/checkJobStatus.js +1 -55
- package/dist/translate/createBranch.d.ts +2 -6
- package/dist/translate/createBranch.js +1 -53
- package/dist/translate/enqueueFiles.js +1 -95
- package/dist/translate/getProjectInfo.d.ts +2 -6
- package/dist/translate/getProjectInfo.js +1 -54
- package/dist/translate/processFileMoves.d.ts +3 -13
- package/dist/translate/processFileMoves.js +1 -90
- package/dist/translate/publishFiles.d.ts +3 -15
- package/dist/translate/publishFiles.js +1 -56
- package/dist/translate/queryBranchData.js +1 -53
- package/dist/translate/queryFileData.d.ts +3 -41
- package/dist/translate/queryFileData.js +1 -71
- package/dist/translate/runtimeTranslate.d.ts +6 -0
- package/dist/translate/runtimeTranslate.js +297 -0
- package/dist/translate/setupProject.d.ts +2 -6
- package/dist/translate/setupProject.js +1 -63
- package/dist/translate/submitUserEditDiffs.js +1 -68
- package/dist/translate/utils/fetchWithTimeout.js +19 -12
- package/dist/{types-bCr8pV1Z.d.cts → types-Si4UstLL.d.mts} +41 -165
- package/dist/types-dir/__tests__/runtimeTranslate.type-test.js +18 -0
- package/dist/types-dir/api/branch.d.ts +3 -9
- package/dist/types-dir/api/checkFileTranslations.d.ts +2 -22
- package/dist/types-dir/api/downloadFileBatch.d.ts +2 -7
- package/dist/types-dir/api/entry.d.ts +3 -8
- package/dist/types-dir/api/file.d.ts +2 -1
- package/dist/types-dir/api/json.d.ts +1 -4
- package/dist/types-dir/api/project.d.ts +2 -7
- package/dist/types-dir/api/uploadAssets.d.ts +3 -10
- package/dist/types-dir/api/uploadAssets.js +0 -4
- package/dist/types-dir/config.d.ts +1 -0
- package/dist/{types-Dp1drjxq.d.mts → types-yByDbKnV.d.cts} +41 -165
- package/dist/types.d.cts +2 -2
- package/dist/types.d.mts +2 -2
- package/dist/types.d.ts +26 -7
- package/package.json +15 -2
- package/dist/derive-2CDqwrvS.cjs +0 -303
- package/dist/derive-2CDqwrvS.cjs.map +0 -1
- package/dist/derive-CTzR56T_.mjs +0 -233
- package/dist/derive-CTzR56T_.mjs.map +0 -1
- package/dist/id-X2zyx5Jk.mjs.map +0 -1
- package/dist/id-pdr3R1xs.cjs.map +0 -1
- package/dist/isVariable-8-Wy5FnX.mjs +0 -20
- package/dist/isVariable-8-Wy5FnX.mjs.map +0 -1
- package/dist/isVariable-I3nllgeI.cjs +0 -25
- package/dist/isVariable-I3nllgeI.cjs.map +0 -1
- package/dist/projects/getProjectData.js +0 -87
- package/dist/runtime-Bcp4F2ME.mjs +0 -974
- package/dist/runtime-Bcp4F2ME.mjs.map +0 -1
- package/dist/runtime-C25lwh9m.cjs +0 -1027
- package/dist/runtime-C25lwh9m.cjs.map +0 -1
- package/dist/translate/api.d.ts +0 -4
- package/dist/translate/api.js +0 -4
- package/dist/translate/createTag.d.ts +0 -19
- package/dist/translate/createTag.js +0 -67
- package/dist/translate/downloadFileBatch.d.ts +0 -1
- package/dist/translate/downloadFileBatch.js +0 -80
- package/dist/translate/getOrphanedFiles.d.ts +0 -8
- package/dist/translate/getOrphanedFiles.js +0 -97
- package/dist/translate/querySourceFile.d.ts +0 -1
- package/dist/translate/querySourceFile.js +0 -67
- package/dist/translate/translateMany.d.ts +0 -1
- package/dist/translate/translateMany.js +0 -124
- package/dist/translate/uploadFonts.d.ts +0 -1
- package/dist/translate/uploadFonts.js +0 -74
- package/dist/translate/uploadSourceFiles.d.ts +0 -1
- package/dist/translate/uploadSourceFiles.js +0 -90
- package/dist/translate/uploadTranslations.d.ts +0 -1
- package/dist/translate/uploadTranslations.js +0 -106
- package/dist/translate/utils/apiRequest.d.ts +0 -1
- package/dist/translate/utils/apiRequest.js +0 -167
- package/dist/translate/utils/generateRequestHeaders.d.ts +0 -2
- package/dist/translate/utils/generateRequestHeaders.js +0 -21
- package/dist/translate/utils/handleFetchError.d.ts +0 -1
- package/dist/translate/utils/handleFetchError.js +0 -12
- package/dist/unwrapApiResult-BzGfPw75.mjs.map +0 -1
- package/dist/unwrapApiResult-Dv6Mfw_K.cjs +0 -134
- package/dist/unwrapApiResult-Dv6Mfw_K.cjs.map +0 -1
- /package/dist/{projects/getProjectData.d.ts → types-dir/__tests__/runtimeTranslate.type-test.d.ts} +0 -0
package/dist/index.mjs
CHANGED
|
@@ -1,686 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { n as isBinaryFileFormat } from "./file-Dga6cyM8.mjs";
|
|
1
|
+
import { c as gtInstanceLogger, d as noSourceLocaleProvidedError, f as noTargetLocaleProvidedError, r as validateAuth } from "./runtimeTranslate-CVw143pQ.mjs";
|
|
2
|
+
import { c as createGtApiAdapter, n as declareVar, r as decodeVars, t as derive } from "./derive-Cv5_y8Tf.mjs";
|
|
3
|
+
import { GTRuntime } from "./runtime.mjs";
|
|
5
4
|
import { LocaleConfig, determineLocale, formatCurrency, formatCutoff, formatDateTime, formatList, formatListToParts, formatMessage, formatNum, formatRelativeTime, formatRelativeTimeFromDate, getLocaleDirection, getLocaleEmoji, getLocaleName, getLocaleProperties, getRegionProperties, isSameDialect, isSameLanguage, isSupersetLocale, isValidLocale, requiresTranslation, resolveAliasLocale, resolveCanonicalLocale, standardizeLocale } from "@generaltranslation/format";
|
|
6
|
-
//#region src/translate/utils/handleFetchError.ts
|
|
7
|
-
function handleFetchError(error, timeout) {
|
|
8
|
-
if (error instanceof Error && error.name === "AbortError") {
|
|
9
|
-
const errorMessage = translationTimeoutError(timeout);
|
|
10
|
-
fetchLogger.error(errorMessage);
|
|
11
|
-
throw new Error(errorMessage);
|
|
12
|
-
}
|
|
13
|
-
const errorMessage = translationRequestFailedError(error instanceof Error ? error.message : String(error));
|
|
14
|
-
fetchLogger.error(errorMessage);
|
|
15
|
-
throw error;
|
|
16
|
-
}
|
|
17
|
-
//#endregion
|
|
18
|
-
//#region src/translate/utils/generateRequestHeaders.ts
|
|
19
|
-
function generateRequestHeaders(config, excludeContentType = false) {
|
|
20
|
-
const authHeaders = {
|
|
21
|
-
...!excludeContentType && { "Content-Type": "application/json" },
|
|
22
|
-
"gt-project-id": config.projectId
|
|
23
|
-
};
|
|
24
|
-
if (config.apiKey) authHeaders["Authorization"] = `Bearer ${config.apiKey}`;
|
|
25
|
-
authHeaders["gt-api-version"] = API_VERSION;
|
|
26
|
-
return authHeaders;
|
|
27
|
-
}
|
|
28
|
-
//#endregion
|
|
29
|
-
//#region src/translate/utils/apiRequest.ts
|
|
30
|
-
const MAX_RETRIES = 3;
|
|
31
|
-
const INITIAL_DELAY_MS = 500;
|
|
32
|
-
const RATE_LIMIT_RETRY_DELAY_MS = 6e4;
|
|
33
|
-
const MS_PER_SECOND = 1e3;
|
|
34
|
-
function sleep(ms) {
|
|
35
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
36
|
-
}
|
|
37
|
-
function getRetryDelay(policy, attempt) {
|
|
38
|
-
switch (policy) {
|
|
39
|
-
case "linear": return INITIAL_DELAY_MS * (attempt + 1);
|
|
40
|
-
case "exponential": return INITIAL_DELAY_MS * 2 ** attempt;
|
|
41
|
-
default: return 0;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
function parseDelayMs(value) {
|
|
45
|
-
if (!value) return;
|
|
46
|
-
const seconds = Number(value.split(",")[0].split(";")[0].trim());
|
|
47
|
-
if (!Number.isFinite(seconds) || seconds < 0) return;
|
|
48
|
-
return seconds * MS_PER_SECOND;
|
|
49
|
-
}
|
|
50
|
-
function parseRetryAfter(value) {
|
|
51
|
-
const delayMs = parseDelayMs(value);
|
|
52
|
-
if (delayMs !== void 0) return delayMs;
|
|
53
|
-
if (!value) return;
|
|
54
|
-
const retryDate = Date.parse(value);
|
|
55
|
-
if (Number.isNaN(retryDate)) return;
|
|
56
|
-
return Math.max(retryDate - Date.now(), 0);
|
|
57
|
-
}
|
|
58
|
-
function getRateLimitRetryDelay(response) {
|
|
59
|
-
return parseRetryAfter(response.headers.get("Retry-After")) ?? parseDelayMs(response.headers.get("RateLimit-Reset")) ?? RATE_LIMIT_RETRY_DELAY_MS;
|
|
60
|
-
}
|
|
61
|
-
function getResponseRetryDelay(response, policy, attempt) {
|
|
62
|
-
if (response.status === 429) return getRateLimitRetryDelay(response);
|
|
63
|
-
return getRetryDelay(policy, attempt);
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* @internal
|
|
67
|
-
*
|
|
68
|
-
* Makes an API request with automatic retry for 429 and 5XX errors.
|
|
69
|
-
*
|
|
70
|
-
* Encapsulates URL construction, fetch with timeout, error handling,
|
|
71
|
-
* response validation, and JSON parsing.
|
|
72
|
-
*
|
|
73
|
-
* @param config - The configuration for the API call.
|
|
74
|
-
* @param endpoint - The API endpoint path (e.g. '/v2/project/jobs/info')
|
|
75
|
-
* @param options - Optional request options.
|
|
76
|
-
* @returns The parsed JSON response.
|
|
77
|
-
*/
|
|
78
|
-
async function apiRequest(config, endpoint, options) {
|
|
79
|
-
const timeout = options?.timeout ?? 6e4;
|
|
80
|
-
const retryPolicy = options?.retryPolicy ?? "exponential";
|
|
81
|
-
const url = `${config.baseUrl || "https://api.gtx.dev"}${endpoint}`;
|
|
82
|
-
const method = options?.method ?? "POST";
|
|
83
|
-
const maxRetries = retryPolicy === "none" ? 0 : MAX_RETRIES;
|
|
84
|
-
const requestInit = {
|
|
85
|
-
method,
|
|
86
|
-
headers: generateRequestHeaders(config)
|
|
87
|
-
};
|
|
88
|
-
if (options?.body !== void 0) requestInit.body = JSON.stringify(options.body);
|
|
89
|
-
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
90
|
-
let response;
|
|
91
|
-
try {
|
|
92
|
-
response = await fetchWithTimeout(url, requestInit, timeout);
|
|
93
|
-
} catch (error) {
|
|
94
|
-
if (attempt < maxRetries) {
|
|
95
|
-
await sleep(getRetryDelay(retryPolicy, attempt));
|
|
96
|
-
continue;
|
|
97
|
-
}
|
|
98
|
-
handleFetchError(error, timeout);
|
|
99
|
-
}
|
|
100
|
-
if ((response.status === 429 || response.status >= 500) && attempt < maxRetries) {
|
|
101
|
-
await sleep(getResponseRetryDelay(response, retryPolicy, attempt));
|
|
102
|
-
continue;
|
|
103
|
-
}
|
|
104
|
-
await validateResponse(response);
|
|
105
|
-
return await response.json();
|
|
106
|
-
}
|
|
107
|
-
throw new Error("Max retries exceeded");
|
|
108
|
-
}
|
|
109
|
-
//#endregion
|
|
110
|
-
//#region src/translate/setupProject.ts
|
|
111
|
-
/**
|
|
112
|
-
* @internal
|
|
113
|
-
* Enqueues files for project setup the General Translation API.
|
|
114
|
-
* @param files - References of files to translate (file content already uploaded)
|
|
115
|
-
* @param config - The configuration for the API call.
|
|
116
|
-
* @param timeoutMS - The timeout in milliseconds
|
|
117
|
-
* @returns The result of the API call.
|
|
118
|
-
*/
|
|
119
|
-
async function _setupProject(files, config, options) {
|
|
120
|
-
return apiRequest(config, "/v2/project/setup/generate", {
|
|
121
|
-
body: {
|
|
122
|
-
files: files.map((f) => ({
|
|
123
|
-
branchId: f.branchId,
|
|
124
|
-
fileId: f.fileId,
|
|
125
|
-
versionId: f.versionId
|
|
126
|
-
})),
|
|
127
|
-
locales: options?.locales,
|
|
128
|
-
force: options?.force
|
|
129
|
-
},
|
|
130
|
-
timeout: options?.timeoutMs
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
//#endregion
|
|
134
|
-
//#region src/translate/utils/batch.ts
|
|
135
|
-
/**
|
|
136
|
-
* Splits an array into batches of a specified size.
|
|
137
|
-
* @param items - The array to split into batches.
|
|
138
|
-
* @param batchSize - The maximum size of each batch.
|
|
139
|
-
* @returns An array of batches.
|
|
140
|
-
*/
|
|
141
|
-
function createBatches(items, batchSize) {
|
|
142
|
-
const batches = [];
|
|
143
|
-
for (let i = 0; i < items.length; i += batchSize) batches.push(items.slice(i, i + batchSize));
|
|
144
|
-
return batches;
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Processes items in batches using a provided processor function.
|
|
148
|
-
*
|
|
149
|
-
* @param items - The items to process.
|
|
150
|
-
* @param processor - Async function that processes a single batch and returns items.
|
|
151
|
-
* @param options - Optional configuration for batch processing.
|
|
152
|
-
* @returns Promise that resolves to a BatchList containing all processed items.
|
|
153
|
-
*
|
|
154
|
-
* @example
|
|
155
|
-
* ```typescript
|
|
156
|
-
* const result = await processBatches(
|
|
157
|
-
* files,
|
|
158
|
-
* async (batch) => {
|
|
159
|
-
* const response = await uploadFiles(batch);
|
|
160
|
-
* return response.uploadedFiles;
|
|
161
|
-
* },
|
|
162
|
-
* { batchSize: 100 }
|
|
163
|
-
* );
|
|
164
|
-
*
|
|
165
|
-
* console.log(result.data); // All items
|
|
166
|
-
* console.log(result.count); // Total count
|
|
167
|
-
* console.log(result.batchCount); // Number of batches processed
|
|
168
|
-
* ```
|
|
169
|
-
*/
|
|
170
|
-
async function processBatches(items, processor, options = {}) {
|
|
171
|
-
const { batchSize = 100, parallel = true } = options;
|
|
172
|
-
if (items.length === 0) return {
|
|
173
|
-
data: [],
|
|
174
|
-
count: 0,
|
|
175
|
-
batchCount: 0
|
|
176
|
-
};
|
|
177
|
-
const batches = createBatches(items, batchSize);
|
|
178
|
-
const allItems = [];
|
|
179
|
-
if (parallel) {
|
|
180
|
-
const results = await Promise.all(batches.map((batch) => processor(batch)));
|
|
181
|
-
for (const result of results) if (result) allItems.push(...result);
|
|
182
|
-
} else for (const batch of batches) {
|
|
183
|
-
const result = await processor(batch);
|
|
184
|
-
if (result) allItems.push(...result);
|
|
185
|
-
}
|
|
186
|
-
return {
|
|
187
|
-
data: allItems,
|
|
188
|
-
count: allItems.length,
|
|
189
|
-
batchCount: batches.length
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
//#endregion
|
|
193
|
-
//#region src/translate/utils/validateFileFormatTransform.ts
|
|
194
|
-
/**
|
|
195
|
-
* Returns a user-facing validation error when a requested file format transform
|
|
196
|
-
* is missing source format context or is not currently supported.
|
|
197
|
-
*/
|
|
198
|
-
function getFileFormatTransformError(file) {
|
|
199
|
-
if (!file.transformFormat) return void 0;
|
|
200
|
-
const fileLabel = file.fileName ?? file.fileId ?? "unknown file";
|
|
201
|
-
if (!file.fileFormat) return `fileFormat is required when transformFormat is provided for ${fileLabel}`;
|
|
202
|
-
if (!isSupportedFileFormatTransform(file.fileFormat, file.transformFormat)) return `Unsupported file format transform: ${file.fileFormat} -> ${file.transformFormat}`;
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* Validates file format transforms before sending upload/enqueue requests.
|
|
206
|
-
*/
|
|
207
|
-
function validateFileFormatTransforms(files) {
|
|
208
|
-
for (const file of files) {
|
|
209
|
-
const error = getFileFormatTransformError(file);
|
|
210
|
-
if (error) throw new Error(error);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
//#endregion
|
|
214
|
-
//#region src/translate/enqueueFiles.ts
|
|
215
|
-
/**
|
|
216
|
-
* @internal
|
|
217
|
-
* Enqueues files for translation in the General Translation API.
|
|
218
|
-
* @param files - References of files to translate (file content already uploaded)
|
|
219
|
-
* @param options - The options for the API call.
|
|
220
|
-
* @param config - The configuration for the API call.
|
|
221
|
-
* @returns The result of the API call.
|
|
222
|
-
*/
|
|
223
|
-
async function _enqueueFiles(files, options, config) {
|
|
224
|
-
validateFileFormatTransforms(files);
|
|
225
|
-
const result = await processBatches(files, async (batch) => {
|
|
226
|
-
const apiResult = await apiRequest(config, "/v2/project/translations/enqueue", {
|
|
227
|
-
body: {
|
|
228
|
-
files: batch.map((f) => ({
|
|
229
|
-
branchId: f.branchId,
|
|
230
|
-
fileId: f.fileId,
|
|
231
|
-
versionId: f.versionId,
|
|
232
|
-
fileName: f.fileName,
|
|
233
|
-
transformFormat: f.transformFormat
|
|
234
|
-
})),
|
|
235
|
-
targetLocales: options.targetLocales,
|
|
236
|
-
sourceLocale: options.sourceLocale,
|
|
237
|
-
modelProvider: options.modelProvider,
|
|
238
|
-
force: options.force
|
|
239
|
-
},
|
|
240
|
-
timeout: options.timeout
|
|
241
|
-
});
|
|
242
|
-
return Array.from(Object.entries(apiResult.jobData));
|
|
243
|
-
}, { batchSize: 100 });
|
|
244
|
-
return {
|
|
245
|
-
jobData: Object.fromEntries(result.data.map(([jobId, jobData]) => [jobId, jobData])),
|
|
246
|
-
locales: options.targetLocales,
|
|
247
|
-
message: `Successfully enqueued ${result.count} file translation jobs in ${result.batchCount} batch(es)`
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
//#endregion
|
|
251
|
-
//#region src/translate/createTag.ts
|
|
252
|
-
/**
|
|
253
|
-
* @internal
|
|
254
|
-
* Creates or upserts a file tag in the General Translation API.
|
|
255
|
-
* @param options - The tag creation options.
|
|
256
|
-
* @param config - The configuration for the API call.
|
|
257
|
-
* @returns The created or updated tag.
|
|
258
|
-
*/
|
|
259
|
-
async function _createTag(options, config) {
|
|
260
|
-
return await apiRequest(config, "/v2/project/tags/create", { body: {
|
|
261
|
-
tagId: options.tagId,
|
|
262
|
-
files: options.files,
|
|
263
|
-
...options.message && { message: options.message }
|
|
264
|
-
} });
|
|
265
|
-
}
|
|
266
|
-
//#endregion
|
|
267
|
-
//#region src/translate/downloadFileBatch.ts
|
|
268
|
-
/**
|
|
269
|
-
* @internal
|
|
270
|
-
* Downloads multiple translation files in batches.
|
|
271
|
-
* @param files - Array of files to download
|
|
272
|
-
* @param options - The options for the API call.
|
|
273
|
-
* @param config - The configuration for the request.
|
|
274
|
-
* @returns Promise resolving to a BatchList with all downloaded files
|
|
275
|
-
*/
|
|
276
|
-
async function _downloadFileBatch(requests, options, config) {
|
|
277
|
-
return processBatches(requests, async (batch) => {
|
|
278
|
-
return (await apiRequest(config, "/v2/project/files/download", {
|
|
279
|
-
body: batch,
|
|
280
|
-
timeout: options.timeout
|
|
281
|
-
})).files.map((file) => ({
|
|
282
|
-
...file,
|
|
283
|
-
data: isBinaryFileFormat(file.fileFormat) ? file.data : decode(file.data)
|
|
284
|
-
}));
|
|
285
|
-
}, { batchSize: 100 });
|
|
286
|
-
}
|
|
287
|
-
//#endregion
|
|
288
|
-
//#region src/translate/submitUserEditDiffs.ts
|
|
289
|
-
/**
|
|
290
|
-
* @internal
|
|
291
|
-
* Submits user edit diffs so the service can learn/persist user-intended rules.
|
|
292
|
-
*/
|
|
293
|
-
async function _submitUserEditDiffs(payload, config, options = {}) {
|
|
294
|
-
await processBatches(payload.diffs, async (batch) => {
|
|
295
|
-
await apiRequest(config, "/v2/project/files/diffs", {
|
|
296
|
-
body: { diffs: batch },
|
|
297
|
-
timeout: options.timeout
|
|
298
|
-
});
|
|
299
|
-
return [{ success: true }];
|
|
300
|
-
}, { batchSize: 100 });
|
|
301
|
-
return { success: true };
|
|
302
|
-
}
|
|
303
|
-
//#endregion
|
|
304
|
-
//#region src/translate/uploadSourceFiles.ts
|
|
305
|
-
/**
|
|
306
|
-
* @internal
|
|
307
|
-
* Uploads source files to the General Translation API in batches.
|
|
308
|
-
* @param files - The files to upload.
|
|
309
|
-
* @param options - The options for the API call.
|
|
310
|
-
* @param config - The configuration for the API call.
|
|
311
|
-
* @returns Promise resolving to a BatchList with all uploaded files
|
|
312
|
-
*/
|
|
313
|
-
async function _uploadSourceFiles(files, options, config) {
|
|
314
|
-
return processBatches(files, async (batch) => {
|
|
315
|
-
return (await apiRequest(config, "/v2/project/files/upload-files", {
|
|
316
|
-
body: {
|
|
317
|
-
data: batch.map(({ source }) => ({ source: {
|
|
318
|
-
content: isBinaryFileFormat(source.fileFormat) ? source.content : encode(source.content),
|
|
319
|
-
fileName: source.fileName,
|
|
320
|
-
fileFormat: source.fileFormat,
|
|
321
|
-
locale: source.locale,
|
|
322
|
-
dataFormat: source.dataFormat,
|
|
323
|
-
formatMetadata: source.formatMetadata,
|
|
324
|
-
fileId: source.fileId,
|
|
325
|
-
versionId: source.versionId,
|
|
326
|
-
branchId: source.branchId,
|
|
327
|
-
incomingBranchId: source.incomingBranchId,
|
|
328
|
-
checkedOutBranchId: source.checkedOutBranchId
|
|
329
|
-
} })),
|
|
330
|
-
sourceLocale: options.sourceLocale
|
|
331
|
-
},
|
|
332
|
-
timeout: options.timeout
|
|
333
|
-
})).uploadedFiles || [];
|
|
334
|
-
}, { batchSize: 100 });
|
|
335
|
-
}
|
|
336
|
-
//#endregion
|
|
337
|
-
//#region src/translate/uploadFonts.ts
|
|
338
|
-
const FONT_UPLOAD_BATCH_SIZE = 50;
|
|
339
|
-
/**
|
|
340
|
-
* @internal
|
|
341
|
-
* Uploads project fonts to the General Translation API in batches. Idempotent
|
|
342
|
-
* on the server (re-running only stores genuinely new fonts). `content` is
|
|
343
|
-
* already base64-encoded by the caller (fonts are binary).
|
|
344
|
-
*/
|
|
345
|
-
async function _uploadFonts(fonts, options, config) {
|
|
346
|
-
return processBatches(fonts, async (batch) => {
|
|
347
|
-
return (await apiRequest(config, "/v2/project/assets", {
|
|
348
|
-
body: { assets: batch.map((font) => ({
|
|
349
|
-
assetType: font.assetType,
|
|
350
|
-
content: font.content,
|
|
351
|
-
fileName: font.fileName
|
|
352
|
-
})) },
|
|
353
|
-
timeout: options.timeout
|
|
354
|
-
})).assets || [];
|
|
355
|
-
}, { batchSize: FONT_UPLOAD_BATCH_SIZE });
|
|
356
|
-
}
|
|
357
|
-
//#endregion
|
|
358
|
-
//#region src/translate/uploadTranslations.ts
|
|
359
|
-
/**
|
|
360
|
-
* @internal
|
|
361
|
-
* Uploads multiple translations to the General Translation API in batches.
|
|
362
|
-
* @param files - Translations to upload with their source
|
|
363
|
-
* @param options - The options for the API call.
|
|
364
|
-
* @param config - The configuration for the API call.
|
|
365
|
-
* @returns Promise resolving to a BatchList with all uploaded files
|
|
366
|
-
*/
|
|
367
|
-
async function _uploadTranslations(files, options, config) {
|
|
368
|
-
validateFileFormatTransforms(files.map(({ source }) => source));
|
|
369
|
-
return processBatches(files, async (batch) => {
|
|
370
|
-
return (await apiRequest(config, "/v2/project/files/upload-translations", {
|
|
371
|
-
body: {
|
|
372
|
-
data: batch.map(({ source, translations }) => ({
|
|
373
|
-
source: {
|
|
374
|
-
content: isBinaryFileFormat(source.fileFormat) ? source.content : encode(source.content),
|
|
375
|
-
fileName: source.fileName,
|
|
376
|
-
fileFormat: source.fileFormat,
|
|
377
|
-
transformFormat: source.transformFormat,
|
|
378
|
-
locale: source.locale,
|
|
379
|
-
dataFormat: source.dataFormat,
|
|
380
|
-
formatMetadata: source.formatMetadata,
|
|
381
|
-
fileId: source.fileId,
|
|
382
|
-
versionId: source.versionId,
|
|
383
|
-
branchId: source.branchId
|
|
384
|
-
},
|
|
385
|
-
translations: translations.map((t) => ({
|
|
386
|
-
content: isBinaryFileFormat(t.fileFormat) ? t.content : encode(t.content),
|
|
387
|
-
fileName: t.fileName,
|
|
388
|
-
fileFormat: t.fileFormat,
|
|
389
|
-
locale: t.locale,
|
|
390
|
-
dataFormat: t.dataFormat,
|
|
391
|
-
fileId: t.fileId,
|
|
392
|
-
versionId: t.versionId,
|
|
393
|
-
branchId: t.branchId
|
|
394
|
-
}))
|
|
395
|
-
})),
|
|
396
|
-
sourceLocale: options.sourceLocale
|
|
397
|
-
},
|
|
398
|
-
timeout: options.timeout
|
|
399
|
-
})).uploadedFiles || [];
|
|
400
|
-
}, { batchSize: 100 });
|
|
401
|
-
}
|
|
402
|
-
//#endregion
|
|
403
|
-
//#region src/translate/querySourceFile.ts
|
|
404
|
-
/**
|
|
405
|
-
* @internal
|
|
406
|
-
* Gets the source file and translation information for a given file ID and version ID.
|
|
407
|
-
* @param query - The file ID and version ID to get the source file and translation information for
|
|
408
|
-
* @param options - The options for the API call.
|
|
409
|
-
* @param config - The configuration for the request.
|
|
410
|
-
* @returns The source file and translation information for the given file ID and version ID
|
|
411
|
-
*/
|
|
412
|
-
async function _querySourceFile(query, options, config) {
|
|
413
|
-
const branchId = query.branchId;
|
|
414
|
-
const versionId = query.versionId;
|
|
415
|
-
const fileId = query.fileId;
|
|
416
|
-
const searchParams = new URLSearchParams();
|
|
417
|
-
if (branchId) searchParams.set("branchId", branchId);
|
|
418
|
-
if (versionId) searchParams.set("versionId", versionId);
|
|
419
|
-
return apiRequest(config, `/v2/project/translations/files/status/${encodeURIComponent(fileId)}?${searchParams.toString()}`, {
|
|
420
|
-
method: "GET",
|
|
421
|
-
timeout: options.timeout
|
|
422
|
-
});
|
|
423
|
-
}
|
|
424
|
-
//#endregion
|
|
425
|
-
//#region src/projects/getProjectData.ts
|
|
426
|
-
/**
|
|
427
|
-
* @internal
|
|
428
|
-
* Gets the project data for a given project ID.
|
|
429
|
-
* @param projectId - The project ID to get the project data for
|
|
430
|
-
* @param options - The options for the API call.
|
|
431
|
-
* @param config - The configuration for the request.
|
|
432
|
-
* @returns The project data for the given project ID.
|
|
433
|
-
*/
|
|
434
|
-
async function _getProjectData(projectId, options, config) {
|
|
435
|
-
const { baseUrl } = config;
|
|
436
|
-
const timeout = options.timeout ? options.timeout : defaultTimeout;
|
|
437
|
-
const url = `${baseUrl || "https://api.gtx.dev"}/v2/project/info/${encodeURIComponent(projectId)}`;
|
|
438
|
-
let response;
|
|
439
|
-
try {
|
|
440
|
-
response = await fetchWithTimeout(url, {
|
|
441
|
-
method: "GET",
|
|
442
|
-
headers: generateRequestHeaders(config)
|
|
443
|
-
}, timeout);
|
|
444
|
-
} catch (error) {
|
|
445
|
-
handleFetchError(error, timeout);
|
|
446
|
-
}
|
|
447
|
-
await validateResponse(response);
|
|
448
|
-
return await response.json();
|
|
449
|
-
}
|
|
450
|
-
//#endregion
|
|
451
|
-
//#region src/translate/checkJobStatus.ts
|
|
452
|
-
/**
|
|
453
|
-
* @internal
|
|
454
|
-
* Queries job statuses for a project.
|
|
455
|
-
* @param jobIds - Job IDs.
|
|
456
|
-
* @param config - The configuration for the API call.
|
|
457
|
-
* @param timeoutMs - The timeout in milliseconds.
|
|
458
|
-
* @returns The result of the API call.
|
|
459
|
-
*/
|
|
460
|
-
async function _checkJobStatus(jobIds, config, timeoutMs) {
|
|
461
|
-
return apiRequest(config, "/v2/project/jobs/info", {
|
|
462
|
-
body: { jobIds },
|
|
463
|
-
timeout: timeoutMs
|
|
464
|
-
});
|
|
465
|
-
}
|
|
466
|
-
//#endregion
|
|
467
|
-
//#region src/translate/awaitJobs.ts
|
|
468
|
-
/**
|
|
469
|
-
* @internal
|
|
470
|
-
* Polls job statuses until all jobs are finished or the timeout is reached.
|
|
471
|
-
* @param jobIds - Job IDs to poll.
|
|
472
|
-
* @param options - Polling configuration.
|
|
473
|
-
* @param config - API credentials and configuration.
|
|
474
|
-
* @returns The final status of all jobs.
|
|
475
|
-
*/
|
|
476
|
-
async function _awaitJobIds(jobIds, options, config) {
|
|
477
|
-
const pollingInterval = (options?.pollingIntervalSeconds ?? 5) * 1e3;
|
|
478
|
-
const timeout = options?.timeoutSeconds !== void 0 ? options.timeoutSeconds * 1e3 : 600 * 1e3;
|
|
479
|
-
if (jobIds.length === 0) return {
|
|
480
|
-
complete: true,
|
|
481
|
-
jobs: []
|
|
482
|
-
};
|
|
483
|
-
const deadline = Date.now() + timeout;
|
|
484
|
-
const finalStatuses = new Map(jobIds.map((id) => [id, {
|
|
485
|
-
jobId: id,
|
|
486
|
-
status: "unknown"
|
|
487
|
-
}]));
|
|
488
|
-
const pendingJobIds = new Set(jobIds);
|
|
489
|
-
while (pendingJobIds.size > 0) {
|
|
490
|
-
const remainingTime = deadline - Date.now();
|
|
491
|
-
if (remainingTime <= 0) break;
|
|
492
|
-
let statuses;
|
|
493
|
-
try {
|
|
494
|
-
statuses = await _checkJobStatus(Array.from(pendingJobIds), config, Math.min(remainingTime, defaultTimeout));
|
|
495
|
-
} catch (error) {
|
|
496
|
-
if (Date.now() >= deadline) break;
|
|
497
|
-
throw error;
|
|
498
|
-
}
|
|
499
|
-
if (Date.now() >= deadline) break;
|
|
500
|
-
const returnedJobIds = new Set(statuses.map(({ jobId }) => jobId));
|
|
501
|
-
for (const job of statuses) if (job.status === "completed" || job.status === "failed" || job.status === "unknown") {
|
|
502
|
-
finalStatuses.set(job.jobId, {
|
|
503
|
-
jobId: job.jobId,
|
|
504
|
-
status: job.status,
|
|
505
|
-
...job.error ? { error: job.error } : {}
|
|
506
|
-
});
|
|
507
|
-
pendingJobIds.delete(job.jobId);
|
|
508
|
-
} else finalStatuses.set(job.jobId, {
|
|
509
|
-
jobId: job.jobId,
|
|
510
|
-
status: job.status
|
|
511
|
-
});
|
|
512
|
-
for (const jobId of Array.from(pendingJobIds)) if (!returnedJobIds.has(jobId)) {
|
|
513
|
-
finalStatuses.set(jobId, {
|
|
514
|
-
jobId,
|
|
515
|
-
status: "unknown"
|
|
516
|
-
});
|
|
517
|
-
pendingJobIds.delete(jobId);
|
|
518
|
-
}
|
|
519
|
-
if (pendingJobIds.size === 0) break;
|
|
520
|
-
const remainingSleepTime = deadline - Date.now();
|
|
521
|
-
if (remainingSleepTime <= 0) break;
|
|
522
|
-
await new Promise((resolve) => setTimeout(resolve, Math.min(pollingInterval, remainingSleepTime)));
|
|
523
|
-
}
|
|
524
|
-
return {
|
|
525
|
-
complete: pendingJobIds.size === 0,
|
|
526
|
-
jobs: Array.from(finalStatuses.values())
|
|
527
|
-
};
|
|
528
|
-
}
|
|
529
|
-
//#endregion
|
|
530
|
-
//#region src/translate/queryFileData.ts
|
|
531
|
-
/**
|
|
532
|
-
* @internal
|
|
533
|
-
* Queries data about one or more source or translation files.
|
|
534
|
-
* @param data - Object mapping source or translation file information
|
|
535
|
-
* @param options - The options for the API call.
|
|
536
|
-
* @param config - The configuration for the API call.
|
|
537
|
-
* @returns The file data.
|
|
538
|
-
*/
|
|
539
|
-
async function _queryFileData(data, options = {}, config) {
|
|
540
|
-
return apiRequest(config, "/v2/project/files/info", {
|
|
541
|
-
body: {
|
|
542
|
-
sourceFiles: data.sourceFiles?.map((item) => ({
|
|
543
|
-
fileId: item.fileId,
|
|
544
|
-
versionId: item.versionId,
|
|
545
|
-
branchId: item.branchId
|
|
546
|
-
})),
|
|
547
|
-
translatedFiles: data.translatedFiles?.map((item) => ({
|
|
548
|
-
fileId: item.fileId,
|
|
549
|
-
versionId: item.versionId,
|
|
550
|
-
branchId: item.branchId,
|
|
551
|
-
locale: item.locale
|
|
552
|
-
}))
|
|
553
|
-
},
|
|
554
|
-
timeout: options.timeout
|
|
555
|
-
});
|
|
556
|
-
}
|
|
557
|
-
//#endregion
|
|
558
|
-
//#region src/translate/getProjectInfo.ts
|
|
559
|
-
/**
|
|
560
|
-
* @internal
|
|
561
|
-
* Fetches project info (name, locales, review settings) for a project.
|
|
562
|
-
* @param options - The options for the API call.
|
|
563
|
-
* @param config - The configuration for the API call.
|
|
564
|
-
* @returns The project info.
|
|
565
|
-
*/
|
|
566
|
-
async function _getProjectInfo(options, config) {
|
|
567
|
-
return apiRequest(config, `/v2/project/info/${config.projectId}`, {
|
|
568
|
-
method: "GET",
|
|
569
|
-
timeout: options.timeout
|
|
570
|
-
});
|
|
571
|
-
}
|
|
572
|
-
//#endregion
|
|
573
|
-
//#region src/translate/queryBranchData.ts
|
|
574
|
-
/**
|
|
575
|
-
* @internal
|
|
576
|
-
* Queries branch information from the API.
|
|
577
|
-
* @param query - Object mapping the current branch and incoming branches
|
|
578
|
-
* @param config - The configuration for the API call.
|
|
579
|
-
* @returns The branch information.
|
|
580
|
-
*/
|
|
581
|
-
async function _queryBranchData(query, config) {
|
|
582
|
-
return apiRequest(config, "/v2/project/branches/info", { body: query });
|
|
583
|
-
}
|
|
584
|
-
//#endregion
|
|
585
|
-
//#region src/translate/createBranch.ts
|
|
586
|
-
/**
|
|
587
|
-
* @internal
|
|
588
|
-
* Creates a new branch in the API.
|
|
589
|
-
* @param query - Object mapping the branch name and default branch flag
|
|
590
|
-
* @param config - The configuration for the API call.
|
|
591
|
-
* @returns The created branch information.
|
|
592
|
-
*/
|
|
593
|
-
async function _createBranch(query, config) {
|
|
594
|
-
return apiRequest(config, "/v2/project/branches/create", { body: query });
|
|
595
|
-
}
|
|
596
|
-
//#endregion
|
|
597
|
-
//#region src/translate/processFileMoves.ts
|
|
598
|
-
/**
|
|
599
|
-
* @internal
|
|
600
|
-
* Processes file moves by cloning source files and translations with new fileIds.
|
|
601
|
-
* Called when the CLI detects that files have been moved/renamed.
|
|
602
|
-
* @param moves - Array of move mappings (old fileId to new fileId)
|
|
603
|
-
* @param options - Options including branchId and timeout
|
|
604
|
-
* @param config - The configuration for the API call.
|
|
605
|
-
* @returns Promise resolving to the move results
|
|
606
|
-
*/
|
|
607
|
-
async function _processFileMoves(moves, options, config) {
|
|
608
|
-
if (moves.length === 0) return {
|
|
609
|
-
results: [],
|
|
610
|
-
summary: {
|
|
611
|
-
total: 0,
|
|
612
|
-
succeeded: 0,
|
|
613
|
-
failed: 0
|
|
614
|
-
}
|
|
615
|
-
};
|
|
616
|
-
const batchResult = await processBatches(moves, async (batch) => {
|
|
617
|
-
return (await apiRequest(config, "/v2/project/files/moves", {
|
|
618
|
-
body: {
|
|
619
|
-
branchId: options.branchId,
|
|
620
|
-
moves: batch
|
|
621
|
-
},
|
|
622
|
-
timeout: options.timeout
|
|
623
|
-
})).results;
|
|
624
|
-
}, { batchSize: 100 });
|
|
625
|
-
const succeeded = batchResult.data.filter((r) => r.success).length;
|
|
626
|
-
const failed = batchResult.data.filter((r) => !r.success).length;
|
|
627
|
-
return {
|
|
628
|
-
results: batchResult.data,
|
|
629
|
-
summary: {
|
|
630
|
-
total: moves.length,
|
|
631
|
-
succeeded,
|
|
632
|
-
failed
|
|
633
|
-
}
|
|
634
|
-
};
|
|
635
|
-
}
|
|
636
|
-
//#endregion
|
|
637
|
-
//#region src/translate/getOrphanedFiles.ts
|
|
638
|
-
/**
|
|
639
|
-
* @internal
|
|
640
|
-
* Gets orphaned files for a branch - files that exist on the branch
|
|
641
|
-
* but whose fileIds are not in the provided list.
|
|
642
|
-
* Used for move detection.
|
|
643
|
-
* @param branchId - The branch to check for orphaned files
|
|
644
|
-
* @param fileIds - List of current file IDs (files that are NOT orphaned)
|
|
645
|
-
* @param options - The options for the API call
|
|
646
|
-
* @param config - The configuration for the API call
|
|
647
|
-
* @returns The orphaned files
|
|
648
|
-
*/
|
|
649
|
-
async function _getOrphanedFiles(branchId, fileIds, options = {}, config) {
|
|
650
|
-
const makeRequest = (batchFileIds) => apiRequest(config, "/v2/project/files/orphaned", {
|
|
651
|
-
body: {
|
|
652
|
-
branchId,
|
|
653
|
-
fileIds: batchFileIds
|
|
654
|
-
},
|
|
655
|
-
timeout: options.timeout
|
|
656
|
-
});
|
|
657
|
-
if (fileIds.length === 0) return makeRequest([]);
|
|
658
|
-
const batches = createBatches(fileIds, 100);
|
|
659
|
-
const batchResults = await Promise.all(batches.map((batch) => makeRequest(batch)));
|
|
660
|
-
if (batchResults.length === 1) return batchResults[0];
|
|
661
|
-
const orphanedFileMap = /* @__PURE__ */ new Map();
|
|
662
|
-
for (const orphan of batchResults[0].orphanedFiles) orphanedFileMap.set(orphan.fileId, orphan);
|
|
663
|
-
for (let i = 1; i < batchResults.length; i++) {
|
|
664
|
-
const batchOrphanIds = new Set(batchResults[i].orphanedFiles.map((f) => f.fileId));
|
|
665
|
-
Array.from(orphanedFileMap.keys()).forEach((fileId) => {
|
|
666
|
-
if (!batchOrphanIds.has(fileId)) orphanedFileMap.delete(fileId);
|
|
667
|
-
});
|
|
668
|
-
}
|
|
669
|
-
return { orphanedFiles: Array.from(orphanedFileMap.values()) };
|
|
670
|
-
}
|
|
671
|
-
//#endregion
|
|
672
|
-
//#region src/translate/publishFiles.ts
|
|
673
|
-
/**
|
|
674
|
-
* @internal
|
|
675
|
-
* Publishes or unpublishes files on the CDN.
|
|
676
|
-
* @param files - Array of file entries with publish flags
|
|
677
|
-
* @param config - The configuration for the API call.
|
|
678
|
-
* @returns The result of the API call.
|
|
679
|
-
*/
|
|
680
|
-
async function _publishFiles(files, config) {
|
|
681
|
-
return await apiRequest(config, "/v2/project/files/publish", { body: { files } });
|
|
682
|
-
}
|
|
683
|
-
//#endregion
|
|
684
5
|
//#region src/index.ts
|
|
685
6
|
/**
|
|
686
7
|
* GT is the core driver for the General Translation library.
|
|
@@ -702,6 +23,23 @@ async function _publishFiles(files, config) {
|
|
|
702
23
|
* });
|
|
703
24
|
*/
|
|
704
25
|
var GT = class extends GTRuntime {
|
|
26
|
+
setConfig(params) {
|
|
27
|
+
try {
|
|
28
|
+
super.setConfig(params);
|
|
29
|
+
} finally {
|
|
30
|
+
this._apiAdapter = void 0;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
_getApiAdapter() {
|
|
34
|
+
this._apiAdapter ??= createGtApiAdapter({
|
|
35
|
+
apiKey: this.apiKey || this.devApiKey,
|
|
36
|
+
userTokenProvider: this.userTokenProvider,
|
|
37
|
+
baseUrl: this.baseUrl || "https://api.gtx.dev",
|
|
38
|
+
projectId: this.projectId,
|
|
39
|
+
customMapping: this.customMapping
|
|
40
|
+
});
|
|
41
|
+
return this._apiAdapter;
|
|
42
|
+
}
|
|
705
43
|
/**
|
|
706
44
|
* Queries branch information from the API.
|
|
707
45
|
*
|
|
@@ -709,8 +47,8 @@ var GT = class extends GTRuntime {
|
|
|
709
47
|
* @returns {Promise<BranchDataResult>} The branch information.
|
|
710
48
|
*/
|
|
711
49
|
async queryBranchData(query) {
|
|
712
|
-
|
|
713
|
-
return await
|
|
50
|
+
validateAuth("queryBranchData", this._getTranslationConfig());
|
|
51
|
+
return await this._getApiAdapter().queryBranchData(query);
|
|
714
52
|
}
|
|
715
53
|
/**
|
|
716
54
|
* Creates a new branch in the API. If the branch already exists, it will be returned.
|
|
@@ -719,8 +57,8 @@ var GT = class extends GTRuntime {
|
|
|
719
57
|
* @returns {Promise<CreateBranchResult>} The created branch information.
|
|
720
58
|
*/
|
|
721
59
|
async createBranch(query) {
|
|
722
|
-
|
|
723
|
-
return await
|
|
60
|
+
validateAuth("createBranch", this._getTranslationConfig());
|
|
61
|
+
return await this._getApiAdapter().createBranch(query);
|
|
724
62
|
}
|
|
725
63
|
/**
|
|
726
64
|
* Processes file moves by cloning source files and translations with new fileIds.
|
|
@@ -736,8 +74,8 @@ var GT = class extends GTRuntime {
|
|
|
736
74
|
* ], { branchId: 'main' });
|
|
737
75
|
*/
|
|
738
76
|
async processFileMoves(moves, options = {}) {
|
|
739
|
-
|
|
740
|
-
return await
|
|
77
|
+
validateAuth("processFileMoves", this._getTranslationConfig());
|
|
78
|
+
return await this._getApiAdapter().processFileMoves(moves, options);
|
|
741
79
|
}
|
|
742
80
|
/**
|
|
743
81
|
* Gets orphaned files for a branch - files that exist on the branch
|
|
@@ -753,8 +91,8 @@ var GT = class extends GTRuntime {
|
|
|
753
91
|
* const result = await gt.getOrphanedFiles('branch-id', ['file-1', 'file-2']);
|
|
754
92
|
*/
|
|
755
93
|
async getOrphanedFiles(branchId, fileIds, options = {}) {
|
|
756
|
-
|
|
757
|
-
return await
|
|
94
|
+
validateAuth("getOrphanedFiles", this._getTranslationConfig());
|
|
95
|
+
return await this._getApiAdapter().getOrphanedFiles(branchId, fileIds, options);
|
|
758
96
|
}
|
|
759
97
|
/**
|
|
760
98
|
* Enqueues project setup job using the specified file references
|
|
@@ -769,12 +107,12 @@ var GT = class extends GTRuntime {
|
|
|
769
107
|
* @returns {Promise<SetupProjectResult>} Object containing the jobId and status
|
|
770
108
|
*/
|
|
771
109
|
async setupProject(files, options) {
|
|
772
|
-
|
|
110
|
+
validateAuth("setupProject", this._getTranslationConfig());
|
|
773
111
|
options = {
|
|
774
112
|
...options,
|
|
775
113
|
locales: options?.locales?.map((locale) => this.resolveServiceLocale(locale))
|
|
776
114
|
};
|
|
777
|
-
return await
|
|
115
|
+
return await this._getApiAdapter().setupProject(files, options);
|
|
778
116
|
}
|
|
779
117
|
/**
|
|
780
118
|
* Checks the current status of one or more project jobs by their unique identifiers.
|
|
@@ -793,8 +131,8 @@ var GT = class extends GTRuntime {
|
|
|
793
131
|
* ], 10000);
|
|
794
132
|
*/
|
|
795
133
|
async checkJobStatus(jobIds, timeoutMs) {
|
|
796
|
-
|
|
797
|
-
return await
|
|
134
|
+
validateAuth("checkJobStatus", this._getTranslationConfig());
|
|
135
|
+
return await this._getApiAdapter().checkJobStatus(jobIds, timeoutMs);
|
|
798
136
|
}
|
|
799
137
|
/**
|
|
800
138
|
* Polls job statuses until all jobs are finished or the timeout is reached.
|
|
@@ -804,8 +142,9 @@ var GT = class extends GTRuntime {
|
|
|
804
142
|
* @returns {Promise<AwaitJobsResult>} The final status of all jobs and whether they all completed.
|
|
805
143
|
*/
|
|
806
144
|
async awaitJobs(jobs, options) {
|
|
807
|
-
|
|
808
|
-
|
|
145
|
+
validateAuth("awaitJobs", this._getTranslationConfig());
|
|
146
|
+
const jobIds = Array.isArray(jobs) ? jobs : Object.keys(jobs.jobData);
|
|
147
|
+
return await this._getApiAdapter().awaitJobs(jobIds, options);
|
|
809
148
|
}
|
|
810
149
|
/**
|
|
811
150
|
* Enqueues translation jobs for previously uploaded source files.
|
|
@@ -821,7 +160,7 @@ var GT = class extends GTRuntime {
|
|
|
821
160
|
* @returns {Promise<EnqueueFilesResult>} Result containing job IDs, queue status, and processing information.
|
|
822
161
|
*/
|
|
823
162
|
async enqueueFiles(files, options) {
|
|
824
|
-
|
|
163
|
+
validateAuth("enqueueFiles", this._getTranslationConfig());
|
|
825
164
|
let mergedOptions = {
|
|
826
165
|
...options,
|
|
827
166
|
sourceLocale: options.sourceLocale ?? this.sourceLocale,
|
|
@@ -844,7 +183,7 @@ var GT = class extends GTRuntime {
|
|
|
844
183
|
targetLocales: mergedOptions.targetLocales.map((locale) => this.resolveServiceLocale(locale))
|
|
845
184
|
};
|
|
846
185
|
return {
|
|
847
|
-
...await
|
|
186
|
+
...await this._getApiAdapter().enqueueFiles(files, mergedOptions),
|
|
848
187
|
locales: targetLocaleIdentities
|
|
849
188
|
};
|
|
850
189
|
}
|
|
@@ -856,8 +195,8 @@ var GT = class extends GTRuntime {
|
|
|
856
195
|
* @returns {Promise<CreateTagResult>} The created or updated tag.
|
|
857
196
|
*/
|
|
858
197
|
async createTag(options) {
|
|
859
|
-
|
|
860
|
-
return await
|
|
198
|
+
validateAuth("createTag", this._getTranslationConfig());
|
|
199
|
+
return await this._getApiAdapter().createTag(options);
|
|
861
200
|
}
|
|
862
201
|
/**
|
|
863
202
|
* Publishes or unpublishes files on the CDN.
|
|
@@ -866,8 +205,8 @@ var GT = class extends GTRuntime {
|
|
|
866
205
|
* @returns {Promise<PublishFilesResult>} Result containing per-file success/failure
|
|
867
206
|
*/
|
|
868
207
|
async publishFiles(files) {
|
|
869
|
-
|
|
870
|
-
return { results: (await
|
|
208
|
+
validateAuth("publishFiles", this._getTranslationConfig());
|
|
209
|
+
return { results: (await this._getApiAdapter().publishFiles(files)).results.map((item) => ({
|
|
871
210
|
...item,
|
|
872
211
|
...item.locale && { locale: this.resolveServiceResponseLocale(item.locale) }
|
|
873
212
|
})) };
|
|
@@ -879,14 +218,15 @@ var GT = class extends GTRuntime {
|
|
|
879
218
|
* @returns {Promise<void>} Resolves when submission succeeds.
|
|
880
219
|
*/
|
|
881
220
|
async submitUserEditDiffs(payload) {
|
|
882
|
-
|
|
883
|
-
|
|
221
|
+
validateAuth("submitUserEditDiffs", this._getTranslationConfig());
|
|
222
|
+
const normalized = {
|
|
884
223
|
...payload,
|
|
885
224
|
diffs: (payload.diffs || []).map((d) => ({
|
|
886
225
|
...d,
|
|
887
226
|
locale: this.resolveServiceLocale(d.locale)
|
|
888
227
|
}))
|
|
889
|
-
}
|
|
228
|
+
};
|
|
229
|
+
await this._getApiAdapter().submitUserEditDiffs(normalized);
|
|
890
230
|
}
|
|
891
231
|
/**
|
|
892
232
|
* Queries data about one or more source or translation files.
|
|
@@ -915,8 +255,8 @@ var GT = class extends GTRuntime {
|
|
|
915
255
|
* @returns The project info.
|
|
916
256
|
*/
|
|
917
257
|
async getProjectInfo(options = {}) {
|
|
918
|
-
|
|
919
|
-
const result = await
|
|
258
|
+
validateAuth("getProjectInfo", this._getTranslationConfig());
|
|
259
|
+
const result = await this._getApiAdapter().getProjectInfo(void 0, options.timeout);
|
|
920
260
|
return {
|
|
921
261
|
...result,
|
|
922
262
|
defaultLocale: this.resolveServiceResponseLocale(result.defaultLocale),
|
|
@@ -924,12 +264,12 @@ var GT = class extends GTRuntime {
|
|
|
924
264
|
};
|
|
925
265
|
}
|
|
926
266
|
async queryFileData(data, options = {}) {
|
|
927
|
-
|
|
267
|
+
validateAuth("queryFileData", this._getTranslationConfig());
|
|
928
268
|
data.translatedFiles = data.translatedFiles?.map((item) => ({
|
|
929
269
|
...item,
|
|
930
270
|
locale: this.resolveServiceLocale(item.locale)
|
|
931
271
|
}));
|
|
932
|
-
const result = await
|
|
272
|
+
const result = await this._getApiAdapter().queryFileData(data, options.timeout);
|
|
933
273
|
result.translatedFiles = result.translatedFiles?.map((item) => ({
|
|
934
274
|
...item,
|
|
935
275
|
...item.locale && { locale: this.resolveServiceResponseLocale(item.locale) }
|
|
@@ -956,8 +296,11 @@ var GT = class extends GTRuntime {
|
|
|
956
296
|
*
|
|
957
297
|
*/
|
|
958
298
|
async querySourceFile(data, options = {}) {
|
|
959
|
-
|
|
960
|
-
const result = await
|
|
299
|
+
validateAuth("querySourceFile", this._getTranslationConfig());
|
|
300
|
+
const result = await this._getApiAdapter().querySourceFile({ fileId: data.fileId }, {
|
|
301
|
+
branchId: data.branchId,
|
|
302
|
+
versionId: data.versionId
|
|
303
|
+
}, options.timeout);
|
|
961
304
|
result.translations = result.translations.map((item) => ({
|
|
962
305
|
...item,
|
|
963
306
|
...item.locale && { locale: this.resolveServiceResponseLocale(item.locale) }
|
|
@@ -969,6 +312,9 @@ var GT = class extends GTRuntime {
|
|
|
969
312
|
/**
|
|
970
313
|
* Get project data for a given project ID.
|
|
971
314
|
*
|
|
315
|
+
* @deprecated Use `getProjectInfo()` on a `GT` instance configured with the
|
|
316
|
+
* target `projectId`; it reads the same resource and also returns
|
|
317
|
+
* `autoApprove`. This method will be removed in the next major version.
|
|
972
318
|
* @param {string} projectId - The ID of the project to get the data for.
|
|
973
319
|
* @returns {Promise<ProjectData>} The project data.
|
|
974
320
|
*
|
|
@@ -979,11 +325,13 @@ var GT = class extends GTRuntime {
|
|
|
979
325
|
*
|
|
980
326
|
*/
|
|
981
327
|
async getProjectData(projectId, options = {}) {
|
|
982
|
-
|
|
983
|
-
const
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
328
|
+
validateAuth("getProjectData", this._getTranslationConfig());
|
|
329
|
+
const { autoApprove: _autoApprove, ...project } = await this._getApiAdapter().getProjectInfo(projectId, options.timeout);
|
|
330
|
+
return {
|
|
331
|
+
...project,
|
|
332
|
+
defaultLocale: this.resolveServiceResponseLocale(project.defaultLocale),
|
|
333
|
+
currentLocales: project.currentLocales.map((item) => this.resolveServiceResponseLocale(item))
|
|
334
|
+
};
|
|
987
335
|
}
|
|
988
336
|
/**
|
|
989
337
|
* Downloads a single file.
|
|
@@ -1007,14 +355,11 @@ var GT = class extends GTRuntime {
|
|
|
1007
355
|
* });
|
|
1008
356
|
*/
|
|
1009
357
|
async downloadFile(file, options = {}) {
|
|
1010
|
-
|
|
1011
|
-
return (await
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
versionId: file.versionId,
|
|
1016
|
-
useLatestAvailableVersion: file.useLatestAvailableVersion
|
|
1017
|
-
}], options, this._getTranslationConfig())).data?.[0]?.data ?? "";
|
|
358
|
+
validateAuth("downloadTranslatedFile", this._getTranslationConfig());
|
|
359
|
+
return (await this._getApiAdapter().downloadFileBatch([{
|
|
360
|
+
...file,
|
|
361
|
+
locale: file.locale ? this.resolveServiceLocale(file.locale) : void 0
|
|
362
|
+
}], options)).files[0]?.data ?? "";
|
|
1018
363
|
}
|
|
1019
364
|
/**
|
|
1020
365
|
* Downloads multiple files in a batch.
|
|
@@ -1033,7 +378,7 @@ var GT = class extends GTRuntime {
|
|
|
1033
378
|
* });
|
|
1034
379
|
*/
|
|
1035
380
|
async downloadFileBatch(requests, options = {}) {
|
|
1036
|
-
|
|
381
|
+
validateAuth("downloadFileBatch", this._getTranslationConfig());
|
|
1037
382
|
const requestedFiles = /* @__PURE__ */ new Map();
|
|
1038
383
|
requests = requests.map((request) => {
|
|
1039
384
|
const locale = request.locale ? this.resolveServiceLocale(request.locale) : void 0;
|
|
@@ -1048,11 +393,11 @@ var GT = class extends GTRuntime {
|
|
|
1048
393
|
locale
|
|
1049
394
|
};
|
|
1050
395
|
});
|
|
1051
|
-
const result = await
|
|
396
|
+
const result = await this._getApiAdapter().downloadFileBatch(requests, options);
|
|
1052
397
|
return {
|
|
1053
|
-
files: result.
|
|
398
|
+
files: result.files.map((file) => {
|
|
1054
399
|
if (!file.locale) return file;
|
|
1055
|
-
const serviceLocale = this.
|
|
400
|
+
const serviceLocale = this.resolveServiceLocale(file.locale);
|
|
1056
401
|
const matchingRequests = (requestedFiles.get(JSON.stringify([file.fileId, serviceLocale])) ?? []).filter((request) => (!request.branchId || request.branchId === file.branchId) && (!request.versionId || request.versionId === file.versionId));
|
|
1057
402
|
return {
|
|
1058
403
|
...file,
|
|
@@ -1075,7 +420,7 @@ var GT = class extends GTRuntime {
|
|
|
1075
420
|
* @returns {Promise<UploadFilesResponse>} Upload result containing file IDs, version information, and upload status.
|
|
1076
421
|
*/
|
|
1077
422
|
async uploadSourceFiles(files, options) {
|
|
1078
|
-
|
|
423
|
+
validateAuth("uploadSourceFiles", this._getTranslationConfig());
|
|
1079
424
|
const mergedOptions = {
|
|
1080
425
|
...options,
|
|
1081
426
|
sourceLocale: this.resolveServiceLocale(options.sourceLocale ?? this.sourceLocale ?? "en")
|
|
@@ -1087,11 +432,11 @@ var GT = class extends GTRuntime {
|
|
|
1087
432
|
locale: this.resolveServiceLocale(f.source.locale)
|
|
1088
433
|
}
|
|
1089
434
|
}));
|
|
1090
|
-
const
|
|
435
|
+
const { uploadedFiles } = await this._getApiAdapter().uploadSourceFiles(files, mergedOptions);
|
|
1091
436
|
return {
|
|
1092
|
-
uploadedFiles
|
|
1093
|
-
count:
|
|
1094
|
-
message: `Successfully uploaded ${
|
|
437
|
+
uploadedFiles,
|
|
438
|
+
count: uploadedFiles.length,
|
|
439
|
+
message: `Successfully uploaded ${uploadedFiles.length} files in ${Math.ceil(files.length / 100)} batch(es)`
|
|
1095
440
|
};
|
|
1096
441
|
}
|
|
1097
442
|
/**
|
|
@@ -1100,15 +445,11 @@ var GT = class extends GTRuntime {
|
|
|
1100
445
|
* re-running only stores new fonts.
|
|
1101
446
|
* @param {AssetUpload[]} fonts - Fonts to upload (`content` base64-encoded).
|
|
1102
447
|
* @param {UploadAssetsOptions} options - Optional settings (e.g. timeout).
|
|
1103
|
-
* @returns {Promise<UploadAssetsResponse>} The stored
|
|
448
|
+
* @returns {Promise<UploadAssetsResponse>} The stored assets.
|
|
1104
449
|
*/
|
|
1105
450
|
async uploadFonts(fonts, options = {}) {
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
return {
|
|
1109
|
-
assets: result.data,
|
|
1110
|
-
count: result.count
|
|
1111
|
-
};
|
|
451
|
+
validateAuth("uploadFonts", this._getTranslationConfig());
|
|
452
|
+
return await this._getApiAdapter().uploadFonts(fonts, options);
|
|
1112
453
|
}
|
|
1113
454
|
/**
|
|
1114
455
|
* Uploads translation files that correspond to previously uploaded source files.
|
|
@@ -1125,7 +466,7 @@ var GT = class extends GTRuntime {
|
|
|
1125
466
|
* @returns {Promise<UploadFilesResponse>} Upload result containing translation IDs, status, and processing information.
|
|
1126
467
|
*/
|
|
1127
468
|
async uploadTranslations(files, options) {
|
|
1128
|
-
|
|
469
|
+
validateAuth("uploadTranslations", this._getTranslationConfig());
|
|
1129
470
|
const mergedOptions = {
|
|
1130
471
|
...options,
|
|
1131
472
|
sourceLocale: options.sourceLocale ?? this.sourceLocale
|
|
@@ -1136,7 +477,7 @@ var GT = class extends GTRuntime {
|
|
|
1136
477
|
throw new Error(error);
|
|
1137
478
|
}
|
|
1138
479
|
mergedOptions.sourceLocale = this.resolveServiceLocale(mergedOptions.sourceLocale);
|
|
1139
|
-
const
|
|
480
|
+
const targetFiles = files.map((f) => ({
|
|
1140
481
|
...f,
|
|
1141
482
|
source: {
|
|
1142
483
|
...f.source,
|
|
@@ -1146,11 +487,12 @@ var GT = class extends GTRuntime {
|
|
|
1146
487
|
...t,
|
|
1147
488
|
locale: this.resolveServiceLocale(t.locale)
|
|
1148
489
|
}))
|
|
1149
|
-
}))
|
|
490
|
+
}));
|
|
491
|
+
const { uploadedFiles } = await this._getApiAdapter().uploadTranslations(targetFiles, mergedOptions);
|
|
1150
492
|
return {
|
|
1151
|
-
uploadedFiles
|
|
1152
|
-
count:
|
|
1153
|
-
message: `Successfully uploaded ${
|
|
493
|
+
uploadedFiles,
|
|
494
|
+
count: uploadedFiles.length,
|
|
495
|
+
message: `Successfully uploaded ${uploadedFiles.length} files in ${Math.ceil(files.length / 100)} batch(es)`
|
|
1154
496
|
};
|
|
1155
497
|
}
|
|
1156
498
|
};
|