gtx-cli 2.5.7 → 2.5.8
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 +6 -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.js +17 -16
- package/dist/cli/commands/stage.js +8 -7
- package/dist/cli/commands/translate.js +3 -5
- package/dist/cli/flags.js +2 -3
- package/dist/cli/react.js +16 -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 +27 -0
- package/dist/console/logger.js +255 -0
- package/dist/console/logging.d.ts +1 -11
- package/dist/console/logging.js +24 -55
- 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.js +3 -3
- 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/utils/addExplicitAnchorIds.js +2 -2
- 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 +3 -3
- package/dist/workflow/SetupStep.js +2 -2
- package/dist/workflow/UploadStep.js +3 -3
- package/dist/workflow/UserEditDiffsStep.js +2 -2
- package/dist/workflow/download.js +4 -3
- package/dist/workflow/stage.js +5 -4
- package/package.json +2 -2
- package/dist/utils/SpinnerManager.d.ts +0 -30
- package/dist/utils/SpinnerManager.js +0 -73
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# gtx-cli
|
|
2
2
|
|
|
3
|
+
## 2.5.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#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
|
|
8
|
+
|
|
3
9
|
## 2.5.7
|
|
4
10
|
|
|
5
11
|
### 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.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';
|
|
@@ -55,7 +56,7 @@ export class BaseCLI {
|
|
|
55
56
|
.description('Submits the project to the General Translation API for translation. Translations created using this command will require human approval.')).action(async (initOptions) => {
|
|
56
57
|
displayHeader('Staging project for translation with approval required...');
|
|
57
58
|
await this.handleStage(initOptions);
|
|
58
|
-
endCommand('Done!');
|
|
59
|
+
logger.endCommand('Done!');
|
|
59
60
|
});
|
|
60
61
|
}
|
|
61
62
|
setupTranslateCommand() {
|
|
@@ -64,7 +65,7 @@ export class BaseCLI {
|
|
|
64
65
|
.description('Translate your project using General Translation')).action(async (initOptions) => {
|
|
65
66
|
displayHeader('Starting translation...');
|
|
66
67
|
await this.handleTranslate(initOptions);
|
|
67
|
-
endCommand('Done!');
|
|
68
|
+
logger.endCommand('Done!');
|
|
68
69
|
});
|
|
69
70
|
}
|
|
70
71
|
setupSendDiffsCommand() {
|
|
@@ -76,7 +77,7 @@ export class BaseCLI {
|
|
|
76
77
|
const config = findFilepath(['gt.config.json']);
|
|
77
78
|
const settings = await generateSettings({ config });
|
|
78
79
|
await saveLocalEdits(settings);
|
|
79
|
-
endCommand('Saved local edits');
|
|
80
|
+
logger.endCommand('Saved local edits');
|
|
80
81
|
});
|
|
81
82
|
}
|
|
82
83
|
async handleStage(initOptions) {
|
|
@@ -126,7 +127,7 @@ export class BaseCLI {
|
|
|
126
127
|
const settings = await generateSettings(initOptions);
|
|
127
128
|
const options = { ...initOptions, ...settings };
|
|
128
129
|
await this.handleUploadCommand(options);
|
|
129
|
-
endCommand('Done!');
|
|
130
|
+
logger.endCommand('Done!');
|
|
130
131
|
});
|
|
131
132
|
}
|
|
132
133
|
setupLoginCommand() {
|
|
@@ -159,7 +160,7 @@ export class BaseCLI {
|
|
|
159
160
|
}
|
|
160
161
|
}
|
|
161
162
|
await this.handleLoginCommand(options);
|
|
162
|
-
endCommand(`Done! A ${options.keyType} key has been generated and saved to your .env.local file.`);
|
|
163
|
+
logger.endCommand(`Done! A ${options.keyType} key has been generated and saved to your .env.local file.`);
|
|
163
164
|
});
|
|
164
165
|
}
|
|
165
166
|
setupInitCommand() {
|
|
@@ -179,20 +180,20 @@ export class BaseCLI {
|
|
|
179
180
|
defaultValue: true,
|
|
180
181
|
});
|
|
181
182
|
if (wrap) {
|
|
182
|
-
|
|
183
|
+
logger.info(`${chalk.yellow('[EXPERIMENTAL]')} Running React setup wizard...`);
|
|
183
184
|
await this.handleSetupReactCommand(options);
|
|
184
|
-
endCommand(`Done! Since this wizard is experimental, please review the changes and make modifications as needed.
|
|
185
|
+
logger.endCommand(`Done! Since this wizard is experimental, please review the changes and make modifications as needed.
|
|
185
186
|
Certain aspects of your app may still need manual setup.
|
|
186
187
|
See the docs for more information: https://generaltranslation.com/docs/react/tutorials/quickstart`);
|
|
187
188
|
ranReactSetup = true;
|
|
188
189
|
}
|
|
189
190
|
}
|
|
190
191
|
if (ranReactSetup) {
|
|
191
|
-
startCommand('Setting up project config...');
|
|
192
|
+
logger.startCommand('Setting up project config...');
|
|
192
193
|
}
|
|
193
194
|
// Configure gt.config.json
|
|
194
195
|
await this.handleInitCommand(ranReactSetup);
|
|
195
|
-
endCommand('Done! Check out our docs for more information on how to use General Translation: https://generaltranslation.com/docs');
|
|
196
|
+
logger.endCommand('Done! Check out our docs for more information on how to use General Translation: https://generaltranslation.com/docs');
|
|
196
197
|
});
|
|
197
198
|
}
|
|
198
199
|
setupConfigureCommand() {
|
|
@@ -201,10 +202,10 @@ See the docs for more information: https://generaltranslation.com/docs/react/tut
|
|
|
201
202
|
.description('Configure your project for General Translation. This will create a gt.config.json file in your codebase.')
|
|
202
203
|
.action(async () => {
|
|
203
204
|
displayHeader('Configuring project...');
|
|
204
|
-
|
|
205
|
+
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
206
|
// Configure gt.config.json
|
|
206
207
|
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
|
+
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');
|
|
208
209
|
});
|
|
209
210
|
}
|
|
210
211
|
setupSetupCommand() {
|
|
@@ -216,7 +217,7 @@ See the docs for more information: https://generaltranslation.com/docs/react/tut
|
|
|
216
217
|
.action(async (options) => {
|
|
217
218
|
displayHeader('Running React setup wizard...');
|
|
218
219
|
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");
|
|
220
|
+
logger.endCommand("Done! Take advantage of all of General Translation's features by signing up for a free account! https://generaltranslation.com/signup");
|
|
220
221
|
});
|
|
221
222
|
}
|
|
222
223
|
async handleUploadCommand(settings) {
|
|
@@ -279,7 +280,7 @@ See the docs for more information: https://generaltranslation.com/docs/react/tut
|
|
|
279
280
|
if (isUsingGT && !usingCDN) {
|
|
280
281
|
// Create loadTranslations.js file for local translations
|
|
281
282
|
await createLoadTranslationsFile(process.cwd(), finalTranslationsDir);
|
|
282
|
-
|
|
283
|
+
logger.message(`Created ${chalk.cyan('loadTranslations.js')} file for local translations.
|
|
283
284
|
Make sure to add this function to your app configuration.
|
|
284
285
|
See https://generaltranslation.com/en/docs/next/guides/local-tx`);
|
|
285
286
|
}
|
|
@@ -325,14 +326,14 @@ See https://generaltranslation.com/en/docs/next/guides/local-tx`);
|
|
|
325
326
|
files: Object.keys(files).length > 0 ? files : undefined,
|
|
326
327
|
publish: isUsingGT && usingCDN,
|
|
327
328
|
});
|
|
328
|
-
|
|
329
|
+
logger.success(`Feel free to edit ${chalk.cyan(configFilepath)} to customize your translation setup. Docs: https://generaltranslation.com/docs/cli/reference/config`);
|
|
329
330
|
// Install gtx-cli if not installed
|
|
330
331
|
const isCLIInstalled = packageJson
|
|
331
332
|
? isPackageInstalled('gtx-cli', packageJson, true, true)
|
|
332
333
|
: true; // if no package.json, we can't install it
|
|
333
334
|
if (!isCLIInstalled) {
|
|
334
335
|
const packageManager = await getPackageManager();
|
|
335
|
-
const spinner = createSpinner();
|
|
336
|
+
const spinner = logger.createSpinner();
|
|
336
337
|
spinner.start(`Installing gtx-cli as a dev dependency with ${packageManager.name}...`);
|
|
337
338
|
await installPackage('gtx-cli', packageManager, true);
|
|
338
339
|
spinner.stop(chalk.green('Installed gtx-cli.'));
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { logger } from '../../console/logger.js';
|
|
2
|
+
import { logErrorAndExit } from '../../console/logging.js';
|
|
2
3
|
import { noLocalesError, noDefaultLocaleError, noApiKeyError, noProjectIdError, devApiKeyError, invalidConfigurationError, } from '../../console/index.js';
|
|
3
4
|
import { aggregateFiles } from '../../formats/files/translate.js';
|
|
4
5
|
import { aggregateReactTranslations } from '../../translation/stage.js';
|
|
@@ -12,19 +13,19 @@ export async function handleStage(options, settings, library, stage) {
|
|
|
12
13
|
// Validate required settings are present if not in dry run
|
|
13
14
|
if (!options.dryRun) {
|
|
14
15
|
if (!settings.locales) {
|
|
15
|
-
logErrorAndExit(noLocalesError);
|
|
16
|
+
return logErrorAndExit(noLocalesError);
|
|
16
17
|
}
|
|
17
18
|
if (!settings.defaultLocale) {
|
|
18
|
-
logErrorAndExit(noDefaultLocaleError);
|
|
19
|
+
return logErrorAndExit(noDefaultLocaleError);
|
|
19
20
|
}
|
|
20
21
|
if (!settings.apiKey) {
|
|
21
|
-
logErrorAndExit(noApiKeyError);
|
|
22
|
+
return logErrorAndExit(noApiKeyError);
|
|
22
23
|
}
|
|
23
24
|
if (settings.apiKey.startsWith('gtx-dev-')) {
|
|
24
|
-
logErrorAndExit(devApiKeyError);
|
|
25
|
+
return logErrorAndExit(devApiKeyError);
|
|
25
26
|
}
|
|
26
27
|
if (!settings.projectId) {
|
|
27
|
-
logErrorAndExit(noProjectIdError);
|
|
28
|
+
return logErrorAndExit(noProjectIdError);
|
|
28
29
|
}
|
|
29
30
|
}
|
|
30
31
|
// Aggregate files
|
|
@@ -77,7 +78,7 @@ export async function handleStage(options, settings, library, stage) {
|
|
|
77
78
|
return `- ${file.fileName}`;
|
|
78
79
|
})
|
|
79
80
|
.join('\n');
|
|
80
|
-
|
|
81
|
+
logger.success(`Dry run: No files were sent to General Translation. Found files:\n${fileNames}`);
|
|
81
82
|
return null;
|
|
82
83
|
}
|
|
83
84
|
// 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/react.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { displayHeader,
|
|
1
|
+
import { displayHeader, exitSync, promptConfirm } from '../console/logging.js';
|
|
2
|
+
import { logger } from '../console/logger.js';
|
|
2
3
|
import loadJSON from '../fs/loadJSON.js';
|
|
3
4
|
import findFilepath from '../fs/findFilepath.js';
|
|
4
5
|
import chalk from 'chalk';
|
|
@@ -37,7 +38,7 @@ export class ReactCLI extends BaseCLI {
|
|
|
37
38
|
.description('Submits the project to the General Translation API for translation. Translations created using this command will require human approval.'))).action(async (options) => {
|
|
38
39
|
displayHeader('Staging project for translation with approval required...');
|
|
39
40
|
await this.handleStage(options);
|
|
40
|
-
endCommand('Done!');
|
|
41
|
+
logger.endCommand('Done!');
|
|
41
42
|
});
|
|
42
43
|
}
|
|
43
44
|
setupTranslateCommand() {
|
|
@@ -46,7 +47,7 @@ export class ReactCLI extends BaseCLI {
|
|
|
46
47
|
.description('Scans the project for a dictionary and/or <T> tags, and sends the updates to the General Translation API for translation.'))).action(async (options) => {
|
|
47
48
|
displayHeader('Translating project...');
|
|
48
49
|
await this.handleTranslate(options);
|
|
49
|
-
endCommand('Done!');
|
|
50
|
+
logger.endCommand('Done!');
|
|
50
51
|
});
|
|
51
52
|
}
|
|
52
53
|
setupValidateCommand() {
|
|
@@ -62,7 +63,7 @@ export class ReactCLI extends BaseCLI {
|
|
|
62
63
|
// intro here since we don't want to show the ascii title
|
|
63
64
|
intro(chalk.cyan('Validating project...'));
|
|
64
65
|
await this.handleValidate(options, files);
|
|
65
|
-
endCommand('Done!');
|
|
66
|
+
logger.endCommand('Done!');
|
|
66
67
|
});
|
|
67
68
|
}
|
|
68
69
|
setupGenerateSourceCommand() {
|
|
@@ -71,7 +72,7 @@ export class ReactCLI extends BaseCLI {
|
|
|
71
72
|
.description('Generate a translation file for the source locale. This command should be used if you are handling your own translations.'))).action(async (initOptions) => {
|
|
72
73
|
displayHeader('Generating source templates...');
|
|
73
74
|
await this.handleGenerateSourceCommand(initOptions);
|
|
74
|
-
endCommand('Done!');
|
|
75
|
+
logger.endCommand('Done!');
|
|
75
76
|
});
|
|
76
77
|
}
|
|
77
78
|
async handleGenerateSourceCommand(initOptions) {
|
|
@@ -93,11 +94,11 @@ export class ReactCLI extends BaseCLI {
|
|
|
93
94
|
if (settings.files && settings.files.placeholderPaths.gt) {
|
|
94
95
|
const translationFiles = resolveLocaleFiles(settings.files.placeholderPaths, settings.defaultLocale);
|
|
95
96
|
if (!translationFiles.gt) {
|
|
96
|
-
|
|
97
|
-
|
|
97
|
+
logger.error(noFilesError);
|
|
98
|
+
exitSync(1);
|
|
98
99
|
}
|
|
99
100
|
await saveJSON(translationFiles.gt, newData);
|
|
100
|
-
|
|
101
|
+
logger.step('Source file saved successfully!');
|
|
101
102
|
// Also save translations (after merging with existing translations)
|
|
102
103
|
for (const locale of settings.locales) {
|
|
103
104
|
const translationsFile = resolveLocaleFiles(settings.files.placeholderPaths, locale);
|
|
@@ -113,7 +114,7 @@ export class ReactCLI extends BaseCLI {
|
|
|
113
114
|
const filteredTranslations = Object.fromEntries(Object.entries(mergedTranslations).filter(([key]) => newData[key]));
|
|
114
115
|
await saveJSON(translationsFile.gt, filteredTranslations);
|
|
115
116
|
}
|
|
116
|
-
|
|
117
|
+
logger.step('Merged translations successfully!');
|
|
117
118
|
}
|
|
118
119
|
}
|
|
119
120
|
async handleScanCommand(options) {
|
|
@@ -123,8 +124,8 @@ export class ReactCLI extends BaseCLI {
|
|
|
123
124
|
defaultValue: true,
|
|
124
125
|
});
|
|
125
126
|
if (!answer) {
|
|
126
|
-
|
|
127
|
-
|
|
127
|
+
logger.error('Operation cancelled.');
|
|
128
|
+
exitSync(0);
|
|
128
129
|
}
|
|
129
130
|
// ----- Create a starter gt.config.json file -----
|
|
130
131
|
await generateSettings(options);
|
|
@@ -139,18 +140,18 @@ export class ReactCLI extends BaseCLI {
|
|
|
139
140
|
// Wrap all JSX elements in the src directory with a <T> tag, with unique ids
|
|
140
141
|
const { filesUpdated } = await this.wrapContent(options, 'react', errors, warnings);
|
|
141
142
|
if (errors.length > 0) {
|
|
142
|
-
|
|
143
|
+
logger.error(chalk.red('Failed to write files:\n') + errors.join('\n'));
|
|
143
144
|
}
|
|
144
145
|
// Format updated files if formatters are available
|
|
145
146
|
if (!options.disableFormatting)
|
|
146
147
|
await formatFiles(filesUpdated);
|
|
147
|
-
|
|
148
|
+
logger.success(`Success! Added <T> tags and updated ${chalk.bold.cyan(filesUpdated.length)} files:\n` +
|
|
148
149
|
filesUpdated.map((file) => `${chalk.green('-')} ${file}`).join('\n'));
|
|
149
150
|
if (filesUpdated.length > 0) {
|
|
150
|
-
|
|
151
|
+
logger.step(chalk.green('Please verify the changes before committing.'));
|
|
151
152
|
}
|
|
152
153
|
if (warnings.length > 0) {
|
|
153
|
-
|
|
154
|
+
logger.warn(chalk.yellow('Warnings encountered:') +
|
|
154
155
|
'\n' +
|
|
155
156
|
warnings
|
|
156
157
|
.map((warning) => `${chalk.yellow('-')} ${warning}`)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { displayProjectId, logErrorAndExit, warnApiKeyInConfig, } from '../console/logging.js';
|
|
1
|
+
import { displayProjectId, exitSync, logErrorAndExit, warnApiKeyInConfig, } from '../console/logging.js';
|
|
2
2
|
import { loadConfig } from '../fs/config/loadConfig.js';
|
|
3
3
|
import { defaultBaseUrl, libraryDefaultLocale, } from 'generaltranslation/internal';
|
|
4
4
|
import fs from 'node:fs';
|
|
@@ -46,7 +46,7 @@ export async function generateSettings(flags, cwd = process.cwd()) {
|
|
|
46
46
|
// Warn if apiKey is present in gt.config.json
|
|
47
47
|
if (gtConfig.apiKey) {
|
|
48
48
|
warnApiKeyInConfig(flags.config);
|
|
49
|
-
|
|
49
|
+
exitSync(1);
|
|
50
50
|
}
|
|
51
51
|
const projectIdEnv = resolveProjectId();
|
|
52
52
|
// Resolve mismatched projectIds
|
|
@@ -6,19 +6,19 @@ export function validateSettings(settings) {
|
|
|
6
6
|
// Validate locales
|
|
7
7
|
for (const locale of settings.locales) {
|
|
8
8
|
if (!isValidLocale(locale, settings.customMapping)) {
|
|
9
|
-
logErrorAndExit(`Provided locales: "${settings?.locales?.join()}", ${locale} is not a valid locale!`);
|
|
9
|
+
return logErrorAndExit(`Provided locales: "${settings?.locales?.join()}", ${locale} is not a valid locale!`);
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
if (settings.defaultLocale &&
|
|
13
13
|
!isValidLocale(settings.defaultLocale, settings.customMapping)) {
|
|
14
|
-
logErrorAndExit(`defaultLocale: ${settings.defaultLocale} is not a valid locale!`);
|
|
14
|
+
return logErrorAndExit(`defaultLocale: ${settings.defaultLocale} is not a valid locale!`);
|
|
15
15
|
}
|
|
16
16
|
// defaultLocale cannot be a superset of any other locale
|
|
17
17
|
if (settings.defaultLocale &&
|
|
18
18
|
settings.locales.some((locale) => isSupersetLocale(settings.defaultLocale, locale) &&
|
|
19
19
|
!isSupersetLocale(locale, settings.defaultLocale))) {
|
|
20
20
|
const locale = settings.locales.find((locale) => isSupersetLocale(settings.defaultLocale, locale));
|
|
21
|
-
logErrorAndExit(`defaultLocale: ${settings.defaultLocale} is a superset of another locale (${locale})! Please change the defaultLocale to a more specific locale.`);
|
|
21
|
+
return logErrorAndExit(`defaultLocale: ${settings.defaultLocale} is a superset of another locale (${locale})! Please change the defaultLocale to a more specific locale.`);
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
export function validateConfigExists() {
|
|
@@ -28,5 +28,5 @@ export function validateConfigExists() {
|
|
|
28
28
|
return possibleConfigPath;
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
logErrorAndExit('No gt.config.json file found. Are you in the correct directory?');
|
|
31
|
+
return logErrorAndExit('No gt.config.json file found. Are you in the correct directory?');
|
|
32
32
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { SpinnerResult, ProgressResult } from '@clack/prompts';
|
|
2
|
+
export type LogFormat = 'default' | 'json';
|
|
3
|
+
declare class Logger {
|
|
4
|
+
private static instance;
|
|
5
|
+
private pinoLogger;
|
|
6
|
+
private fileLogger;
|
|
7
|
+
private logFormat;
|
|
8
|
+
private constructor();
|
|
9
|
+
static getInstance(): Logger;
|
|
10
|
+
trace(message: string): void;
|
|
11
|
+
debug(message: string): void;
|
|
12
|
+
info(message: string): void;
|
|
13
|
+
warn(message: string): void;
|
|
14
|
+
error(message: string): void;
|
|
15
|
+
fatal(message: string): void;
|
|
16
|
+
silent(message: string): void;
|
|
17
|
+
success(message: string): void;
|
|
18
|
+
step(message: string): void;
|
|
19
|
+
message(message: string, symbol?: string): void;
|
|
20
|
+
createSpinner(indicator?: 'dots' | 'timer'): SpinnerResult;
|
|
21
|
+
createProgressBar(total: number): ProgressResult;
|
|
22
|
+
startCommand(message: string): void;
|
|
23
|
+
endCommand(message: string): void;
|
|
24
|
+
flush(): void;
|
|
25
|
+
}
|
|
26
|
+
export declare const logger: Logger;
|
|
27
|
+
export {};
|