gt 2.19.0 → 2.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/api/collectUserEditDiffs.js +23 -23
  3. package/dist/api/collectUserEditDiffs.js.map +1 -1
  4. package/dist/api/downloadFileBatch.js +7 -4
  5. package/dist/api/downloadFileBatch.js.map +1 -1
  6. package/dist/api/saveLocalEdits.js +2 -2
  7. package/dist/api/saveLocalEdits.js.map +1 -1
  8. package/dist/cli/base.d.ts +2 -0
  9. package/dist/cli/base.js +45 -2
  10. package/dist/cli/base.js.map +1 -1
  11. package/dist/cli/commands/api.d.ts +17 -0
  12. package/dist/cli/commands/api.js +153 -0
  13. package/dist/cli/commands/api.js.map +1 -0
  14. package/dist/cli/commands/upload.js +15 -5
  15. package/dist/cli/commands/upload.js.map +1 -1
  16. package/dist/cli/commands/utils/validation.d.ts +4 -0
  17. package/dist/cli/commands/utils/validation.js +12 -5
  18. package/dist/cli/commands/utils/validation.js.map +1 -1
  19. package/dist/cli/flags.js +1 -1
  20. package/dist/cli/flags.js.map +1 -1
  21. package/dist/config/generateSettings.d.ts +1 -0
  22. package/dist/config/generateSettings.js +9 -1
  23. package/dist/config/generateSettings.js.map +1 -1
  24. package/dist/console/index.d.ts +1 -0
  25. package/dist/console/index.js +2 -1
  26. package/dist/console/index.js.map +1 -1
  27. package/dist/formats/files/aggregateFiles.js +14 -6
  28. package/dist/formats/files/aggregateFiles.js.map +1 -1
  29. package/dist/fs/fileContent.d.ts +65 -0
  30. package/dist/fs/fileContent.js +171 -0
  31. package/dist/fs/fileContent.js.map +1 -0
  32. package/dist/generated/version.d.ts +1 -1
  33. package/dist/generated/version.js +1 -1
  34. package/dist/generated/version.js.map +1 -1
  35. package/dist/state/recentDownloads.d.ts +3 -2
  36. package/dist/state/recentDownloads.js.map +1 -1
  37. package/dist/translation/reviewSetupWarning.js +3 -3
  38. package/dist/translation/reviewSetupWarning.js.map +1 -1
  39. package/dist/types/index.d.ts +1 -0
  40. package/dist/utils/api.d.ts +194 -0
  41. package/dist/utils/api.js +268 -0
  42. package/dist/utils/api.js.map +1 -0
  43. package/dist/utils/persistPostprocessHashes.d.ts +1 -7
  44. package/dist/utils/persistPostprocessHashes.js +15 -1
  45. package/dist/utils/persistPostprocessHashes.js.map +1 -1
  46. package/dist/workflows/download.js +4 -4
  47. package/dist/workflows/download.js.map +1 -1
  48. package/dist/workflows/enqueue.js +4 -4
  49. package/dist/workflows/enqueue.js.map +1 -1
  50. package/dist/workflows/publish.js +2 -2
  51. package/dist/workflows/publish.js.map +1 -1
  52. package/dist/workflows/setupProject.js +4 -4
  53. package/dist/workflows/setupProject.js.map +1 -1
  54. package/dist/workflows/stage.js +8 -8
  55. package/dist/workflows/stage.js.map +1 -1
  56. package/dist/workflows/steps/BranchStep.d.ts +2 -2
  57. package/dist/workflows/steps/BranchStep.js +9 -9
  58. package/dist/workflows/steps/BranchStep.js.map +1 -1
  59. package/dist/workflows/steps/DownloadStep.d.ts +3 -3
  60. package/dist/workflows/steps/DownloadStep.js +3 -3
  61. package/dist/workflows/steps/DownloadStep.js.map +1 -1
  62. package/dist/workflows/steps/EnqueueStep.d.ts +5 -3
  63. package/dist/workflows/steps/EnqueueStep.js.map +1 -1
  64. package/dist/workflows/steps/PollJobsStep.d.ts +3 -3
  65. package/dist/workflows/steps/PollJobsStep.js +6 -6
  66. package/dist/workflows/steps/PollJobsStep.js.map +1 -1
  67. package/dist/workflows/steps/PublishStep.d.ts +3 -3
  68. package/dist/workflows/steps/PublishStep.js +3 -3
  69. package/dist/workflows/steps/PublishStep.js.map +1 -1
  70. package/dist/workflows/steps/SetupStep.d.ts +6 -4
  71. package/dist/workflows/steps/SetupStep.js.map +1 -1
  72. package/dist/workflows/steps/TagStep.d.ts +3 -3
  73. package/dist/workflows/steps/TagStep.js +3 -3
  74. package/dist/workflows/steps/TagStep.js.map +1 -1
  75. package/dist/workflows/steps/UploadSourcesStep.d.ts +3 -3
  76. package/dist/workflows/steps/UploadSourcesStep.js +8 -6
  77. package/dist/workflows/steps/UploadSourcesStep.js.map +1 -1
  78. package/dist/workflows/steps/UploadTranslationsStep.d.ts +3 -3
  79. package/dist/workflows/steps/UploadTranslationsStep.js +24 -6
  80. package/dist/workflows/steps/UploadTranslationsStep.js.map +1 -1
  81. package/dist/workflows/upload.js +4 -4
  82. package/dist/workflows/upload.js.map +1 -1
  83. package/dist/workflows/utils/filterFilesForEnqueue.d.ts +2 -2
  84. package/dist/workflows/utils/filterFilesForEnqueue.js.map +1 -1
  85. package/dist/workflows/utils/queryCompletedTranslations.d.ts +3 -3
  86. package/dist/workflows/utils/queryCompletedTranslations.js +2 -2
  87. package/dist/workflows/utils/queryCompletedTranslations.js.map +1 -1
  88. package/package.json +5 -5
