gtx-cli 2.5.7 → 2.5.9
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/downloadFileBatch.js +5 -5
- package/dist/api/saveLocalEdits.js +4 -3
- package/dist/api/uploadFiles.d.ts +1 -1
- package/dist/api/uploadFiles.js +5 -4
- package/dist/cli/base.d.ts +2 -1
- package/dist/cli/base.js +36 -30
- package/dist/cli/commands/setupProject.d.ts +7 -0
- package/dist/cli/commands/setupProject.js +50 -0
- package/dist/cli/commands/stage.d.ts +0 -2
- package/dist/cli/commands/stage.js +13 -61
- package/dist/cli/commands/translate.js +3 -5
- package/dist/cli/flags.js +2 -3
- package/dist/cli/next.js +1 -0
- package/dist/cli/react.d.ts +1 -0
- package/dist/cli/react.js +26 -15
- package/dist/config/generateSettings.js +2 -2
- package/dist/config/validateSettings.d.ts +1 -1
- package/dist/config/validateSettings.js +4 -4
- package/dist/console/logger.d.ts +35 -0
- package/dist/console/logger.js +270 -0
- package/dist/console/logging.d.ts +6 -11
- package/dist/console/logging.js +40 -55
- package/dist/formats/files/collectFiles.d.ts +6 -0
- package/dist/formats/files/collectFiles.js +49 -0
- package/dist/formats/files/fileMapping.js +1 -1
- package/dist/formats/files/save.js +2 -2
- package/dist/formats/files/translate.js +8 -8
- package/dist/formats/files/upload.js +7 -6
- package/dist/formats/gt/save.js +4 -3
- package/dist/formats/json/flattenJson.js +3 -3
- package/dist/formats/json/mergeJson.js +19 -18
- package/dist/formats/json/parseJson.js +14 -13
- package/dist/formats/json/utils.js +16 -15
- package/dist/formats/yaml/mergeYaml.js +6 -5
- package/dist/formats/yaml/parseYaml.js +4 -3
- package/dist/formats/yaml/utils.js +4 -3
- package/dist/fs/clearLocaleDirs.js +6 -6
- package/dist/fs/config/downloadedVersions.js +3 -3
- package/dist/fs/config/parseFilesConfig.js +2 -2
- package/dist/fs/config/setupConfig.js +2 -2
- package/dist/fs/config/updateConfig.js +2 -2
- package/dist/fs/config/updateVersions.js +3 -3
- package/dist/fs/copyFile.js +2 -2
- package/dist/fs/createLoadTranslationsFile.d.ts +1 -1
- package/dist/fs/createLoadTranslationsFile.js +11 -4
- package/dist/fs/determineFramework.js +3 -3
- package/dist/fs/findFilepath.js +5 -4
- package/dist/hooks/postProcess.js +9 -9
- package/dist/next/parse/handleInitGT.js +2 -2
- package/dist/react/parse/addVitePlugin/index.js +4 -3
- package/dist/react/parse/addVitePlugin/installCompiler.js +2 -2
- package/dist/react/parse/addVitePlugin/updateViteConfig.js +9 -12
- package/dist/react/parse/createDictionaryUpdates.js +4 -3
- package/dist/react/parse/createInlineUpdates.js +2 -2
- package/dist/setup/wizard.js +17 -16
- package/dist/translation/parse.js +4 -3
- package/dist/translation/stage.js +4 -4
- package/dist/translation/validate.js +6 -6
- package/dist/types/index.d.ts +1 -0
- package/dist/utils/addExplicitAnchorIds.js +2 -2
- package/dist/utils/constants.d.ts +2 -0
- package/dist/utils/constants.js +3 -0
- package/dist/utils/credentials.js +4 -3
- package/dist/utils/installPackage.js +11 -11
- package/dist/utils/packageJson.js +4 -3
- package/dist/workflow/BranchStep.js +5 -4
- package/dist/workflow/DownloadStep.js +5 -5
- package/dist/workflow/EnqueueStep.js +2 -2
- package/dist/workflow/PollJobsStep.js +4 -4
- package/dist/workflow/SetupStep.d.ts +1 -1
- package/dist/workflow/SetupStep.js +4 -3
- package/dist/workflow/UploadStep.js +3 -3
- package/dist/workflow/UserEditDiffsStep.js +2 -2
- package/dist/workflow/download.js +4 -3
- package/dist/workflow/setupProject.d.ts +13 -0
- package/dist/workflow/setupProject.js +48 -0
- package/dist/workflow/stage.js +4 -21
- package/package.json +3 -3
- package/dist/utils/SpinnerManager.d.ts +0 -30
- package/dist/utils/SpinnerManager.js +0 -73
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# gtx-cli
|
|
2
2
|
|
|
3
|
+
## 2.5.9
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#823](https://github.com/generaltranslation/gt/pull/823) [`afbd29a`](https://github.com/generaltranslation/gt/commit/afbd29a34b051c76fce387269c4eb4a2e00a5831) Thanks [@brian-lou](https://github.com/brian-lou)! - Deprecate old 'setup' command -> Use 'init' instead. New 'setup' command runs project setup
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`afbd29a`](https://github.com/generaltranslation/gt/commit/afbd29a34b051c76fce387269c4eb4a2e00a5831)]:
|
|
10
|
+
- generaltranslation@8.0.3
|
|
11
|
+
|
|
12
|
+
## 2.5.8
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- [#821](https://github.com/generaltranslation/gt/pull/821) [`321854a`](https://github.com/generaltranslation/gt/commit/321854ad881ca07b6a0207b3b0cbc004c6c0f5a4) Thanks [@brian-lou](https://github.com/brian-lou)! - Refactor CLI Logging behavior
|
|
17
|
+
|
|
3
18
|
## 2.5.7
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
|
-
import {
|
|
3
|
+
import { logger } from '../console/logger.js';
|
|
4
4
|
import { gt } from '../utils/gt.js';
|
|
5
5
|
import { validateJsonSchema } from '../formats/json/utils.js';
|
|
6
6
|
import { validateYamlSchema } from '../formats/yaml/utils.js';
|
|
@@ -55,7 +55,7 @@ export async function downloadFileBatch(fileTracker, files, options, forceDownlo
|
|
|
55
55
|
const outputPath = outputPathMap.get(fileKey);
|
|
56
56
|
const fileProperties = fileTracker.completed.get(fileKey);
|
|
57
57
|
if (!outputPath || !fileProperties) {
|
|
58
|
-
|
|
58
|
+
logger.warn(`No input/output path found for file: ${fileKey}`);
|
|
59
59
|
result.failed.push(requestedFile);
|
|
60
60
|
continue;
|
|
61
61
|
}
|
|
@@ -110,7 +110,7 @@ export async function downloadFileBatch(fileTracker, files, options, forceDownlo
|
|
|
110
110
|
data = JSON.stringify(sortedJsonData, null, 2); // format the data
|
|
111
111
|
}
|
|
112
112
|
catch (error) {
|
|
113
|
-
|
|
113
|
+
logger.warn(`Failed to sort GTJson file: ${file.id}: ` + error);
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
// Write the file to disk
|
|
@@ -132,7 +132,7 @@ export async function downloadFileBatch(fileTracker, files, options, forceDownlo
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
catch (error) {
|
|
135
|
-
|
|
135
|
+
logger.error(`Error saving file ${fileKey}: ` + error);
|
|
136
136
|
result.failed.push(requestedFile);
|
|
137
137
|
}
|
|
138
138
|
}
|
|
@@ -151,7 +151,7 @@ export async function downloadFileBatch(fileTracker, files, options, forceDownlo
|
|
|
151
151
|
return result;
|
|
152
152
|
}
|
|
153
153
|
catch (error) {
|
|
154
|
-
|
|
154
|
+
logger.error(`An unexpected error occurred while downloading files: ` + error);
|
|
155
155
|
}
|
|
156
156
|
// Mark all files as failed if we get here
|
|
157
157
|
result.failed = [...requestedFileMap.values()];
|
|
@@ -2,7 +2,8 @@ import { aggregateFiles } from '../formats/files/translate.js';
|
|
|
2
2
|
import { collectAndSendUserEditDiffs } from './collectUserEditDiffs.js';
|
|
3
3
|
import { gt } from '../utils/gt.js';
|
|
4
4
|
import { BranchStep } from '../workflow/BranchStep.js';
|
|
5
|
-
import {
|
|
5
|
+
import { logErrorAndExit } from '../console/logging.js';
|
|
6
|
+
import { logger } from '../console/logger.js';
|
|
6
7
|
import chalk from 'chalk';
|
|
7
8
|
/**
|
|
8
9
|
* Uploads current source files to obtain file references, then collects and sends
|
|
@@ -21,7 +22,7 @@ export async function saveLocalEdits(settings) {
|
|
|
21
22
|
const branchResult = await branchStep.run();
|
|
22
23
|
await branchStep.wait();
|
|
23
24
|
if (!branchResult) {
|
|
24
|
-
logErrorAndExit('Failed to resolve git branch information.');
|
|
25
|
+
return logErrorAndExit('Failed to resolve git branch information.');
|
|
25
26
|
}
|
|
26
27
|
const uploads = files.map((file) => ({
|
|
27
28
|
fileName: file.fileName,
|
|
@@ -30,7 +31,7 @@ export async function saveLocalEdits(settings) {
|
|
|
30
31
|
fileId: file.fileId,
|
|
31
32
|
versionId: file.versionId,
|
|
32
33
|
}));
|
|
33
|
-
const spinner = createSpinner('dots');
|
|
34
|
+
const spinner = logger.createSpinner('dots');
|
|
34
35
|
spinner.start('Saving local edits...');
|
|
35
36
|
await collectAndSendUserEditDiffs(uploads, settings);
|
|
36
37
|
spinner.stop(chalk.green('Local edits saved successfully'));
|
package/dist/api/uploadFiles.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import {
|
|
2
|
+
import { logger } from '../console/logger.js';
|
|
3
|
+
import { exitSync } from '../console/logging.js';
|
|
3
4
|
import { gt } from '../utils/gt.js';
|
|
4
5
|
/**
|
|
5
6
|
* Uploads multiple files to the API
|
|
@@ -8,14 +9,14 @@ import { gt } from '../utils/gt.js';
|
|
|
8
9
|
* @returns The uploaded content or version ID
|
|
9
10
|
*/
|
|
10
11
|
export async function uploadFiles(files, options) {
|
|
11
|
-
|
|
12
|
+
logger.message(chalk.cyan('Files to upload:') +
|
|
12
13
|
'\n' +
|
|
13
14
|
files
|
|
14
15
|
.map((file) => ` - ${chalk.bold(file.source.fileName)} -> ${file.translations
|
|
15
16
|
.map((t) => t.locale)
|
|
16
17
|
.join(', ')}`)
|
|
17
18
|
.join('\n'));
|
|
18
|
-
const spinner = createSpinner('dots');
|
|
19
|
+
const spinner = logger.createSpinner('dots');
|
|
19
20
|
spinner.start(`Uploading ${files.length} file${files.length !== 1 ? 's' : ''} to General Translation...`);
|
|
20
21
|
try {
|
|
21
22
|
// Upload sources
|
|
@@ -35,6 +36,6 @@ export async function uploadFiles(files, options) {
|
|
|
35
36
|
}
|
|
36
37
|
catch {
|
|
37
38
|
spinner.stop(chalk.red('An unexpected error occurred while uploading files'));
|
|
38
|
-
|
|
39
|
+
return exitSync(1);
|
|
39
40
|
}
|
|
40
41
|
}
|
package/dist/cli/base.d.ts
CHANGED
|
@@ -16,16 +16,17 @@ export declare class BaseCLI {
|
|
|
16
16
|
constructor(program: Command, library: SupportedLibraries, additionalModules?: SupportedLibraries[]);
|
|
17
17
|
init(): void;
|
|
18
18
|
execute(): void;
|
|
19
|
+
protected setupSetupProjectCommand(): void;
|
|
19
20
|
protected setupStageCommand(): void;
|
|
20
21
|
protected setupTranslateCommand(): void;
|
|
21
22
|
protected setupSendDiffsCommand(): void;
|
|
23
|
+
protected handleSetupProject(initOptions: TranslateFlags): Promise<void>;
|
|
22
24
|
protected handleStage(initOptions: TranslateFlags): Promise<void>;
|
|
23
25
|
protected handleTranslate(initOptions: TranslateFlags): Promise<void>;
|
|
24
26
|
protected setupUploadCommand(): void;
|
|
25
27
|
protected setupLoginCommand(): void;
|
|
26
28
|
protected setupInitCommand(): void;
|
|
27
29
|
protected setupConfigureCommand(): void;
|
|
28
|
-
protected setupSetupCommand(): void;
|
|
29
30
|
protected handleUploadCommand(settings: Settings & UploadOptions): Promise<void>;
|
|
30
31
|
protected handleSetupReactCommand(options: SetupOptions): Promise<void>;
|
|
31
32
|
protected handleInitCommand(ranReactSetup: boolean): Promise<void>;
|
package/dist/cli/base.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createOrUpdateConfig } from '../fs/config/setupConfig.js';
|
|
2
2
|
import findFilepath from '../fs/findFilepath.js';
|
|
3
|
-
import { displayHeader, promptText, logErrorAndExit,
|
|
3
|
+
import { displayHeader, promptText, logErrorAndExit, promptConfirm, promptMultiSelect, } from '../console/logging.js';
|
|
4
|
+
import { logger } from '../console/logger.js';
|
|
4
5
|
import path from 'node:path';
|
|
5
6
|
import fs from 'node:fs';
|
|
6
7
|
import { generateSettings } from '../config/generateSettings.js';
|
|
@@ -16,6 +17,7 @@ import { areCredentialsSet } from '../utils/credentials.js';
|
|
|
16
17
|
import { upload } from '../formats/files/upload.js';
|
|
17
18
|
import { attachTranslateFlags } from './flags.js';
|
|
18
19
|
import { handleStage } from './commands/stage.js';
|
|
20
|
+
import { handleSetupProject } from './commands/setupProject.js';
|
|
19
21
|
import { handleDownload, handleTranslate, postProcessTranslations, } from './commands/translate.js';
|
|
20
22
|
import { getDownloaded, clearDownloaded } from '../state/recentDownloads.js';
|
|
21
23
|
import updateConfig from '../fs/config/updateConfig.js';
|
|
@@ -33,13 +35,14 @@ export class BaseCLI {
|
|
|
33
35
|
this.additionalModules = additionalModules || [];
|
|
34
36
|
this.setupInitCommand();
|
|
35
37
|
this.setupConfigureCommand();
|
|
36
|
-
this.setupSetupCommand();
|
|
37
38
|
this.setupUploadCommand();
|
|
38
39
|
this.setupLoginCommand();
|
|
39
40
|
this.setupSendDiffsCommand();
|
|
40
41
|
}
|
|
41
42
|
// Init is never called in a child class
|
|
42
43
|
init() {
|
|
44
|
+
this.setupSetupProjectCommand();
|
|
45
|
+
this.setupStageCommand();
|
|
43
46
|
this.setupTranslateCommand();
|
|
44
47
|
}
|
|
45
48
|
// Execute is called by the main program
|
|
@@ -49,13 +52,22 @@ export class BaseCLI {
|
|
|
49
52
|
process.argv.push('init');
|
|
50
53
|
}
|
|
51
54
|
}
|
|
55
|
+
setupSetupProjectCommand() {
|
|
56
|
+
attachTranslateFlags(this.program
|
|
57
|
+
.command('setup')
|
|
58
|
+
.description('Upload source files and setup the project for translation')).action(async (initOptions) => {
|
|
59
|
+
displayHeader('Uploading source files and setting up project...');
|
|
60
|
+
await this.handleSetupProject(initOptions);
|
|
61
|
+
logger.endCommand('Done!');
|
|
62
|
+
});
|
|
63
|
+
}
|
|
52
64
|
setupStageCommand() {
|
|
53
65
|
attachTranslateFlags(this.program
|
|
54
66
|
.command('stage')
|
|
55
67
|
.description('Submits the project to the General Translation API for translation. Translations created using this command will require human approval.')).action(async (initOptions) => {
|
|
56
68
|
displayHeader('Staging project for translation with approval required...');
|
|
57
69
|
await this.handleStage(initOptions);
|
|
58
|
-
endCommand('Done!');
|
|
70
|
+
logger.endCommand('Done!');
|
|
59
71
|
});
|
|
60
72
|
}
|
|
61
73
|
setupTranslateCommand() {
|
|
@@ -64,7 +76,7 @@ export class BaseCLI {
|
|
|
64
76
|
.description('Translate your project using General Translation')).action(async (initOptions) => {
|
|
65
77
|
displayHeader('Starting translation...');
|
|
66
78
|
await this.handleTranslate(initOptions);
|
|
67
|
-
endCommand('Done!');
|
|
79
|
+
logger.endCommand('Done!');
|
|
68
80
|
});
|
|
69
81
|
}
|
|
70
82
|
setupSendDiffsCommand() {
|
|
@@ -76,9 +88,15 @@ export class BaseCLI {
|
|
|
76
88
|
const config = findFilepath(['gt.config.json']);
|
|
77
89
|
const settings = await generateSettings({ config });
|
|
78
90
|
await saveLocalEdits(settings);
|
|
79
|
-
endCommand('Saved local edits');
|
|
91
|
+
logger.endCommand('Saved local edits');
|
|
80
92
|
});
|
|
81
93
|
}
|
|
94
|
+
async handleSetupProject(initOptions) {
|
|
95
|
+
const settings = await generateSettings(initOptions);
|
|
96
|
+
// Preprocess shared static assets if configured (move + rewrite sources)
|
|
97
|
+
await processSharedStaticAssets(settings);
|
|
98
|
+
await handleSetupProject(initOptions, settings, this.library);
|
|
99
|
+
}
|
|
82
100
|
async handleStage(initOptions) {
|
|
83
101
|
const settings = await generateSettings(initOptions);
|
|
84
102
|
// Preprocess shared static assets if configured (move + rewrite sources)
|
|
@@ -126,7 +144,7 @@ export class BaseCLI {
|
|
|
126
144
|
const settings = await generateSettings(initOptions);
|
|
127
145
|
const options = { ...initOptions, ...settings };
|
|
128
146
|
await this.handleUploadCommand(options);
|
|
129
|
-
endCommand('Done!');
|
|
147
|
+
logger.endCommand('Done!');
|
|
130
148
|
});
|
|
131
149
|
}
|
|
132
150
|
setupLoginCommand() {
|
|
@@ -159,7 +177,7 @@ export class BaseCLI {
|
|
|
159
177
|
}
|
|
160
178
|
}
|
|
161
179
|
await this.handleLoginCommand(options);
|
|
162
|
-
endCommand(`Done! A ${options.keyType} key has been generated and saved to your .env.local file.`);
|
|
180
|
+
logger.endCommand(`Done! A ${options.keyType} key has been generated and saved to your .env.local file.`);
|
|
163
181
|
});
|
|
164
182
|
}
|
|
165
183
|
setupInitCommand() {
|
|
@@ -179,20 +197,20 @@ export class BaseCLI {
|
|
|
179
197
|
defaultValue: true,
|
|
180
198
|
});
|
|
181
199
|
if (wrap) {
|
|
182
|
-
|
|
200
|
+
logger.info(`${chalk.yellow('[EXPERIMENTAL]')} Running React setup wizard...`);
|
|
183
201
|
await this.handleSetupReactCommand(options);
|
|
184
|
-
endCommand(`Done! Since this wizard is experimental, please review the changes and make modifications as needed.
|
|
202
|
+
logger.endCommand(`Done! Since this wizard is experimental, please review the changes and make modifications as needed.
|
|
185
203
|
Certain aspects of your app may still need manual setup.
|
|
186
204
|
See the docs for more information: https://generaltranslation.com/docs/react/tutorials/quickstart`);
|
|
187
205
|
ranReactSetup = true;
|
|
188
206
|
}
|
|
189
207
|
}
|
|
190
208
|
if (ranReactSetup) {
|
|
191
|
-
startCommand('Setting up project config...');
|
|
209
|
+
logger.startCommand('Setting up project config...');
|
|
192
210
|
}
|
|
193
211
|
// Configure gt.config.json
|
|
194
212
|
await this.handleInitCommand(ranReactSetup);
|
|
195
|
-
endCommand('Done! Check out our docs for more information on how to use General Translation: https://generaltranslation.com/docs');
|
|
213
|
+
logger.endCommand('Done! Check out our docs for more information on how to use General Translation: https://generaltranslation.com/docs');
|
|
196
214
|
});
|
|
197
215
|
}
|
|
198
216
|
setupConfigureCommand() {
|
|
@@ -201,22 +219,10 @@ See the docs for more information: https://generaltranslation.com/docs/react/tut
|
|
|
201
219
|
.description('Configure your project for General Translation. This will create a gt.config.json file in your codebase.')
|
|
202
220
|
.action(async () => {
|
|
203
221
|
displayHeader('Configuring project...');
|
|
204
|
-
|
|
222
|
+
logger.info('Welcome! This tool will help you configure your gt.config.json file. See the docs: https://generaltranslation.com/docs/cli/reference/config for more information.');
|
|
205
223
|
// Configure gt.config.json
|
|
206
224
|
await this.handleInitCommand(false);
|
|
207
|
-
endCommand('Done! Make sure you have an API key and project ID to use General Translation. Get them on the dashboard: https://generaltranslation.com/dashboard');
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
setupSetupCommand() {
|
|
211
|
-
this.program
|
|
212
|
-
.command('setup')
|
|
213
|
-
.description('Run the setup to configure your Next.js or React project for General Translation')
|
|
214
|
-
.option('--src <paths...>', "Space-separated list of glob patterns containing the app's source code, by default 'src/**/*.{js,jsx,ts,tsx}' 'app/**/*.{js,jsx,ts,tsx}' 'pages/**/*.{js,jsx,ts,tsx}' 'components/**/*.{js,jsx,ts,tsx}'")
|
|
215
|
-
.option('-c, --config <path>', 'Filepath to config file, by default gt.config.json', findFilepath(['gt.config.json']))
|
|
216
|
-
.action(async (options) => {
|
|
217
|
-
displayHeader('Running React setup wizard...');
|
|
218
|
-
await this.handleSetupReactCommand(options);
|
|
219
|
-
endCommand("Done! Take advantage of all of General Translation's features by signing up for a free account! https://generaltranslation.com/signup");
|
|
225
|
+
logger.endCommand('Done! Make sure you have an API key and project ID to use General Translation. Get them on the dashboard: https://generaltranslation.com/dashboard');
|
|
220
226
|
});
|
|
221
227
|
}
|
|
222
228
|
async handleUploadCommand(settings) {
|
|
@@ -264,7 +270,7 @@ See the docs for more information: https://generaltranslation.com/docs/react/tut
|
|
|
264
270
|
message: `Auto-detected that you're using gt-next or gt-react. Would you like to use the General Translation CDN to store your translations?\nSee ${isUsingGTNext
|
|
265
271
|
? 'https://generaltranslation.com/en/docs/next/guides/local-tx'
|
|
266
272
|
: 'https://generaltranslation.com/en/docs/react/guides/local-tx'} for more information.\nIf you answer no, we'll configure the CLI tool to download completed translations.`,
|
|
267
|
-
defaultValue:
|
|
273
|
+
defaultValue: false,
|
|
268
274
|
})
|
|
269
275
|
: false;
|
|
270
276
|
// Ask where the translations are stored
|
|
@@ -278,8 +284,8 @@ See the docs for more information: https://generaltranslation.com/docs/react/tut
|
|
|
278
284
|
const finalTranslationsDir = translationsDir?.trim() || './public/_gt';
|
|
279
285
|
if (isUsingGT && !usingCDN) {
|
|
280
286
|
// Create loadTranslations.js file for local translations
|
|
281
|
-
await createLoadTranslationsFile(process.cwd(), finalTranslationsDir);
|
|
282
|
-
|
|
287
|
+
await createLoadTranslationsFile(process.cwd(), finalTranslationsDir, locales);
|
|
288
|
+
logger.message(`Created ${chalk.cyan('loadTranslations.js')} file for local translations.
|
|
283
289
|
Make sure to add this function to your app configuration.
|
|
284
290
|
See https://generaltranslation.com/en/docs/next/guides/local-tx`);
|
|
285
291
|
}
|
|
@@ -325,14 +331,14 @@ See https://generaltranslation.com/en/docs/next/guides/local-tx`);
|
|
|
325
331
|
files: Object.keys(files).length > 0 ? files : undefined,
|
|
326
332
|
publish: isUsingGT && usingCDN,
|
|
327
333
|
});
|
|
328
|
-
|
|
334
|
+
logger.success(`Feel free to edit ${chalk.cyan(configFilepath)} to customize your translation setup. Docs: https://generaltranslation.com/docs/cli/reference/config`);
|
|
329
335
|
// Install gtx-cli if not installed
|
|
330
336
|
const isCLIInstalled = packageJson
|
|
331
337
|
? isPackageInstalled('gtx-cli', packageJson, true, true)
|
|
332
338
|
: true; // if no package.json, we can't install it
|
|
333
339
|
if (!isCLIInstalled) {
|
|
334
340
|
const packageManager = await getPackageManager();
|
|
335
|
-
const spinner = createSpinner();
|
|
341
|
+
const spinner = logger.createSpinner();
|
|
336
342
|
spinner.start(`Installing gtx-cli as a dev dependency with ${packageManager.name}...`);
|
|
337
343
|
await installPackage('gtx-cli', packageManager, true);
|
|
338
344
|
spinner.stop(chalk.green('Installed gtx-cli.'));
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Settings, SupportedLibraries, TranslateFlags } from '../../types/index.js';
|
|
2
|
+
import { FileTranslationData } from '../../workflow/download.js';
|
|
3
|
+
import { BranchData } from '../../types/branch.js';
|
|
4
|
+
export declare function handleSetupProject(options: TranslateFlags, settings: Settings, library: SupportedLibraries): Promise<{
|
|
5
|
+
fileVersionData: FileTranslationData | undefined;
|
|
6
|
+
branchData: BranchData | undefined;
|
|
7
|
+
} | null>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { logger } from '../../console/logger.js';
|
|
2
|
+
import { logCollectedFiles, logErrorAndExit } from '../../console/logging.js';
|
|
3
|
+
import { noLocalesError, noDefaultLocaleError, noApiKeyError, noProjectIdError, devApiKeyError, } from '../../console/index.js';
|
|
4
|
+
import { collectFiles } from '../../formats/files/collectFiles.js';
|
|
5
|
+
import { setupProject } from '../../workflow/setupProject.js';
|
|
6
|
+
export async function handleSetupProject(options, settings, library) {
|
|
7
|
+
// Validate required settings are present if not in dry run
|
|
8
|
+
if (!options.dryRun) {
|
|
9
|
+
if (!settings.locales) {
|
|
10
|
+
return logErrorAndExit(noLocalesError);
|
|
11
|
+
}
|
|
12
|
+
if (!settings.defaultLocale) {
|
|
13
|
+
return logErrorAndExit(noDefaultLocaleError);
|
|
14
|
+
}
|
|
15
|
+
if (!settings.apiKey) {
|
|
16
|
+
return logErrorAndExit(noApiKeyError);
|
|
17
|
+
}
|
|
18
|
+
if (settings.apiKey.startsWith('gtx-dev-')) {
|
|
19
|
+
return logErrorAndExit(devApiKeyError);
|
|
20
|
+
}
|
|
21
|
+
if (!settings.projectId) {
|
|
22
|
+
return logErrorAndExit(noProjectIdError);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const { files: allFiles, reactComponents } = await collectFiles(options, settings, library);
|
|
26
|
+
// Dry run
|
|
27
|
+
if (options.dryRun) {
|
|
28
|
+
logger.success(`Dry run: No files were uploaded to General Translation.`);
|
|
29
|
+
logCollectedFiles(allFiles, reactComponents);
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
// Upload files and run setup step
|
|
33
|
+
let fileVersionData;
|
|
34
|
+
let branchData;
|
|
35
|
+
if (allFiles.length > 0) {
|
|
36
|
+
const { branchData: branchDataResult } = await setupProject(allFiles, options, settings);
|
|
37
|
+
branchData = branchDataResult;
|
|
38
|
+
fileVersionData = Object.fromEntries(allFiles.map((file) => [
|
|
39
|
+
file.fileId,
|
|
40
|
+
{
|
|
41
|
+
fileName: file.fileName,
|
|
42
|
+
versionId: file.versionId,
|
|
43
|
+
},
|
|
44
|
+
]));
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
fileVersionData,
|
|
48
|
+
branchData,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -2,8 +2,6 @@ import { Settings, SupportedLibraries, TranslateFlags } from '../../types/index.
|
|
|
2
2
|
import type { EnqueueFilesResult } from 'generaltranslation/types';
|
|
3
3
|
import { FileTranslationData } from '../../workflow/download.js';
|
|
4
4
|
import { BranchData } from '../../types/branch.js';
|
|
5
|
-
export declare const TEMPLATE_FILE_NAME = "__INTERNAL_GT_TEMPLATE_NAME__";
|
|
6
|
-
export declare const TEMPLATE_FILE_ID: string;
|
|
7
5
|
export declare function handleStage(options: TranslateFlags, settings: Settings, library: SupportedLibraries, stage: boolean): Promise<{
|
|
8
6
|
fileVersionData: FileTranslationData | undefined;
|
|
9
7
|
jobData: EnqueueFilesResult | undefined;
|
|
@@ -1,83 +1,35 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { aggregateReactTranslations } from '../../translation/stage.js';
|
|
1
|
+
import { logger } from '../../console/logger.js';
|
|
2
|
+
import { logCollectedFiles, logErrorAndExit } from '../../console/logging.js';
|
|
3
|
+
import { noLocalesError, noDefaultLocaleError, noApiKeyError, noProjectIdError, devApiKeyError, } from '../../console/index.js';
|
|
5
4
|
import { stageFiles } from '../../workflow/stage.js';
|
|
6
5
|
import { updateVersions } from '../../fs/config/updateVersions.js';
|
|
7
6
|
import updateConfig from '../../fs/config/updateConfig.js';
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
export const TEMPLATE_FILE_ID = hashStringSync(TEMPLATE_FILE_NAME);
|
|
7
|
+
import { TEMPLATE_FILE_ID } from '../../utils/constants.js';
|
|
8
|
+
import { collectFiles } from '../../formats/files/collectFiles.js';
|
|
11
9
|
export async function handleStage(options, settings, library, stage) {
|
|
12
10
|
// Validate required settings are present if not in dry run
|
|
13
11
|
if (!options.dryRun) {
|
|
14
12
|
if (!settings.locales) {
|
|
15
|
-
logErrorAndExit(noLocalesError);
|
|
13
|
+
return logErrorAndExit(noLocalesError);
|
|
16
14
|
}
|
|
17
15
|
if (!settings.defaultLocale) {
|
|
18
|
-
logErrorAndExit(noDefaultLocaleError);
|
|
16
|
+
return logErrorAndExit(noDefaultLocaleError);
|
|
19
17
|
}
|
|
20
18
|
if (!settings.apiKey) {
|
|
21
|
-
logErrorAndExit(noApiKeyError);
|
|
19
|
+
return logErrorAndExit(noApiKeyError);
|
|
22
20
|
}
|
|
23
21
|
if (settings.apiKey.startsWith('gtx-dev-')) {
|
|
24
|
-
logErrorAndExit(devApiKeyError);
|
|
22
|
+
return logErrorAndExit(devApiKeyError);
|
|
25
23
|
}
|
|
26
24
|
if (!settings.projectId) {
|
|
27
|
-
logErrorAndExit(noProjectIdError);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
// Aggregate files
|
|
31
|
-
const allFiles = await aggregateFiles(settings);
|
|
32
|
-
// Parse for React components
|
|
33
|
-
let reactComponents = 0;
|
|
34
|
-
if (library === 'gt-react' || library === 'gt-next') {
|
|
35
|
-
const updates = await aggregateReactTranslations(options, settings, library);
|
|
36
|
-
if (updates.length > 0) {
|
|
37
|
-
if (!options.dryRun &&
|
|
38
|
-
!settings.publish &&
|
|
39
|
-
!settings.files?.placeholderPaths.gt) {
|
|
40
|
-
logErrorAndExit(invalidConfigurationError);
|
|
41
|
-
}
|
|
42
|
-
reactComponents = updates.length;
|
|
43
|
-
// Convert updates to a file object
|
|
44
|
-
const fileData = {};
|
|
45
|
-
const fileMetadata = {};
|
|
46
|
-
// Convert updates to the proper data format
|
|
47
|
-
for (const update of updates) {
|
|
48
|
-
const { source, metadata, dataFormat } = update;
|
|
49
|
-
metadata.dataFormat = dataFormat; // add the data format to the metadata
|
|
50
|
-
const { hash, id } = metadata;
|
|
51
|
-
if (id) {
|
|
52
|
-
fileData[id] = source;
|
|
53
|
-
fileMetadata[id] = metadata;
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
fileData[hash] = source;
|
|
57
|
-
fileMetadata[hash] = metadata;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
allFiles.push({
|
|
61
|
-
fileName: TEMPLATE_FILE_NAME,
|
|
62
|
-
content: JSON.stringify(fileData),
|
|
63
|
-
fileFormat: 'GTJSON',
|
|
64
|
-
formatMetadata: fileMetadata,
|
|
65
|
-
fileId: TEMPLATE_FILE_ID,
|
|
66
|
-
versionId: hashStringSync(JSON.stringify(fileData)),
|
|
67
|
-
});
|
|
25
|
+
return logErrorAndExit(noProjectIdError);
|
|
68
26
|
}
|
|
69
27
|
}
|
|
28
|
+
const { files: allFiles, reactComponents } = await collectFiles(options, settings, library);
|
|
70
29
|
// Dry run
|
|
71
30
|
if (options.dryRun) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if (file.fileName === TEMPLATE_FILE_NAME) {
|
|
75
|
-
return `- <React Elements> (${reactComponents})`;
|
|
76
|
-
}
|
|
77
|
-
return `- ${file.fileName}`;
|
|
78
|
-
})
|
|
79
|
-
.join('\n');
|
|
80
|
-
logSuccess(`Dry run: No files were sent to General Translation. Found files:\n${fileNames}`);
|
|
31
|
+
logger.success(`Dry run: No files were sent to General Translation.`);
|
|
32
|
+
logCollectedFiles(allFiles, reactComponents);
|
|
81
33
|
return null;
|
|
82
34
|
}
|
|
83
35
|
// Send translations to General Translation
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { downloadTranslations, } from '../../workflow/download.js';
|
|
2
2
|
import { createFileMapping } from '../../formats/files/fileMapping.js';
|
|
3
|
-
import { logError } from '../../console/logging.js';
|
|
4
3
|
import { getStagedVersions } from '../../fs/config/updateVersions.js';
|
|
5
4
|
import copyFile from '../../fs/copyFile.js';
|
|
6
5
|
import flattenJsonFiles from '../../utils/flattenJsonFiles.js';
|
|
@@ -8,6 +7,7 @@ import localizeStaticUrls from '../../utils/localizeStaticUrls.js';
|
|
|
8
7
|
import processAnchorIds from '../../utils/processAnchorIds.js';
|
|
9
8
|
import { noFilesError, noVersionIdError } from '../../console/index.js';
|
|
10
9
|
import localizeStaticImports from '../../utils/localizeStaticImports.js';
|
|
10
|
+
import { logErrorAndExit } from '../../console/logging.js';
|
|
11
11
|
// Downloads translations that were completed
|
|
12
12
|
export async function handleTranslate(options, settings, fileVersionData, jobData, branchData) {
|
|
13
13
|
if (fileVersionData) {
|
|
@@ -20,12 +20,10 @@ export async function handleTranslate(options, settings, fileVersionData, jobDat
|
|
|
20
20
|
// Downloads translations that were originally staged
|
|
21
21
|
export async function handleDownload(options, settings) {
|
|
22
22
|
if (!settings._versionId) {
|
|
23
|
-
|
|
24
|
-
process.exit(1);
|
|
23
|
+
logErrorAndExit(noVersionIdError);
|
|
25
24
|
}
|
|
26
25
|
if (!settings.files) {
|
|
27
|
-
|
|
28
|
-
process.exit(1);
|
|
26
|
+
logErrorAndExit(noFilesError);
|
|
29
27
|
}
|
|
30
28
|
// Files
|
|
31
29
|
const { resolvedPaths, placeholderPaths, transformPaths } = settings.files;
|
package/dist/cli/flags.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import findFilepath from '../fs/findFilepath.js';
|
|
2
|
-
import { logErrorAndExit } from '../console/logging.js';
|
|
3
2
|
const DEFAULT_TIMEOUT = 600;
|
|
4
3
|
export function attachTranslateFlags(command) {
|
|
5
4
|
command
|
|
@@ -13,10 +12,10 @@ export function attachTranslateFlags(command) {
|
|
|
13
12
|
.option('--timeout <seconds>', 'Translation wait timeout in seconds', (value) => {
|
|
14
13
|
const parsedValue = parseInt(value, 10);
|
|
15
14
|
if (isNaN(parsedValue)) {
|
|
16
|
-
|
|
15
|
+
throw new Error('Invalid timeout: not a number.');
|
|
17
16
|
}
|
|
18
17
|
if (parsedValue < 0) {
|
|
19
|
-
|
|
18
|
+
throw new Error('Invalid timeout: must be a positive number.');
|
|
20
19
|
}
|
|
21
20
|
return parsedValue;
|
|
22
21
|
}, DEFAULT_TIMEOUT)
|
package/dist/cli/next.js
CHANGED
package/dist/cli/react.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export declare class ReactCLI extends BaseCLI {
|
|
|
8
8
|
protected wrapContent(options: WrapOptions, framework: SupportedFrameworks, errors: string[], warnings: string[]): Promise<{
|
|
9
9
|
filesUpdated: string[];
|
|
10
10
|
}>;
|
|
11
|
+
protected setupSetupProjectCommand(): void;
|
|
11
12
|
protected setupStageCommand(): void;
|
|
12
13
|
protected setupTranslateCommand(): void;
|
|
13
14
|
protected setupValidateCommand(): void;
|