gt 2.14.21 → 2.14.22
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 +10 -0
- package/dist/api/collectUserEditDiffs.js +2 -2
- package/dist/api/downloadFileBatch.js +23 -0
- package/dist/cli/commands/download.js +2 -2
- package/dist/cli/commands/translate.js +46 -9
- package/dist/cli/commands/upload.js +10 -4
- package/dist/config/generateSettings.js +3 -1
- package/dist/formats/files/aggregateFiles.js +5 -0
- package/dist/formats/files/fileMapping.d.ts +3 -2
- package/dist/formats/files/fileMapping.js +8 -2
- package/dist/formats/files/supportedFiles.d.ts +2 -1
- package/dist/formats/files/supportedFiles.js +2 -0
- package/dist/formats/files/transformFormat.d.ts +68 -0
- package/dist/formats/files/transformFormat.js +122 -0
- package/dist/fs/config/parseFilesConfig.js +9 -0
- package/dist/generated/version.d.ts +1 -1
- package/dist/generated/version.js +1 -1
- package/dist/types/index.d.ts +6 -1
- package/dist/utils/flattenJsonFiles.js +1 -1
- package/dist/utils/localizeRelativeAssets.js +1 -1
- package/dist/utils/localizeStaticImports.js +1 -1
- package/dist/utils/localizeStaticUrls.js +1 -1
- package/dist/utils/processAnchorIds.js +2 -2
- package/dist/utils/processOpenApi.js +2 -2
- package/dist/utils/sharedStaticAssets.js +2 -2
- package/dist/workflows/steps/UploadSourcesStep.js +10 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# gtx-cli
|
|
2
2
|
|
|
3
|
+
## 2.14.22
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1248](https://github.com/generaltranslation/gt/pull/1248) [`b12d57d`](https://github.com/generaltranslation/gt/commit/b12d57dab1d5cb1f602c5ac24a702b48cda7f11e) Thanks [@ErnestM1234](https://github.com/ErnestM1234)! - Add PO/POT file format support and transformFormat plumbing for API uploads and CLI file downloads.
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`b12d57d`](https://github.com/generaltranslation/gt/commit/b12d57dab1d5cb1f602c5ac24a702b48cda7f11e)]:
|
|
10
|
+
- generaltranslation@8.2.8
|
|
11
|
+
- @generaltranslation/python-extractor@0.2.13
|
|
12
|
+
|
|
3
13
|
## 2.14.21
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
|
@@ -27,8 +27,8 @@ const findLatestDownloadedVersion = (entryMap, fileId, locale) => {
|
|
|
27
27
|
export async function collectAndSendUserEditDiffs(files, settings) {
|
|
28
28
|
if (!settings.files)
|
|
29
29
|
return false;
|
|
30
|
-
const { resolvedPaths, placeholderPaths, transformPaths } = settings.files;
|
|
31
|
-
const fileMapping = createFileMapping(resolvedPaths, placeholderPaths, transformPaths, settings.locales, settings.defaultLocale);
|
|
30
|
+
const { resolvedPaths, placeholderPaths, transformPaths, transformFormats } = settings.files;
|
|
31
|
+
const fileMapping = createFileMapping(resolvedPaths, placeholderPaths, transformPaths, transformFormats, settings.locales, settings.defaultLocale);
|
|
32
32
|
const { entryMap } = readLockfile(settings);
|
|
33
33
|
const tempDir = path.join(os.tmpdir(), randomUUID());
|
|
34
34
|
if (!fs.existsSync(tempDir))
|
|
@@ -13,10 +13,16 @@ import { readLockfile, writeLockfile, findOrCreateEntry, } from '../fs/config/do
|
|
|
13
13
|
import { recordDownloaded, recordRemerged } from '../state/recentDownloads.js';
|
|
14
14
|
import { recordWarning } from '../state/translateWarnings.js';
|
|
15
15
|
import stringify from 'fast-json-stable-stringify';
|
|
16
|
+
import { SUPPORTED_FILE_EXTENSIONS } from '../formats/files/supportedFiles.js';
|
|
17
|
+
import { hasNonIdentityFileFormatTransformForType } from '../formats/files/transformFormat.js';
|
|
18
|
+
import { getRelative } from '../fs/findFilepath.js';
|
|
16
19
|
/**
|
|
17
20
|
* Merges translated content with the current source file for schema-based formats.
|
|
18
21
|
*/
|
|
19
22
|
function mergeWithSource(translatedContent, locale, inputPath, options) {
|
|
23
|
+
if (shouldSkipSourceFormatMerge(inputPath, options)) {
|
|
24
|
+
return translatedContent;
|
|
25
|
+
}
|
|
20
26
|
if (!options.options)
|
|
21
27
|
return translatedContent;
|
|
22
28
|
const jsonSchema = options.options.jsonSchema
|
|
@@ -49,6 +55,23 @@ function mergeWithSource(translatedContent, locale, inputPath, options) {
|
|
|
49
55
|
return mergeYaml(sourceContent, inputPath, options.options, [{ translatedContent, targetLocale: locale }], options.defaultLocale)[0];
|
|
50
56
|
}
|
|
51
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Determines whether a source file should be skipped for schema re-merging.
|
|
60
|
+
* @param inputPath - The path of the source file
|
|
61
|
+
* @param options - The settings for the project
|
|
62
|
+
* @returns True if the source file should be skipped for schema re-merging, false otherwise
|
|
63
|
+
*/
|
|
64
|
+
function shouldSkipSourceFormatMerge(inputPath, options) {
|
|
65
|
+
for (const fileType of SUPPORTED_FILE_EXTENSIONS) {
|
|
66
|
+
if (!hasNonIdentityFileFormatTransformForType(options, fileType))
|
|
67
|
+
continue;
|
|
68
|
+
const transformedSourcePaths = options.files.resolvedPaths[fileType] || [];
|
|
69
|
+
if (transformedSourcePaths.some((sourcePath) => getRelative(sourcePath) === inputPath)) {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
52
75
|
/**
|
|
53
76
|
* Downloads multiple translation files in a single batch request
|
|
54
77
|
* @param files - Array of files to download with their output paths
|
|
@@ -25,8 +25,8 @@ export async function handleDownload(options, settings, library) {
|
|
|
25
25
|
return logErrorAndExit(noFilesError);
|
|
26
26
|
}
|
|
27
27
|
// Files
|
|
28
|
-
const { resolvedPaths, placeholderPaths, transformPaths } = settings.files;
|
|
29
|
-
const fileMapping = createFileMapping(resolvedPaths, placeholderPaths, transformPaths, settings.locales, settings.defaultLocale);
|
|
28
|
+
const { resolvedPaths, placeholderPaths, transformPaths, transformFormats } = settings.files;
|
|
29
|
+
const fileMapping = createFileMapping(resolvedPaths, placeholderPaths, transformPaths, transformFormats, settings.locales, settings.defaultLocale);
|
|
30
30
|
// Collect the hashes for all files we need to download
|
|
31
31
|
let fileVersionData;
|
|
32
32
|
if (settings.stageTranslations) {
|
|
@@ -10,11 +10,14 @@ import localizeStaticImports from '../../utils/localizeStaticImports.js';
|
|
|
10
10
|
import { getDownloadedMeta } from '../../state/recentDownloads.js';
|
|
11
11
|
import { persistPostProcessHashes } from '../../utils/persistPostprocessHashes.js';
|
|
12
12
|
import { runPublishWorkflow } from '../../workflows/publish.js';
|
|
13
|
+
import { SUPPORTED_FILE_EXTENSIONS } from '../../formats/files/supportedFiles.js';
|
|
14
|
+
import { hasNonIdentityFileFormatTransformForType } from '../../formats/files/transformFormat.js';
|
|
15
|
+
import { getRelative } from '../../fs/findFilepath.js';
|
|
13
16
|
// Downloads translations that were completed
|
|
14
17
|
export async function handleTranslate(options, settings, fileVersionData, jobData, branchData, publishMap) {
|
|
15
18
|
if (fileVersionData) {
|
|
16
|
-
const { resolvedPaths, placeholderPaths, transformPaths } = settings.files;
|
|
17
|
-
const fileMapping = createFileMapping(resolvedPaths, placeholderPaths, transformPaths, settings.locales, settings.defaultLocale);
|
|
19
|
+
const { resolvedPaths, placeholderPaths, transformPaths, transformFormats, } = settings.files;
|
|
20
|
+
const fileMapping = createFileMapping(resolvedPaths, placeholderPaths, transformPaths, transformFormats, settings.locales, settings.defaultLocale);
|
|
18
21
|
// Check for remaining translations
|
|
19
22
|
await runDownloadWorkflow({
|
|
20
23
|
fileVersionData: fileVersionData,
|
|
@@ -39,21 +42,24 @@ export async function handleTranslate(options, settings, fileVersionData, jobDat
|
|
|
39
42
|
}
|
|
40
43
|
}
|
|
41
44
|
export async function postProcessTranslations(settings, includeFiles) {
|
|
45
|
+
const postProcessIncludes = filterPostProcessIncludesForFormatTransforms(settings, includeFiles);
|
|
46
|
+
if (includeFiles && postProcessIncludes?.size === 0)
|
|
47
|
+
return;
|
|
42
48
|
// Mintlify OpenAPI localization (spec routing + validation)
|
|
43
|
-
await processOpenApi(settings,
|
|
49
|
+
await processOpenApi(settings, postProcessIncludes);
|
|
44
50
|
// Localize static urls (/docs -> /[locale]/docs) and preserve anchor IDs for non-default locales
|
|
45
51
|
// Default locale is processed earlier in the flow in base.ts
|
|
46
52
|
if (settings.options?.experimentalLocalizeStaticUrls) {
|
|
47
53
|
const nonDefaultLocales = settings.locales.filter((locale) => locale !== settings.defaultLocale);
|
|
48
54
|
if (nonDefaultLocales.length > 0) {
|
|
49
|
-
await localizeStaticUrls(settings, nonDefaultLocales,
|
|
55
|
+
await localizeStaticUrls(settings, nonDefaultLocales, postProcessIncludes);
|
|
50
56
|
}
|
|
51
57
|
}
|
|
52
58
|
// Rewrite relative asset URLs in translated md/mdx files
|
|
53
59
|
if (settings.options?.experimentalLocalizeRelativeAssets) {
|
|
54
60
|
const nonDefaultLocales = settings.locales.filter((locale) => locale !== settings.defaultLocale);
|
|
55
61
|
if (nonDefaultLocales.length > 0) {
|
|
56
|
-
await localizeRelativeAssets(settings, nonDefaultLocales,
|
|
62
|
+
await localizeRelativeAssets(settings, nonDefaultLocales, postProcessIncludes);
|
|
57
63
|
}
|
|
58
64
|
}
|
|
59
65
|
const shouldProcessAnchorIds = settings.options?.experimentalLocalizeStaticUrls ||
|
|
@@ -61,20 +67,51 @@ export async function postProcessTranslations(settings, includeFiles) {
|
|
|
61
67
|
// Add explicit anchor IDs to translated MDX/MD files to preserve navigation
|
|
62
68
|
// Uses inline {#id} format by default, or div wrapping if experimentalAddHeaderAnchorIds is 'mintlify'
|
|
63
69
|
if (shouldProcessAnchorIds) {
|
|
64
|
-
await processAnchorIds(settings,
|
|
70
|
+
await processAnchorIds(settings, postProcessIncludes);
|
|
65
71
|
}
|
|
66
72
|
// Localize static imports (import Snippet from /snippets/file.mdx -> import Snippet from /snippets/[locale]/file.mdx)
|
|
67
73
|
if (settings.options?.experimentalLocalizeStaticImports) {
|
|
68
|
-
await localizeStaticImports(settings,
|
|
74
|
+
await localizeStaticImports(settings, postProcessIncludes);
|
|
69
75
|
}
|
|
70
76
|
// Flatten json files into a single file
|
|
71
77
|
if (settings.options?.experimentalFlattenJsonFiles) {
|
|
72
|
-
await flattenJsonFiles(settings,
|
|
78
|
+
await flattenJsonFiles(settings, postProcessIncludes);
|
|
73
79
|
}
|
|
74
80
|
// Copy files to the target locale
|
|
75
81
|
if (settings.options?.copyFiles) {
|
|
76
82
|
await copyFile(settings);
|
|
77
83
|
}
|
|
78
84
|
// Record postprocessed content hashes for newly downloaded files
|
|
79
|
-
persistPostProcessHashes(settings,
|
|
85
|
+
persistPostProcessHashes(settings, postProcessIncludes, getDownloadedMeta());
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Exclude only outputs whose source file was translated into a different format.
|
|
89
|
+
* @param settings - The settings for the project
|
|
90
|
+
* @param includeFiles - The files to include in the post-processing
|
|
91
|
+
* @returns The files to exclude in the post-processing
|
|
92
|
+
*/
|
|
93
|
+
function filterPostProcessIncludesForFormatTransforms(settings, includeFiles) {
|
|
94
|
+
if (!includeFiles)
|
|
95
|
+
return includeFiles;
|
|
96
|
+
const transformedSourcePaths = new Set();
|
|
97
|
+
for (const fileType of SUPPORTED_FILE_EXTENSIONS) {
|
|
98
|
+
if (!hasNonIdentityFileFormatTransformForType(settings, fileType))
|
|
99
|
+
continue;
|
|
100
|
+
for (const sourcePath of settings.files.resolvedPaths[fileType] || []) {
|
|
101
|
+
transformedSourcePaths.add(getRelative(sourcePath));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (transformedSourcePaths.size === 0)
|
|
105
|
+
return includeFiles;
|
|
106
|
+
const { resolvedPaths, placeholderPaths, transformPaths, transformFormats } = settings.files;
|
|
107
|
+
const fileMapping = createFileMapping(resolvedPaths, placeholderPaths, transformPaths, transformFormats, settings.locales, settings.defaultLocale);
|
|
108
|
+
const transformedOutputPaths = new Set();
|
|
109
|
+
for (const localeMapping of Object.values(fileMapping)) {
|
|
110
|
+
for (const [sourcePath, outputPath] of Object.entries(localeMapping)) {
|
|
111
|
+
if (transformedSourcePaths.has(sourcePath)) {
|
|
112
|
+
transformedOutputPaths.add(outputPath);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return new Set([...includeFiles].filter((filePath) => !transformedOutputPaths.has(filePath)));
|
|
80
117
|
}
|
|
@@ -16,6 +16,7 @@ import { hashStringSync } from '../../utils/hash.js';
|
|
|
16
16
|
import { hasValidCredentials } from './utils/validation.js';
|
|
17
17
|
import { buildPublishMap } from '../../utils/resolvePublish.js';
|
|
18
18
|
import { runPublishWorkflow } from '../../workflows/publish.js';
|
|
19
|
+
import { getTransformFormatProperty } from '../../formats/files/transformFormat.js';
|
|
19
20
|
const SUPPORTED_DATA_FORMATS = ['JSX', 'ICU', 'I18NEXT'];
|
|
20
21
|
/**
|
|
21
22
|
* Sends multiple files to the API for translation
|
|
@@ -60,6 +61,7 @@ export async function upload(filePaths, placeholderPaths, transformPaths, dataFo
|
|
|
60
61
|
content: parsedJson,
|
|
61
62
|
fileName: relativePath,
|
|
62
63
|
fileFormat: 'JSON',
|
|
64
|
+
...getTransformFormatProperty(settings, 'json'),
|
|
63
65
|
dataFormat,
|
|
64
66
|
locale: settings.defaultLocale,
|
|
65
67
|
fileId: hashStringSync(relativePath),
|
|
@@ -81,6 +83,7 @@ export async function upload(filePaths, placeholderPaths, transformPaths, dataFo
|
|
|
81
83
|
content: parsedYaml,
|
|
82
84
|
fileName: relativePath,
|
|
83
85
|
fileFormat,
|
|
86
|
+
...getTransformFormatProperty(settings, 'yaml'),
|
|
84
87
|
dataFormat,
|
|
85
88
|
locale: settings.defaultLocale,
|
|
86
89
|
fileId: hashStringSync(relativePath),
|
|
@@ -99,6 +102,7 @@ export async function upload(filePaths, placeholderPaths, transformPaths, dataFo
|
|
|
99
102
|
content: parsedJson,
|
|
100
103
|
fileName: relativePath,
|
|
101
104
|
fileFormat: 'TWILIO_CONTENT_JSON',
|
|
105
|
+
...getTransformFormatProperty(settings, 'twilioContentJson'),
|
|
102
106
|
dataFormat: 'STRING',
|
|
103
107
|
locale: settings.defaultLocale,
|
|
104
108
|
fileId: hashStringSync(relativePath),
|
|
@@ -121,6 +125,7 @@ export async function upload(filePaths, placeholderPaths, transformPaths, dataFo
|
|
|
121
125
|
content: sanitizedContent,
|
|
122
126
|
fileName: relativePath,
|
|
123
127
|
fileFormat: fileType.toUpperCase(),
|
|
128
|
+
...getTransformFormatProperty(settings, fileType),
|
|
124
129
|
dataFormat,
|
|
125
130
|
locale: settings.defaultLocale,
|
|
126
131
|
fileId: hashStringSync(relativePath),
|
|
@@ -141,13 +146,14 @@ export async function upload(filePaths, placeholderPaths, transformPaths, dataFo
|
|
|
141
146
|
return exitSync(1);
|
|
142
147
|
const locales = settings.locales || [];
|
|
143
148
|
// Create file mapping for all file types
|
|
144
|
-
const fileMapping = createFileMapping(filePaths, placeholderPaths, transformPaths, locales, settings.defaultLocale);
|
|
149
|
+
const fileMapping = createFileMapping(filePaths, placeholderPaths, transformPaths, settings.files?.transformFormats || {}, locales, settings.defaultLocale);
|
|
145
150
|
// construct object
|
|
146
151
|
const uploadData = allFiles.map((file) => {
|
|
147
152
|
const sourceFile = {
|
|
148
153
|
content: file.content,
|
|
149
154
|
fileName: file.fileName,
|
|
150
155
|
fileFormat: file.fileFormat,
|
|
156
|
+
transformFormat: file.transformFormat,
|
|
151
157
|
dataFormat: file.dataFormat,
|
|
152
158
|
locale: file.locale,
|
|
153
159
|
fileId: file.fileId,
|
|
@@ -163,7 +169,7 @@ export async function upload(filePaths, placeholderPaths, transformPaths, dataFo
|
|
|
163
169
|
translations.push({
|
|
164
170
|
content: extracted,
|
|
165
171
|
fileName: file.fileName,
|
|
166
|
-
fileFormat: file.fileFormat,
|
|
172
|
+
fileFormat: file.transformFormat ?? file.fileFormat,
|
|
167
173
|
dataFormat: file.dataFormat,
|
|
168
174
|
locale,
|
|
169
175
|
fileId: file.fileId,
|
|
@@ -178,8 +184,8 @@ export async function upload(filePaths, placeholderPaths, transformPaths, dataFo
|
|
|
178
184
|
const translatedContent = readFileSync(translatedFileName, 'utf8');
|
|
179
185
|
translations.push({
|
|
180
186
|
content: translatedContent,
|
|
181
|
-
fileName:
|
|
182
|
-
fileFormat: file.fileFormat,
|
|
187
|
+
fileName: translatedFileName,
|
|
188
|
+
fileFormat: file.transformFormat ?? file.fileFormat,
|
|
183
189
|
dataFormat: file.dataFormat,
|
|
184
190
|
locale,
|
|
185
191
|
fileId: file.fileId,
|
|
@@ -13,6 +13,7 @@ import { resolveConfig } from './resolveConfig.js';
|
|
|
13
13
|
import { gt } from '../utils/gt.js';
|
|
14
14
|
import { generatePreset } from './optionPresets.js';
|
|
15
15
|
import { GT_PARSING_FLAGS_DEFAULT } from './defaults.js';
|
|
16
|
+
import { normalizeFilesOptions } from '../formats/files/transformFormat.js';
|
|
16
17
|
export const DEFAULT_SRC_PATTERNS = [
|
|
17
18
|
'src/**/*.{js,jsx,ts,tsx}',
|
|
18
19
|
'app/**/*.{js,jsx,ts,tsx}',
|
|
@@ -147,11 +148,12 @@ export async function generateSettings(flags, cwd = process.cwd(), options) {
|
|
|
147
148
|
.filter(([, schema]) => schema.composite)
|
|
148
149
|
.map(([key]) => key);
|
|
149
150
|
mergedOptions.files = mergedOptions.files
|
|
150
|
-
? resolveFiles(mergedOptions.files, mergedOptions.defaultLocale, mergedOptions.locales, cwd, compositePatterns)
|
|
151
|
+
? resolveFiles(normalizeFilesOptions(mergedOptions.files), mergedOptions.defaultLocale, mergedOptions.locales, cwd, compositePatterns)
|
|
151
152
|
: {
|
|
152
153
|
resolvedPaths: {},
|
|
153
154
|
placeholderPaths: {},
|
|
154
155
|
transformPaths: {},
|
|
156
|
+
transformFormats: {},
|
|
155
157
|
publishPaths: new Set(),
|
|
156
158
|
unpublishPaths: new Set(),
|
|
157
159
|
parsingFlags: {},
|
|
@@ -14,6 +14,7 @@ import { hashStringSync } from '../../utils/hash.js';
|
|
|
14
14
|
import { preprocessContent } from './preprocessContent.js';
|
|
15
15
|
import { parseKeyedMetadata, } from '../parseKeyedMetadata.js';
|
|
16
16
|
import { buildPublishMap } from '../../utils/resolvePublish.js';
|
|
17
|
+
import { getTransformFormatProperty } from './transformFormat.js';
|
|
17
18
|
/**
|
|
18
19
|
* Checks if a file path is a metadata companion file (e.g. foo.metadata.json)
|
|
19
20
|
* AND its corresponding source file (e.g. foo.json) exists in the file list.
|
|
@@ -123,6 +124,7 @@ export async function aggregateFiles(settings) {
|
|
|
123
124
|
content: parsedJson,
|
|
124
125
|
fileName: relativePath,
|
|
125
126
|
fileFormat: 'JSON',
|
|
127
|
+
...getTransformFormatProperty(settings, 'json'),
|
|
126
128
|
dataFormat,
|
|
127
129
|
locale: settings.defaultLocale,
|
|
128
130
|
...(keyedMetadata && {
|
|
@@ -193,6 +195,7 @@ export async function aggregateFiles(settings) {
|
|
|
193
195
|
content: parsedYaml,
|
|
194
196
|
fileName: relativePath,
|
|
195
197
|
fileFormat,
|
|
198
|
+
...getTransformFormatProperty(settings, 'yaml'),
|
|
196
199
|
fileId: hashStringSync(relativePath),
|
|
197
200
|
versionId: hashStringSync(parsedYaml),
|
|
198
201
|
locale: settings.defaultLocale,
|
|
@@ -235,6 +238,7 @@ export async function aggregateFiles(settings) {
|
|
|
235
238
|
content: parsedJson,
|
|
236
239
|
fileName: relativePath,
|
|
237
240
|
fileFormat: 'TWILIO_CONTENT_JSON',
|
|
241
|
+
...getTransformFormatProperty(settings, 'twilioContentJson'),
|
|
238
242
|
dataFormat: 'STRING',
|
|
239
243
|
locale: settings.defaultLocale,
|
|
240
244
|
};
|
|
@@ -271,6 +275,7 @@ export async function aggregateFiles(settings) {
|
|
|
271
275
|
content: processed,
|
|
272
276
|
fileName: relativePath,
|
|
273
277
|
fileFormat: fileType.toUpperCase(),
|
|
278
|
+
...getTransformFormatProperty(settings, fileType),
|
|
274
279
|
fileId: hashStringSync(relativePath),
|
|
275
280
|
versionId: hashStringSync(processed),
|
|
276
281
|
locale: settings.defaultLocale,
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { ResolvedFiles, TransformFiles } from '../../types/index.js';
|
|
1
|
+
import { ResolvedFiles, TransformFiles, TransformFormats } from '../../types/index.js';
|
|
2
2
|
import { FileMapping } from '../../types/files.js';
|
|
3
3
|
/**
|
|
4
4
|
* Creates a mapping between source files and their translated counterparts for each locale
|
|
5
5
|
* @param filePaths - Resolved file paths for different file types
|
|
6
6
|
* @param placeholderPaths - Placeholder paths for translated files
|
|
7
7
|
* @param transformPaths - Transform paths for file naming
|
|
8
|
+
* @param transformFormats - Output file format transforms for translated files
|
|
8
9
|
* @param locales - List of locales to create a mapping for
|
|
9
10
|
* @returns A mapping between source files and their translated counterparts for each locale, in the form of relative paths
|
|
10
11
|
*/
|
|
11
|
-
export declare function createFileMapping(filePaths: ResolvedFiles, placeholderPaths: ResolvedFiles, transformPaths: TransformFiles, targetLocales: string[], defaultLocale: string): FileMapping;
|
|
12
|
+
export declare function createFileMapping(filePaths: ResolvedFiles, placeholderPaths: ResolvedFiles, transformPaths: TransformFiles, transformFormats: TransformFormats, targetLocales: string[], defaultLocale: string): FileMapping;
|
|
@@ -5,15 +5,17 @@ import { getRelative } from '../../fs/findFilepath.js';
|
|
|
5
5
|
import { getLocaleProperties } from 'generaltranslation';
|
|
6
6
|
import { replaceLocalePlaceholders } from '../utils.js';
|
|
7
7
|
import { TEMPLATE_FILE_NAME } from '../../utils/constants.js';
|
|
8
|
+
import { replaceFileExtensionForFormat } from './transformFormat.js';
|
|
8
9
|
/**
|
|
9
10
|
* Creates a mapping between source files and their translated counterparts for each locale
|
|
10
11
|
* @param filePaths - Resolved file paths for different file types
|
|
11
12
|
* @param placeholderPaths - Placeholder paths for translated files
|
|
12
13
|
* @param transformPaths - Transform paths for file naming
|
|
14
|
+
* @param transformFormats - Output file format transforms for translated files
|
|
13
15
|
* @param locales - List of locales to create a mapping for
|
|
14
16
|
* @returns A mapping between source files and their translated counterparts for each locale, in the form of relative paths
|
|
15
17
|
*/
|
|
16
|
-
export function createFileMapping(filePaths, placeholderPaths, transformPaths, targetLocales, defaultLocale) {
|
|
18
|
+
export function createFileMapping(filePaths, placeholderPaths, transformPaths, transformFormats, targetLocales, defaultLocale) {
|
|
17
19
|
const fileMapping = {};
|
|
18
20
|
for (const locale of targetLocales) {
|
|
19
21
|
const translatedPaths = resolveLocaleFiles(placeholderPaths, locale);
|
|
@@ -32,6 +34,7 @@ export function createFileMapping(filePaths, placeholderPaths, transformPaths, t
|
|
|
32
34
|
if (!translatedFiles)
|
|
33
35
|
continue;
|
|
34
36
|
const transformPath = transformPaths[typeIndex];
|
|
37
|
+
const transformFormat = transformFormats?.[typeIndex];
|
|
35
38
|
if (transformPath) {
|
|
36
39
|
if (typeof transformPath === 'string') {
|
|
37
40
|
translatedFiles = translatedFiles.map((filePath) => {
|
|
@@ -105,7 +108,10 @@ export function createFileMapping(filePaths, placeholderPaths, transformPaths, t
|
|
|
105
108
|
}
|
|
106
109
|
for (let i = 0; i < sourcePaths.length; i++) {
|
|
107
110
|
const sourceFile = getRelative(sourcePaths[i]);
|
|
108
|
-
|
|
111
|
+
// Format transforms keep the mapped path but rewrite the output suffix.
|
|
112
|
+
const translatedFile = getRelative(transformFormat
|
|
113
|
+
? replaceFileExtensionForFormat(translatedFiles[i], transformFormat)
|
|
114
|
+
: translatedFiles[i]);
|
|
109
115
|
localeMapping[sourceFile] = translatedFile;
|
|
110
116
|
}
|
|
111
117
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export declare const SUPPORTED_FILE_EXTENSIONS: readonly ["json", "mdx", "md", "ts", "js", "yaml", "html", "txt", "twilioContentJson"];
|
|
1
|
+
export declare const SUPPORTED_FILE_EXTENSIONS: readonly ["json", "pot", "mdx", "md", "ts", "js", "yaml", "html", "txt", "twilioContentJson"];
|
|
2
2
|
export declare const FILE_EXT_TO_EXT_LABEL: {
|
|
3
3
|
json: string;
|
|
4
|
+
pot: string;
|
|
4
5
|
mdx: string;
|
|
5
6
|
md: string;
|
|
6
7
|
ts: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export const SUPPORTED_FILE_EXTENSIONS = [
|
|
2
2
|
'json',
|
|
3
|
+
'pot',
|
|
3
4
|
'mdx',
|
|
4
5
|
'md',
|
|
5
6
|
'ts',
|
|
@@ -11,6 +12,7 @@ export const SUPPORTED_FILE_EXTENSIONS = [
|
|
|
11
12
|
];
|
|
12
13
|
export const FILE_EXT_TO_EXT_LABEL = {
|
|
13
14
|
json: 'JSON',
|
|
15
|
+
pot: 'POT',
|
|
14
16
|
mdx: 'MDX',
|
|
15
17
|
md: 'Markdown',
|
|
16
18
|
ts: 'TypeScript',
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { FileFormat } from '../../types/data.js';
|
|
2
|
+
import type { FilesOptions, Settings, SupportedFileExtension } from '../../types/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Maps CLI config file keys to API file format enum values.
|
|
5
|
+
*/
|
|
6
|
+
export declare const CONFIG_FILE_TYPE_TO_FILE_FORMAT: {
|
|
7
|
+
readonly json: "JSON";
|
|
8
|
+
readonly pot: "POT";
|
|
9
|
+
readonly mdx: "MDX";
|
|
10
|
+
readonly md: "MD";
|
|
11
|
+
readonly ts: "TS";
|
|
12
|
+
readonly js: "JS";
|
|
13
|
+
readonly yaml: "YAML";
|
|
14
|
+
readonly html: "HTML";
|
|
15
|
+
readonly txt: "TXT";
|
|
16
|
+
readonly twilioContentJson: "TWILIO_CONTENT_JSON";
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Maps uppercase config aliases to the CLI's canonical lowercase file keys.
|
|
20
|
+
*/
|
|
21
|
+
export declare const FILE_FORMAT_TO_CONFIG_FILE_TYPE: {
|
|
22
|
+
readonly JSON: "json";
|
|
23
|
+
readonly POT: "pot";
|
|
24
|
+
readonly MDX: "mdx";
|
|
25
|
+
readonly MD: "md";
|
|
26
|
+
readonly TS: "ts";
|
|
27
|
+
readonly JS: "js";
|
|
28
|
+
readonly YAML: "yaml";
|
|
29
|
+
readonly HTML: "html";
|
|
30
|
+
readonly TXT: "txt";
|
|
31
|
+
readonly TWILIO_CONTENT_JSON: "twilioContentJson";
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Converts uppercase file format config keys into the CLI's canonical lowercase keys.
|
|
35
|
+
*
|
|
36
|
+
* This lets users write either `files.POT` or `files.pot` while keeping the
|
|
37
|
+
* rest of the CLI on its existing lowercase file-type convention.
|
|
38
|
+
*/
|
|
39
|
+
export declare function normalizeFilesOptions(files: FilesOptions): FilesOptions;
|
|
40
|
+
/**
|
|
41
|
+
* Validates and resolves a configured output format for a source file type.
|
|
42
|
+
*
|
|
43
|
+
* Throws when the requested source -> output format is not supported by
|
|
44
|
+
* `generaltranslation/internal`.
|
|
45
|
+
*/
|
|
46
|
+
export declare function resolveTransformationFormat(fileType: SupportedFileExtension, transformationFormat: string | undefined): FileFormat | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Returns the API upload/enqueue property for a file type when one is configured.
|
|
49
|
+
*/
|
|
50
|
+
export declare function getTransformFormatProperty(settings: Settings, fileType: SupportedFileExtension): {
|
|
51
|
+
transformFormat?: FileFormat;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Returns the preferred file extension for a translated file format.
|
|
55
|
+
*/
|
|
56
|
+
export declare function getFileExtensionForFormat(format: FileFormat): string;
|
|
57
|
+
/**
|
|
58
|
+
* Rewrites a path's extension to match the translated file format.
|
|
59
|
+
*/
|
|
60
|
+
export declare function replaceFileExtensionForFormat(filePath: string, format: FileFormat): string;
|
|
61
|
+
/**
|
|
62
|
+
* Detects whether any configured format transform changes the output file type.
|
|
63
|
+
*/
|
|
64
|
+
export declare function hasNonIdentityFileFormatTransform(settings: Settings): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Returns true when the configured transform for a file type changes its format.
|
|
67
|
+
*/
|
|
68
|
+
export declare function hasNonIdentityFileFormatTransformForType(settings: Settings, fileType: SupportedFileExtension): boolean;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { validateFileFormatTransforms } from 'generaltranslation/internal';
|
|
2
|
+
/**
|
|
3
|
+
* Maps CLI config file keys to API file format enum values.
|
|
4
|
+
*/
|
|
5
|
+
export const CONFIG_FILE_TYPE_TO_FILE_FORMAT = {
|
|
6
|
+
json: 'JSON',
|
|
7
|
+
pot: 'POT',
|
|
8
|
+
mdx: 'MDX',
|
|
9
|
+
md: 'MD',
|
|
10
|
+
ts: 'TS',
|
|
11
|
+
js: 'JS',
|
|
12
|
+
yaml: 'YAML',
|
|
13
|
+
html: 'HTML',
|
|
14
|
+
txt: 'TXT',
|
|
15
|
+
twilioContentJson: 'TWILIO_CONTENT_JSON',
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Maps uppercase config aliases to the CLI's canonical lowercase file keys.
|
|
19
|
+
*/
|
|
20
|
+
export const FILE_FORMAT_TO_CONFIG_FILE_TYPE = {
|
|
21
|
+
JSON: 'json',
|
|
22
|
+
POT: 'pot',
|
|
23
|
+
MDX: 'mdx',
|
|
24
|
+
MD: 'md',
|
|
25
|
+
TS: 'ts',
|
|
26
|
+
JS: 'js',
|
|
27
|
+
YAML: 'yaml',
|
|
28
|
+
HTML: 'html',
|
|
29
|
+
TXT: 'txt',
|
|
30
|
+
TWILIO_CONTENT_JSON: 'twilioContentJson',
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Maps API file format enum values to the extension the CLI should write.
|
|
34
|
+
*/
|
|
35
|
+
const FILE_FORMAT_EXTENSIONS = {
|
|
36
|
+
GTJSON: 'json',
|
|
37
|
+
JSON: 'json',
|
|
38
|
+
PO: 'po',
|
|
39
|
+
POT: 'pot',
|
|
40
|
+
YAML: 'yaml',
|
|
41
|
+
MDX: 'mdx',
|
|
42
|
+
MD: 'md',
|
|
43
|
+
TS: 'ts',
|
|
44
|
+
JS: 'js',
|
|
45
|
+
HTML: 'html',
|
|
46
|
+
TXT: 'txt',
|
|
47
|
+
TWILIO_CONTENT_JSON: 'json',
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Converts uppercase file format config keys into the CLI's canonical lowercase keys.
|
|
51
|
+
*
|
|
52
|
+
* This lets users write either `files.POT` or `files.pot` while keeping the
|
|
53
|
+
* rest of the CLI on its existing lowercase file-type convention.
|
|
54
|
+
*/
|
|
55
|
+
export function normalizeFilesOptions(files) {
|
|
56
|
+
const normalized = { ...files };
|
|
57
|
+
for (const [fileFormat, fileType] of Object.entries(FILE_FORMAT_TO_CONFIG_FILE_TYPE)) {
|
|
58
|
+
const uppercaseConfig = normalized[fileFormat];
|
|
59
|
+
if (!normalized[fileType] && uppercaseConfig) {
|
|
60
|
+
normalized[fileType] = uppercaseConfig;
|
|
61
|
+
}
|
|
62
|
+
delete normalized[fileFormat];
|
|
63
|
+
}
|
|
64
|
+
return normalized;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Validates and resolves a configured output format for a source file type.
|
|
68
|
+
*
|
|
69
|
+
* Throws when the requested source -> output format is not supported by
|
|
70
|
+
* `generaltranslation/internal`.
|
|
71
|
+
*/
|
|
72
|
+
export function resolveTransformationFormat(fileType, transformationFormat) {
|
|
73
|
+
if (!transformationFormat)
|
|
74
|
+
return undefined;
|
|
75
|
+
const fileFormat = CONFIG_FILE_TYPE_TO_FILE_FORMAT[fileType];
|
|
76
|
+
validateFileFormatTransforms([
|
|
77
|
+
{
|
|
78
|
+
fileFormat,
|
|
79
|
+
transformFormat: transformationFormat,
|
|
80
|
+
fileName: `files.${fileType}`,
|
|
81
|
+
},
|
|
82
|
+
]);
|
|
83
|
+
return transformationFormat;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Returns the API upload/enqueue property for a file type when one is configured.
|
|
87
|
+
*/
|
|
88
|
+
export function getTransformFormatProperty(settings, fileType) {
|
|
89
|
+
const transformFormat = settings.files?.transformFormats?.[fileType];
|
|
90
|
+
return transformFormat ? { transformFormat } : {};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Returns the preferred file extension for a translated file format.
|
|
94
|
+
*/
|
|
95
|
+
export function getFileExtensionForFormat(format) {
|
|
96
|
+
return FILE_FORMAT_EXTENSIONS[format];
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Rewrites a path's extension to match the translated file format.
|
|
100
|
+
*/
|
|
101
|
+
export function replaceFileExtensionForFormat(filePath, format) {
|
|
102
|
+
const extension = getFileExtensionForFormat(format);
|
|
103
|
+
return /\.[^/.]+$/.test(filePath)
|
|
104
|
+
? filePath.replace(/\.[^/.]+$/, `.${extension}`)
|
|
105
|
+
: `${filePath}.${extension}`;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Detects whether any configured format transform changes the output file type.
|
|
109
|
+
*/
|
|
110
|
+
export function hasNonIdentityFileFormatTransform(settings) {
|
|
111
|
+
return Object.entries(settings.files?.transformFormats || {}).some(([fileType, transformFormat]) => transformFormat &&
|
|
112
|
+
CONFIG_FILE_TYPE_TO_FILE_FORMAT[fileType] !==
|
|
113
|
+
transformFormat);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Returns true when the configured transform for a file type changes its format.
|
|
117
|
+
*/
|
|
118
|
+
export function hasNonIdentityFileFormatTransformForType(settings, fileType) {
|
|
119
|
+
const transformFormat = settings.files?.transformFormats?.[fileType];
|
|
120
|
+
return !!(transformFormat &&
|
|
121
|
+
CONFIG_FILE_TYPE_TO_FILE_FORMAT[fileType] !== transformFormat);
|
|
122
|
+
}
|
|
@@ -5,6 +5,7 @@ import { logger } from '../../console/logger.js';
|
|
|
5
5
|
import chalk from 'chalk';
|
|
6
6
|
import micromatch from 'micromatch';
|
|
7
7
|
import { BASE_PARSING_FLAGS_DEFAULT, GT_PARSING_FLAGS_DEFAULT, } from '../../config/defaults.js';
|
|
8
|
+
import { resolveTransformationFormat } from '../../formats/files/transformFormat.js';
|
|
8
9
|
/**
|
|
9
10
|
* Resolves the files from the files object
|
|
10
11
|
* Replaces [locale] with the actual locale in the files
|
|
@@ -59,6 +60,8 @@ export function resolveFiles(files, locale, locales, cwd, compositePatterns) {
|
|
|
59
60
|
const resolvedPaths = {};
|
|
60
61
|
const placeholderResult = {};
|
|
61
62
|
const transformPaths = {};
|
|
63
|
+
// Output format transforms are tracked separately from path transforms.
|
|
64
|
+
const transformFormats = {};
|
|
62
65
|
const publishPaths = new Set();
|
|
63
66
|
const unpublishPaths = new Set();
|
|
64
67
|
const parsingFlags = {};
|
|
@@ -75,6 +78,11 @@ export function resolveFiles(files, locale, locales, cwd, compositePatterns) {
|
|
|
75
78
|
Array.isArray(transform))) {
|
|
76
79
|
transformPaths[fileType] = transform;
|
|
77
80
|
}
|
|
81
|
+
// Validate source -> output format transforms during settings generation.
|
|
82
|
+
const transformFormat = resolveTransformationFormat(fileType, files[fileType]?.transformationFormat);
|
|
83
|
+
if (transformFormat) {
|
|
84
|
+
transformFormats[fileType] = transformFormat;
|
|
85
|
+
}
|
|
78
86
|
// ==== PLACEHOLDERS ==== //
|
|
79
87
|
if (files[fileType]?.include) {
|
|
80
88
|
const { paths, publishPatterns, unpublishPatterns } = normalizeIncludePatterns(files[fileType].include);
|
|
@@ -96,6 +104,7 @@ export function resolveFiles(files, locale, locales, cwd, compositePatterns) {
|
|
|
96
104
|
resolvedPaths,
|
|
97
105
|
placeholderPaths: placeholderResult,
|
|
98
106
|
transformPaths: transformPaths,
|
|
107
|
+
transformFormats,
|
|
99
108
|
publishPaths,
|
|
100
109
|
unpublishPaths,
|
|
101
110
|
parsingFlags,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const PACKAGE_VERSION = "2.14.
|
|
1
|
+
export declare const PACKAGE_VERSION = "2.14.22";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// This file is auto-generated. Do not edit manually.
|
|
2
|
-
export const PACKAGE_VERSION = '2.14.
|
|
2
|
+
export const PACKAGE_VERSION = '2.14.22';
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CustomMapping } from 'generaltranslation/types';
|
|
1
|
+
import { CustomMapping, FileFormat } from 'generaltranslation/types';
|
|
2
2
|
import { SUPPORTED_FILE_EXTENSIONS } from '../formats/files/supportedFiles.js';
|
|
3
3
|
import { ParsingConfigOptions, GTParsingFlags, BaseParsingFlags, ParseFlagsByFileType } from './parsing.js';
|
|
4
4
|
import { Libraries, InlineLibrary } from './libraries.js';
|
|
@@ -135,6 +135,9 @@ export type TransformOption = {
|
|
|
135
135
|
export type TransformFiles = {
|
|
136
136
|
[K in SupportedFileExtension]?: TransformOption | string | TransformOption[];
|
|
137
137
|
};
|
|
138
|
+
export type TransformFormats = {
|
|
139
|
+
[K in SupportedFileExtension]?: FileFormat;
|
|
140
|
+
};
|
|
138
141
|
export type IncludePattern = string | {
|
|
139
142
|
pattern: string;
|
|
140
143
|
publish?: boolean;
|
|
@@ -144,6 +147,7 @@ export type FilesOptions = {
|
|
|
144
147
|
include: IncludePattern[];
|
|
145
148
|
exclude?: string[];
|
|
146
149
|
transform?: string | TransformOption | TransformOption[];
|
|
150
|
+
transformationFormat?: FileFormat;
|
|
147
151
|
parsingFlags?: BaseParsingFlags;
|
|
148
152
|
};
|
|
149
153
|
} & {
|
|
@@ -172,6 +176,7 @@ export type Settings = {
|
|
|
172
176
|
resolvedPaths: ResolvedFiles;
|
|
173
177
|
placeholderPaths: ResolvedFiles;
|
|
174
178
|
transformPaths: TransformFiles;
|
|
179
|
+
transformFormats: TransformFormats;
|
|
175
180
|
publishPaths: Set<string>;
|
|
176
181
|
unpublishPaths: Set<string>;
|
|
177
182
|
parsingFlags: ParseFlagsByFileType;
|
|
@@ -7,7 +7,7 @@ export default async function flattenJsonFiles(settings, includeFiles) {
|
|
|
7
7
|
return;
|
|
8
8
|
}
|
|
9
9
|
const { resolvedPaths: sourceFiles } = settings.files;
|
|
10
|
-
const fileMapping = createFileMapping(sourceFiles, settings.files.placeholderPaths, settings.files.transformPaths, settings.locales, settings.defaultLocale);
|
|
10
|
+
const fileMapping = createFileMapping(sourceFiles, settings.files.placeholderPaths, settings.files.transformPaths, settings.files.transformFormats, settings.locales, settings.defaultLocale);
|
|
11
11
|
await Promise.all(Object.values(fileMapping).map(async (filesMap) => {
|
|
12
12
|
const targetFiles = Object.values(filesMap).filter((p) => p.endsWith('.json') && (!includeFiles || includeFiles.has(p)));
|
|
13
13
|
await Promise.all(targetFiles.map(async (file) => {
|
|
@@ -136,7 +136,7 @@ export default async function localizeRelativeAssets(settings, targetLocales, in
|
|
|
136
136
|
}
|
|
137
137
|
const { resolvedPaths: sourceFiles } = settings.files;
|
|
138
138
|
const locales = targetLocales || settings.locales;
|
|
139
|
-
const fileMapping = createFileMapping(sourceFiles, settings.files.placeholderPaths, settings.files.transformPaths, settings.locales, settings.defaultLocale);
|
|
139
|
+
const fileMapping = createFileMapping(sourceFiles, settings.files.placeholderPaths, settings.files.transformPaths, settings.files.transformFormats, settings.locales, settings.defaultLocale);
|
|
140
140
|
const cwd = process.cwd();
|
|
141
141
|
const processPromises = Object.entries(fileMapping)
|
|
142
142
|
.filter(([locale]) => locales.includes(locale))
|
|
@@ -28,7 +28,7 @@ export default async function localizeStaticImports(settings, includeFiles) {
|
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
30
30
|
const { resolvedPaths: sourceFiles } = settings.files;
|
|
31
|
-
const fileMapping = createFileMapping(sourceFiles, settings.files.placeholderPaths, settings.files.transformPaths, settings.locales, settings.defaultLocale);
|
|
31
|
+
const fileMapping = createFileMapping(sourceFiles, settings.files.placeholderPaths, settings.files.transformPaths, settings.files.transformFormats, settings.locales, settings.defaultLocale);
|
|
32
32
|
// Process all file types at once with a single call
|
|
33
33
|
const processPromises = [];
|
|
34
34
|
// First, process default locale files (from source files)
|
|
@@ -31,7 +31,7 @@ export default async function localizeStaticUrls(settings, targetLocales, includ
|
|
|
31
31
|
const { resolvedPaths: sourceFiles } = settings.files;
|
|
32
32
|
// Use filtered locales if provided, otherwise use all locales
|
|
33
33
|
const locales = targetLocales || settings.locales;
|
|
34
|
-
const fileMapping = createFileMapping(sourceFiles, settings.files.placeholderPaths, settings.files.transformPaths, settings.locales, // Always use all locales for mapping, filter later
|
|
34
|
+
const fileMapping = createFileMapping(sourceFiles, settings.files.placeholderPaths, settings.files.transformPaths, settings.files.transformFormats, settings.locales, // Always use all locales for mapping, filter later
|
|
35
35
|
settings.defaultLocale);
|
|
36
36
|
// Process all file types at once with a single call
|
|
37
37
|
const processPromises = [];
|
|
@@ -9,8 +9,8 @@ import * as fs from 'fs';
|
|
|
9
9
|
export default async function processAnchorIds(settings, includeFiles) {
|
|
10
10
|
if (!settings.files)
|
|
11
11
|
return;
|
|
12
|
-
const { resolvedPaths, placeholderPaths, transformPaths } = settings.files;
|
|
13
|
-
const fileMapping = createFileMapping(resolvedPaths, placeholderPaths, transformPaths, settings.locales, settings.defaultLocale);
|
|
12
|
+
const { resolvedPaths, placeholderPaths, transformPaths, transformFormats } = settings.files;
|
|
13
|
+
const fileMapping = createFileMapping(resolvedPaths, placeholderPaths, transformPaths, transformFormats, settings.locales, settings.defaultLocale);
|
|
14
14
|
const sourceTypeByPath = new Map();
|
|
15
15
|
if (resolvedPaths.md) {
|
|
16
16
|
for (const filePath of resolvedPaths.md) {
|
|
@@ -34,8 +34,8 @@ export default async function processOpenApi(settings, includeFiles) {
|
|
|
34
34
|
if (!specAnalyses.length)
|
|
35
35
|
return;
|
|
36
36
|
const warnings = new Set();
|
|
37
|
-
const { resolvedPaths, placeholderPaths, transformPaths } = settings.files;
|
|
38
|
-
const fileMapping = createFileMapping(resolvedPaths, placeholderPaths, transformPaths, settings.locales, settings.defaultLocale);
|
|
37
|
+
const { resolvedPaths, placeholderPaths, transformPaths, transformFormats } = settings.files;
|
|
38
|
+
const fileMapping = createFileMapping(resolvedPaths, placeholderPaths, transformPaths, transformFormats, settings.locales, settings.defaultLocale);
|
|
39
39
|
const fileMappingAbs = {};
|
|
40
40
|
for (const [locale, mapping] of Object.entries(fileMapping)) {
|
|
41
41
|
fileMappingAbs[locale] = {};
|
|
@@ -226,11 +226,11 @@ export async function mirrorAssetsToLocales(settings) {
|
|
|
226
226
|
const assetPaths = resolveAssetPaths(include, cwd);
|
|
227
227
|
if (assetPaths.size === 0)
|
|
228
228
|
return;
|
|
229
|
-
const { resolvedPaths, placeholderPaths, transformPaths } = settings.files;
|
|
229
|
+
const { resolvedPaths, placeholderPaths, transformPaths, transformFormats } = settings.files;
|
|
230
230
|
const targetLocales = settings.locales.filter((l) => l !== settings.defaultLocale);
|
|
231
231
|
if (targetLocales.length === 0)
|
|
232
232
|
return;
|
|
233
|
-
const fileMapping = createFileMapping(resolvedPaths, placeholderPaths, transformPaths, targetLocales, settings.defaultLocale);
|
|
233
|
+
const fileMapping = createFileMapping(resolvedPaths, placeholderPaths, transformPaths, transformFormats, targetLocales, settings.defaultLocale);
|
|
234
234
|
for (const locale of targetLocales) {
|
|
235
235
|
const filesMap = fileMapping[locale];
|
|
236
236
|
if (!filesMap)
|
|
@@ -110,7 +110,15 @@ export class UploadSourcesStep extends WorkflowStep {
|
|
|
110
110
|
sourceLocale: this.settings.defaultLocale,
|
|
111
111
|
modelProvider: this.settings.modelProvider,
|
|
112
112
|
});
|
|
113
|
-
|
|
113
|
+
// The API may not echo transformFormat, so preserve it from local inputs.
|
|
114
|
+
const localFileMap = new Map(files.map((f) => [`${f.fileId}:${f.versionId}`, f]));
|
|
115
|
+
this.result = response.uploadedFiles.map((uploadedFile) => {
|
|
116
|
+
const localFile = localFileMap.get(`${uploadedFile.fileId}:${uploadedFile.versionId}`);
|
|
117
|
+
return {
|
|
118
|
+
...uploadedFile,
|
|
119
|
+
transformFormat: localFile?.transformFormat ?? uploadedFile.transformFormat,
|
|
120
|
+
};
|
|
121
|
+
});
|
|
114
122
|
// Merge files that were already uploaded into the result
|
|
115
123
|
this.result.push(...filesToSkipUpload.map((f) => ({
|
|
116
124
|
fileId: f.fileId,
|
|
@@ -118,6 +126,7 @@ export class UploadSourcesStep extends WorkflowStep {
|
|
|
118
126
|
branchId: f.branchId ?? currentBranchId,
|
|
119
127
|
fileName: f.fileName,
|
|
120
128
|
fileFormat: f.fileFormat,
|
|
129
|
+
transformFormat: f.transformFormat,
|
|
121
130
|
dataFormat: f.dataFormat,
|
|
122
131
|
locale: f.locale,
|
|
123
132
|
})));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gt",
|
|
3
|
-
"version": "2.14.
|
|
3
|
+
"version": "2.14.22",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"bin": "dist/main.js",
|
|
6
6
|
"files": [
|
|
@@ -110,8 +110,8 @@
|
|
|
110
110
|
"unified": "^11.0.5",
|
|
111
111
|
"unist-util-visit": "^5.0.0",
|
|
112
112
|
"yaml": "^2.8.0",
|
|
113
|
-
"@generaltranslation/python-extractor": "0.2.
|
|
114
|
-
"generaltranslation": "8.2.
|
|
113
|
+
"@generaltranslation/python-extractor": "0.2.13",
|
|
114
|
+
"generaltranslation": "8.2.8",
|
|
115
115
|
"gt-remark": "1.0.7"
|
|
116
116
|
},
|
|
117
117
|
"devDependencies": {
|