gtx-cli 2.1.5-alpha.5 → 2.1.5-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/checkFileTranslations.d.ts +1 -4
- package/dist/api/checkFileTranslations.js +32 -35
- package/dist/api/downloadFileBatch.d.ts +1 -0
- package/dist/api/sendFiles.d.ts +2 -13
- package/dist/api/sendFiles.js +15 -8
- package/dist/cli/base.d.ts +5 -17
- package/dist/cli/base.js +57 -75
- package/dist/cli/commands/stage.d.ts +5 -0
- package/dist/cli/commands/stage.js +100 -0
- package/dist/cli/commands/translate.d.ts +6 -0
- package/dist/cli/commands/translate.js +58 -0
- package/dist/cli/flags.d.ts +3 -0
- package/dist/cli/flags.js +37 -0
- package/dist/cli/next.js +0 -1
- package/dist/cli/react.d.ts +2 -5
- package/dist/cli/react.js +13 -153
- package/dist/config/generateSettings.js +11 -6
- package/dist/console/index.d.ts +1 -0
- package/dist/console/index.js +1 -0
- package/dist/console/logging.d.ts +1 -0
- package/dist/console/logging.js +3 -0
- package/dist/formats/files/fileMapping.d.ts +2 -1
- package/dist/formats/files/fileMapping.js +6 -0
- package/dist/formats/files/translate.d.ts +4 -13
- package/dist/formats/files/translate.js +30 -142
- package/dist/formats/files/upload.js +1 -75
- package/dist/formats/gt/save.d.ts +1 -2
- package/dist/formats/gt/save.js +2 -5
- package/dist/fs/config/setupConfig.d.ts +1 -0
- package/dist/fs/config/setupConfig.js +1 -0
- package/dist/fs/config/updateConfig.d.ts +1 -2
- package/dist/fs/config/updateConfig.js +1 -1
- package/dist/fs/config/updateVersions.d.ts +10 -0
- package/dist/fs/config/updateVersions.js +30 -0
- package/dist/fs/copyFile.d.ts +1 -2
- package/dist/translation/parse.d.ts +2 -2
- package/dist/translation/parse.js +4 -6
- package/dist/translation/stage.d.ts +2 -5
- package/dist/translation/stage.js +13 -55
- package/dist/types/files.d.ts +1 -0
- package/dist/types/files.js +1 -0
- package/dist/types/index.d.ts +27 -3
- package/dist/utils/flattenJsonFiles.d.ts +2 -2
- package/dist/utils/hash.d.ts +6 -0
- package/dist/utils/hash.js +11 -0
- package/dist/utils/localizeStaticImports.d.ts +2 -2
- package/dist/utils/localizeStaticUrls.d.ts +2 -2
- package/dist/utils/localizeStaticUrls.js +22 -16
- package/package.json +2 -2
- package/dist/api/downloadFile.d.ts +0 -9
- package/dist/api/downloadFile.js +0 -74
- package/dist/api/fetchTranslations.d.ts +0 -7
- package/dist/api/fetchTranslations.js +0 -18
- package/dist/api/sendUpdates.d.ts +0 -19
- package/dist/api/sendUpdates.js +0 -48
- package/dist/api/waitForUpdates.d.ts +0 -9
- package/dist/api/waitForUpdates.js +0 -89
- package/dist/translation/translate.d.ts +0 -2
- package/dist/translation/translate.js +0 -18
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { noSupportedFormatError, noDefaultLocaleError, noApiKeyError, noProjectIdError, devApiKeyError, } from '../../console/index.js';
|
|
2
|
-
import { logErrorAndExit,
|
|
2
|
+
import { logErrorAndExit, logError } from '../../console/logging.js';
|
|
3
3
|
import { getRelative, readFile } from '../../fs/findFilepath.js';
|
|
4
|
-
import chalk from 'chalk';
|
|
5
|
-
import { downloadFile } from '../../api/downloadFile.js';
|
|
6
|
-
import { downloadFileBatch } from '../../api/downloadFileBatch.js';
|
|
7
4
|
import { SUPPORTED_FILE_EXTENSIONS } from './supportedFiles.js';
|
|
8
5
|
import sanitizeFileContent from '../../utils/sanitizeFileContent.js';
|
|
9
6
|
import { parseJson } from '../json/parseJson.js';
|
|
@@ -139,74 +136,3 @@ export async function upload(filePaths, placeholderPaths, transformPaths, dataFo
|
|
|
139
136
|
logErrorAndExit(`Error uploading files: ${error}`);
|
|
140
137
|
}
|
|
141
138
|
}
|
|
142
|
-
/**
|
|
143
|
-
* Processes translations that were already completed and returned with the initial API response
|
|
144
|
-
* @returns Set of downloaded file+locale combinations
|
|
145
|
-
*/
|
|
146
|
-
async function processInitialTranslations(translations = [], fileMapping, options) {
|
|
147
|
-
const downloadStatus = {
|
|
148
|
-
downloaded: new Set(),
|
|
149
|
-
failed: new Set(),
|
|
150
|
-
};
|
|
151
|
-
if (!translations || translations.length === 0) {
|
|
152
|
-
return downloadStatus;
|
|
153
|
-
}
|
|
154
|
-
// Filter for ready translations
|
|
155
|
-
const readyTranslations = translations.filter((translation) => translation.isReady && translation.fileName);
|
|
156
|
-
if (readyTranslations.length > 0) {
|
|
157
|
-
const spinner = createSpinner('dots');
|
|
158
|
-
spinner.start('Downloading translations...');
|
|
159
|
-
// Prepare batch download data
|
|
160
|
-
const batchFiles = readyTranslations
|
|
161
|
-
.map((translation) => {
|
|
162
|
-
const { locale, fileName, id } = translation;
|
|
163
|
-
const outputPath = fileMapping[locale][fileName];
|
|
164
|
-
if (!outputPath) {
|
|
165
|
-
return null;
|
|
166
|
-
}
|
|
167
|
-
return {
|
|
168
|
-
translationId: id,
|
|
169
|
-
outputPath,
|
|
170
|
-
inputPath: fileName,
|
|
171
|
-
fileLocale: `${fileName}:${locale}`,
|
|
172
|
-
locale,
|
|
173
|
-
};
|
|
174
|
-
})
|
|
175
|
-
.filter(Boolean);
|
|
176
|
-
if (batchFiles.length === 0 || batchFiles[0] === null) {
|
|
177
|
-
return downloadStatus;
|
|
178
|
-
}
|
|
179
|
-
// Use batch download if there are multiple files
|
|
180
|
-
if (batchFiles.length > 1) {
|
|
181
|
-
const batchResult = await downloadFileBatch(batchFiles.map(({ translationId, outputPath, inputPath, locale }) => ({
|
|
182
|
-
translationId,
|
|
183
|
-
outputPath,
|
|
184
|
-
inputPath,
|
|
185
|
-
locale,
|
|
186
|
-
})), options);
|
|
187
|
-
// Process results
|
|
188
|
-
batchFiles.forEach((file) => {
|
|
189
|
-
const { translationId, fileLocale } = file;
|
|
190
|
-
if (batchResult.successful.includes(translationId)) {
|
|
191
|
-
downloadStatus.downloaded.add(fileLocale);
|
|
192
|
-
}
|
|
193
|
-
else if (batchResult.failed.includes(translationId)) {
|
|
194
|
-
downloadStatus.failed.add(fileLocale);
|
|
195
|
-
}
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
else if (batchFiles.length === 1) {
|
|
199
|
-
// For a single file, use the original downloadFile method
|
|
200
|
-
const file = batchFiles[0];
|
|
201
|
-
const result = await downloadFile(file.translationId, file.outputPath, file.inputPath, file.locale, options);
|
|
202
|
-
if (result) {
|
|
203
|
-
downloadStatus.downloaded.add(file.fileLocale);
|
|
204
|
-
}
|
|
205
|
-
else {
|
|
206
|
-
downloadStatus.failed.add(file.fileLocale);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
spinner.stop(chalk.green('Downloaded cached translations'));
|
|
210
|
-
}
|
|
211
|
-
return downloadStatus;
|
|
212
|
-
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { RetrievedTranslations } from 'generaltranslation/types';
|
|
2
2
|
import { ResolvedFiles } from '../../types/index.js';
|
|
3
|
-
import { DataFormat } from '../../types/data.js';
|
|
4
3
|
/**
|
|
5
4
|
* Saves translations to a local directory
|
|
6
5
|
* @param translations - The translations to save
|
|
7
6
|
* @param translationsDir - The directory to save the translations to
|
|
8
7
|
* @param fileType - The file type to save the translations as (file extension)
|
|
9
8
|
*/
|
|
10
|
-
export declare function saveTranslations(translations: RetrievedTranslations, placeholderPaths: ResolvedFiles
|
|
9
|
+
export declare function saveTranslations(translations: RetrievedTranslations, placeholderPaths: ResolvedFiles): Promise<void>;
|
package/dist/formats/gt/save.js
CHANGED
|
@@ -9,7 +9,7 @@ import { resolveLocaleFiles } from '../../fs/config/parseFilesConfig.js';
|
|
|
9
9
|
* @param translationsDir - The directory to save the translations to
|
|
10
10
|
* @param fileType - The file type to save the translations as (file extension)
|
|
11
11
|
*/
|
|
12
|
-
export async function saveTranslations(translations, placeholderPaths
|
|
12
|
+
export async function saveTranslations(translations, placeholderPaths) {
|
|
13
13
|
for (const translation of translations) {
|
|
14
14
|
const locale = translation.locale;
|
|
15
15
|
const translationFiles = resolveLocaleFiles(placeholderPaths, locale);
|
|
@@ -21,9 +21,6 @@ export async function saveTranslations(translations, placeholderPaths, dataForma
|
|
|
21
21
|
const translationData = translation.translation;
|
|
22
22
|
// Ensure directory exists
|
|
23
23
|
await fs.promises.mkdir(path.dirname(filepath), { recursive: true });
|
|
24
|
-
|
|
25
|
-
if (dataFormat === 'JSX') {
|
|
26
|
-
await fs.promises.writeFile(filepath, JSON.stringify(translationData, null, 2));
|
|
27
|
-
}
|
|
24
|
+
await fs.promises.writeFile(filepath, JSON.stringify(translationData, null, 2));
|
|
28
25
|
}
|
|
29
26
|
}
|
|
@@ -17,6 +17,7 @@ export async function createOrUpdateConfig(configFilepath, options) {
|
|
|
17
17
|
...(options.files && { files: options.files }),
|
|
18
18
|
...(options.framework && { framework: options.framework }),
|
|
19
19
|
...(options.baseUrl && { baseUrl: options.baseUrl }),
|
|
20
|
+
...(options.publish && { publish: options.publish }),
|
|
20
21
|
};
|
|
21
22
|
try {
|
|
22
23
|
// if file exists
|
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
* Update the config file version id, locales, and projectId (if necessary)
|
|
3
3
|
* @param {Record<string, any>} configObject - The config object to write if the file does not exist.
|
|
4
4
|
*/
|
|
5
|
-
export default function updateConfig({ configFilepath, projectId, _versionId,
|
|
5
|
+
export default function updateConfig({ configFilepath, projectId, _versionId, stageTranslations, }: {
|
|
6
6
|
configFilepath: string;
|
|
7
7
|
projectId?: string;
|
|
8
8
|
_versionId?: string;
|
|
9
|
-
locales?: string[];
|
|
10
9
|
stageTranslations?: boolean;
|
|
11
10
|
}): Promise<void>;
|
|
@@ -5,7 +5,7 @@ import { logError } from '../../console/logging.js';
|
|
|
5
5
|
* Update the config file version id, locales, and projectId (if necessary)
|
|
6
6
|
* @param {Record<string, any>} configObject - The config object to write if the file does not exist.
|
|
7
7
|
*/
|
|
8
|
-
export default async function updateConfig({ configFilepath, projectId, _versionId,
|
|
8
|
+
export default async function updateConfig({ configFilepath, projectId, _versionId, stageTranslations, }) {
|
|
9
9
|
// Filter out empty string values from the config object
|
|
10
10
|
const newContent = {
|
|
11
11
|
...(projectId && { projectId }),
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type StagedVersionData = Record<string, {
|
|
2
|
+
fileName: string;
|
|
3
|
+
versionId: string;
|
|
4
|
+
}>;
|
|
5
|
+
export declare function updateVersions({ configDirectory, versionData, }: {
|
|
6
|
+
configDirectory: string;
|
|
7
|
+
versionData: StagedVersionData;
|
|
8
|
+
}): Promise<void>;
|
|
9
|
+
export declare function getStagedVersions(configDirectory: string): Promise<StagedVersionData>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import { displayUpdatedVersionsFile } from '../../console/logging.js';
|
|
3
|
+
import { logError } from '../../console/logging.js';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
const STAGED_VERSIONS_FILE = 'staged-versions.json';
|
|
6
|
+
// Update the versions.json file with the new version ids
|
|
7
|
+
// of the translations that were sent to the API
|
|
8
|
+
export async function updateVersions({ configDirectory, versionData, }) {
|
|
9
|
+
const versionFilepath = path.join(configDirectory, STAGED_VERSIONS_FILE);
|
|
10
|
+
try {
|
|
11
|
+
fs.mkdirSync(configDirectory, { recursive: true });
|
|
12
|
+
fs.writeFileSync(versionFilepath, JSON.stringify(versionData, null, 2));
|
|
13
|
+
// show update in console
|
|
14
|
+
displayUpdatedVersionsFile(versionFilepath);
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
logError(`An error occurred while updating ${versionFilepath}: ${error}`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export async function getStagedVersions(configDirectory) {
|
|
21
|
+
try {
|
|
22
|
+
const versionFilepath = path.join(configDirectory, STAGED_VERSIONS_FILE);
|
|
23
|
+
const versionData = JSON.parse(fs.readFileSync(versionFilepath, 'utf8'));
|
|
24
|
+
return versionData;
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
logError(`An error occurred while getting staged versions: ${error}`);
|
|
28
|
+
return {};
|
|
29
|
+
}
|
|
30
|
+
}
|
package/dist/fs/copyFile.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Settings } from '../types/index.js';
|
|
2
|
-
import { TranslateOptions } from '../cli/base.js';
|
|
3
2
|
/**
|
|
4
3
|
* Copy a file to target locale without translation
|
|
5
4
|
*
|
|
6
5
|
* This is a naive approach, does not allow for wild cards
|
|
7
6
|
*/
|
|
8
|
-
export default function copyFile(settings: Settings
|
|
7
|
+
export default function copyFile(settings: Settings): Promise<void>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Updates, TranslateFlags } from '../types/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* Searches for gt-react or gt-next dictionary files and creates updates for them,
|
|
4
4
|
* as well as inline updates for <T> tags and useGT()/getGT() calls
|
|
@@ -8,7 +8,7 @@ import { Options, GenerateSourceOptions, Updates } from '../types/index.js';
|
|
|
8
8
|
* @param pkg - The package name
|
|
9
9
|
* @returns An object containing the updates and errors
|
|
10
10
|
*/
|
|
11
|
-
export declare function createUpdates(options:
|
|
11
|
+
export declare function createUpdates(options: TranslateFlags, sourceDictionary: string | undefined, pkg: 'gt-react' | 'gt-next', validate: boolean): Promise<{
|
|
12
12
|
updates: Updates;
|
|
13
13
|
errors: string[];
|
|
14
14
|
warnings: string[];
|
|
@@ -48,12 +48,10 @@ export async function createUpdates(options, sourceDictionary, pkg, validate) {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
// Scan through project for <T> tags
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
updates = [...updates, ...newUpdates];
|
|
56
|
-
}
|
|
51
|
+
const { updates: newUpdates, errors: newErrors, warnings: newWarnings, } = await createInlineUpdates(pkg, validate, options.src);
|
|
52
|
+
errors = [...errors, ...newErrors];
|
|
53
|
+
warnings = [...warnings, ...newWarnings];
|
|
54
|
+
updates = [...updates, ...newUpdates];
|
|
57
55
|
// Metadata addition and validation
|
|
58
56
|
const idHashMap = new Map();
|
|
59
57
|
const duplicateIds = new Set();
|
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function
|
|
3
|
-
versionId: string;
|
|
4
|
-
locales: string[];
|
|
5
|
-
} | null>;
|
|
1
|
+
import { Settings, TranslateFlags, Updates } from '../types/index.js';
|
|
2
|
+
export declare function aggregateReactTranslations(options: TranslateFlags, settings: Settings, library: 'gt-react' | 'gt-next'): Promise<Updates>;
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import { devApiKeyError } from '../console/index.js';
|
|
2
1
|
import { logErrorAndExit } from '../console/logging.js';
|
|
3
2
|
import chalk from 'chalk';
|
|
4
3
|
import findFilepath from '../fs/findFilepath.js';
|
|
5
|
-
import {
|
|
4
|
+
import { logWarning, logError } from '../console/logging.js';
|
|
6
5
|
import { createUpdates } from './parse.js';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (!settings.dictionary) {
|
|
11
|
-
settings.dictionary = findFilepath([
|
|
6
|
+
export async function aggregateReactTranslations(options, settings, library) {
|
|
7
|
+
if (!options.dictionary) {
|
|
8
|
+
options.dictionary = findFilepath([
|
|
12
9
|
'./dictionary.js',
|
|
13
10
|
'./src/dictionary.js',
|
|
14
11
|
'./dictionary.json',
|
|
@@ -17,29 +14,16 @@ export async function stageProject(settings, pkg) {
|
|
|
17
14
|
'./src/dictionary.ts',
|
|
18
15
|
]);
|
|
19
16
|
}
|
|
20
|
-
// Separate defaultLocale from locales
|
|
21
|
-
settings.locales = settings.locales.filter((locale) => locale !== settings.defaultLocale);
|
|
22
|
-
// validate timeout
|
|
23
|
-
const timeout = parseInt(settings.timeout);
|
|
24
|
-
if (isNaN(timeout) || timeout < 0) {
|
|
25
|
-
logErrorAndExit(`Invalid timeout: ${settings.timeout}. Must be a positive integer.`);
|
|
26
|
-
}
|
|
27
|
-
settings.timeout = timeout.toString();
|
|
28
17
|
// ---- CREATING UPDATES ---- //
|
|
29
|
-
const { updates, errors, warnings } = await createUpdates(
|
|
18
|
+
const { updates, errors, warnings } = await createUpdates(options, options.dictionary, library, false);
|
|
30
19
|
if (warnings.length > 0) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
logWarning(chalk.yellow(`CLI tool encountered ${warnings.length} warnings while scanning for translatable content. ${chalk.gray('To suppress these warnings, re-run with --suppress-warnings')}\n` +
|
|
36
|
-
warnings
|
|
37
|
-
.map((warning) => chalk.yellow('• Warning: ') + chalk.white(warning))
|
|
38
|
-
.join('\n')));
|
|
39
|
-
}
|
|
20
|
+
logWarning(chalk.yellow(`CLI tool encountered ${warnings.length} warnings while scanning for translatable content.\n` +
|
|
21
|
+
warnings
|
|
22
|
+
.map((warning) => chalk.yellow('• Warning: ') + chalk.white(warning))
|
|
23
|
+
.join('\n')));
|
|
40
24
|
}
|
|
41
25
|
if (errors.length > 0) {
|
|
42
|
-
if (
|
|
26
|
+
if (options.ignoreErrors) {
|
|
43
27
|
logWarning(chalk.yellow(`Warning: CLI tool encountered ${errors.length} syntax errors while scanning for translatable content. These components will not be translated.\n` +
|
|
44
28
|
errors
|
|
45
29
|
.map((error) => chalk.yellow('• ') + chalk.white(error) + '\n')
|
|
@@ -52,35 +36,9 @@ export async function stageProject(settings, pkg) {
|
|
|
52
36
|
.join('')));
|
|
53
37
|
}
|
|
54
38
|
}
|
|
55
|
-
if (settings.dryRun) {
|
|
56
|
-
logSuccess('Dry run: No translations were sent to General Translation.');
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
59
39
|
if (updates.length == 0) {
|
|
60
|
-
logError(chalk.red(`No in-line content or dictionaries were found for ${chalk.green(
|
|
61
|
-
return
|
|
62
|
-
}
|
|
63
|
-
// Send updates to General Translation API
|
|
64
|
-
if (!settings.locales) {
|
|
65
|
-
logErrorAndExit(noLocalesError);
|
|
66
|
-
}
|
|
67
|
-
if (!settings.defaultLocale) {
|
|
68
|
-
logErrorAndExit(noDefaultLocaleError);
|
|
69
|
-
}
|
|
70
|
-
if (!settings.apiKey) {
|
|
71
|
-
logErrorAndExit(noApiKeyError);
|
|
72
|
-
}
|
|
73
|
-
if (settings.apiKey.startsWith('gtx-dev-')) {
|
|
74
|
-
logErrorAndExit(devApiKeyError);
|
|
75
|
-
}
|
|
76
|
-
if (!settings.projectId) {
|
|
77
|
-
logErrorAndExit(noProjectIdError);
|
|
40
|
+
logError(chalk.red(`No in-line content or dictionaries were found for ${chalk.green(library)}. Are you sure you're running this command in the right directory?`));
|
|
41
|
+
return updates;
|
|
78
42
|
}
|
|
79
|
-
|
|
80
|
-
...settings,
|
|
81
|
-
timeout: settings.timeout,
|
|
82
|
-
dataFormat: 'JSX',
|
|
83
|
-
}, pkg);
|
|
84
|
-
const { versionId, locales } = updateResponse;
|
|
85
|
-
return { versionId, locales };
|
|
43
|
+
return updates;
|
|
86
44
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type FileMapping = Record<string, Record<string, string>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -15,13 +15,35 @@ export type Options = {
|
|
|
15
15
|
ignoreErrors: boolean;
|
|
16
16
|
suppressWarnings: boolean;
|
|
17
17
|
dryRun: boolean;
|
|
18
|
-
timeout:
|
|
18
|
+
timeout: number;
|
|
19
19
|
stageTranslations?: boolean;
|
|
20
20
|
experimentalLocalizeStaticUrls?: boolean;
|
|
21
21
|
experimentalHideDefaultLocale?: boolean;
|
|
22
22
|
experimentalFlattenJsonFiles?: boolean;
|
|
23
23
|
experimentalLocalizeStaticImports?: boolean;
|
|
24
24
|
};
|
|
25
|
+
export type TranslateFlags = {
|
|
26
|
+
config?: string;
|
|
27
|
+
apiKey?: string;
|
|
28
|
+
projectId?: string;
|
|
29
|
+
versionId?: string;
|
|
30
|
+
jsconfig?: string;
|
|
31
|
+
dictionary?: string;
|
|
32
|
+
defaultLocale?: string;
|
|
33
|
+
locales?: string[];
|
|
34
|
+
ignoreErrors?: boolean;
|
|
35
|
+
src?: string[];
|
|
36
|
+
timeout: number;
|
|
37
|
+
dryRun: boolean;
|
|
38
|
+
stageTranslations?: boolean;
|
|
39
|
+
publish?: boolean;
|
|
40
|
+
experimentalLocalizeStaticUrls?: boolean;
|
|
41
|
+
experimentalHideDefaultLocale?: boolean;
|
|
42
|
+
experimentalFlattenJsonFiles?: boolean;
|
|
43
|
+
experimentalLocalizeStaticImports?: boolean;
|
|
44
|
+
excludeStaticUrls?: string[];
|
|
45
|
+
excludeStaticImports?: string[];
|
|
46
|
+
};
|
|
25
47
|
export type WrapOptions = {
|
|
26
48
|
src?: string[];
|
|
27
49
|
config: string;
|
|
@@ -80,10 +102,11 @@ export type FilesOptions = {
|
|
|
80
102
|
};
|
|
81
103
|
export type Settings = {
|
|
82
104
|
config: string;
|
|
105
|
+
configDirectory: string;
|
|
83
106
|
baseUrl: string;
|
|
84
107
|
dashboardUrl: string;
|
|
85
|
-
apiKey
|
|
86
|
-
projectId
|
|
108
|
+
apiKey?: string;
|
|
109
|
+
projectId?: string;
|
|
87
110
|
defaultLocale: string;
|
|
88
111
|
locales: string[];
|
|
89
112
|
files: {
|
|
@@ -92,6 +115,7 @@ export type Settings = {
|
|
|
92
115
|
transformPaths: TransformFiles;
|
|
93
116
|
} | undefined;
|
|
94
117
|
stageTranslations: boolean;
|
|
118
|
+
publish: boolean;
|
|
95
119
|
_versionId?: string;
|
|
96
120
|
version?: string;
|
|
97
121
|
description?: string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Settings
|
|
2
|
-
export default function flattenJsonFiles(settings:
|
|
1
|
+
import { Settings } from '../types/index.js';
|
|
2
|
+
export default function flattenJsonFiles(settings: Settings): Promise<void>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
/**
|
|
3
|
+
* Hashes a string using SHA-256 algorithm.
|
|
4
|
+
* @param {string} string - The string to be hashed.
|
|
5
|
+
* @returns {string} The hashed string.
|
|
6
|
+
*/
|
|
7
|
+
export function hashStringSync(string) {
|
|
8
|
+
const hash = crypto.createHash('sha256');
|
|
9
|
+
hash.update(string);
|
|
10
|
+
return hash.digest('hex');
|
|
11
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Settings } from '../types/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* Localizes static imports in content files.
|
|
4
4
|
* Currently only supported for md and mdx files. (/docs/ -> /[locale]/docs/)
|
|
@@ -12,4 +12,4 @@ import { Options, Settings } from '../types/index.js';
|
|
|
12
12
|
* - Support more file types
|
|
13
13
|
* - Support more complex paths
|
|
14
14
|
*/
|
|
15
|
-
export default function localizeStaticImports(settings:
|
|
15
|
+
export default function localizeStaticImports(settings: Settings): Promise<void>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Settings } from '../types/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* Localizes static urls in content files.
|
|
4
4
|
* Currently only supported for md and mdx files. (/docs/ -> /[locale]/docs/)
|
|
@@ -12,7 +12,7 @@ import { Options, Settings } from '../types/index.js';
|
|
|
12
12
|
* - Support more file types
|
|
13
13
|
* - Support more complex paths
|
|
14
14
|
*/
|
|
15
|
-
export default function localizeStaticUrls(settings:
|
|
15
|
+
export default function localizeStaticUrls(settings: Settings, targetLocales?: string[]): Promise<void>;
|
|
16
16
|
/**
|
|
17
17
|
* Main URL transformation function that delegates to specific scenarios
|
|
18
18
|
*/
|
|
@@ -7,7 +7,6 @@ import remarkMdx from 'remark-mdx';
|
|
|
7
7
|
import remarkFrontmatter from 'remark-frontmatter';
|
|
8
8
|
import remarkStringify from 'remark-stringify';
|
|
9
9
|
import { visit } from 'unist-util-visit';
|
|
10
|
-
import { logMessage } from '../console/logging.js';
|
|
11
10
|
const { isMatch } = micromatch;
|
|
12
11
|
/**
|
|
13
12
|
* Localizes static urls in content files.
|
|
@@ -22,8 +21,7 @@ const { isMatch } = micromatch;
|
|
|
22
21
|
* - Support more file types
|
|
23
22
|
* - Support more complex paths
|
|
24
23
|
*/
|
|
25
|
-
export default async function localizeStaticUrls(settings, targetLocales
|
|
26
|
-
) {
|
|
24
|
+
export default async function localizeStaticUrls(settings, targetLocales) {
|
|
27
25
|
if (!settings.files ||
|
|
28
26
|
(Object.keys(settings.files.placeholderPaths).length === 1 &&
|
|
29
27
|
settings.files.placeholderPaths.gt)) {
|
|
@@ -54,10 +52,12 @@ export default async function localizeStaticUrls(settings, targetLocales // Opti
|
|
|
54
52
|
// Get file content
|
|
55
53
|
const fileContent = await fs.promises.readFile(filePath, 'utf8');
|
|
56
54
|
// Localize the file using default locale
|
|
57
|
-
const
|
|
58
|
-
settings.experimentalHideDefaultLocale || false, settings.options?.docsUrlPattern, settings.options?.excludeStaticUrls, settings.options?.baseDomain);
|
|
59
|
-
//
|
|
60
|
-
|
|
55
|
+
const result = localizeStaticUrlsForFile(fileContent, settings.defaultLocale, settings.defaultLocale, // Process as default locale
|
|
56
|
+
settings.options?.experimentalHideDefaultLocale || false, settings.options?.docsUrlPattern, settings.options?.excludeStaticUrls, settings.options?.baseDomain);
|
|
57
|
+
// Only write the file if there were changes
|
|
58
|
+
if (result.hasChanges) {
|
|
59
|
+
await fs.promises.writeFile(filePath, result.content);
|
|
60
|
+
}
|
|
61
61
|
}));
|
|
62
62
|
processPromises.push(defaultPromise);
|
|
63
63
|
}
|
|
@@ -73,9 +73,11 @@ export default async function localizeStaticUrls(settings, targetLocales // Opti
|
|
|
73
73
|
// Get file content
|
|
74
74
|
const fileContent = await fs.promises.readFile(filePath, 'utf8');
|
|
75
75
|
// Localize the file (handles both URLs and hrefs in single AST pass)
|
|
76
|
-
const
|
|
77
|
-
//
|
|
78
|
-
|
|
76
|
+
const result = localizeStaticUrlsForFile(fileContent, settings.defaultLocale, locale, settings.options?.experimentalHideDefaultLocale || false, settings.options?.docsUrlPattern, settings.options?.excludeStaticUrls, settings.options?.baseDomain);
|
|
77
|
+
// Only write the file if there were changes
|
|
78
|
+
if (result.hasChanges) {
|
|
79
|
+
await fs.promises.writeFile(filePath, result.content);
|
|
80
|
+
}
|
|
79
81
|
}));
|
|
80
82
|
});
|
|
81
83
|
processPromises.push(...mappingPromises);
|
|
@@ -233,7 +235,7 @@ function transformMdxUrls(mdxContent, defaultLocale, targetLocale, hideDefaultLo
|
|
|
233
235
|
return {
|
|
234
236
|
content: mdxContent,
|
|
235
237
|
hasChanges: false,
|
|
236
|
-
transformedUrls
|
|
238
|
+
transformedUrls,
|
|
237
239
|
};
|
|
238
240
|
}
|
|
239
241
|
// Helper function to transform URL based on pattern
|
|
@@ -245,11 +247,16 @@ function transformMdxUrls(mdxContent, defaultLocale, targetLocale, hideDefaultLo
|
|
|
245
247
|
// Skip absolute URLs (http://, https://, //, etc.)
|
|
246
248
|
if (baseDomain && shouldProcessAbsoluteUrl(originalUrl, baseDomain)) {
|
|
247
249
|
// Get everything after the base domain
|
|
248
|
-
logMessage(`originalUrl: ${originalUrl}`);
|
|
249
|
-
logMessage(`baseDomain: ${baseDomain}`);
|
|
250
250
|
const afterDomain = originalUrl.substring(baseDomain.length);
|
|
251
|
-
logMessage(`afterDomain: ${afterDomain}`);
|
|
252
251
|
const transformedPath = transformUrlPath(afterDomain, patternHead, targetLocale, defaultLocale, hideDefaultLocale);
|
|
252
|
+
if (!transformedPath) {
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
transformedUrls.push({
|
|
256
|
+
originalPath: originalUrl,
|
|
257
|
+
newPath: transformedPath,
|
|
258
|
+
type: linkType,
|
|
259
|
+
});
|
|
253
260
|
return transformedPath ? baseDomain + transformedPath : null;
|
|
254
261
|
}
|
|
255
262
|
// Exclude colon-prefixed URLs (http://, https://, //, etc.)
|
|
@@ -390,8 +397,7 @@ function transformMdxUrls(mdxContent, defaultLocale, targetLocale, hideDefaultLo
|
|
|
390
397
|
function localizeStaticUrlsForFile(file, defaultLocale, targetLocale, hideDefaultLocale, pattern = '/[locale]', // eg /docs/[locale] or /[locale]
|
|
391
398
|
exclude = [], baseDomain) {
|
|
392
399
|
// Use AST-based transformation for MDX files
|
|
393
|
-
|
|
394
|
-
return result.content;
|
|
400
|
+
return transformMdxUrls(file, defaultLocale, targetLocale, hideDefaultLocale, pattern, exclude, baseDomain || '');
|
|
395
401
|
}
|
|
396
402
|
function cleanPath(path) {
|
|
397
403
|
let cleanedPath = path.startsWith('/') ? path.slice(1) : path;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gtx-cli",
|
|
3
|
-
"version": "2.1.5-alpha.
|
|
3
|
+
"version": "2.1.5-alpha.7",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"bin": "dist/main.js",
|
|
6
6
|
"files": [
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"esbuild": "^0.25.4",
|
|
88
88
|
"fast-glob": "^3.3.3",
|
|
89
89
|
"form-data": "^4.0.4",
|
|
90
|
-
"generaltranslation": "^7.4.
|
|
90
|
+
"generaltranslation": "^7.4.1-alpha.2",
|
|
91
91
|
"json-pointer": "^0.6.2",
|
|
92
92
|
"jsonpath-plus": "^10.3.0",
|
|
93
93
|
"jsonpointer": "^5.0.1",
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { Settings } from '../types/index.js';
|
|
2
|
-
/**
|
|
3
|
-
* Downloads a file from the API and saves it to a local directory
|
|
4
|
-
* @param translationId - The ID of the translation to download
|
|
5
|
-
* @param outputPath - The path to save the file to
|
|
6
|
-
* @param maxRetries - The maximum number of retries to attempt
|
|
7
|
-
* @param retryDelay - The delay between retries in milliseconds
|
|
8
|
-
*/
|
|
9
|
-
export declare function downloadFile(translationId: string, outputPath: string, inputPath: string, locale: string, options: Settings, maxRetries?: number, retryDelay?: number): Promise<boolean>;
|