gtx-cli 2.3.5 → 2.3.6-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +23 -18
- package/dist/api/checkFileTranslations.d.ts +0 -23
- package/dist/api/checkFileTranslations.js +0 -236
- package/dist/api/downloadFileBatch.d.ts +0 -20
- package/dist/api/downloadFileBatch.js +0 -113
- package/dist/api/sendFiles.d.ts +0 -17
- package/dist/api/sendFiles.js +0 -115
- package/dist/api/uploadFiles.d.ts +0 -27
- package/dist/api/uploadFiles.js +0 -40
- package/dist/cli/base.d.ts +0 -32
- package/dist/cli/base.js +0 -335
- package/dist/cli/commands/stage.d.ts +0 -5
- package/dist/cli/commands/stage.js +0 -100
- package/dist/cli/commands/translate.d.ts +0 -6
- package/dist/cli/commands/translate.js +0 -63
- package/dist/cli/flags.d.ts +0 -3
- package/dist/cli/flags.js +0 -38
- package/dist/cli/next.d.ts +0 -11
- package/dist/cli/next.js +0 -20
- package/dist/cli/react.d.ts +0 -18
- package/dist/cli/react.js +0 -175
- package/dist/config/generateSettings.d.ts +0 -9
- package/dist/config/generateSettings.js +0 -176
- package/dist/config/optionPresets.d.ts +0 -2
- package/dist/config/optionPresets.js +0 -56
- package/dist/config/resolveConfig.d.ts +0 -4
- package/dist/config/resolveConfig.js +0 -19
- package/dist/config/utils.d.ts +0 -2
- package/dist/config/utils.js +0 -4
- package/dist/config/validateSettings.d.ts +0 -3
- package/dist/config/validateSettings.js +0 -32
- package/dist/console/colors.d.ts +0 -5
- package/dist/console/colors.js +0 -16
- package/dist/console/index.d.ts +0 -21
- package/dist/console/index.js +0 -24
- package/dist/console/logging.d.ts +0 -53
- package/dist/console/logging.js +0 -185
- package/dist/formats/files/fileMapping.d.ts +0 -11
- package/dist/formats/files/fileMapping.js +0 -82
- package/dist/formats/files/save.d.ts +0 -5
- package/dist/formats/files/save.js +0 -17
- package/dist/formats/files/supportedFiles.d.ts +0 -10
- package/dist/formats/files/supportedFiles.js +0 -18
- package/dist/formats/files/translate.d.ts +0 -4
- package/dist/formats/files/translate.js +0 -119
- package/dist/formats/files/upload.d.ts +0 -13
- package/dist/formats/files/upload.js +0 -136
- package/dist/formats/gt/save.d.ts +0 -9
- package/dist/formats/gt/save.js +0 -26
- package/dist/formats/json/flattenJson.d.ts +0 -14
- package/dist/formats/json/flattenJson.js +0 -64
- package/dist/formats/json/mergeJson.d.ts +0 -13
- package/dist/formats/json/mergeJson.js +0 -257
- package/dist/formats/json/parseJson.d.ts +0 -2
- package/dist/formats/json/parseJson.js +0 -108
- package/dist/formats/json/utils.d.ts +0 -47
- package/dist/formats/json/utils.js +0 -149
- package/dist/formats/utils.d.ts +0 -2
- package/dist/formats/utils.js +0 -24
- package/dist/formats/yaml/mergeYaml.d.ts +0 -5
- package/dist/formats/yaml/mergeYaml.js +0 -55
- package/dist/formats/yaml/parseYaml.d.ts +0 -5
- package/dist/formats/yaml/parseYaml.js +0 -23
- package/dist/formats/yaml/utils.d.ts +0 -2
- package/dist/formats/yaml/utils.js +0 -22
- package/dist/fs/config/loadConfig.d.ts +0 -1
- package/dist/fs/config/loadConfig.js +0 -9
- package/dist/fs/config/parseFilesConfig.d.ts +0 -27
- package/dist/fs/config/parseFilesConfig.js +0 -129
- package/dist/fs/config/setupConfig.d.ts +0 -17
- package/dist/fs/config/setupConfig.js +0 -50
- package/dist/fs/config/updateConfig.d.ts +0 -10
- package/dist/fs/config/updateConfig.js +0 -36
- package/dist/fs/config/updateVersions.d.ts +0 -10
- package/dist/fs/config/updateVersions.js +0 -30
- package/dist/fs/copyFile.d.ts +0 -7
- package/dist/fs/copyFile.js +0 -39
- package/dist/fs/createLoadTranslationsFile.d.ts +0 -1
- package/dist/fs/createLoadTranslationsFile.js +0 -36
- package/dist/fs/determineFramework.d.ts +0 -5
- package/dist/fs/determineFramework.js +0 -46
- package/dist/fs/findFilepath.d.ts +0 -36
- package/dist/fs/findFilepath.js +0 -89
- package/dist/fs/getPackageResource.d.ts +0 -1
- package/dist/fs/getPackageResource.js +0 -6
- package/dist/fs/index.d.ts +0 -1
- package/dist/fs/index.js +0 -1
- package/dist/fs/loadJSON.d.ts +0 -6
- package/dist/fs/loadJSON.js +0 -17
- package/dist/fs/matchFiles.d.ts +0 -1
- package/dist/fs/matchFiles.js +0 -8
- package/dist/fs/saveJSON.d.ts +0 -1
- package/dist/fs/saveJSON.js +0 -7
- package/dist/fs/utils.d.ts +0 -1
- package/dist/fs/utils.js +0 -16
- package/dist/hooks/postProcess.d.ts +0 -4
- package/dist/hooks/postProcess.js +0 -110
- package/dist/index.d.ts +0 -4
- package/dist/index.js +0 -20
- package/dist/main.d.ts +0 -2
- package/dist/main.js +0 -9
- package/dist/next/config/parseNextConfig.d.ts +0 -10
- package/dist/next/config/parseNextConfig.js +0 -53
- package/dist/next/jsx/utils.d.ts +0 -7
- package/dist/next/jsx/utils.js +0 -42
- package/dist/next/parse/handleInitGT.d.ts +0 -7
- package/dist/next/parse/handleInitGT.js +0 -208
- package/dist/next/parse/wrapContent.d.ts +0 -11
- package/dist/next/parse/wrapContent.js +0 -163
- package/dist/react/config/createESBuildConfig.d.ts +0 -2
- package/dist/react/config/createESBuildConfig.js +0 -119
- package/dist/react/data-_gt/addGTIdentifierToSyntaxTree.d.ts +0 -8
- package/dist/react/data-_gt/addGTIdentifierToSyntaxTree.js +0 -111
- package/dist/react/jsx/evaluateJsx.d.ts +0 -17
- package/dist/react/jsx/evaluateJsx.js +0 -85
- package/dist/react/jsx/trimJsxStringChildren.d.ts +0 -7
- package/dist/react/jsx/trimJsxStringChildren.js +0 -95
- package/dist/react/jsx/utils/constants.d.ts +0 -10
- package/dist/react/jsx/utils/constants.js +0 -31
- package/dist/react/jsx/utils/parseAst.d.ts +0 -30
- package/dist/react/jsx/utils/parseAst.js +0 -277
- package/dist/react/jsx/utils/parseJsx.d.ts +0 -21
- package/dist/react/jsx/utils/parseJsx.js +0 -244
- package/dist/react/jsx/utils/parseStringFunction.d.ts +0 -16
- package/dist/react/jsx/utils/parseStringFunction.js +0 -411
- package/dist/react/jsx/utils/validateStringFunction.d.ts +0 -7
- package/dist/react/jsx/utils/validateStringFunction.js +0 -31
- package/dist/react/jsx/wrapJsx.d.ts +0 -51
- package/dist/react/jsx/wrapJsx.js +0 -387
- package/dist/react/parse/createDictionaryUpdates.d.ts +0 -3
- package/dist/react/parse/createDictionaryUpdates.js +0 -169
- package/dist/react/parse/createInlineUpdates.d.ts +0 -6
- package/dist/react/parse/createInlineUpdates.js +0 -122
- package/dist/react/parse/wrapContent.d.ts +0 -11
- package/dist/react/parse/wrapContent.js +0 -162
- package/dist/react/utils/flattenDictionary.d.ts +0 -20
- package/dist/react/utils/flattenDictionary.js +0 -75
- package/dist/react/utils/getEntryAndMetadata.d.ts +0 -5
- package/dist/react/utils/getEntryAndMetadata.js +0 -11
- package/dist/react/utils/getVariableName.d.ts +0 -25
- package/dist/react/utils/getVariableName.js +0 -37
- package/dist/setup/userInput.d.ts +0 -4
- package/dist/setup/userInput.js +0 -29
- package/dist/setup/wizard.d.ts +0 -2
- package/dist/setup/wizard.js +0 -127
- package/dist/translation/parse.d.ts +0 -15
- package/dist/translation/parse.js +0 -76
- package/dist/translation/stage.d.ts +0 -2
- package/dist/translation/stage.js +0 -44
- package/dist/translation/validate.d.ts +0 -2
- package/dist/translation/validate.js +0 -50
- package/dist/types/data/json.d.ts +0 -6
- package/dist/types/data/json.js +0 -1
- package/dist/types/data.d.ts +0 -30
- package/dist/types/data.js +0 -1
- package/dist/types/files.d.ts +0 -1
- package/dist/types/files.js +0 -1
- package/dist/types/index.d.ts +0 -173
- package/dist/types/index.js +0 -1
- package/dist/utils/addExplicitAnchorIds.d.ts +0 -24
- package/dist/utils/addExplicitAnchorIds.js +0 -260
- package/dist/utils/constants.d.ts +0 -2
- package/dist/utils/constants.js +0 -2
- package/dist/utils/credentials.d.ts +0 -12
- package/dist/utils/credentials.js +0 -119
- package/dist/utils/flattenJsonFiles.d.ts +0 -2
- package/dist/utils/flattenJsonFiles.js +0 -36
- package/dist/utils/gt.d.ts +0 -2
- package/dist/utils/gt.js +0 -2
- package/dist/utils/hash.d.ts +0 -6
- package/dist/utils/hash.js +0 -11
- package/dist/utils/headers.d.ts +0 -1
- package/dist/utils/headers.js +0 -14
- package/dist/utils/installPackage.d.ts +0 -3
- package/dist/utils/installPackage.js +0 -77
- package/dist/utils/localizeStaticImports.d.ts +0 -15
- package/dist/utils/localizeStaticImports.js +0 -341
- package/dist/utils/localizeStaticUrls.d.ts +0 -19
- package/dist/utils/localizeStaticUrls.js +0 -432
- package/dist/utils/packageInfo.d.ts +0 -3
- package/dist/utils/packageInfo.js +0 -17
- package/dist/utils/packageJson.d.ts +0 -6
- package/dist/utils/packageJson.js +0 -76
- package/dist/utils/packageManager.d.ts +0 -28
- package/dist/utils/packageManager.js +0 -269
- package/dist/utils/processAnchorIds.d.ts +0 -6
- package/dist/utils/processAnchorIds.js +0 -47
- package/dist/utils/sanitizeFileContent.d.ts +0 -6
- package/dist/utils/sanitizeFileContent.js +0 -29
- package/dist/utils/validateMdx.d.ts +0 -10
- package/dist/utils/validateMdx.js +0 -25
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gtx-cli",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.6-alpha.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"bin": "dist/main.js",
|
|
6
6
|
"files": [
|
|
@@ -8,19 +8,6 @@
|
|
|
8
8
|
"CHANGELOG.md"
|
|
9
9
|
],
|
|
10
10
|
"type": "module",
|
|
11
|
-
"scripts": {
|
|
12
|
-
"build": "tsc",
|
|
13
|
-
"build:clean": "rm -rf dist; npm run build",
|
|
14
|
-
"build:release": "npm run build:clean",
|
|
15
|
-
"lint": "eslint \"src/**/*.{js,ts}\" \"./**/__tests__/**/*.{js,ts}\"",
|
|
16
|
-
"lint:fix": "eslint \"src/**/*.{js,ts}\" \"./**/__tests__/**/*.{js,ts}\" --fix",
|
|
17
|
-
"test": "vitest run --config=./vitest.config.ts",
|
|
18
|
-
"test:watch": "vitest --config=./vitest.config.ts",
|
|
19
|
-
"release": "npm run build:clean && npm publish",
|
|
20
|
-
"release:alpha": "npm run build:clean && npm publish --tag alpha",
|
|
21
|
-
"release:beta": "npm run build:clean && npm publish --tag beta",
|
|
22
|
-
"release:latest": "npm run build:clean && npm publish --tag latest"
|
|
23
|
-
},
|
|
24
11
|
"exports": {
|
|
25
12
|
".": {
|
|
26
13
|
"import": "./dist/index.js"
|
|
@@ -87,7 +74,6 @@
|
|
|
87
74
|
"esbuild": "^0.25.4",
|
|
88
75
|
"fast-glob": "^3.3.3",
|
|
89
76
|
"form-data": "^4.0.4",
|
|
90
|
-
"generaltranslation": "^7.6.2",
|
|
91
77
|
"gt-remark": "^1.0.1",
|
|
92
78
|
"json-pointer": "^0.6.2",
|
|
93
79
|
"jsonpath-plus": "^10.3.0",
|
|
@@ -104,22 +90,41 @@
|
|
|
104
90
|
"tsconfig-paths": "^4.2.0",
|
|
105
91
|
"unified": "^11.0.5",
|
|
106
92
|
"unist-util-visit": "^5.0.0",
|
|
107
|
-
"yaml": "^2.8.0"
|
|
93
|
+
"yaml": "^2.8.0",
|
|
94
|
+
"generaltranslation": "7.6.4-alpha.1"
|
|
108
95
|
},
|
|
109
96
|
"devDependencies": {
|
|
97
|
+
"@babel/types": "^7.28.4",
|
|
110
98
|
"@biomejs/biome": "^1.9.4",
|
|
111
99
|
"@types/babel__generator": "^7.27.0",
|
|
112
100
|
"@types/babel__traverse": "^7.20.6",
|
|
113
101
|
"@types/figlet": "^1.7.0",
|
|
102
|
+
"@types/mdast": "^4.0.0",
|
|
103
|
+
"@types/micromatch": "^4.0.9",
|
|
114
104
|
"@types/mock-require": "^2.0.3",
|
|
115
105
|
"@types/node": "^22.5.1",
|
|
116
106
|
"@types/react": "^18.3.4",
|
|
117
107
|
"@types/resolve": "^1.20.2",
|
|
118
108
|
"eslint": "^9.20.0",
|
|
119
109
|
"esm": "^3.2.25",
|
|
120
|
-
"mdast": "^3.
|
|
110
|
+
"mdast-util-mdx-jsx": "^3.2.0",
|
|
111
|
+
"mdast-util-mdxjs-esm": "^2.0.1",
|
|
121
112
|
"prettier": "^3.4.2",
|
|
122
113
|
"ts-node": "^10.9.2",
|
|
114
|
+
"tslib": "^2.8.1",
|
|
123
115
|
"typescript": "^5.5.4"
|
|
116
|
+
},
|
|
117
|
+
"scripts": {
|
|
118
|
+
"build": "tsc",
|
|
119
|
+
"build:clean": "rm -rf dist; pnpm run build",
|
|
120
|
+
"build:release": "pnpm run build:clean",
|
|
121
|
+
"lint": "eslint \"src/**/*.{js,ts}\" \"./**/__tests__/**/*.{js,ts}\"",
|
|
122
|
+
"lint:fix": "eslint \"src/**/*.{js,ts}\" \"./**/__tests__/**/*.{js,ts}\" --fix",
|
|
123
|
+
"test": "vitest run --config=./vitest.config.ts",
|
|
124
|
+
"test:watch": "vitest --config=./vitest.config.ts",
|
|
125
|
+
"release": "pnpm run build:clean && pnpm publish",
|
|
126
|
+
"release:alpha": "pnpm run build:clean && pnpm publish --tag alpha",
|
|
127
|
+
"release:beta": "pnpm run build:clean && pnpm publish --tag beta",
|
|
128
|
+
"release:latest": "pnpm run build:clean && pnpm publish --tag latest"
|
|
124
129
|
}
|
|
125
|
-
}
|
|
130
|
+
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { Settings } from '../types/index.js';
|
|
2
|
-
export type CheckFileTranslationData = {
|
|
3
|
-
[key: string]: {
|
|
4
|
-
versionId: string;
|
|
5
|
-
fileName: string;
|
|
6
|
-
};
|
|
7
|
-
};
|
|
8
|
-
/**
|
|
9
|
-
* Checks the status of translations for a given version ID
|
|
10
|
-
* @param apiKey - The API key for the General Translation API
|
|
11
|
-
* @param baseUrl - The base URL for the General Translation API
|
|
12
|
-
* @param versionId - The version ID of the project
|
|
13
|
-
* @param locales - The locales to wait for
|
|
14
|
-
* @param startTime - The start time of the wait
|
|
15
|
-
* @param timeoutDuration - The timeout duration for the wait in seconds
|
|
16
|
-
* @returns True if all translations are deployed, false otherwise
|
|
17
|
-
*/
|
|
18
|
-
export declare function checkFileTranslations(data: {
|
|
19
|
-
[key: string]: {
|
|
20
|
-
versionId: string;
|
|
21
|
-
fileName: string;
|
|
22
|
-
};
|
|
23
|
-
}, locales: string[], timeoutDuration: number, resolveOutputPath: (sourcePath: string, locale: string) => string | null, options: Settings, forceRetranslation?: boolean): Promise<boolean>;
|
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import { createOraSpinner, logError } from '../console/logging.js';
|
|
3
|
-
import { getLocaleProperties } from 'generaltranslation';
|
|
4
|
-
import { downloadFileBatch } from './downloadFileBatch.js';
|
|
5
|
-
import { gt } from '../utils/gt.js';
|
|
6
|
-
import { TEMPLATE_FILE_NAME } from '../cli/commands/stage.js';
|
|
7
|
-
/**
|
|
8
|
-
* Checks the status of translations for a given version ID
|
|
9
|
-
* @param apiKey - The API key for the General Translation API
|
|
10
|
-
* @param baseUrl - The base URL for the General Translation API
|
|
11
|
-
* @param versionId - The version ID of the project
|
|
12
|
-
* @param locales - The locales to wait for
|
|
13
|
-
* @param startTime - The start time of the wait
|
|
14
|
-
* @param timeoutDuration - The timeout duration for the wait in seconds
|
|
15
|
-
* @returns True if all translations are deployed, false otherwise
|
|
16
|
-
*/
|
|
17
|
-
export async function checkFileTranslations(data, locales, timeoutDuration, resolveOutputPath, options, forceRetranslation) {
|
|
18
|
-
const startTime = Date.now();
|
|
19
|
-
console.log();
|
|
20
|
-
const spinner = await createOraSpinner();
|
|
21
|
-
const spinnerMessage = forceRetranslation
|
|
22
|
-
? 'Waiting for retranslation...'
|
|
23
|
-
: 'Waiting for translation...';
|
|
24
|
-
spinner.start(spinnerMessage);
|
|
25
|
-
// Initialize the query data
|
|
26
|
-
const fileQueryData = prepareFileQueryData(data, locales);
|
|
27
|
-
const downloadStatus = {
|
|
28
|
-
downloaded: new Set(),
|
|
29
|
-
failed: new Set(),
|
|
30
|
-
skipped: new Set(),
|
|
31
|
-
};
|
|
32
|
-
// Do first check immediately, but skip if force retranslation is enabled
|
|
33
|
-
if (!forceRetranslation) {
|
|
34
|
-
const initialCheck = await checkTranslationDeployment(fileQueryData, downloadStatus, spinner, resolveOutputPath, options);
|
|
35
|
-
if (initialCheck) {
|
|
36
|
-
spinner.succeed(chalk.green('Files translated!'));
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
// Calculate time until next 5-second interval since startTime
|
|
41
|
-
const msUntilNextInterval = Math.max(0, 5000 - ((Date.now() - startTime) % 5000));
|
|
42
|
-
return new Promise((resolve) => {
|
|
43
|
-
let intervalCheck;
|
|
44
|
-
// Start the interval aligned with the original request time
|
|
45
|
-
setTimeout(() => {
|
|
46
|
-
intervalCheck = setInterval(async () => {
|
|
47
|
-
const isDeployed = await checkTranslationDeployment(fileQueryData, downloadStatus, spinner, resolveOutputPath, options);
|
|
48
|
-
const elapsed = Date.now() - startTime;
|
|
49
|
-
if (isDeployed || elapsed >= timeoutDuration * 1000) {
|
|
50
|
-
clearInterval(intervalCheck);
|
|
51
|
-
if (isDeployed) {
|
|
52
|
-
spinner.succeed(chalk.green('All files translated!'));
|
|
53
|
-
resolve(true);
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
spinner.fail(chalk.red('Timed out waiting for translations'));
|
|
57
|
-
resolve(false);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}, 5000);
|
|
61
|
-
}, msUntilNextInterval);
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Prepares the file query data from input data and locales
|
|
66
|
-
*/
|
|
67
|
-
function prepareFileQueryData(data, locales) {
|
|
68
|
-
const fileQueryData = [];
|
|
69
|
-
for (const file in data) {
|
|
70
|
-
for (const locale of locales) {
|
|
71
|
-
fileQueryData.push({
|
|
72
|
-
versionId: data[file].versionId,
|
|
73
|
-
fileName: data[file].fileName,
|
|
74
|
-
locale,
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
return fileQueryData;
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Generates a formatted status text showing translation progress
|
|
82
|
-
* @param downloadedFiles - Set of downloaded file+locale combinations
|
|
83
|
-
* @param fileQueryData - Array of file query data objects
|
|
84
|
-
* @returns Formatted status text
|
|
85
|
-
*/
|
|
86
|
-
function generateStatusSuffixText(downloadStatus, fileQueryData) {
|
|
87
|
-
// Simple progress indicator
|
|
88
|
-
const progressText = chalk.green(`[${downloadStatus.downloaded.size + downloadStatus.failed.size}/${fileQueryData.length}]`) + ` translations completed`;
|
|
89
|
-
// Get terminal height to adapt our output
|
|
90
|
-
const terminalHeight = process.stdout.rows || 24; // Default to 24 if undefined
|
|
91
|
-
// If terminal is very small, just show the basic progress
|
|
92
|
-
if (terminalHeight < 6) {
|
|
93
|
-
return `${progressText}`;
|
|
94
|
-
}
|
|
95
|
-
const newSuffixText = [`${progressText}`];
|
|
96
|
-
// Organize data by filename
|
|
97
|
-
const fileStatus = new Map();
|
|
98
|
-
// Initialize with all files and locales from fileQueryData
|
|
99
|
-
for (const item of fileQueryData) {
|
|
100
|
-
if (!fileStatus.has(item.fileName)) {
|
|
101
|
-
fileStatus.set(item.fileName, {
|
|
102
|
-
completed: new Set(),
|
|
103
|
-
pending: new Set([item.locale]),
|
|
104
|
-
failed: new Set(),
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
fileStatus.get(item.fileName)?.pending.add(item.locale);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
// Mark which ones are completed or failed
|
|
112
|
-
for (const fileLocale of downloadStatus.downloaded) {
|
|
113
|
-
const [fileName, locale] = fileLocale.split(':');
|
|
114
|
-
const status = fileStatus.get(fileName);
|
|
115
|
-
if (status) {
|
|
116
|
-
status.pending.delete(locale);
|
|
117
|
-
status.completed.add(locale);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
for (const fileLocale of downloadStatus.failed) {
|
|
121
|
-
const [fileName, locale] = fileLocale.split(':');
|
|
122
|
-
const status = fileStatus.get(fileName);
|
|
123
|
-
if (status) {
|
|
124
|
-
status.pending.delete(locale);
|
|
125
|
-
status.failed.add(locale);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
// Calculate how many files we can show based on terminal height
|
|
129
|
-
const filesArray = Array.from(fileStatus.entries());
|
|
130
|
-
const maxFilesToShow = Math.min(filesArray.length, terminalHeight - 3 // Header + progress + buffer
|
|
131
|
-
);
|
|
132
|
-
// Display each file with its status on a single line
|
|
133
|
-
for (let i = 0; i < maxFilesToShow; i++) {
|
|
134
|
-
const [fileName, status] = filesArray[i];
|
|
135
|
-
// Create condensed locale status
|
|
136
|
-
const localeStatuses = [];
|
|
137
|
-
// Add completed locales
|
|
138
|
-
if (status.completed.size > 0) {
|
|
139
|
-
const completedCodes = Array.from(status.completed)
|
|
140
|
-
.map((locale) => getLocaleProperties(locale).code)
|
|
141
|
-
.join(', ');
|
|
142
|
-
localeStatuses.push(chalk.green(`${completedCodes}`));
|
|
143
|
-
}
|
|
144
|
-
// Add failed locales
|
|
145
|
-
if (status.failed.size > 0) {
|
|
146
|
-
const failedCodes = Array.from(status.failed)
|
|
147
|
-
.map((locale) => getLocaleProperties(locale).code)
|
|
148
|
-
.join(', ');
|
|
149
|
-
localeStatuses.push(chalk.red(`${failedCodes}`));
|
|
150
|
-
}
|
|
151
|
-
// Add pending locales
|
|
152
|
-
if (status.pending.size > 0) {
|
|
153
|
-
const pendingCodes = Array.from(status.pending)
|
|
154
|
-
.map((locale) => getLocaleProperties(locale).code)
|
|
155
|
-
.join(', ');
|
|
156
|
-
localeStatuses.push(chalk.yellow(`${pendingCodes}`));
|
|
157
|
-
}
|
|
158
|
-
// Format the line
|
|
159
|
-
const prettyFileName = fileName === TEMPLATE_FILE_NAME ? '<React Elements>' : fileName;
|
|
160
|
-
newSuffixText.push(`${chalk.bold(prettyFileName)} [${localeStatuses.join(', ')}]`);
|
|
161
|
-
}
|
|
162
|
-
// If we couldn't show all files, add an indicator
|
|
163
|
-
if (filesArray.length > maxFilesToShow) {
|
|
164
|
-
newSuffixText.push(`... and ${filesArray.length - maxFilesToShow} more files`);
|
|
165
|
-
}
|
|
166
|
-
return newSuffixText.join('\n');
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Checks translation status and downloads ready files
|
|
170
|
-
*/
|
|
171
|
-
async function checkTranslationDeployment(fileQueryData, downloadStatus, spinner, resolveOutputPath, options) {
|
|
172
|
-
try {
|
|
173
|
-
// Only query for files that haven't been downloaded yet
|
|
174
|
-
const currentQueryData = fileQueryData.filter((item) => !downloadStatus.downloaded.has(`${item.fileName}:${item.locale}`) &&
|
|
175
|
-
!downloadStatus.failed.has(`${item.fileName}:${item.locale}`) &&
|
|
176
|
-
!downloadStatus.skipped.has(`${item.fileName}:${item.locale}`));
|
|
177
|
-
// If all files have been downloaded, we're done
|
|
178
|
-
if (currentQueryData.length === 0) {
|
|
179
|
-
return true;
|
|
180
|
-
}
|
|
181
|
-
// Check for translations
|
|
182
|
-
const responseData = await gt.checkFileTranslations(currentQueryData);
|
|
183
|
-
const translations = responseData.translations || [];
|
|
184
|
-
// Filter for ready translations
|
|
185
|
-
const readyTranslations = translations.filter((translation) => translation.isReady && translation.fileName);
|
|
186
|
-
if (readyTranslations.length > 0) {
|
|
187
|
-
// Prepare batch download data
|
|
188
|
-
const batchFiles = readyTranslations
|
|
189
|
-
.map((translation) => {
|
|
190
|
-
const locale = gt.resolveAliasLocale(translation.locale);
|
|
191
|
-
const fileName = translation.fileName;
|
|
192
|
-
const translationId = translation.id;
|
|
193
|
-
const outputPath = resolveOutputPath(fileName, locale);
|
|
194
|
-
// Skip downloading GTJSON files that are not in the files configuration
|
|
195
|
-
if (outputPath === null) {
|
|
196
|
-
downloadStatus.skipped.add(`${fileName}:${locale}`);
|
|
197
|
-
return null;
|
|
198
|
-
}
|
|
199
|
-
return {
|
|
200
|
-
translationId,
|
|
201
|
-
inputPath: fileName,
|
|
202
|
-
outputPath,
|
|
203
|
-
locale,
|
|
204
|
-
fileLocale: `${fileName}:${locale}`,
|
|
205
|
-
};
|
|
206
|
-
})
|
|
207
|
-
.filter((file) => file !== null);
|
|
208
|
-
const batchResult = await downloadFileBatch(batchFiles, options);
|
|
209
|
-
// Process results
|
|
210
|
-
batchFiles.forEach((file) => {
|
|
211
|
-
const { translationId, fileLocale } = file;
|
|
212
|
-
if (batchResult.successful.includes(translationId)) {
|
|
213
|
-
downloadStatus.downloaded.add(fileLocale);
|
|
214
|
-
}
|
|
215
|
-
else if (batchResult.failed.includes(translationId)) {
|
|
216
|
-
downloadStatus.failed.add(fileLocale);
|
|
217
|
-
}
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
// Force a refresh of the spinner display
|
|
221
|
-
const statusText = generateStatusSuffixText(downloadStatus, fileQueryData);
|
|
222
|
-
// Clear and reapply the suffix to force a refresh
|
|
223
|
-
spinner.text = statusText;
|
|
224
|
-
// If all files have been downloaded, we're done
|
|
225
|
-
if (downloadStatus.downloaded.size +
|
|
226
|
-
downloadStatus.failed.size +
|
|
227
|
-
downloadStatus.skipped.size ===
|
|
228
|
-
fileQueryData.length) {
|
|
229
|
-
return true;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
catch (error) {
|
|
233
|
-
logError(chalk.red('Error checking translation status: ') + error);
|
|
234
|
-
}
|
|
235
|
-
return false;
|
|
236
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { Settings } from '../types/index.js';
|
|
2
|
-
export type BatchedFiles = Array<{
|
|
3
|
-
translationId: string;
|
|
4
|
-
outputPath: string;
|
|
5
|
-
inputPath: string;
|
|
6
|
-
locale: string;
|
|
7
|
-
fileLocale: string;
|
|
8
|
-
}>;
|
|
9
|
-
export type DownloadFileBatchResult = {
|
|
10
|
-
successful: string[];
|
|
11
|
-
failed: string[];
|
|
12
|
-
};
|
|
13
|
-
/**
|
|
14
|
-
* Downloads multiple translation files in a single batch request
|
|
15
|
-
* @param files - Array of files to download with their output paths
|
|
16
|
-
* @param maxRetries - Maximum number of retry attempts
|
|
17
|
-
* @param retryDelay - Delay between retries in milliseconds
|
|
18
|
-
* @returns Object containing successful and failed file IDs
|
|
19
|
-
*/
|
|
20
|
-
export declare function downloadFileBatch(files: BatchedFiles, options: Settings, maxRetries?: number, retryDelay?: number): Promise<DownloadFileBatchResult>;
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import * as fs from 'fs';
|
|
2
|
-
import * as path from 'path';
|
|
3
|
-
import { logError, logWarning } from '../console/logging.js';
|
|
4
|
-
import { gt } from '../utils/gt.js';
|
|
5
|
-
import { validateJsonSchema } from '../formats/json/utils.js';
|
|
6
|
-
import { validateYamlSchema } from '../formats/yaml/utils.js';
|
|
7
|
-
import { mergeJson } from '../formats/json/mergeJson.js';
|
|
8
|
-
import mergeYaml from '../formats/yaml/mergeYaml.js';
|
|
9
|
-
/**
|
|
10
|
-
* Downloads multiple translation files in a single batch request
|
|
11
|
-
* @param files - Array of files to download with their output paths
|
|
12
|
-
* @param maxRetries - Maximum number of retry attempts
|
|
13
|
-
* @param retryDelay - Delay between retries in milliseconds
|
|
14
|
-
* @returns Object containing successful and failed file IDs
|
|
15
|
-
*/
|
|
16
|
-
export async function downloadFileBatch(files, options, maxRetries = 3, retryDelay = 1000) {
|
|
17
|
-
let retries = 0;
|
|
18
|
-
const fileIds = files.map((file) => file.translationId);
|
|
19
|
-
const result = { successful: [], failed: [] };
|
|
20
|
-
// Create a map of translationId to outputPath for easier lookup
|
|
21
|
-
const outputPathMap = new Map(files.map((file) => [file.translationId, file.outputPath]));
|
|
22
|
-
const inputPathMap = new Map(files.map((file) => [file.translationId, file.inputPath]));
|
|
23
|
-
const localeMap = new Map(files.map((file) => [
|
|
24
|
-
file.translationId,
|
|
25
|
-
gt.resolveAliasLocale(file.locale),
|
|
26
|
-
]));
|
|
27
|
-
while (retries <= maxRetries) {
|
|
28
|
-
try {
|
|
29
|
-
// Download the files
|
|
30
|
-
const responseData = await gt.downloadFileBatch(fileIds);
|
|
31
|
-
const downloadedFiles = responseData.files || [];
|
|
32
|
-
// Process each file in the response
|
|
33
|
-
for (const file of downloadedFiles) {
|
|
34
|
-
try {
|
|
35
|
-
const translationId = file.id;
|
|
36
|
-
const outputPath = outputPathMap.get(translationId);
|
|
37
|
-
const inputPath = inputPathMap.get(translationId);
|
|
38
|
-
const locale = localeMap.get(translationId);
|
|
39
|
-
if (!outputPath || !inputPath) {
|
|
40
|
-
logWarning(`No input/output path found for file: ${translationId}`);
|
|
41
|
-
result.failed.push(translationId);
|
|
42
|
-
continue;
|
|
43
|
-
}
|
|
44
|
-
// Ensure the directory exists
|
|
45
|
-
const dir = path.dirname(outputPath);
|
|
46
|
-
if (!fs.existsSync(dir)) {
|
|
47
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
48
|
-
}
|
|
49
|
-
let data = file.data;
|
|
50
|
-
if (options.options?.jsonSchema && locale) {
|
|
51
|
-
const jsonSchema = validateJsonSchema(options.options, inputPath);
|
|
52
|
-
if (jsonSchema) {
|
|
53
|
-
const originalContent = fs.readFileSync(inputPath, 'utf8');
|
|
54
|
-
if (originalContent) {
|
|
55
|
-
data = mergeJson(originalContent, inputPath, options.options, [
|
|
56
|
-
{
|
|
57
|
-
translatedContent: file.data,
|
|
58
|
-
targetLocale: locale,
|
|
59
|
-
},
|
|
60
|
-
], options.defaultLocale)[0];
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
if (options.options?.yamlSchema && locale) {
|
|
65
|
-
const yamlSchema = validateYamlSchema(options.options, inputPath);
|
|
66
|
-
if (yamlSchema) {
|
|
67
|
-
const originalContent = fs.readFileSync(inputPath, 'utf8');
|
|
68
|
-
if (originalContent) {
|
|
69
|
-
data = mergeYaml(originalContent, inputPath, options.options, [
|
|
70
|
-
{
|
|
71
|
-
translatedContent: file.data,
|
|
72
|
-
targetLocale: locale,
|
|
73
|
-
},
|
|
74
|
-
])[0];
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
// Write the file to disk
|
|
79
|
-
await fs.promises.writeFile(outputPath, data);
|
|
80
|
-
result.successful.push(translationId);
|
|
81
|
-
}
|
|
82
|
-
catch (error) {
|
|
83
|
-
logError(`Error saving file ${file.id}: ` + error);
|
|
84
|
-
result.failed.push(file.id);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
// Add any files that weren't in the response to the failed list
|
|
88
|
-
const downloadedIds = new Set(downloadedFiles.map((file) => file.id));
|
|
89
|
-
for (const fileId of fileIds) {
|
|
90
|
-
if (!downloadedIds.has(fileId) && !result.failed.includes(fileId)) {
|
|
91
|
-
result.failed.push(fileId);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
return result;
|
|
95
|
-
}
|
|
96
|
-
catch (error) {
|
|
97
|
-
// If we've retried too many times, log an error and return false
|
|
98
|
-
if (retries >= maxRetries) {
|
|
99
|
-
logError(`Error downloading files in batch after ${maxRetries + 1} attempts: ` +
|
|
100
|
-
error);
|
|
101
|
-
// Mark all files as failed
|
|
102
|
-
result.failed = [...fileIds];
|
|
103
|
-
return result;
|
|
104
|
-
}
|
|
105
|
-
// Increment retry counter and wait before next attempt
|
|
106
|
-
retries++;
|
|
107
|
-
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
// Mark all files as failed if we get here
|
|
111
|
-
result.failed = [...fileIds];
|
|
112
|
-
return result;
|
|
113
|
-
}
|
package/dist/api/sendFiles.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { Settings, TranslateFlags } from '../types/index.js';
|
|
2
|
-
import { CompletedFileTranslationData, FileToTranslate } from 'generaltranslation/types';
|
|
3
|
-
export type SendFilesResult = {
|
|
4
|
-
data: Record<string, {
|
|
5
|
-
fileName: string;
|
|
6
|
-
versionId: string;
|
|
7
|
-
}>;
|
|
8
|
-
locales: string[];
|
|
9
|
-
translations: CompletedFileTranslationData[];
|
|
10
|
-
};
|
|
11
|
-
/**
|
|
12
|
-
* Sends multiple files for translation to the API
|
|
13
|
-
* @param files - Array of file objects to translate
|
|
14
|
-
* @param options - The options for the API call
|
|
15
|
-
* @returns The translated content or version ID
|
|
16
|
-
*/
|
|
17
|
-
export declare function sendFiles(files: FileToTranslate[], options: TranslateFlags, settings: Settings): Promise<SendFilesResult>;
|
package/dist/api/sendFiles.js
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import { createSpinner, logError, logMessage, logSuccess, } from '../console/logging.js';
|
|
3
|
-
import { gt } from '../utils/gt.js';
|
|
4
|
-
import { TEMPLATE_FILE_NAME } from '../cli/commands/stage.js';
|
|
5
|
-
/**
|
|
6
|
-
* Sends multiple files for translation to the API
|
|
7
|
-
* @param files - Array of file objects to translate
|
|
8
|
-
* @param options - The options for the API call
|
|
9
|
-
* @returns The translated content or version ID
|
|
10
|
-
*/
|
|
11
|
-
export async function sendFiles(files, options, settings) {
|
|
12
|
-
// Keep track of the most recent spinner so we can stop it on error
|
|
13
|
-
let currentSpinner = null;
|
|
14
|
-
logMessage(chalk.cyan('Files to translate:') +
|
|
15
|
-
'\n' +
|
|
16
|
-
files
|
|
17
|
-
.map((file) => {
|
|
18
|
-
if (file.fileName === TEMPLATE_FILE_NAME) {
|
|
19
|
-
return `- <React Elements>`;
|
|
20
|
-
}
|
|
21
|
-
return `- ${file.fileName}`;
|
|
22
|
-
})
|
|
23
|
-
.join('\n'));
|
|
24
|
-
try {
|
|
25
|
-
// Step 1: Upload files (get references)
|
|
26
|
-
const uploadSpinner = createSpinner('dots');
|
|
27
|
-
currentSpinner = uploadSpinner;
|
|
28
|
-
uploadSpinner.start(`Uploading ${files.length} file${files.length !== 1 ? 's' : ''} to General Translation API...`);
|
|
29
|
-
const sourceLocale = settings.defaultLocale;
|
|
30
|
-
if (!sourceLocale) {
|
|
31
|
-
uploadSpinner.stop(chalk.red('Missing default source locale'));
|
|
32
|
-
throw new Error('sendFiles: settings.defaultLocale is required to upload source files');
|
|
33
|
-
}
|
|
34
|
-
// Convert FileToTranslate[] -> { source: FileUpload }[]
|
|
35
|
-
const uploads = files.map(({ content, fileName, fileFormat, dataFormat }) => ({
|
|
36
|
-
source: {
|
|
37
|
-
content,
|
|
38
|
-
fileName,
|
|
39
|
-
fileFormat,
|
|
40
|
-
dataFormat,
|
|
41
|
-
locale: sourceLocale,
|
|
42
|
-
},
|
|
43
|
-
}));
|
|
44
|
-
const upload = await gt.uploadSourceFiles(uploads, {
|
|
45
|
-
sourceLocale,
|
|
46
|
-
modelProvider: settings.modelProvider,
|
|
47
|
-
});
|
|
48
|
-
uploadSpinner.stop(chalk.green('Files uploaded successfully'));
|
|
49
|
-
// Check if setup is needed
|
|
50
|
-
const setupDecision = await Promise.resolve(gt.shouldSetupProject?.())
|
|
51
|
-
.then((v) => v)
|
|
52
|
-
.catch(() => ({ shouldSetupProject: false }));
|
|
53
|
-
const shouldSetupProject = Boolean(setupDecision?.shouldSetupProject);
|
|
54
|
-
// Step 2: Setup if needed and poll until complete
|
|
55
|
-
if (shouldSetupProject) {
|
|
56
|
-
// Calculate timeout once for setup fetching
|
|
57
|
-
// Accept number or numeric string, default to 600s
|
|
58
|
-
const timeoutVal = options?.timeout !== undefined ? Number(options.timeout) : 600;
|
|
59
|
-
const setupTimeoutMs = (Number.isFinite(timeoutVal) ? timeoutVal : 600) * 1000;
|
|
60
|
-
const { setupJobId } = await gt.setupProject(upload.uploadedFiles);
|
|
61
|
-
const setupSpinner = createSpinner('dots');
|
|
62
|
-
currentSpinner = setupSpinner;
|
|
63
|
-
setupSpinner.start('Setting up project...');
|
|
64
|
-
const start = Date.now();
|
|
65
|
-
const pollInterval = 2000;
|
|
66
|
-
let setupCompleted = false;
|
|
67
|
-
let setupFailedMessage = null;
|
|
68
|
-
while (true) {
|
|
69
|
-
const status = await gt.checkSetupStatus(setupJobId);
|
|
70
|
-
if (status.status === 'completed') {
|
|
71
|
-
setupCompleted = true;
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
if (status.status === 'failed') {
|
|
75
|
-
setupFailedMessage = status.error?.message || 'Unknown error';
|
|
76
|
-
break;
|
|
77
|
-
}
|
|
78
|
-
if (Date.now() - start > setupTimeoutMs) {
|
|
79
|
-
setupFailedMessage = 'Timed out while waiting for setup generation';
|
|
80
|
-
break;
|
|
81
|
-
}
|
|
82
|
-
await new Promise((r) => setTimeout(r, pollInterval));
|
|
83
|
-
}
|
|
84
|
-
if (setupCompleted) {
|
|
85
|
-
setupSpinner.stop(chalk.green('Setup successfully completed'));
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
setupSpinner.stop(chalk.yellow(`Setup ${setupFailedMessage ? 'failed' : 'timed out'} — proceeding without setup${setupFailedMessage ? ` (${setupFailedMessage})` : ''}`));
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
// Step 3: Enqueue translations by reference
|
|
92
|
-
const enqueueSpinner = createSpinner('dots');
|
|
93
|
-
currentSpinner = enqueueSpinner;
|
|
94
|
-
enqueueSpinner.start('Enqueuing translations...');
|
|
95
|
-
const enqueueResult = await gt.enqueueFiles(upload.uploadedFiles, {
|
|
96
|
-
sourceLocale: settings.defaultLocale,
|
|
97
|
-
targetLocales: settings.locales,
|
|
98
|
-
publish: settings.publish,
|
|
99
|
-
requireApproval: settings.stageTranslations,
|
|
100
|
-
modelProvider: settings.modelProvider,
|
|
101
|
-
force: options?.force,
|
|
102
|
-
});
|
|
103
|
-
const { data, message, locales, translations } = enqueueResult;
|
|
104
|
-
enqueueSpinner.stop(chalk.green('Files for translation uploaded successfully'));
|
|
105
|
-
logSuccess(message);
|
|
106
|
-
return { data, locales, translations };
|
|
107
|
-
}
|
|
108
|
-
catch (error) {
|
|
109
|
-
if (currentSpinner) {
|
|
110
|
-
currentSpinner.stop(chalk.red('Failed to send files for translation'));
|
|
111
|
-
}
|
|
112
|
-
logError('Failed to send files for translation');
|
|
113
|
-
throw error;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { Settings } from '../types/index.js';
|
|
2
|
-
import { DataFormat, FileFormat } from '../types/data.js';
|
|
3
|
-
export type FileUpload = {
|
|
4
|
-
content: string;
|
|
5
|
-
fileName: string;
|
|
6
|
-
fileFormat: FileFormat;
|
|
7
|
-
dataFormat?: DataFormat;
|
|
8
|
-
locale: string;
|
|
9
|
-
};
|
|
10
|
-
export type UploadData = {
|
|
11
|
-
data: {
|
|
12
|
-
source: FileUpload;
|
|
13
|
-
translations: FileUpload[];
|
|
14
|
-
}[];
|
|
15
|
-
sourceLocale: string;
|
|
16
|
-
modelProvider?: string;
|
|
17
|
-
};
|
|
18
|
-
/**
|
|
19
|
-
* Uploads multiple files to the API
|
|
20
|
-
* @param files - Array of file objects to upload
|
|
21
|
-
* @param options - The options for the API call
|
|
22
|
-
* @returns The uploaded content or version ID
|
|
23
|
-
*/
|
|
24
|
-
export declare function uploadFiles(files: {
|
|
25
|
-
source: FileUpload;
|
|
26
|
-
translations: FileUpload[];
|
|
27
|
-
}[], options: Settings): Promise<void>;
|
package/dist/api/uploadFiles.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import { createSpinner, exit, logMessage } from '../console/logging.js';
|
|
3
|
-
import { gt } from '../utils/gt.js';
|
|
4
|
-
/**
|
|
5
|
-
* Uploads multiple files to the API
|
|
6
|
-
* @param files - Array of file objects to upload
|
|
7
|
-
* @param options - The options for the API call
|
|
8
|
-
* @returns The uploaded content or version ID
|
|
9
|
-
*/
|
|
10
|
-
export async function uploadFiles(files, options) {
|
|
11
|
-
logMessage(chalk.cyan('Files to upload:') +
|
|
12
|
-
'\n' +
|
|
13
|
-
files
|
|
14
|
-
.map((file) => ` - ${chalk.bold(file.source.fileName)} -> ${file.translations
|
|
15
|
-
.map((t) => t.locale)
|
|
16
|
-
.join(', ')}`)
|
|
17
|
-
.join('\n'));
|
|
18
|
-
const spinner = createSpinner('dots');
|
|
19
|
-
spinner.start(`Uploading ${files.length} file${files.length !== 1 ? 's' : ''} to General Translation...`);
|
|
20
|
-
try {
|
|
21
|
-
// Upload sources
|
|
22
|
-
await gt.uploadSourceFiles(files, {
|
|
23
|
-
...options,
|
|
24
|
-
sourceLocale: options.defaultLocale,
|
|
25
|
-
});
|
|
26
|
-
// Upload translations (if any exist)
|
|
27
|
-
const withTranslations = files.filter((f) => f.translations.length > 0);
|
|
28
|
-
if (withTranslations.length > 0) {
|
|
29
|
-
await gt.uploadTranslations(withTranslations, {
|
|
30
|
-
...options,
|
|
31
|
-
sourceLocale: options.defaultLocale, // optional, safe to include
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
spinner.stop(chalk.green('Files uploaded successfully'));
|
|
35
|
-
}
|
|
36
|
-
catch {
|
|
37
|
-
spinner.stop(chalk.red('An unexpected error occurred while uploading files'));
|
|
38
|
-
exit(1);
|
|
39
|
-
}
|
|
40
|
-
}
|