@@ -0,0 +1,268 @@
1
+ import { unwrapApiResult } from "generaltranslation/internal";
2
+ import { resolveAliasLocale, resolveCanonicalLocale } from "@generaltranslation/format";
3
+ import { DEFAULT_BATCH_SIZE, createApiClient, createBranch, createProject, createTag, decodeFileContent, downloadFiles, encodeFileContent, enqueueFileTranslations, generateProjectContext, getBranchInfo, getFileInfo, getOrphanedFiles, getProjectInfo, getTranslationJobInfo, pollJobs, processBatches, processFileMoves, publishFiles, submitUserEditDiffs, uploadSourceFiles, uploadTranslations } from "generaltranslation/api";
4
+ //#region src/utils/api.ts
5
+ let client;
6
+ let configuredClientConfig;
7
+ let customMapping;
8
+ function getConfiguredClient() {
9
+ if (!client || !configuredClientConfig) throw new Error("API client not configured — call configureApiClient first");
10
+ return {
11
+ client,
12
+ config: configuredClientConfig
13
+ };
14
+ }
15
+ function getClient() {
16
+ return getConfiguredClient().client;
17
+ }
18
+ function getClientConfig() {
19
+ return getConfiguredClient().config;
20
+ }
21
+ function configureApiClient(config) {
22
+ const { customMapping: mapping, ...clientConfig } = config;
23
+ client = createApiClient(clientConfig);
24
+ configuredClientConfig = clientConfig;
25
+ customMapping = mapping;
26
+ }
27
+ const api = {
28
+ async queryBranchData(body) {
29
+ return unwrapApiResult(await getBranchInfo({
30
+ body,
31
+ client: getClient()
32
+ }));
33
+ },
34
+ async createBranch(body) {
35
+ return unwrapApiResult(await createBranch({
36
+ body,
37
+ client: getClient()
38
+ }));
39
+ },
40
+ async queryFileData(body) {
41
+ const result = unwrapApiResult(await getFileInfo({
42
+ body: {
43
+ ...body,
44
+ translatedFiles: body.translatedFiles?.map((file) => ({
45
+ ...file,
46
+ locale: resolveCanonicalLocale(file.locale, customMapping)
47
+ }))
48
+ },
49
+ client: getClient()
50
+ }));
51
+ return {
52
+ ...result,
53
+ translatedFiles: result.translatedFiles.map((file) => ({
54
+ ...file,
55
+ locale: resolveAliasLocale(file.locale, customMapping)
56
+ })),
57
+ sourceFiles: result.sourceFiles.map((file) => ({
58
+ ...file,
59
+ sourceLocale: resolveAliasLocale(file.sourceLocale, customMapping),
60
+ locales: file.locales.map((locale) => resolveAliasLocale(locale, customMapping))
61
+ }))
62
+ };
63
+ },
64
+ async checkJobStatus(jobIds) {
65
+ return unwrapApiResult(await getTranslationJobInfo({
66
+ body: { jobIds },
67
+ client: getClient()
68
+ }));
69
+ },
70
+ async getProjectInfo(timeoutMs) {
71
+ const config = getClientConfig();
72
+ if (!config.projectId) throw new Error("Project ID is required to fetch project information");
73
+ return unwrapApiResult(await getProjectInfo({
74
+ client: createApiClient({
75
+ ...config,
76
+ timeoutMs
77
+ }),
78
+ path: { projectId: config.projectId }
79
+ }));
80
+ },
81
+ resolveAliasLocale(locale) {
82
+ return resolveAliasLocale(locale, customMapping);
83
+ },
84
+ async downloadFileBatch(files) {
85
+ if (files.length === 0) return {
86
+ files: [],
87
+ count: 0,
88
+ pending: []
89
+ };
90
+ const request = async (batch) => unwrapApiResult(await downloadFiles({
91
+ body: batch.map((file) => ({
92
+ ...file,
93
+ locale: file.locale ? resolveCanonicalLocale(file.locale, customMapping) : void 0
94
+ })),
95
+ client: getClient()
96
+ }));
97
+ const responses = await processBatches(files, async (batch) => [await request(batch)]);
98
+ return {
99
+ files: responses.flatMap((response) => response.files.map((file) => ({
100
+ ...file,
101
+ ...file.locale && { locale: resolveAliasLocale(file.locale, customMapping) },
102
+ data: decodeFileContent(file.data, file.fileFormat)
103
+ }))),
104
+ count: responses.reduce((count, response) => count + response.count, 0),
105
+ pending: responses.flatMap((response) => response.pending ?? [])
106
+ };
107
+ },
108
+ async publishFiles(files) {
109
+ return unwrapApiResult(await publishFiles({
110
+ body: { files },
111
+ client: getClient()
112
+ }));
113
+ },
114
+ async submitUserEditDiffs(body) {
115
+ return processBatches(body.diffs, async (diffs) => [unwrapApiResult(await submitUserEditDiffs({
116
+ body: {
117
+ projectId: body.projectId,
118
+ diffs: diffs.map((diff) => ({
119
+ ...diff,
120
+ locale: resolveCanonicalLocale(diff.locale, customMapping)
121
+ }))
122
+ },
123
+ client: getClient()
124
+ }))]);
125
+ },
126
+ async createTag(body) {
127
+ return unwrapApiResult(await createTag({
128
+ body,
129
+ client: getClient()
130
+ }));
131
+ },
132
+ async createProject(body) {
133
+ return unwrapApiResult(await createProject({
134
+ body: {
135
+ ...body,
136
+ defaultLocale: resolveCanonicalLocale(body.defaultLocale, customMapping)
137
+ },
138
+ client: getClient()
139
+ }));
140
+ },
141
+ async getOrphanedFiles(branchId, fileIds) {
142
+ const request = async (batch) => unwrapApiResult(await getOrphanedFiles({
143
+ body: {
144
+ branchId,
145
+ fileIds: batch
146
+ },
147
+ client: getClient()
148
+ }));
149
+ if (fileIds.length === 0) return request([]);
150
+ const results = await processBatches(fileIds, async (batch) => [await request(batch)]);
151
+ const orphanedFiles = new Map(results[0].orphanedFiles.map((file) => [file.fileId, file]));
152
+ for (const result of results.slice(1)) {
153
+ const batchFileIds = new Set(result.orphanedFiles.map((file) => file.fileId));
154
+ for (const fileId of orphanedFiles.keys()) if (!batchFileIds.has(fileId)) orphanedFiles.delete(fileId);
155
+ }
156
+ return { orphanedFiles: [...orphanedFiles.values()] };
157
+ },
158
+ async processFileMoves(moves, options) {
159
+ const result = await processBatches(moves, async (batch) => {
160
+ return unwrapApiResult(await processFileMoves({
161
+ body: {
162
+ branchId: options.branchId,
163
+ moves: batch
164
+ },
165
+ client: getClient()
166
+ })).results;
167
+ });
168
+ const succeeded = result.filter(({ success }) => success).length;
169
+ return {
170
+ results: result,
171
+ summary: {
172
+ total: moves.length,
173
+ succeeded,
174
+ failed: result.length - succeeded
175
+ }
176
+ };
177
+ },
178
+ async setupProject(files, options = {}) {
179
+ return unwrapApiResult(await generateProjectContext({
180
+ body: {
181
+ files: files.map(({ branchId, fileId, versionId }) => ({
182
+ branchId,
183
+ fileId,
184
+ versionId
185
+ })),
186
+ locales: options.locales?.map((locale) => resolveCanonicalLocale(locale, customMapping)),
187
+ force: options.force
188
+ },
189
+ client: getClient()
190
+ }));
191
+ },
192
+ async awaitJobs(jobIds, options) {
193
+ return pollJobs(jobIds, async (pendingJobIds, signal) => unwrapApiResult(await getTranslationJobInfo({
194
+ body: { jobIds: pendingJobIds },
195
+ client: getClient(),
196
+ signal
197
+ })), options);
198
+ },
199
+ async enqueueFiles(files, options) {
200
+ const targetLocales = options.targetLocales.map((locale) => resolveCanonicalLocale(locale, customMapping));
201
+ const result = await processBatches(files, async (batch) => {
202
+ const response = unwrapApiResult(await enqueueFileTranslations({
203
+ body: {
204
+ files: batch.map(({ branchId, fileId, versionId, fileName, transformFormat }) => ({
205
+ branchId,
206
+ fileId,
207
+ versionId,
208
+ fileName,
209
+ transformFormat
210
+ })),
211
+ targetLocales,
212
+ sourceLocale: options.sourceLocale ? resolveCanonicalLocale(options.sourceLocale, customMapping) : void 0,
213
+ modelProvider: options.modelProvider,
214
+ force: options.force
215
+ },
216
+ client: getClient()
217
+ }));
218
+ const jobData = "jobData" in response ? response.jobData : response.data;
219
+ return Object.entries(jobData);
220
+ });
221
+ return {
222
+ jobData: Object.fromEntries(result),
223
+ locales: targetLocales,
224
+ message: `Successfully enqueued ${result.length} file translation jobs in ${Math.ceil(files.length / DEFAULT_BATCH_SIZE)} batch(es)`
225
+ };
226
+ },
227
+ async uploadSourceFiles(files, options) {
228
+ const sourceLocale = resolveCanonicalLocale(options.sourceLocale, customMapping);
229
+ return { uploadedFiles: await processBatches(files, async (batch) => {
230
+ return unwrapApiResult(await uploadSourceFiles({
231
+ body: {
232
+ data: batch.map(({ source }) => ({ source: {
233
+ ...source,
234
+ content: encodeFileContent(source.content, source.fileFormat),
235
+ locale: resolveCanonicalLocale(source.locale, customMapping)
236
+ } })),
237
+ sourceLocale
238
+ },
239
+ client: getClient()
240
+ })).uploadedFiles;
241
+ }) };
242
+ },
243
+ async uploadTranslations(files, options) {
244
+ return { uploadedFiles: await processBatches(files, async (batch) => {
245
+ return unwrapApiResult(await uploadTranslations({
246
+ body: {
247
+ data: batch.map(({ source, translations }) => ({
248
+ source: {
249
+ ...source,
250
+ content: encodeFileContent(source.content, source.fileFormat)
251
+ },
252
+ translations: translations.map((translation) => ({
253
+ ...translation,
254
+ locale: resolveCanonicalLocale(translation.locale, customMapping),
255
+ content: encodeFileContent(translation.content, translation.fileFormat)
256
+ }))
257
+ })),
258
+ sourceLocale: resolveCanonicalLocale(options.sourceLocale, customMapping)
259
+ },
260
+ client: getClient()
261
+ })).uploadedFiles;
262
+ }) };
263
+ }
264
+ };
265
+ //#endregion
266
+ export { api, configureApiClient };
267
+
268
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","names":[],"sources":["../../src/utils/api.ts"],"sourcesContent":["import {\n resolveAliasLocale,\n resolveCanonicalLocale,\n} from '@generaltranslation/format';\nimport type { CustomMapping } from '@generaltranslation/format/types';\nimport {\n createApiClient,\n createBranch,\n createProject,\n createTag,\n decodeFileContent,\n DEFAULT_BATCH_SIZE,\n downloadFiles,\n encodeFileContent,\n enqueueFileTranslations,\n generateProjectContext,\n getBranchInfo,\n getFileInfo,\n getOrphanedFiles,\n getProjectInfo,\n getTranslationJobInfo,\n pollJobs,\n processBatches,\n processFileMoves,\n publishFiles,\n submitUserEditDiffs,\n uploadSourceFiles,\n uploadTranslations,\n type ApiClientConfig,\n type AwaitJobsOptions,\n type CreateBranchData,\n type CreateProjectData,\n type CreateTagData,\n type DownloadFilesData,\n type EnqueueFileTranslationsData,\n type GenerateProjectContextData,\n type GetBranchInfoData,\n type GetFileInfoData,\n type ProcessFileMovesData,\n type PublishFilesData,\n type SubmitUserEditDiffsData,\n type UploadSourceFilesData,\n type UploadTranslationsData,\n} from 'generaltranslation/api';\nimport { unwrapApiResult } from 'generaltranslation/internal';\n\nlet client: ReturnType<typeof createApiClient> | undefined;\nlet configuredClientConfig: ApiClientConfig | undefined;\nlet customMapping: CustomMapping | undefined;\n\nfunction getConfiguredClient(): {\n client: ReturnType<typeof createApiClient>;\n config: ApiClientConfig;\n} {\n if (!client || !configuredClientConfig) {\n throw new Error(\n 'API client not configured — call configureApiClient first'\n );\n }\n return { client, config: configuredClientConfig };\n}\n\nfunction getClient(): ReturnType<typeof createApiClient> {\n return getConfiguredClient().client;\n}\n\nfunction getClientConfig(): ApiClientConfig {\n return getConfiguredClient().config;\n}\n\nexport function configureApiClient(\n config: ApiClientConfig & { customMapping?: CustomMapping }\n): void {\n const { customMapping: mapping, ...clientConfig } = config;\n client = createApiClient(clientConfig);\n // Retain the resolved config for the one project-info call that deliberately\n // uses a shorter timeout than normal translation requests.\n configuredClientConfig = clientConfig;\n customMapping = mapping;\n}\n\nexport const api = {\n async queryBranchData(body: GetBranchInfoData['body']) {\n return unwrapApiResult(await getBranchInfo({ body, client: getClient() }));\n },\n\n async createBranch(body: CreateBranchData['body']) {\n return unwrapApiResult(await createBranch({ body, client: getClient() }));\n },\n\n async queryFileData(body: GetFileInfoData['body']) {\n const result = unwrapApiResult(\n await getFileInfo({\n body: {\n ...body,\n translatedFiles: body.translatedFiles?.map((file) => ({\n ...file,\n locale: resolveCanonicalLocale(file.locale, customMapping),\n })),\n },\n client: getClient(),\n })\n );\n return {\n ...result,\n translatedFiles: result.translatedFiles.map((file) => ({\n ...file,\n locale: resolveAliasLocale(file.locale, customMapping),\n })),\n sourceFiles: result.sourceFiles.map((file) => ({\n ...file,\n sourceLocale: resolveAliasLocale(file.sourceLocale, customMapping),\n locales: file.locales.map((locale) =>\n resolveAliasLocale(locale, customMapping)\n ),\n })),\n };\n },\n\n async checkJobStatus(jobIds: string[]) {\n return unwrapApiResult(\n await getTranslationJobInfo({\n body: { jobIds },\n client: getClient(),\n })\n );\n },\n\n async getProjectInfo(timeoutMs: number) {\n const config = getClientConfig();\n if (!config.projectId) {\n throw new Error('Project ID is required to fetch project information');\n }\n const projectInfoClient = createApiClient({ ...config, timeoutMs });\n return unwrapApiResult(\n await getProjectInfo({\n client: projectInfoClient,\n path: { projectId: config.projectId },\n })\n );\n },\n\n resolveAliasLocale(locale: string) {\n return resolveAliasLocale(locale, customMapping);\n },\n\n async downloadFileBatch(files: DownloadFilesData['body']) {\n if (files.length === 0) return { files: [], count: 0, pending: [] };\n\n const request = async (batch: DownloadFilesData['body']) =>\n unwrapApiResult(\n await downloadFiles({\n body: batch.map((file) => ({\n ...file,\n locale: file.locale\n ? resolveCanonicalLocale(file.locale, customMapping)\n : undefined,\n })),\n client: getClient(),\n })\n );\n const responses = await processBatches(files, async (batch) => [\n await request(batch),\n ]);\n return {\n files: responses.flatMap((response) =>\n response.files.map((file) => ({\n ...file,\n ...(file.locale && {\n locale: resolveAliasLocale(file.locale, customMapping),\n }),\n data: decodeFileContent(file.data, file.fileFormat),\n }))\n ),\n count: responses.reduce((count, response) => count + response.count, 0),\n pending: responses.flatMap((response) => response.pending ?? []),\n };\n },\n\n async publishFiles(files: PublishFilesData['body']['files']) {\n return unwrapApiResult(\n await publishFiles({ body: { files }, client: getClient() })\n );\n },\n\n async submitUserEditDiffs(body: SubmitUserEditDiffsData['body']) {\n return processBatches(body.diffs, async (diffs) => [\n unwrapApiResult(\n await submitUserEditDiffs({\n body: {\n projectId: body.projectId,\n diffs: diffs.map((diff) => ({\n ...diff,\n locale: resolveCanonicalLocale(diff.locale, customMapping),\n })),\n },\n client: getClient(),\n })\n ),\n ]);\n },\n\n async createTag(body: CreateTagData['body']) {\n return unwrapApiResult(await createTag({ body, client: getClient() }));\n },\n\n async createProject(body: CreateProjectData['body']) {\n return unwrapApiResult(\n await createProject({\n body: {\n ...body,\n defaultLocale: resolveCanonicalLocale(\n body.defaultLocale,\n customMapping\n ),\n },\n client: getClient(),\n })\n );\n },\n\n // ponytail: duplicates core/src/translate/getOrphanedFiles.ts batching +\n // intersection; delete one copy when utils/gt.ts is removed.\n async getOrphanedFiles(branchId: string, fileIds: string[]) {\n const request = async (batch: string[]) =>\n unwrapApiResult(\n await getOrphanedFiles({\n body: { branchId, fileIds: batch },\n client: getClient(),\n })\n );\n\n if (fileIds.length === 0) return request([]);\n\n const results = await processBatches(fileIds, async (batch) => [\n await request(batch),\n ]);\n const orphanedFiles = new Map(\n results[0].orphanedFiles.map((file) => [file.fileId, file])\n );\n for (const result of results.slice(1)) {\n const batchFileIds = new Set(\n result.orphanedFiles.map((file) => file.fileId)\n );\n for (const fileId of orphanedFiles.keys()) {\n if (!batchFileIds.has(fileId)) orphanedFiles.delete(fileId);\n }\n }\n return { orphanedFiles: [...orphanedFiles.values()] };\n },\n\n async processFileMoves(\n moves: ProcessFileMovesData['body']['moves'],\n options: Pick<ProcessFileMovesData['body'], 'branchId'>\n ) {\n const result = await processBatches(moves, async (batch) => {\n const response = unwrapApiResult(\n await processFileMoves({\n body: { branchId: options.branchId, moves: batch },\n client: getClient(),\n })\n );\n return response.results;\n });\n const succeeded = result.filter(({ success }) => success).length;\n\n return {\n results: result,\n summary: {\n total: moves.length,\n succeeded,\n failed: result.length - succeeded,\n },\n };\n },\n\n async setupProject(\n files: GenerateProjectContextData['body']['files'],\n options: Omit<GenerateProjectContextData['body'], 'files'> = {}\n ) {\n return unwrapApiResult(\n await generateProjectContext({\n body: {\n files: files.map(({ branchId, fileId, versionId }) => ({\n branchId,\n fileId,\n versionId,\n })),\n locales: options.locales?.map((locale) =>\n resolveCanonicalLocale(locale, customMapping)\n ),\n force: options.force,\n },\n client: getClient(),\n })\n );\n },\n\n async awaitJobs(jobIds: readonly string[], options?: AwaitJobsOptions) {\n // Poll through unwrapApiResult so HTTP failures throw ApiError with the\n // status code instead of the decoded response body.\n return pollJobs(\n jobIds,\n async (pendingJobIds, signal) =>\n unwrapApiResult(\n await getTranslationJobInfo({\n body: { jobIds: pendingJobIds },\n client: getClient(),\n signal,\n })\n ),\n options\n );\n },\n\n async enqueueFiles(\n files: EnqueueFileTranslationsData['body']['files'],\n options: {\n sourceLocale?: string;\n targetLocales: string[];\n modelProvider?: string;\n force?: boolean;\n }\n ) {\n const targetLocales = options.targetLocales.map((locale) =>\n resolveCanonicalLocale(locale, customMapping)\n );\n const result = await processBatches(files, async (batch) => {\n const response = unwrapApiResult(\n await enqueueFileTranslations({\n body: {\n files: batch.map(\n ({ branchId, fileId, versionId, fileName, transformFormat }) => ({\n branchId,\n fileId,\n versionId,\n fileName,\n transformFormat,\n })\n ),\n targetLocales,\n sourceLocale: options.sourceLocale\n ? resolveCanonicalLocale(options.sourceLocale, customMapping)\n : undefined,\n // The CLI intentionally accepts custom model-provider strings beyond\n // the OpenAPI ANTHROPIC|OPENAI|XAI|GOOGLE enum; preserve wire behavior.\n modelProvider:\n options.modelProvider as EnqueueFileTranslationsData['body']['modelProvider'],\n force: options.force,\n },\n client: getClient(),\n })\n );\n const jobData = 'jobData' in response ? response.jobData : response.data;\n return Object.entries(jobData);\n });\n\n return {\n jobData: Object.fromEntries(result),\n locales: targetLocales,\n message: `Successfully enqueued ${result.length} file translation jobs in ${Math.ceil(files.length / DEFAULT_BATCH_SIZE)} batch(es)`,\n };\n },\n\n async uploadSourceFiles(\n files: Array<{\n source: UploadSourceFilesData['body']['data'][number]['source'];\n }>,\n options: { sourceLocale: string }\n ) {\n const sourceLocale = resolveCanonicalLocale(\n options.sourceLocale,\n customMapping\n );\n const result = await processBatches(files, async (batch) => {\n const response = unwrapApiResult(\n await uploadSourceFiles({\n body: {\n data: batch.map(({ source }) => ({\n source: {\n ...source,\n content: encodeFileContent(source.content, source.fileFormat),\n locale: resolveCanonicalLocale(source.locale, customMapping),\n },\n })),\n sourceLocale,\n },\n client: getClient(),\n })\n );\n return response.uploadedFiles;\n });\n\n return { uploadedFiles: result };\n },\n\n async uploadTranslations(\n files: UploadTranslationsData['body']['data'],\n options: { sourceLocale: string }\n ) {\n const result = await processBatches(files, async (batch) => {\n const response = unwrapApiResult(\n await uploadTranslations({\n body: {\n data: batch.map(({ source, translations }) => ({\n source: {\n ...source,\n content: encodeFileContent(source.content, source.fileFormat),\n },\n translations: translations.map((translation) => ({\n ...translation,\n locale: resolveCanonicalLocale(\n translation.locale,\n customMapping\n ),\n content: encodeFileContent(\n translation.content,\n translation.fileFormat\n ),\n })),\n })),\n sourceLocale: resolveCanonicalLocale(\n options.sourceLocale,\n customMapping\n ),\n },\n client: getClient(),\n })\n );\n return response.uploadedFiles;\n });\n\n return { uploadedFiles: result };\n },\n};\n\nexport type ApiClient = typeof api;\n"],"mappings":"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"}
@@ -1,12 +1,6 @@
1
+ import type { DownloadMeta } from '../state/recentDownloads.js';
1
2
  import type { Settings } from '../types/index.js';
2
- type DownloadMeta = {
3
- branchId: string;
4
- fileId: string;
5
- versionId: string;
6
- locale: string;
7
- };
8
3
  /**
9
4
  * Persist postprocessed content hashes for recently downloaded files into gt-lock.json.
10
5
  */
11
6
  export declare function persistPostProcessHashes(settings: Settings, includeFiles: Set<string> | undefined, downloadedMeta: Map<string, DownloadMeta>): void;
12
- export {};
@@ -1,4 +1,9 @@
1
+ import { logger } from "../console/logger.js";
1
2
  import { hashStringSync } from "./hash.js";
3
+ import { getRelative } from "../fs/findFilepath.js";
4
+ import { fileEncodingSkipReason } from "../console/index.js";
5
+ import { readFileContent } from "../fs/fileContent.js";
6
+ import { recordWarning } from "../state/translateWarnings.js";
2
7
  import { findOrCreateEntry, readLockfile, writeLockfile } from "../fs/config/downloadedVersions.js";
3
8
  import * as fs$1 from "node:fs";
4
9
  //#region src/utils/persistPostprocessHashes.ts
@@ -18,7 +23,16 @@ function persistPostProcessHashes(settings, includeFiles, downloadedMeta) {
18
23
  const meta = downloadedMeta.get(filePath);
19
24
  if (!meta) continue;
20
25
  if (!fs$1.existsSync(filePath)) continue;
21
- const hash = hashStringSync(fs$1.readFileSync(filePath, "utf8"));
26
+ let hash;
27
+ try {
28
+ hash = hashStringSync(readFileContent(filePath, meta.fileFormat));
29
+ } catch (error) {
30
+ const relativePath = getRelative(filePath);
31
+ const reason = fileEncodingSkipReason(error);
32
+ logger.warn(`Skipping ${relativePath}: ${reason}`);
33
+ recordWarning("skipped_file", relativePath, reason);
34
+ continue;
35
+ }
22
36
  const entry = findOrCreateEntry(entryMap, data.entries, meta.fileId, meta.versionId);
23
37
  const existing = entry.translations[meta.locale] || {};
24
38
  if (existing.postProcessHash !== hash) {
@@ -1 +1 @@
1
- {"version":3,"file":"persistPostprocessHashes.js","names":["fs"],"sources":["../../src/utils/persistPostprocessHashes.ts"],"sourcesContent":["import * as fs from 'node:fs';\nimport {\n findOrCreateEntry,\n readLockfile,\n writeLockfile,\n} from '../fs/config/downloadedVersions.js';\nimport { hashStringSync } from './hash.js';\nimport type { Settings } from '../types/index.js';\n\ntype DownloadMeta = {\n branchId: string;\n fileId: string;\n versionId: string;\n locale: string;\n};\n\n/**\n * Persist postprocessed content hashes for recently downloaded files into gt-lock.json.\n */\nexport function persistPostProcessHashes(\n settings: Settings,\n includeFiles: Set<string> | undefined,\n downloadedMeta: Map<string, DownloadMeta>\n): void {\n if (!includeFiles || includeFiles.size === 0 || downloadedMeta.size === 0) {\n return;\n }\n\n const branchId = findDownloadedBranchId(includeFiles, downloadedMeta);\n if (!branchId) return;\n\n const { data, entryMap, originalV1 } = readLockfile({\n ...settings,\n _branchId: branchId,\n });\n let lockUpdated = false;\n\n for (const filePath of includeFiles) {\n const meta = downloadedMeta.get(filePath);\n if (!meta) continue;\n if (!fs.existsSync(filePath)) continue;\n\n const content = fs.readFileSync(filePath, 'utf8');\n const hash = hashStringSync(content);\n\n const entry = findOrCreateEntry(\n entryMap,\n data.entries,\n meta.fileId,\n meta.versionId\n );\n\n const existing = entry.translations[meta.locale] || {};\n\n if (existing.postProcessHash !== hash) {\n entry.translations[meta.locale] = {\n ...existing,\n postProcessHash: hash,\n };\n lockUpdated = true;\n }\n }\n\n if (lockUpdated) {\n writeLockfile(data, originalV1);\n }\n}\n\nfunction findDownloadedBranchId(\n includeFiles: Set<string>,\n downloadedMeta: Map<string, DownloadMeta>\n): string | undefined {\n for (const filePath of includeFiles) {\n const meta = downloadedMeta.get(filePath);\n if (meta) return meta.branchId;\n }\n return undefined;\n}\n"],"mappings":";;;;;;;AAmBA,SAAgB,yBACd,UACA,cACA,gBACM;AACN,KAAI,CAAC,gBAAgB,aAAa,SAAS,KAAK,eAAe,SAAS,EACtE;CAGF,MAAM,WAAW,uBAAuB,cAAc,eAAe;AACrE,KAAI,CAAC,SAAU;CAEf,MAAM,EAAE,MAAM,UAAU,eAAe,aAAa;EAClD,GAAG;EACH,WAAW;EACZ,CAAC;CACF,IAAI,cAAc;AAElB,MAAK,MAAM,YAAY,cAAc;EACnC,MAAM,OAAO,eAAe,IAAI,SAAS;AACzC,MAAI,CAAC,KAAM;AACX,MAAI,CAACA,KAAG,WAAW,SAAS,CAAE;EAG9B,MAAM,OAAO,eADGA,KAAG,aAAa,UAAU,OACP,CAAC;EAEpC,MAAM,QAAQ,kBACZ,UACA,KAAK,SACL,KAAK,QACL,KAAK,UACN;EAED,MAAM,WAAW,MAAM,aAAa,KAAK,WAAW,EAAE;AAEtD,MAAI,SAAS,oBAAoB,MAAM;AACrC,SAAM,aAAa,KAAK,UAAU;IAChC,GAAG;IACH,iBAAiB;IAClB;AACD,iBAAc;;;AAIlB,KAAI,YACF,eAAc,MAAM,WAAW;;AAInC,SAAS,uBACP,cACA,gBACoB;AACpB,MAAK,MAAM,YAAY,cAAc;EACnC,MAAM,OAAO,eAAe,IAAI,SAAS;AACzC,MAAI,KAAM,QAAO,KAAK"}
1
+ {"version":3,"file":"persistPostprocessHashes.js","names":["fs"],"sources":["../../src/utils/persistPostprocessHashes.ts"],"sourcesContent":["import * as fs from 'node:fs';\nimport {\n findOrCreateEntry,\n readLockfile,\n writeLockfile,\n} from '../fs/config/downloadedVersions.js';\nimport { hashStringSync } from './hash.js';\nimport { fileEncodingSkipReason } from '../console/index.js';\nimport { logger } from '../console/logger.js';\nimport { getRelative } from '../fs/findFilepath.js';\nimport { recordWarning } from '../state/translateWarnings.js';\nimport { readFileContent } from '../fs/fileContent.js';\nimport type { DownloadMeta } from '../state/recentDownloads.js';\nimport type { Settings } from '../types/index.js';\n\n/**\n * Persist postprocessed content hashes for recently downloaded files into gt-lock.json.\n */\nexport function persistPostProcessHashes(\n settings: Settings,\n includeFiles: Set<string> | undefined,\n downloadedMeta: Map<string, DownloadMeta>\n): void {\n if (!includeFiles || includeFiles.size === 0 || downloadedMeta.size === 0) {\n return;\n }\n\n const branchId = findDownloadedBranchId(includeFiles, downloadedMeta);\n if (!branchId) return;\n\n const { data, entryMap, originalV1 } = readLockfile({\n ...settings,\n _branchId: branchId,\n });\n let lockUpdated = false;\n\n for (const filePath of includeFiles) {\n const meta = downloadedMeta.get(filePath);\n if (!meta) continue;\n if (!fs.existsSync(filePath)) continue;\n\n // The hash stands for the file's pipeline content, which is what every\n // other producer and consumer of it compares against.\n let hash: string;\n try {\n hash = hashStringSync(readFileContent(filePath, meta.fileFormat));\n } catch (error) {\n // The translation is already written; failing here would lose the whole\n // run's lockfile update over one unreadable file. Skip it and report it\n const relativePath = getRelative(filePath);\n const reason = fileEncodingSkipReason(error);\n logger.warn(`Skipping ${relativePath}: ${reason}`);\n recordWarning('skipped_file', relativePath, reason);\n continue;\n }\n\n const entry = findOrCreateEntry(\n entryMap,\n data.entries,\n meta.fileId,\n meta.versionId\n );\n\n const existing = entry.translations[meta.locale] || {};\n\n if (existing.postProcessHash !== hash) {\n entry.translations[meta.locale] = {\n ...existing,\n postProcessHash: hash,\n };\n lockUpdated = true;\n }\n }\n\n if (lockUpdated) {\n writeLockfile(data, originalV1);\n }\n}\n\nfunction findDownloadedBranchId(\n includeFiles: Set<string>,\n downloadedMeta: Map<string, DownloadMeta>\n): string | undefined {\n for (const filePath of includeFiles) {\n const meta = downloadedMeta.get(filePath);\n if (meta) return meta.branchId;\n }\n return undefined;\n}\n"],"mappings":";;;;;;;;;;;;AAkBA,SAAgB,yBACd,UACA,cACA,gBACM;AACN,KAAI,CAAC,gBAAgB,aAAa,SAAS,KAAK,eAAe,SAAS,EACtE;CAGF,MAAM,WAAW,uBAAuB,cAAc,eAAe;AACrE,KAAI,CAAC,SAAU;CAEf,MAAM,EAAE,MAAM,UAAU,eAAe,aAAa;EAClD,GAAG;EACH,WAAW;EACZ,CAAC;CACF,IAAI,cAAc;AAElB,MAAK,MAAM,YAAY,cAAc;EACnC,MAAM,OAAO,eAAe,IAAI,SAAS;AACzC,MAAI,CAAC,KAAM;AACX,MAAI,CAACA,KAAG,WAAW,SAAS,CAAE;EAI9B,IAAI;AACJ,MAAI;AACF,UAAO,eAAe,gBAAgB,UAAU,KAAK,WAAW,CAAC;WAC1D,OAAO;GAGd,MAAM,eAAe,YAAY,SAAS;GAC1C,MAAM,SAAS,uBAAuB,MAAM;AAC5C,UAAO,KAAK,YAAY,aAAa,IAAI,SAAS;AAClD,iBAAc,gBAAgB,cAAc,OAAO;AACnD;;EAGF,MAAM,QAAQ,kBACZ,UACA,KAAK,SACL,KAAK,QACL,KAAK,UACN;EAED,MAAM,WAAW,MAAM,aAAa,KAAK,WAAW,EAAE;AAEtD,MAAI,SAAS,oBAAoB,MAAM;AACrC,SAAM,aAAa,KAAK,UAAU;IAChC,GAAG;IACH,iBAAiB;IAClB;AACD,iBAAc;;;AAIlB,KAAI,YACF,eAAc,MAAM,WAAW;;AAInC,SAAS,uBACP,cACA,gBACoB;AACpB,MAAK,MAAM,YAAY,cAAc;EACnC,MAAM,OAAO,eAAe,IAAI,SAAS;AACzC,MAAI,KAAM,QAAO,KAAK"}
@@ -1,7 +1,7 @@
1
1
  import { logger } from "../console/logger.js";
2
- import { gt } from "../utils/gt.js";
3
2
  import { logErrorAndExit } from "../console/logging.js";
4
3
  import { branchResolutionError } from "../console/index.js";
4
+ import { api } from "../utils/api.js";
5
5
  import { BranchStep } from "./steps/BranchStep.js";
6
6
  import { recordWarning } from "../state/translateWarnings.js";
7
7
  import { clearLocaleDirs } from "../fs/clearLocaleDirs.js";
@@ -24,7 +24,7 @@ import path from "node:path";
24
24
  */
25
25
  async function runDownloadWorkflow({ fileVersionData, jobData, branchData, locales, timeoutDuration, resolveOutputPath, options, inlineLibrary, forceRetranslation, forceDownload }) {
26
26
  if (!branchData) {
27
- const branchResult = await new BranchStep(gt, options).run();
27
+ const branchResult = await new BranchStep(api, options).run();
28
28
  if (!branchResult) return logErrorAndExit(branchResolutionError);
29
29
  branchData = branchResult;
30
30
  }
@@ -41,7 +41,7 @@ async function runDownloadWorkflow({ fileVersionData, jobData, branchData, local
41
41
  };
42
42
  let pollTimedOut = false;
43
43
  if (jobData) {
44
- const pollResult = await new PollTranslationJobsStep(gt, inlineLibrary).run({
44
+ const pollResult = await new PollTranslationJobsStep(api, inlineLibrary).run({
45
45
  fileTracker,
46
46
  fileQueryData,
47
47
  jobData,
@@ -65,7 +65,7 @@ async function runDownloadWorkflow({ fileVersionData, jobData, branchData, local
65
65
  resolveOutputPath,
66
66
  options
67
67
  });
68
- const downloadResult = await new DownloadTranslationsStep(gt, settingsForBranch, inlineLibrary).run({
68
+ const downloadResult = await new DownloadTranslationsStep(api, settingsForBranch, inlineLibrary).run({
69
69
  fileTracker,
70
70
  resolveOutputPath,
71
71
  forceDownload
@@ -1 +1 @@
1
- {"version":3,"file":"download.js","names":[],"sources":["../../src/workflows/download.ts"],"sourcesContent":["import path from 'node:path';\nimport { Settings } from '../types/index.js';\nimport { gt } from '../utils/gt.js';\nimport { EnqueueFilesResult } from 'generaltranslation/types';\nimport { clearLocaleDirs } from '../fs/clearLocaleDirs.js';\nimport {\n FileStatusTracker,\n PollTranslationJobsStep,\n} from './steps/PollJobsStep.js';\nimport { DownloadTranslationsStep } from './steps/DownloadStep.js';\nimport { BranchData } from '../types/branch.js';\nimport { branchResolutionError } from '../console/index.js';\nimport { logErrorAndExit } from '../console/logging.js';\nimport { logger } from '../console/logger.js';\nimport { recordWarning } from '../state/translateWarnings.js';\nimport { BranchStep } from './steps/BranchStep.js';\nimport { FileProperties } from '../types/files.js';\nimport chalk from 'chalk';\nimport type { InlineLibrary } from '../types/libraries.js';\n\nexport type FileTranslationData = {\n [fileId: string]: {\n versionId: string;\n fileName: string;\n /** Source component count for GTJSON files */\n componentCount?: number;\n };\n};\n\n/**\n * Checks the status of translations and downloads them using a workflow pattern\n * @param fileVersionData - Mapping of file IDs to their version and name information\n * @param jobData - Optional job data from enqueue operation\n * @param locales - The locales to wait for\n * @param timeoutDuration - The timeout duration for the wait in seconds\n * @param resolveOutputPath - Function to resolve the output path for a given source path and locale\n * @param options - Settings configuration\n * @param forceRetranslation - Whether to force retranslation\n * @param forceDownload - Whether to force download even if file exists\n * @returns True if all translations are downloaded successfully, false otherwise\n */\nexport async function runDownloadWorkflow({\n fileVersionData,\n jobData,\n branchData,\n locales,\n timeoutDuration,\n resolveOutputPath,\n options,\n inlineLibrary,\n forceRetranslation,\n forceDownload,\n}: {\n fileVersionData: FileTranslationData;\n jobData: EnqueueFilesResult | undefined;\n branchData: BranchData | undefined;\n locales: string[];\n timeoutDuration: number;\n resolveOutputPath: (sourcePath: string, locale: string) => string | null;\n options: Settings;\n inlineLibrary?: InlineLibrary;\n forceRetranslation?: boolean;\n forceDownload?: boolean;\n}): Promise<boolean> {\n if (!branchData) {\n // Run the branch step\n const branchStep = new BranchStep(gt, options);\n const branchResult = await branchStep.run();\n if (!branchResult) {\n return logErrorAndExit(branchResolutionError);\n }\n branchData = branchResult;\n }\n // readLockfile uses _branchId to select branch-specific lockfile entries.\n // Keep it on a scoped copy so the caller's settings object is not mutated.\n const settingsForBranch: Settings = {\n ...options,\n _branchId: branchData.currentBranch.id,\n };\n // Prepare the query data\n const fileQueryData = prepareFileQueryData(\n fileVersionData,\n locales,\n branchData\n );\n\n // Initialize download status\n const fileTracker: FileStatusTracker = {\n completed: new Map<string, FileProperties>(),\n inProgress: new Map<string, FileProperties>(),\n failed: new Map<string, FileProperties>(),\n skipped: new Map<string, FileProperties>(),\n };\n\n // Step 1: Poll translation jobs if jobData exists\n let pollTimedOut = false;\n if (jobData) {\n const pollStep = new PollTranslationJobsStep(gt, inlineLibrary);\n const pollResult = await pollStep.run({\n fileTracker,\n fileQueryData,\n jobData,\n timeoutDuration,\n forceRetranslation,\n });\n\n if (pollResult.fileTracker.failed.size > 0) {\n logger.error(\n `${chalk.red(`${pollResult.fileTracker.failed.size} file(s) failed to translate:`)}\\n${Array.from(\n pollResult.fileTracker.failed.entries()\n )\n .map(([, value]) => `- ${value.fileName}`)\n .join('\\n')}`\n );\n for (const [, value] of pollResult.fileTracker.failed) {\n recordWarning(\n 'failed_translation',\n value.fileName,\n `Failed to translate for locale ${value.locale}`\n );\n }\n\n // If all files failed translation, exit early\n if (pollResult.fileTracker.completed.size === 0) {\n return false;\n }\n }\n\n // Even if polling timed out, still download whatever completed successfully\n if (!pollResult.success) {\n pollTimedOut = true;\n if (pollResult.fileTracker.completed.size > 0) {\n logger.warn(\n chalk.yellow(\n `Timed out, but ${pollResult.fileTracker.completed.size} translation(s) completed successfully. Downloading completed files...`\n )\n );\n } else {\n return false;\n }\n }\n } else {\n for (const file of fileQueryData) {\n // Staging - assume all files are completed\n fileTracker.completed.set(\n `${file.branchId}:${file.fileId}:${file.versionId}:${file.locale}`,\n file\n );\n }\n }\n\n await clearCompletedLocaleDirs({\n fileTracker,\n locales,\n resolveOutputPath,\n options,\n });\n\n // Step 2: Download translations\n const downloadStep = new DownloadTranslationsStep(\n gt,\n settingsForBranch,\n inlineLibrary\n );\n const downloadResult = await downloadStep.run({\n fileTracker,\n resolveOutputPath,\n forceDownload,\n });\n\n // If polling timed out, report failure even though we downloaded what we could\n if (pollTimedOut) {\n return false;\n }\n\n return downloadResult;\n}\n\nasync function clearCompletedLocaleDirs({\n fileTracker,\n locales,\n resolveOutputPath,\n options,\n}: {\n fileTracker: FileStatusTracker;\n locales: string[];\n resolveOutputPath: (sourcePath: string, locale: string) => string | null;\n options: Settings;\n}): Promise<void> {\n if (\n options.options?.experimentalClearLocaleDirs !== true ||\n fileTracker.completed.size === 0\n ) {\n return;\n }\n\n const translatedFiles = new Set(\n Array.from(fileTracker.completed.values())\n .map((file) => {\n const outputPath = resolveOutputPath(file.fileName, file.locale);\n // Only clear if the output path is different from the source.\n return outputPath !== null && outputPath !== file.fileName\n ? outputPath\n : null;\n })\n .filter((filePath): filePath is string => filePath !== null)\n );\n\n if (translatedFiles.size === 0) return;\n\n const cwd = path.dirname(options.config);\n\n await clearLocaleDirs(\n translatedFiles,\n locales,\n options.options?.clearLocaleDirsExclude,\n cwd\n );\n}\n\n/**\n * Prepares the file query data from input data and locales\n */\nfunction prepareFileQueryData(\n fileVersionData: FileTranslationData,\n locales: string[],\n branchData: BranchData\n): FileProperties[] {\n const fileQueryData: FileProperties[] = [];\n\n for (const fileId in fileVersionData) {\n for (const locale of locales) {\n fileQueryData.push({\n versionId: fileVersionData[fileId].versionId,\n fileName: fileVersionData[fileId].fileName,\n fileId,\n locale,\n branchId: branchData.currentBranch.id,\n componentCount: fileVersionData[fileId].componentCount,\n });\n }\n }\n\n return fileQueryData;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAyCA,eAAsB,oBAAoB,EACxC,iBACA,SACA,YACA,SACA,iBACA,mBACA,SACA,eACA,oBACA,iBAYmB;AACnB,KAAI,CAAC,YAAY;EAGf,MAAM,eAAe,MAAM,IADJ,WAAW,IAAI,QACD,CAAC,KAAK;AAC3C,MAAI,CAAC,aACH,QAAO,gBAAgB,sBAAsB;AAE/C,eAAa;;CAIf,MAAM,oBAA8B;EAClC,GAAG;EACH,WAAW,WAAW,cAAc;EACrC;CAED,MAAM,gBAAgB,qBACpB,iBACA,SACA,WACD;CAGD,MAAM,cAAiC;EACrC,2BAAW,IAAI,KAA6B;EAC5C,4BAAY,IAAI,KAA6B;EAC7C,wBAAQ,IAAI,KAA6B;EACzC,yBAAS,IAAI,KAA6B;EAC3C;CAGD,IAAI,eAAe;AACnB,KAAI,SAAS;EAEX,MAAM,aAAa,MAAM,IADJ,wBAAwB,IAAI,cAChB,CAAC,IAAI;GACpC;GACA;GACA;GACA;GACA;GACD,CAAC;AAEF,MAAI,WAAW,YAAY,OAAO,OAAO,GAAG;AAC1C,UAAO,MACL,GAAG,MAAM,IAAI,GAAG,WAAW,YAAY,OAAO,KAAK,+BAA+B,CAAC,IAAI,MAAM,KAC3F,WAAW,YAAY,OAAO,SAAS,CACxC,CACE,KAAK,GAAG,WAAW,KAAK,MAAM,WAAW,CACzC,KAAK,KAAK,GACd;AACD,QAAK,MAAM,GAAG,UAAU,WAAW,YAAY,OAC7C,eACE,sBACA,MAAM,UACN,kCAAkC,MAAM,SACzC;AAIH,OAAI,WAAW,YAAY,UAAU,SAAS,EAC5C,QAAO;;AAKX,MAAI,CAAC,WAAW,SAAS;AACvB,kBAAe;AACf,OAAI,WAAW,YAAY,UAAU,OAAO,EAC1C,QAAO,KACL,MAAM,OACJ,kBAAkB,WAAW,YAAY,UAAU,KAAK,wEACzD,CACF;OAED,QAAO;;OAIX,MAAK,MAAM,QAAQ,cAEjB,aAAY,UAAU,IACpB,GAAG,KAAK,SAAS,GAAG,KAAK,OAAO,GAAG,KAAK,UAAU,GAAG,KAAK,UAC1D,KACD;AAIL,OAAM,yBAAyB;EAC7B;EACA;EACA;EACA;EACD,CAAC;CAQF,MAAM,iBAAiB,MAAM,IALJ,yBACvB,IACA,mBACA,cAEuC,CAAC,IAAI;EAC5C;EACA;EACA;EACD,CAAC;AAGF,KAAI,aACF,QAAO;AAGT,QAAO;;AAGT,eAAe,yBAAyB,EACtC,aACA,SACA,mBACA,WAMgB;AAChB,KACE,QAAQ,SAAS,gCAAgC,QACjD,YAAY,UAAU,SAAS,EAE/B;CAGF,MAAM,kBAAkB,IAAI,IAC1B,MAAM,KAAK,YAAY,UAAU,QAAQ,CAAC,CACvC,KAAK,SAAS;EACb,MAAM,aAAa,kBAAkB,KAAK,UAAU,KAAK,OAAO;AAEhE,SAAO,eAAe,QAAQ,eAAe,KAAK,WAC9C,aACA;GACJ,CACD,QAAQ,aAAiC,aAAa,KAAK,CAC/D;AAED,KAAI,gBAAgB,SAAS,EAAG;CAEhC,MAAM,MAAM,KAAK,QAAQ,QAAQ,OAAO;AAExC,OAAM,gBACJ,iBACA,SACA,QAAQ,SAAS,wBACjB,IACD;;;;;AAMH,SAAS,qBACP,iBACA,SACA,YACkB;CAClB,MAAM,gBAAkC,EAAE;AAE1C,MAAK,MAAM,UAAU,gBACnB,MAAK,MAAM,UAAU,QACnB,eAAc,KAAK;EACjB,WAAW,gBAAgB,QAAQ;EACnC,UAAU,gBAAgB,QAAQ;EAClC;EACA;EACA,UAAU,WAAW,cAAc;EACnC,gBAAgB,gBAAgB,QAAQ;EACzC,CAAC;AAIN,QAAO"}
1
+ {"version":3,"file":"download.js","names":[],"sources":["../../src/workflows/download.ts"],"sourcesContent":["import path from 'node:path';\nimport { Settings } from '../types/index.js';\nimport { api } from '../utils/api.js';\nimport { EnqueueFilesResult } from 'generaltranslation/types';\nimport { clearLocaleDirs } from '../fs/clearLocaleDirs.js';\nimport {\n FileStatusTracker,\n PollTranslationJobsStep,\n} from './steps/PollJobsStep.js';\nimport { DownloadTranslationsStep } from './steps/DownloadStep.js';\nimport { BranchData } from '../types/branch.js';\nimport { branchResolutionError } from '../console/index.js';\nimport { logErrorAndExit } from '../console/logging.js';\nimport { logger } from '../console/logger.js';\nimport { recordWarning } from '../state/translateWarnings.js';\nimport { BranchStep } from './steps/BranchStep.js';\nimport { FileProperties } from '../types/files.js';\nimport chalk from 'chalk';\nimport type { InlineLibrary } from '../types/libraries.js';\n\nexport type FileTranslationData = {\n [fileId: string]: {\n versionId: string;\n fileName: string;\n /** Source component count for GTJSON files */\n componentCount?: number;\n };\n};\n\n/**\n * Checks the status of translations and downloads them using a workflow pattern\n * @param fileVersionData - Mapping of file IDs to their version and name information\n * @param jobData - Optional job data from enqueue operation\n * @param locales - The locales to wait for\n * @param timeoutDuration - The timeout duration for the wait in seconds\n * @param resolveOutputPath - Function to resolve the output path for a given source path and locale\n * @param options - Settings configuration\n * @param forceRetranslation - Whether to force retranslation\n * @param forceDownload - Whether to force download even if file exists\n * @returns True if all translations are downloaded successfully, false otherwise\n */\nexport async function runDownloadWorkflow({\n fileVersionData,\n jobData,\n branchData,\n locales,\n timeoutDuration,\n resolveOutputPath,\n options,\n inlineLibrary,\n forceRetranslation,\n forceDownload,\n}: {\n fileVersionData: FileTranslationData;\n jobData: EnqueueFilesResult | undefined;\n branchData: BranchData | undefined;\n locales: string[];\n timeoutDuration: number;\n resolveOutputPath: (sourcePath: string, locale: string) => string | null;\n options: Settings;\n inlineLibrary?: InlineLibrary;\n forceRetranslation?: boolean;\n forceDownload?: boolean;\n}): Promise<boolean> {\n if (!branchData) {\n // Run the branch step\n const branchStep = new BranchStep(api, options);\n const branchResult = await branchStep.run();\n if (!branchResult) {\n return logErrorAndExit(branchResolutionError);\n }\n branchData = branchResult;\n }\n // readLockfile uses _branchId to select branch-specific lockfile entries.\n // Keep it on a scoped copy so the caller's settings object is not mutated.\n const settingsForBranch: Settings = {\n ...options,\n _branchId: branchData.currentBranch.id,\n };\n // Prepare the query data\n const fileQueryData = prepareFileQueryData(\n fileVersionData,\n locales,\n branchData\n );\n\n // Initialize download status\n const fileTracker: FileStatusTracker = {\n completed: new Map<string, FileProperties>(),\n inProgress: new Map<string, FileProperties>(),\n failed: new Map<string, FileProperties>(),\n skipped: new Map<string, FileProperties>(),\n };\n\n // Step 1: Poll translation jobs if jobData exists\n let pollTimedOut = false;\n if (jobData) {\n const pollStep = new PollTranslationJobsStep(api, inlineLibrary);\n const pollResult = await pollStep.run({\n fileTracker,\n fileQueryData,\n jobData,\n timeoutDuration,\n forceRetranslation,\n });\n\n if (pollResult.fileTracker.failed.size > 0) {\n logger.error(\n `${chalk.red(`${pollResult.fileTracker.failed.size} file(s) failed to translate:`)}\\n${Array.from(\n pollResult.fileTracker.failed.entries()\n )\n .map(([, value]) => `- ${value.fileName}`)\n .join('\\n')}`\n );\n for (const [, value] of pollResult.fileTracker.failed) {\n recordWarning(\n 'failed_translation',\n value.fileName,\n `Failed to translate for locale ${value.locale}`\n );\n }\n\n // If all files failed translation, exit early\n if (pollResult.fileTracker.completed.size === 0) {\n return false;\n }\n }\n\n // Even if polling timed out, still download whatever completed successfully\n if (!pollResult.success) {\n pollTimedOut = true;\n if (pollResult.fileTracker.completed.size > 0) {\n logger.warn(\n chalk.yellow(\n `Timed out, but ${pollResult.fileTracker.completed.size} translation(s) completed successfully. Downloading completed files...`\n )\n );\n } else {\n return false;\n }\n }\n } else {\n for (const file of fileQueryData) {\n // Staging - assume all files are completed\n fileTracker.completed.set(\n `${file.branchId}:${file.fileId}:${file.versionId}:${file.locale}`,\n file\n );\n }\n }\n\n await clearCompletedLocaleDirs({\n fileTracker,\n locales,\n resolveOutputPath,\n options,\n });\n\n // Step 2: Download translations\n const downloadStep = new DownloadTranslationsStep(\n api,\n settingsForBranch,\n inlineLibrary\n );\n const downloadResult = await downloadStep.run({\n fileTracker,\n resolveOutputPath,\n forceDownload,\n });\n\n // If polling timed out, report failure even though we downloaded what we could\n if (pollTimedOut) {\n return false;\n }\n\n return downloadResult;\n}\n\nasync function clearCompletedLocaleDirs({\n fileTracker,\n locales,\n resolveOutputPath,\n options,\n}: {\n fileTracker: FileStatusTracker;\n locales: string[];\n resolveOutputPath: (sourcePath: string, locale: string) => string | null;\n options: Settings;\n}): Promise<void> {\n if (\n options.options?.experimentalClearLocaleDirs !== true ||\n fileTracker.completed.size === 0\n ) {\n return;\n }\n\n const translatedFiles = new Set(\n Array.from(fileTracker.completed.values())\n .map((file) => {\n const outputPath = resolveOutputPath(file.fileName, file.locale);\n // Only clear if the output path is different from the source.\n return outputPath !== null && outputPath !== file.fileName\n ? outputPath\n : null;\n })\n .filter((filePath): filePath is string => filePath !== null)\n );\n\n if (translatedFiles.size === 0) return;\n\n const cwd = path.dirname(options.config);\n\n await clearLocaleDirs(\n translatedFiles,\n locales,\n options.options?.clearLocaleDirsExclude,\n cwd\n );\n}\n\n/**\n * Prepares the file query data from input data and locales\n */\nfunction prepareFileQueryData(\n fileVersionData: FileTranslationData,\n locales: string[],\n branchData: BranchData\n): FileProperties[] {\n const fileQueryData: FileProperties[] = [];\n\n for (const fileId in fileVersionData) {\n for (const locale of locales) {\n fileQueryData.push({\n versionId: fileVersionData[fileId].versionId,\n fileName: fileVersionData[fileId].fileName,\n fileId,\n locale,\n branchId: branchData.currentBranch.id,\n componentCount: fileVersionData[fileId].componentCount,\n });\n }\n }\n\n return fileQueryData;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAyCA,eAAsB,oBAAoB,EACxC,iBACA,SACA,YACA,SACA,iBACA,mBACA,SACA,eACA,oBACA,iBAYmB;AACnB,KAAI,CAAC,YAAY;EAGf,MAAM,eAAe,MAAM,IADJ,WAAW,KAAK,QACF,CAAC,KAAK;AAC3C,MAAI,CAAC,aACH,QAAO,gBAAgB,sBAAsB;AAE/C,eAAa;;CAIf,MAAM,oBAA8B;EAClC,GAAG;EACH,WAAW,WAAW,cAAc;EACrC;CAED,MAAM,gBAAgB,qBACpB,iBACA,SACA,WACD;CAGD,MAAM,cAAiC;EACrC,2BAAW,IAAI,KAA6B;EAC5C,4BAAY,IAAI,KAA6B;EAC7C,wBAAQ,IAAI,KAA6B;EACzC,yBAAS,IAAI,KAA6B;EAC3C;CAGD,IAAI,eAAe;AACnB,KAAI,SAAS;EAEX,MAAM,aAAa,MAAM,IADJ,wBAAwB,KAAK,cACjB,CAAC,IAAI;GACpC;GACA;GACA;GACA;GACA;GACD,CAAC;AAEF,MAAI,WAAW,YAAY,OAAO,OAAO,GAAG;AAC1C,UAAO,MACL,GAAG,MAAM,IAAI,GAAG,WAAW,YAAY,OAAO,KAAK,+BAA+B,CAAC,IAAI,MAAM,KAC3F,WAAW,YAAY,OAAO,SAAS,CACxC,CACE,KAAK,GAAG,WAAW,KAAK,MAAM,WAAW,CACzC,KAAK,KAAK,GACd;AACD,QAAK,MAAM,GAAG,UAAU,WAAW,YAAY,OAC7C,eACE,sBACA,MAAM,UACN,kCAAkC,MAAM,SACzC;AAIH,OAAI,WAAW,YAAY,UAAU,SAAS,EAC5C,QAAO;;AAKX,MAAI,CAAC,WAAW,SAAS;AACvB,kBAAe;AACf,OAAI,WAAW,YAAY,UAAU,OAAO,EAC1C,QAAO,KACL,MAAM,OACJ,kBAAkB,WAAW,YAAY,UAAU,KAAK,wEACzD,CACF;OAED,QAAO;;OAIX,MAAK,MAAM,QAAQ,cAEjB,aAAY,UAAU,IACpB,GAAG,KAAK,SAAS,GAAG,KAAK,OAAO,GAAG,KAAK,UAAU,GAAG,KAAK,UAC1D,KACD;AAIL,OAAM,yBAAyB;EAC7B;EACA;EACA;EACA;EACD,CAAC;CAQF,MAAM,iBAAiB,MAAM,IALJ,yBACvB,KACA,mBACA,cAEuC,CAAC,IAAI;EAC5C;EACA;EACA;EACD,CAAC;AAGF,KAAI,aACF,QAAO;AAGT,QAAO;;AAGT,eAAe,yBAAyB,EACtC,aACA,SACA,mBACA,WAMgB;AAChB,KACE,QAAQ,SAAS,gCAAgC,QACjD,YAAY,UAAU,SAAS,EAE/B;CAGF,MAAM,kBAAkB,IAAI,IAC1B,MAAM,KAAK,YAAY,UAAU,QAAQ,CAAC,CACvC,KAAK,SAAS;EACb,MAAM,aAAa,kBAAkB,KAAK,UAAU,KAAK,OAAO;AAEhE,SAAO,eAAe,QAAQ,eAAe,KAAK,WAC9C,aACA;GACJ,CACD,QAAQ,aAAiC,aAAa,KAAK,CAC/D;AAED,KAAI,gBAAgB,SAAS,EAAG;CAEhC,MAAM,MAAM,KAAK,QAAQ,QAAQ,OAAO;AAExC,OAAM,gBACJ,iBACA,SACA,QAAQ,SAAS,wBACjB,IACD;;;;;AAMH,SAAS,qBACP,iBACA,SACA,YACkB;CAClB,MAAM,gBAAkC,EAAE;AAE1C,MAAK,MAAM,UAAU,gBACnB,MAAK,MAAM,UAAU,QACnB,eAAc,KAAK;EACjB,WAAW,gBAAgB,QAAQ;EACnC,UAAU,gBAAgB,QAAQ;EAClC;EACA;EACA,UAAU,WAAW,cAAc;EACnC,gBAAgB,gBAAgB,QAAQ;EACzC,CAAC;AAIN,QAAO"}
@@ -1,7 +1,7 @@
1
1
  import { logger } from "../console/logger.js";
2
- import { gt } from "../utils/gt.js";
3
2
  import { logCollectedFiles, logErrorAndExit } from "../console/logging.js";
4
3
  import { branchResolutionError, withOriginalError } from "../console/index.js";
4
+ import { api } from "../utils/api.js";
5
5
  import { syncFonts } from "./utils/syncFonts.js";
6
6
  import { BranchStep } from "./steps/BranchStep.js";
7
7
  import { EnqueueStep } from "./steps/EnqueueStep.js";
@@ -22,13 +22,13 @@ async function runEnqueueWorkflow({ files, options, settings, inlineLibrary }) {
22
22
  logCollectedFiles(files, void 0, inlineLibrary);
23
23
  logger.debug("Files: " + JSON.stringify(files, null, 2));
24
24
  await syncFonts(settings);
25
- const branchStep = new BranchStep(gt, settings);
26
- const enqueueStep = new EnqueueStep(gt, settings, options.force);
25
+ const branchStep = new BranchStep(api, settings);
26
+ const enqueueStep = new EnqueueStep(api, settings, options.force);
27
27
  const branchData = await branchStep.run();
28
28
  if (!branchData) return logErrorAndExit(branchResolutionError);
29
29
  logger.debug("Branch data: " + JSON.stringify(branchData, null, 2));
30
30
  const { filesToEnqueue, skippedFiles } = await filterFilesForEnqueue({
31
- gt,
31
+ gt: api,
32
32
  files: files.map((files) => ({
33
33
  branchId: branchData.currentBranch.id,
34
34
  ...files
@@ -1 +1 @@
1
- {"version":3,"file":"enqueue.js","names":[],"sources":["../../src/workflows/enqueue.ts"],"sourcesContent":["import { logCollectedFiles, logErrorAndExit } from '../console/logging.js';\nimport { branchResolutionError, withOriginalError } from '../console/index.js';\nimport { Settings, TranslateFlags } from '../types/index.js';\nimport { gt } from '../utils/gt.js';\nimport { EnqueueFilesResult, FileToUpload } from 'generaltranslation/types';\nimport { EnqueueStep } from './steps/EnqueueStep.js';\nimport { BranchStep } from './steps/BranchStep.js';\nimport { logger } from '../console/logger.js';\nimport { filterFilesForEnqueue } from './utils/filterFilesForEnqueue.js';\nimport { syncFonts } from './utils/syncFonts.js';\nimport type { InlineLibrary } from '../types/libraries.js';\n\n/**\n * Enqueues translations for a given set of files\n * - Only enqueues uploaded files\n * - Don't have to worry about double enqueuing files because dedupe on API side\n *\n * @param {FileTranslationData} fileVersionData - The file version data\n * @param {TranslateFlags} options - The options for the enqueue operation\n * @param {Settings} settings - The settings for the enqueue operation\n * @returns {Promise<EnqueueFilesResult>} The enqueue result\n */\nexport async function runEnqueueWorkflow({\n files,\n options,\n settings,\n inlineLibrary,\n}: {\n files: FileToUpload[];\n options: TranslateFlags;\n settings: Settings;\n inlineLibrary?: InlineLibrary;\n}): Promise<EnqueueFilesResult> {\n try {\n // Log files to be enqueued\n logCollectedFiles(files, undefined, inlineLibrary);\n\n logger.debug('Files: ' + JSON.stringify(files, null, 2));\n\n // Sync fonts before enqueueing so the translation jobs (e.g. Lottie\n // layout refinement) can use them instead of fallback fonts.\n await syncFonts(settings);\n\n // Create workflow with steps\n const branchStep = new BranchStep(gt, settings);\n // const queryFileDataStep = new QueryFileDataStep(gt);\n const enqueueStep = new EnqueueStep(gt, settings, options.force);\n\n // (1) run the branch step\n const branchData = await branchStep.run();\n if (!branchData) {\n return logErrorAndExit(branchResolutionError);\n }\n logger.debug('Branch data: ' + JSON.stringify(branchData, null, 2));\n\n // (2) Enqueue the files\n const filesWithBranch = files.map((files) => ({\n branchId: branchData.currentBranch.id,\n ...files,\n }));\n const { filesToEnqueue, skippedFiles } = await filterFilesForEnqueue({\n gt,\n files: filesWithBranch,\n locales: settings.locales,\n force: options.force,\n });\n if (skippedFiles.length > 0) {\n logger.info(\n `Skipped enqueue for ${skippedFiles.length} already translated file${skippedFiles.length === 1 ? '' : 's'}`\n );\n }\n\n const enqueueResult = await enqueueStep.run(filesToEnqueue);\n\n logger.debug('Enqueue result: ' + JSON.stringify(enqueueResult, null, 2));\n\n logEnqueueResult(\n enqueueResult,\n filesToEnqueue.length === 0 ? files.length : filesToEnqueue.length\n );\n return enqueueResult;\n } catch (error) {\n return logErrorAndExit(\n withOriginalError(\n 'Translations could not be enqueued. Check the files, branch configuration, and API credentials, then try again.',\n error\n )\n );\n }\n}\n\n// ----- Helper functions ----- //\n\n/**\n * Logs the enqueue result\n * @param enqueueResult - The enqueue result\n * @returns void\n */\nfunction logEnqueueResult(\n enqueueResult: EnqueueFilesResult,\n fileCount: number\n): void {\n if (Object.keys(enqueueResult.jobData).length === 0) {\n logger.success(\n `All ${fileCount} ${fileCount === 1 ? 'file' : 'files'} already translated. 0 files enqueued.`\n );\n } else {\n logger.success(enqueueResult.message);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAsBA,eAAsB,mBAAmB,EACvC,OACA,SACA,UACA,iBAM8B;AAC9B,KAAI;AAEF,oBAAkB,OAAO,KAAA,GAAW,cAAc;AAElD,SAAO,MAAM,YAAY,KAAK,UAAU,OAAO,MAAM,EAAE,CAAC;AAIxD,QAAM,UAAU,SAAS;EAGzB,MAAM,aAAa,IAAI,WAAW,IAAI,SAAS;EAE/C,MAAM,cAAc,IAAI,YAAY,IAAI,UAAU,QAAQ,MAAM;EAGhE,MAAM,aAAa,MAAM,WAAW,KAAK;AACzC,MAAI,CAAC,WACH,QAAO,gBAAgB,sBAAsB;AAE/C,SAAO,MAAM,kBAAkB,KAAK,UAAU,YAAY,MAAM,EAAE,CAAC;EAOnE,MAAM,EAAE,gBAAgB,iBAAiB,MAAM,sBAAsB;GACnE;GACA,OANsB,MAAM,KAAK,WAAW;IAC5C,UAAU,WAAW,cAAc;IACnC,GAAG;IACJ,EAGuB;GACtB,SAAS,SAAS;GAClB,OAAO,QAAQ;GAChB,CAAC;AACF,MAAI,aAAa,SAAS,EACxB,QAAO,KACL,uBAAuB,aAAa,OAAO,0BAA0B,aAAa,WAAW,IAAI,KAAK,MACvG;EAGH,MAAM,gBAAgB,MAAM,YAAY,IAAI,eAAe;AAE3D,SAAO,MAAM,qBAAqB,KAAK,UAAU,eAAe,MAAM,EAAE,CAAC;AAEzE,mBACE,eACA,eAAe,WAAW,IAAI,MAAM,SAAS,eAAe,OAC7D;AACD,SAAO;UACA,OAAO;AACd,SAAO,gBACL,kBACE,mHACA,MACD,CACF;;;;;;;;AAWL,SAAS,iBACP,eACA,WACM;AACN,KAAI,OAAO,KAAK,cAAc,QAAQ,CAAC,WAAW,EAChD,QAAO,QACL,OAAO,UAAU,GAAG,cAAc,IAAI,SAAS,QAAQ,wCACxD;KAED,QAAO,QAAQ,cAAc,QAAQ"}
1
+ {"version":3,"file":"enqueue.js","names":[],"sources":["../../src/workflows/enqueue.ts"],"sourcesContent":["import { logCollectedFiles, logErrorAndExit } from '../console/logging.js';\nimport { branchResolutionError, withOriginalError } from '../console/index.js';\nimport { Settings, TranslateFlags } from '../types/index.js';\nimport { api } from '../utils/api.js';\nimport { EnqueueFilesResult, FileToUpload } from 'generaltranslation/types';\nimport { EnqueueStep } from './steps/EnqueueStep.js';\nimport { BranchStep } from './steps/BranchStep.js';\nimport { logger } from '../console/logger.js';\nimport { filterFilesForEnqueue } from './utils/filterFilesForEnqueue.js';\nimport { syncFonts } from './utils/syncFonts.js';\nimport type { InlineLibrary } from '../types/libraries.js';\n\n/**\n * Enqueues translations for a given set of files\n * - Only enqueues uploaded files\n * - Don't have to worry about double enqueuing files because dedupe on API side\n *\n * @param {FileTranslationData} fileVersionData - The file version data\n * @param {TranslateFlags} options - The options for the enqueue operation\n * @param {Settings} settings - The settings for the enqueue operation\n * @returns {Promise<EnqueueFilesResult>} The enqueue result\n */\nexport async function runEnqueueWorkflow({\n files,\n options,\n settings,\n inlineLibrary,\n}: {\n files: FileToUpload[];\n options: TranslateFlags;\n settings: Settings;\n inlineLibrary?: InlineLibrary;\n}): Promise<EnqueueFilesResult> {\n try {\n // Log files to be enqueued\n logCollectedFiles(files, undefined, inlineLibrary);\n\n logger.debug('Files: ' + JSON.stringify(files, null, 2));\n\n // Sync fonts before enqueueing so the translation jobs (e.g. Lottie\n // layout refinement) can use them instead of fallback fonts.\n await syncFonts(settings);\n\n // Create workflow with steps\n const branchStep = new BranchStep(api, settings);\n // const queryFileDataStep = new QueryFileDataStep(gt);\n const enqueueStep = new EnqueueStep(api, settings, options.force);\n\n // (1) run the branch step\n const branchData = await branchStep.run();\n if (!branchData) {\n return logErrorAndExit(branchResolutionError);\n }\n logger.debug('Branch data: ' + JSON.stringify(branchData, null, 2));\n\n // (2) Enqueue the files\n const filesWithBranch = files.map((files) => ({\n branchId: branchData.currentBranch.id,\n ...files,\n }));\n const { filesToEnqueue, skippedFiles } = await filterFilesForEnqueue({\n gt: api,\n files: filesWithBranch,\n locales: settings.locales,\n force: options.force,\n });\n if (skippedFiles.length > 0) {\n logger.info(\n `Skipped enqueue for ${skippedFiles.length} already translated file${skippedFiles.length === 1 ? '' : 's'}`\n );\n }\n\n const enqueueResult = await enqueueStep.run(filesToEnqueue);\n\n logger.debug('Enqueue result: ' + JSON.stringify(enqueueResult, null, 2));\n\n logEnqueueResult(\n enqueueResult,\n filesToEnqueue.length === 0 ? files.length : filesToEnqueue.length\n );\n return enqueueResult;\n } catch (error) {\n return logErrorAndExit(\n withOriginalError(\n 'Translations could not be enqueued. Check the files, branch configuration, and API credentials, then try again.',\n error\n )\n );\n }\n}\n\n// ----- Helper functions ----- //\n\n/**\n * Logs the enqueue result\n * @param enqueueResult - The enqueue result\n * @returns void\n */\nfunction logEnqueueResult(\n enqueueResult: EnqueueFilesResult,\n fileCount: number\n): void {\n if (Object.keys(enqueueResult.jobData).length === 0) {\n logger.success(\n `All ${fileCount} ${fileCount === 1 ? 'file' : 'files'} already translated. 0 files enqueued.`\n );\n } else {\n logger.success(enqueueResult.message);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAsBA,eAAsB,mBAAmB,EACvC,OACA,SACA,UACA,iBAM8B;AAC9B,KAAI;AAEF,oBAAkB,OAAO,KAAA,GAAW,cAAc;AAElD,SAAO,MAAM,YAAY,KAAK,UAAU,OAAO,MAAM,EAAE,CAAC;AAIxD,QAAM,UAAU,SAAS;EAGzB,MAAM,aAAa,IAAI,WAAW,KAAK,SAAS;EAEhD,MAAM,cAAc,IAAI,YAAY,KAAK,UAAU,QAAQ,MAAM;EAGjE,MAAM,aAAa,MAAM,WAAW,KAAK;AACzC,MAAI,CAAC,WACH,QAAO,gBAAgB,sBAAsB;AAE/C,SAAO,MAAM,kBAAkB,KAAK,UAAU,YAAY,MAAM,EAAE,CAAC;EAOnE,MAAM,EAAE,gBAAgB,iBAAiB,MAAM,sBAAsB;GACnE,IAAI;GACJ,OANsB,MAAM,KAAK,WAAW;IAC5C,UAAU,WAAW,cAAc;IACnC,GAAG;IACJ,EAGuB;GACtB,SAAS,SAAS;GAClB,OAAO,QAAQ;GAChB,CAAC;AACF,MAAI,aAAa,SAAS,EACxB,QAAO,KACL,uBAAuB,aAAa,OAAO,0BAA0B,aAAa,WAAW,IAAI,KAAK,MACvG;EAGH,MAAM,gBAAgB,MAAM,YAAY,IAAI,eAAe;AAE3D,SAAO,MAAM,qBAAqB,KAAK,UAAU,eAAe,MAAM,EAAE,CAAC;AAEzE,mBACE,eACA,eAAe,WAAW,IAAI,MAAM,SAAS,eAAe,OAC7D;AACD,SAAO;UACA,OAAO;AACd,SAAO,gBACL,kBACE,mHACA,MACD,CACF;;;;;;;;AAWL,SAAS,iBACP,eACA,WACM;AACN,KAAI,OAAO,KAAK,cAAc,QAAQ,CAAC,WAAW,EAChD,QAAO,QACL,OAAO,UAAU,GAAG,cAAc,IAAI,SAAS,QAAQ,wCACxD;KAED,QAAO,QAAQ,cAAc,QAAQ"}
@@ -1,5 +1,5 @@
1
1
  import { logger } from "../console/logger.js";
2
- import { gt } from "../utils/gt.js";
2
+ import { api } from "../utils/api.js";
3
3
  import { PublishStep } from "./steps/PublishStep.js";
4
4
  import { hasPublishConfig } from "../utils/resolvePublish.js";
5
5
  //#region src/workflows/publish.ts
@@ -18,7 +18,7 @@ async function runPublishWorkflow(files, publishMap, branchId, settings) {
18
18
  fileName: file.fileName
19
19
  }));
20
20
  if (allFileRefs.length === 0) return;
21
- await new PublishStep(gt).run(allFileRefs);
21
+ await new PublishStep(api).run(allFileRefs);
22
22
  } catch (error) {
23
23
  logger.warn(`Failed to publish files: ${error instanceof Error ? error.message : String(error)}`);
24
24
  }
@@ -1 +1 @@
1
- {"version":3,"file":"publish.js","names":[],"sources":["../../src/workflows/publish.ts"],"sourcesContent":["import { Settings } from '../types/index.js';\nimport { PublishStep } from './steps/PublishStep.js';\nimport { gt } from '../utils/gt.js';\nimport { hasPublishConfig } from '../utils/resolvePublish.js';\nimport { logger } from '../console/logger.js';\n\n/**\n * Publishes files to the CDN if publish config exists and the publishMap is non-empty.\n * Shared by translate, upload, and save-local commands.\n */\nexport async function runPublishWorkflow(\n files: { fileId: string; versionId: string; fileName: string }[],\n publishMap: Map<string, boolean>,\n branchId: string,\n settings: Settings\n): Promise<void> {\n if (publishMap.size === 0 || !hasPublishConfig(settings)) return;\n\n try {\n const allFileRefs = files\n .filter((file) => publishMap.has(file.fileId))\n .map((file) => ({\n fileId: file.fileId,\n versionId: file.versionId,\n branchId,\n publish: publishMap.get(file.fileId)!,\n fileName: file.fileName,\n }));\n if (allFileRefs.length === 0) return;\n const publishStep = new PublishStep(gt);\n await publishStep.run(allFileRefs);\n } catch (error) {\n logger.warn(\n `Failed to publish files: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n"],"mappings":";;;;;;;;;AAUA,eAAsB,mBACpB,OACA,YACA,UACA,UACe;AACf,KAAI,WAAW,SAAS,KAAK,CAAC,iBAAiB,SAAS,CAAE;AAE1D,KAAI;EACF,MAAM,cAAc,MACjB,QAAQ,SAAS,WAAW,IAAI,KAAK,OAAO,CAAC,CAC7C,KAAK,UAAU;GACd,QAAQ,KAAK;GACb,WAAW,KAAK;GAChB;GACA,SAAS,WAAW,IAAI,KAAK,OAAO;GACpC,UAAU,KAAK;GAChB,EAAE;AACL,MAAI,YAAY,WAAW,EAAG;AAE9B,QAAM,IADkB,YAAY,GACnB,CAAC,IAAI,YAAY;UAC3B,OAAO;AACd,SAAO,KACL,4BAA4B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,GACnF"}
1
+ {"version":3,"file":"publish.js","names":[],"sources":["../../src/workflows/publish.ts"],"sourcesContent":["import { Settings } from '../types/index.js';\nimport { PublishStep } from './steps/PublishStep.js';\nimport { api } from '../utils/api.js';\nimport { hasPublishConfig } from '../utils/resolvePublish.js';\nimport { logger } from '../console/logger.js';\n\n/**\n * Publishes files to the CDN if publish config exists and the publishMap is non-empty.\n * Shared by translate, upload, and save-local commands.\n */\nexport async function runPublishWorkflow(\n files: { fileId: string; versionId: string; fileName: string }[],\n publishMap: Map<string, boolean>,\n branchId: string,\n settings: Settings\n): Promise<void> {\n if (publishMap.size === 0 || !hasPublishConfig(settings)) return;\n\n try {\n const allFileRefs = files\n .filter((file) => publishMap.has(file.fileId))\n .map((file) => ({\n fileId: file.fileId,\n versionId: file.versionId,\n branchId,\n publish: publishMap.get(file.fileId)!,\n fileName: file.fileName,\n }));\n if (allFileRefs.length === 0) return;\n const publishStep = new PublishStep(api);\n await publishStep.run(allFileRefs);\n } catch (error) {\n logger.warn(\n `Failed to publish files: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n"],"mappings":";;;;;;;;;AAUA,eAAsB,mBACpB,OACA,YACA,UACA,UACe;AACf,KAAI,WAAW,SAAS,KAAK,CAAC,iBAAiB,SAAS,CAAE;AAE1D,KAAI;EACF,MAAM,cAAc,MACjB,QAAQ,SAAS,WAAW,IAAI,KAAK,OAAO,CAAC,CAC7C,KAAK,UAAU;GACd,QAAQ,KAAK;GACb,WAAW,KAAK;GAChB;GACA,SAAS,WAAW,IAAI,KAAK,OAAO;GACpC,UAAU,KAAK;GAChB,EAAE;AACL,MAAI,YAAY,WAAW,EAAG;AAE9B,QAAM,IADkB,YAAY,IACnB,CAAC,IAAI,YAAY;UAC3B,OAAO;AACd,SAAO,KACL,4BAA4B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,GACnF"}
@@ -1,6 +1,6 @@
1
- import { gt } from "../utils/gt.js";
2
1
  import { logCollectedFiles, logErrorAndExit } from "../console/logging.js";
3
2
  import { branchResolutionError, withOriginalError } from "../console/index.js";
3
+ import { api } from "../utils/api.js";
4
4
  import { BranchStep } from "./steps/BranchStep.js";
5
5
  import { UploadSourcesStep } from "./steps/UploadSourcesStep.js";
6
6
  import { SetupStep } from "./steps/SetupStep.js";
@@ -17,9 +17,9 @@ async function runSetupProjectWorkflow(files, options, settings, inlineLibrary)
17
17
  try {
18
18
  logCollectedFiles(files, void 0, inlineLibrary);
19
19
  const timeoutMs = calculateTimeoutMs(options.timeout);
20
- const branchStep = new BranchStep(gt, settings);
21
- const uploadStep = new UploadSourcesStep(gt, settings);
22
- const setupStep = new SetupStep(gt, settings, timeoutMs);
20
+ const branchStep = new BranchStep(api, settings);
21
+ const uploadStep = new UploadSourcesStep(api, settings);
22
+ const setupStep = new SetupStep(api, settings, timeoutMs);
23
23
  const branchData = await branchStep.run();
24
24
  if (!branchData) return logErrorAndExit(branchResolutionError);
25
25
  const uploadedFiles = await uploadStep.run({
@@ -1 +1 @@
1
- {"version":3,"file":"setupProject.js","names":[],"sources":["../../src/workflows/setupProject.ts"],"sourcesContent":["import { logErrorAndExit } from '../console/logging.js';\nimport { branchResolutionError, withOriginalError } from '../console/index.js';\nimport { Settings, TranslateFlags } from '../types/index.js';\nimport { gt } from '../utils/gt.js';\nimport { FileToUpload } from 'generaltranslation/types';\nimport { UploadSourcesStep } from './steps/UploadSourcesStep.js';\nimport { SetupStep } from './steps/SetupStep.js';\nimport { BranchStep } from './steps/BranchStep.js';\nimport { BranchData } from '../types/branch.js';\nimport { logCollectedFiles } from '../console/logging.js';\nimport { calculateTimeoutMs } from '../utils/calculateTimeoutMs.js';\nimport type { InlineLibrary } from '../types/libraries.js';\n\n/**\n * Sets up a project by uploading files running the setup step\n * @param files - Array of file objects to upload\n * @param options - The options for the API call\n * @param settings - Settings configuration\n * @returns The branch data\n */\nexport async function runSetupProjectWorkflow(\n files: FileToUpload[],\n options: TranslateFlags,\n settings: Settings,\n inlineLibrary?: InlineLibrary\n): Promise<{\n branchData: BranchData;\n}> {\n try {\n // Log files to be translated\n logCollectedFiles(files, undefined, inlineLibrary);\n\n // Calculate timeout for setup step\n const timeoutMs = calculateTimeoutMs(options.timeout);\n\n // Create workflow with steps\n const branchStep = new BranchStep(gt, settings);\n const uploadStep = new UploadSourcesStep(gt, settings);\n const setupStep = new SetupStep(gt, settings, timeoutMs);\n\n // first run the branch step\n const branchData = await branchStep.run();\n\n if (!branchData) {\n return logErrorAndExit(branchResolutionError);\n }\n\n // then run the upload step\n const uploadedFiles = await uploadStep.run({ files, branchData });\n\n // then run the setup step\n await setupStep.run(uploadedFiles, options.force ?? false);\n\n return { branchData };\n } catch (error) {\n return logErrorAndExit(\n withOriginalError(\n 'Project setup could not be completed. Check the files, branch configuration, and API credentials, then try again.',\n error\n )\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAoBA,eAAsB,wBACpB,OACA,SACA,UACA,eAGC;AACD,KAAI;AAEF,oBAAkB,OAAO,KAAA,GAAW,cAAc;EAGlD,MAAM,YAAY,mBAAmB,QAAQ,QAAQ;EAGrD,MAAM,aAAa,IAAI,WAAW,IAAI,SAAS;EAC/C,MAAM,aAAa,IAAI,kBAAkB,IAAI,SAAS;EACtD,MAAM,YAAY,IAAI,UAAU,IAAI,UAAU,UAAU;EAGxD,MAAM,aAAa,MAAM,WAAW,KAAK;AAEzC,MAAI,CAAC,WACH,QAAO,gBAAgB,sBAAsB;EAI/C,MAAM,gBAAgB,MAAM,WAAW,IAAI;GAAE;GAAO;GAAY,CAAC;AAGjE,QAAM,UAAU,IAAI,eAAe,QAAQ,SAAS,MAAM;AAE1D,SAAO,EAAE,YAAY;UACd,OAAO;AACd,SAAO,gBACL,kBACE,qHACA,MACD,CACF"}
1
+ {"version":3,"file":"setupProject.js","names":[],"sources":["../../src/workflows/setupProject.ts"],"sourcesContent":["import { logErrorAndExit } from '../console/logging.js';\nimport { branchResolutionError, withOriginalError } from '../console/index.js';\nimport { Settings, TranslateFlags } from '../types/index.js';\nimport { api } from '../utils/api.js';\nimport { FileToUpload } from 'generaltranslation/types';\nimport { UploadSourcesStep } from './steps/UploadSourcesStep.js';\nimport { SetupStep } from './steps/SetupStep.js';\nimport { BranchStep } from './steps/BranchStep.js';\nimport { BranchData } from '../types/branch.js';\nimport { logCollectedFiles } from '../console/logging.js';\nimport { calculateTimeoutMs } from '../utils/calculateTimeoutMs.js';\nimport type { InlineLibrary } from '../types/libraries.js';\n\n/**\n * Sets up a project by uploading files running the setup step\n * @param files - Array of file objects to upload\n * @param options - The options for the API call\n * @param settings - Settings configuration\n * @returns The branch data\n */\nexport async function runSetupProjectWorkflow(\n files: FileToUpload[],\n options: TranslateFlags,\n settings: Settings,\n inlineLibrary?: InlineLibrary\n): Promise<{\n branchData: BranchData;\n}> {\n try {\n // Log files to be translated\n logCollectedFiles(files, undefined, inlineLibrary);\n\n // Calculate timeout for setup step\n const timeoutMs = calculateTimeoutMs(options.timeout);\n\n // Create workflow with steps\n const branchStep = new BranchStep(api, settings);\n const uploadStep = new UploadSourcesStep(api, settings);\n const setupStep = new SetupStep(api, settings, timeoutMs);\n\n // first run the branch step\n const branchData = await branchStep.run();\n\n if (!branchData) {\n return logErrorAndExit(branchResolutionError);\n }\n\n // then run the upload step\n const uploadedFiles = await uploadStep.run({ files, branchData });\n\n // then run the setup step\n await setupStep.run(uploadedFiles, options.force ?? false);\n\n return { branchData };\n } catch (error) {\n return logErrorAndExit(\n withOriginalError(\n 'Project setup could not be completed. Check the files, branch configuration, and API credentials, then try again.',\n error\n )\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAoBA,eAAsB,wBACpB,OACA,SACA,UACA,eAGC;AACD,KAAI;AAEF,oBAAkB,OAAO,KAAA,GAAW,cAAc;EAGlD,MAAM,YAAY,mBAAmB,QAAQ,QAAQ;EAGrD,MAAM,aAAa,IAAI,WAAW,KAAK,SAAS;EAChD,MAAM,aAAa,IAAI,kBAAkB,KAAK,SAAS;EACvD,MAAM,YAAY,IAAI,UAAU,KAAK,UAAU,UAAU;EAGzD,MAAM,aAAa,MAAM,WAAW,KAAK;AAEzC,MAAI,CAAC,WACH,QAAO,gBAAgB,sBAAsB;EAI/C,MAAM,gBAAgB,MAAM,WAAW,IAAI;GAAE;GAAO;GAAY,CAAC;AAGjE,QAAM,UAAU,IAAI,eAAe,QAAQ,SAAS,MAAM;AAE1D,SAAO,EAAE,YAAY;UACd,OAAO;AACd,SAAO,gBACL,kBACE,qHACA,MACD,CACF"}
@@ -1,7 +1,7 @@
1
1
  import { logger } from "../console/logger.js";
2
- import { gt } from "../utils/gt.js";
3
2
  import { logCollectedFiles, logErrorAndExit } from "../console/logging.js";
4
3
  import { branchResolutionError, withOriginalError } from "../console/index.js";
4
+ import { api } from "../utils/api.js";
5
5
  import { syncFonts } from "./utils/syncFonts.js";
6
6
  import { BranchStep } from "./steps/BranchStep.js";
7
7
  import { UploadSourcesStep } from "./steps/UploadSourcesStep.js";
@@ -24,26 +24,26 @@ async function runStageFilesWorkflow({ files, options, settings, inlineLibrary }
24
24
  logCollectedFiles(files, void 0, inlineLibrary);
25
25
  await syncFonts(settings);
26
26
  const timeoutMs = calculateTimeoutMs(options.timeout);
27
- const branchStep = new BranchStep(gt, settings);
28
- const uploadStep = new UploadSourcesStep(gt, settings);
27
+ const branchStep = new BranchStep(api, settings);
28
+ const uploadStep = new UploadSourcesStep(api, settings);
29
29
  const userEditDiffsStep = new UserEditDiffsStep(settings);
30
- const setupStep = new SetupStep(gt, settings, timeoutMs);
31
- const enqueueStep = new EnqueueStep(gt, settings, options.force);
30
+ const setupStep = new SetupStep(api, settings, timeoutMs);
31
+ const enqueueStep = new EnqueueStep(api, settings, options.force);
32
32
  const branchData = await branchStep.run();
33
33
  if (!branchData) return logErrorAndExit(branchResolutionError);
34
34
  const uploadedFiles = await uploadStep.run({
35
35
  files,
36
36
  branchData
37
37
  });
38
- if (options?.saveLocal) await userEditDiffsStep.run(uploadedFiles);
38
+ if (settings.options?.saveLocal !== false) await userEditDiffsStep.run(uploadedFiles);
39
39
  if (settings.tag) try {
40
- await new TagStep(gt, settings, !!options.tag).run(uploadedFiles);
40
+ await new TagStep(api, settings, !!options.tag).run(uploadedFiles);
41
41
  } catch {
42
42
  logger.warn("Failed to create translation tag. Continuing...");
43
43
  }
44
44
  await setupStep.run(uploadedFiles);
45
45
  const { filesToEnqueue, skippedFiles } = await filterFilesForEnqueue({
46
- gt,
46
+ gt: api,
47
47
  files: uploadedFiles,
48
48
  locales: settings.locales,
49
49
  force: options.force