gtx-cli 2.1.5 → 2.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- 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 +48 -68
- 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 +54 -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 +2 -2
- 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,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 localizeStaticUrls(settings:
|
|
15
|
+
export default function localizeStaticUrls(settings: Settings): Promise<void>;
|
|
@@ -48,7 +48,7 @@ export default async function localizeStaticUrls(settings) {
|
|
|
48
48
|
const fileContent = await fs.promises.readFile(filePath, 'utf8');
|
|
49
49
|
// Localize the file using default locale
|
|
50
50
|
const localizedFile = localizeStaticUrlsForFile(fileContent, settings.defaultLocale, settings.defaultLocale, // Process as default locale
|
|
51
|
-
settings.experimentalHideDefaultLocale || false, settings.options?.docsUrlPattern, settings.options?.excludeStaticUrls);
|
|
51
|
+
settings.options?.experimentalHideDefaultLocale || false, settings.options?.docsUrlPattern, settings.options?.excludeStaticUrls);
|
|
52
52
|
// Write the localized file back to the same path
|
|
53
53
|
await fs.promises.writeFile(filePath, localizedFile);
|
|
54
54
|
}));
|
|
@@ -64,7 +64,7 @@ export default async function localizeStaticUrls(settings) {
|
|
|
64
64
|
// Get file content
|
|
65
65
|
const fileContent = await fs.promises.readFile(filePath, 'utf8');
|
|
66
66
|
// Localize the file (handles both URLs and hrefs in single AST pass)
|
|
67
|
-
const localizedFile = localizeStaticUrlsForFile(fileContent, settings.defaultLocale, locale, settings.experimentalHideDefaultLocale || false, settings.options?.docsUrlPattern, settings.options?.excludeStaticUrls);
|
|
67
|
+
const localizedFile = localizeStaticUrlsForFile(fileContent, settings.defaultLocale, locale, settings.options?.experimentalHideDefaultLocale || false, settings.options?.docsUrlPattern, settings.options?.excludeStaticUrls);
|
|
68
68
|
// Write the localized file to the target path
|
|
69
69
|
await fs.promises.writeFile(filePath, localizedFile);
|
|
70
70
|
}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gtx-cli",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.6",
|
|
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",
|
|
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>;
|
package/dist/api/downloadFile.js
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import * as fs from 'fs';
|
|
2
|
-
import * as path from 'path';
|
|
3
|
-
import { logError } from '../console/logging.js';
|
|
4
|
-
import { gt } from '../utils/gt.js';
|
|
5
|
-
import { validateJsonSchema } from '../formats/json/utils.js';
|
|
6
|
-
import { mergeJson } from '../formats/json/mergeJson.js';
|
|
7
|
-
import { TextDecoder } from 'node:util';
|
|
8
|
-
import mergeYaml from '../formats/yaml/mergeYaml.js';
|
|
9
|
-
import { validateYamlSchema } from '../formats/yaml/utils.js';
|
|
10
|
-
/**
|
|
11
|
-
* Downloads a file from the API and saves it to a local directory
|
|
12
|
-
* @param translationId - The ID of the translation to download
|
|
13
|
-
* @param outputPath - The path to save the file to
|
|
14
|
-
* @param maxRetries - The maximum number of retries to attempt
|
|
15
|
-
* @param retryDelay - The delay between retries in milliseconds
|
|
16
|
-
*/
|
|
17
|
-
export async function downloadFile(translationId, outputPath, inputPath, locale, options, maxRetries = 3, retryDelay = 1000) {
|
|
18
|
-
let retries = 0;
|
|
19
|
-
while (retries <= maxRetries) {
|
|
20
|
-
try {
|
|
21
|
-
// Get the file data as an ArrayBuffer
|
|
22
|
-
const fileData = await gt.downloadFile(translationId);
|
|
23
|
-
// Ensure the directory exists
|
|
24
|
-
const dir = path.dirname(outputPath);
|
|
25
|
-
if (!fs.existsSync(dir)) {
|
|
26
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
27
|
-
}
|
|
28
|
-
let data = new TextDecoder().decode(fileData);
|
|
29
|
-
if (options.options?.jsonSchema && locale) {
|
|
30
|
-
const jsonSchema = validateJsonSchema(options.options, inputPath);
|
|
31
|
-
if (jsonSchema) {
|
|
32
|
-
const originalContent = fs.readFileSync(inputPath, 'utf8');
|
|
33
|
-
if (originalContent) {
|
|
34
|
-
data = mergeJson(originalContent, inputPath, options.options, [
|
|
35
|
-
{
|
|
36
|
-
translatedContent: data,
|
|
37
|
-
targetLocale: locale,
|
|
38
|
-
},
|
|
39
|
-
], options.defaultLocale)[0];
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
if (options.options?.yamlSchema && locale) {
|
|
44
|
-
const yamlSchema = validateYamlSchema(options.options, inputPath);
|
|
45
|
-
if (yamlSchema) {
|
|
46
|
-
const originalContent = fs.readFileSync(inputPath, 'utf8');
|
|
47
|
-
if (originalContent) {
|
|
48
|
-
data = mergeYaml(originalContent, inputPath, options.options, [
|
|
49
|
-
{
|
|
50
|
-
translatedContent: data,
|
|
51
|
-
targetLocale: locale,
|
|
52
|
-
},
|
|
53
|
-
])[0];
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
// Write the file to disk
|
|
58
|
-
await fs.promises.writeFile(outputPath, data);
|
|
59
|
-
return true;
|
|
60
|
-
}
|
|
61
|
-
catch (error) {
|
|
62
|
-
// If we've retried too many times, log an error and return false
|
|
63
|
-
if (retries >= maxRetries) {
|
|
64
|
-
logError(`Error downloading file ${outputPath} after ${maxRetries + 1} attempts: ` +
|
|
65
|
-
error);
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
// Increment retry counter and wait before next attempt
|
|
69
|
-
retries++;
|
|
70
|
-
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { RetrievedTranslations } from 'generaltranslation/types';
|
|
2
|
-
/**
|
|
3
|
-
* Fetches translations from the API and saves them to a local directory
|
|
4
|
-
* @param translationsDir - The directory to save the translations to
|
|
5
|
-
* @param fileType - The file type to save the translations as (file extension)
|
|
6
|
-
*/
|
|
7
|
-
export declare function fetchTranslations(versionId: string): Promise<RetrievedTranslations>;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import { logError } from '../console/logging.js';
|
|
3
|
-
import { gt } from '../utils/gt.js';
|
|
4
|
-
/**
|
|
5
|
-
* Fetches translations from the API and saves them to a local directory
|
|
6
|
-
* @param translationsDir - The directory to save the translations to
|
|
7
|
-
* @param fileType - The file type to save the translations as (file extension)
|
|
8
|
-
*/
|
|
9
|
-
export async function fetchTranslations(versionId) {
|
|
10
|
-
try {
|
|
11
|
-
const result = await gt.fetchTranslations(versionId);
|
|
12
|
-
return result.translations;
|
|
13
|
-
}
|
|
14
|
-
catch {
|
|
15
|
-
logError(chalk.red('Failed to fetch translations'));
|
|
16
|
-
return [];
|
|
17
|
-
}
|
|
18
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { Settings, SupportedLibraries, Updates } from '../types/index.js';
|
|
2
|
-
import { DataFormat } from '../types/data.js';
|
|
3
|
-
export type ApiOptions = Settings & {
|
|
4
|
-
timeout: string;
|
|
5
|
-
dataFormat: DataFormat;
|
|
6
|
-
description?: string;
|
|
7
|
-
requireApproval?: boolean;
|
|
8
|
-
};
|
|
9
|
-
export type SendUpdatesResult = {
|
|
10
|
-
versionId: string;
|
|
11
|
-
locales: string[];
|
|
12
|
-
};
|
|
13
|
-
/**
|
|
14
|
-
* Sends updates to the API
|
|
15
|
-
* @param updates - The updates to send
|
|
16
|
-
* @param options - The options for the API call
|
|
17
|
-
* @returns The versionId of the updated project
|
|
18
|
-
*/
|
|
19
|
-
export declare function sendUpdates(updates: Updates, options: ApiOptions, library: SupportedLibraries): Promise<SendUpdatesResult>;
|