gtx-cli 2.5.6 → 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 +12 -0
- package/dist/api/downloadFileBatch.js +6 -6
- 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.d.ts +1 -1
- package/dist/formats/json/mergeJson.js +69 -21
- 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/types/index.d.ts +1 -0
- 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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import { spawn } from 'node:child_process';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
|
-
import {
|
|
4
|
+
import { logger } from '../console/logger.js';
|
|
5
5
|
export async function detectFormatter() {
|
|
6
6
|
// Try Prettier
|
|
7
7
|
try {
|
|
@@ -43,11 +43,11 @@ export async function formatFiles(filesUpdated, formatter) {
|
|
|
43
43
|
try {
|
|
44
44
|
const detectedFormatter = formatter || (await detectFormatter());
|
|
45
45
|
if (!detectedFormatter) {
|
|
46
|
-
|
|
46
|
+
logger.warn(chalk.yellow('No supported formatter detected'));
|
|
47
47
|
return;
|
|
48
48
|
}
|
|
49
49
|
if (detectedFormatter === 'prettier') {
|
|
50
|
-
|
|
50
|
+
logger.message(chalk.dim('Cleaning up with prettier...'));
|
|
51
51
|
const prettier = await import('prettier');
|
|
52
52
|
for (const file of filesUpdated) {
|
|
53
53
|
const config = await prettier.resolveConfig(file);
|
|
@@ -61,7 +61,7 @@ export async function formatFiles(filesUpdated, formatter) {
|
|
|
61
61
|
return;
|
|
62
62
|
}
|
|
63
63
|
if (detectedFormatter === 'biome') {
|
|
64
|
-
|
|
64
|
+
logger.message(chalk.dim('Cleaning up with biome...'));
|
|
65
65
|
try {
|
|
66
66
|
await new Promise((resolve, reject) => {
|
|
67
67
|
const args = [
|
|
@@ -74,24 +74,24 @@ export async function formatFiles(filesUpdated, formatter) {
|
|
|
74
74
|
stdio: ['ignore', 'inherit', 'inherit'],
|
|
75
75
|
});
|
|
76
76
|
child.on('error', (error) => {
|
|
77
|
-
|
|
77
|
+
logger.warn(chalk.yellow('Biome formatting failed: ' + error.message));
|
|
78
78
|
resolve();
|
|
79
79
|
});
|
|
80
80
|
child.on('close', (code) => {
|
|
81
81
|
if (code !== 0) {
|
|
82
|
-
|
|
82
|
+
logger.warn(chalk.yellow(`Biome formatting failed with exit code ${code}`));
|
|
83
83
|
}
|
|
84
84
|
resolve();
|
|
85
85
|
});
|
|
86
86
|
});
|
|
87
87
|
}
|
|
88
88
|
catch (error) {
|
|
89
|
-
|
|
89
|
+
logger.warn(chalk.yellow('Biome formatting failed: ' + String(error)));
|
|
90
90
|
}
|
|
91
91
|
return;
|
|
92
92
|
}
|
|
93
93
|
if (detectedFormatter === 'eslint') {
|
|
94
|
-
|
|
94
|
+
logger.message(chalk.dim('Cleaning up with eslint...'));
|
|
95
95
|
const { ESLint } = await import('eslint');
|
|
96
96
|
const eslint = new ESLint({
|
|
97
97
|
fix: true,
|
|
@@ -105,6 +105,6 @@ export async function formatFiles(filesUpdated, formatter) {
|
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
catch (e) {
|
|
108
|
-
|
|
108
|
+
logger.warn(chalk.yellow('Unable to run code formatter: ' + String(e)));
|
|
109
109
|
}
|
|
110
110
|
}
|
|
@@ -6,7 +6,7 @@ import traverseModule from '@babel/traverse';
|
|
|
6
6
|
const traverse = traverseModule.default || traverseModule;
|
|
7
7
|
const generate = generateModule.default || generateModule;
|
|
8
8
|
import * as t from '@babel/types';
|
|
9
|
-
import {
|
|
9
|
+
import { logger } from '../../console/logger.js';
|
|
10
10
|
import { needsCJS } from '../../utils/parse/needsCJS.js';
|
|
11
11
|
export async function handleInitGT(filepath, errors, warnings, filesUpdated, packageJson, tsconfigJson) {
|
|
12
12
|
const code = await fs.promises.readFile(filepath, 'utf8');
|
|
@@ -151,7 +151,7 @@ export async function handleInitGT(filepath, errors, warnings, filesUpdated, pac
|
|
|
151
151
|
filesUpdated.push(filepath);
|
|
152
152
|
}
|
|
153
153
|
catch (error) {
|
|
154
|
-
|
|
154
|
+
logger.error(`Error parsing file ${filepath}: ${error}`);
|
|
155
155
|
errors.push(`Failed to parse ${filepath}: ${error}`);
|
|
156
156
|
}
|
|
157
157
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import findFilepath from '../../../fs/findFilepath.js';
|
|
2
|
-
import {
|
|
2
|
+
import { logger } from '../../../console/logger.js';
|
|
3
3
|
import { installCompiler } from './installCompiler.js';
|
|
4
4
|
import { updateViteConfig } from './updateViteConfig.js';
|
|
5
|
+
import { exitSync } from '../../../console/logging.js';
|
|
5
6
|
const VITE_CONFIG_PATH_BASE = './vite.config.';
|
|
6
7
|
/**
|
|
7
8
|
* Adds the gt compiler plugin to the vite config file
|
|
@@ -17,13 +18,13 @@ export async function addVitePlugin({ errors, warnings, filesUpdated, packageJso
|
|
|
17
18
|
VITE_CONFIG_PATH_BASE + 'cts',
|
|
18
19
|
]);
|
|
19
20
|
if (!viteConfigPath) {
|
|
20
|
-
|
|
21
|
+
logger.error(`No ${VITE_CONFIG_PATH_BASE}[js|ts|mjs|mts|cjs|cts] file found. Please add the @generaltranslation/compiler plugin to your vite configuration file:
|
|
21
22
|
import { vite as gtCompiler } from '@generaltranslation/compiler';
|
|
22
23
|
export default defineConfig({
|
|
23
24
|
plugins: [gtCompiler()],
|
|
24
25
|
});
|
|
25
26
|
`);
|
|
26
|
-
|
|
27
|
+
exitSync(1);
|
|
27
28
|
}
|
|
28
29
|
// Install @generaltranslation/compiler if not installed
|
|
29
30
|
await installCompiler({ packageJson });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { logger } from '../../../console/logger.js';
|
|
2
2
|
import { installPackage } from '../../../utils/installPackage.js';
|
|
3
3
|
import { isPackageInstalled } from '../../../utils/packageJson.js';
|
|
4
4
|
import { getPackageManager } from '../../../utils/packageManager.js';
|
|
@@ -12,7 +12,7 @@ export async function installCompiler({ packageJson, }) {
|
|
|
12
12
|
return;
|
|
13
13
|
}
|
|
14
14
|
// Animation
|
|
15
|
-
const spinner = createSpinner();
|
|
15
|
+
const spinner = logger.createSpinner();
|
|
16
16
|
spinner.start(`Installing @generaltranslation/compiler...`);
|
|
17
17
|
// Install
|
|
18
18
|
const packageManager = await getPackageManager();
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { logError } from '../../../console/logging.js';
|
|
1
|
+
import { logger } from '../../../console/logger.js';
|
|
3
2
|
import fs from 'node:fs';
|
|
4
3
|
import chalk from 'chalk';
|
|
5
4
|
import generateModule from '@babel/generator';
|
|
@@ -9,6 +8,7 @@ import { addCompilerImport } from './utils/addCompilerImport.js';
|
|
|
9
8
|
import { checkCompilerImport } from './utils/checkCompilerImport.js';
|
|
10
9
|
import { checkPluginInvocation } from './utils/checkPluginInvocation.js';
|
|
11
10
|
import { addPluginInvocation } from './utils/addPluginInvocation.js';
|
|
11
|
+
import { exitSync } from '../../../console/logging.js';
|
|
12
12
|
// Handle CommonJS/ESM interop
|
|
13
13
|
const generate = generateModule.default || generateModule;
|
|
14
14
|
/**
|
|
@@ -18,7 +18,7 @@ const generate = generateModule.default || generateModule;
|
|
|
18
18
|
*/
|
|
19
19
|
export async function updateViteConfig({ errors, warnings, filesUpdated, viteConfigPath, packageJson, tsconfigJson, }) {
|
|
20
20
|
// Animation
|
|
21
|
-
const spinner = createSpinner();
|
|
21
|
+
const spinner = logger.createSpinner();
|
|
22
22
|
spinner.start(`Adding gt compiler plugin to ${viteConfigPath}...`);
|
|
23
23
|
// Read the file
|
|
24
24
|
let code;
|
|
@@ -26,9 +26,8 @@ export async function updateViteConfig({ errors, warnings, filesUpdated, viteCon
|
|
|
26
26
|
code = await fs.promises.readFile(viteConfigPath, 'utf8');
|
|
27
27
|
}
|
|
28
28
|
catch (error) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return;
|
|
29
|
+
logger.error(`Error: Failed to read ${viteConfigPath}: ${error}`);
|
|
30
|
+
exitSync(1);
|
|
32
31
|
}
|
|
33
32
|
// Update the ast
|
|
34
33
|
let updatedCode, success;
|
|
@@ -43,9 +42,8 @@ export async function updateViteConfig({ errors, warnings, filesUpdated, viteCon
|
|
|
43
42
|
}));
|
|
44
43
|
}
|
|
45
44
|
catch (error) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return;
|
|
45
|
+
logger.error(`Error: Failed to update ${viteConfigPath}: ${error}`);
|
|
46
|
+
exitSync(1);
|
|
49
47
|
}
|
|
50
48
|
// Write the file
|
|
51
49
|
try {
|
|
@@ -53,9 +51,8 @@ export async function updateViteConfig({ errors, warnings, filesUpdated, viteCon
|
|
|
53
51
|
filesUpdated.push(viteConfigPath);
|
|
54
52
|
}
|
|
55
53
|
catch (error) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return;
|
|
54
|
+
logger.error(`Error: Failed to write ${viteConfigPath}: ${error}`);
|
|
55
|
+
exitSync(1);
|
|
59
56
|
}
|
|
60
57
|
// Animation
|
|
61
58
|
spinner.stop(success
|
|
@@ -6,10 +6,11 @@ import flattenDictionary from '../utils/flattenDictionary.js';
|
|
|
6
6
|
import loadJSON from '../../fs/loadJSON.js';
|
|
7
7
|
import { hashSource } from 'generaltranslation/id';
|
|
8
8
|
import getEntryAndMetadata from '../utils/getEntryAndMetadata.js';
|
|
9
|
-
import {
|
|
9
|
+
import { logger } from '../../console/logger.js';
|
|
10
10
|
import { randomUUID } from 'node:crypto';
|
|
11
11
|
import { isValidIcu } from '../jsx/evaluateJsx.js';
|
|
12
12
|
import { warnInvalidIcuSync } from '../../console/index.js';
|
|
13
|
+
import { exitSync } from '../../console/logging.js';
|
|
13
14
|
export async function createDictionaryUpdates(dictionaryPath, warnings, esbuildConfig) {
|
|
14
15
|
let dictionary;
|
|
15
16
|
// ---- HANDLE JSON STRING DICTIONARY ----- //
|
|
@@ -32,8 +33,8 @@ export async function createDictionaryUpdates(dictionaryPath, warnings, esbuildC
|
|
|
32
33
|
dictionaryModule = await import(tempFilePath);
|
|
33
34
|
}
|
|
34
35
|
catch (error) {
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
logger.error(`Failed to load the bundled dictionary code: ${error}`);
|
|
37
|
+
exitSync(1);
|
|
37
38
|
}
|
|
38
39
|
finally {
|
|
39
40
|
// Clean up the temporary file
|
|
@@ -3,7 +3,7 @@ import { parse } from '@babel/parser';
|
|
|
3
3
|
import { hashSource } from 'generaltranslation/id';
|
|
4
4
|
import { parseTranslationComponent } from '../jsx/utils/jsxParsing/parseJsx.js';
|
|
5
5
|
import { parseStrings } from '../jsx/utils/parseStringFunction.js';
|
|
6
|
-
import {
|
|
6
|
+
import { logger } from '../../console/logger.js';
|
|
7
7
|
import { matchFiles } from '../../fs/matchFiles.js';
|
|
8
8
|
import { DEFAULT_SRC_PATTERNS } from '../../config/generateSettings.js';
|
|
9
9
|
import { getPathsAndAliases } from '../jsx/utils/getPathsAndAliases.js';
|
|
@@ -23,7 +23,7 @@ export async function createInlineUpdates(pkg, validate, filePatterns, parsingOp
|
|
|
23
23
|
});
|
|
24
24
|
}
|
|
25
25
|
catch (error) {
|
|
26
|
-
|
|
26
|
+
logger.error(`Error parsing file ${file}: ${error}`);
|
|
27
27
|
continue;
|
|
28
28
|
}
|
|
29
29
|
// First pass: collect imports and process translation functions
|
package/dist/setup/wizard.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { detectFormatter } from '../hooks/postProcess.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { promptSelect } from '../console/logging.js';
|
|
3
|
+
import { logger } from '../console/logger.js';
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import { promptConfirm } from '../console/logging.js';
|
|
6
6
|
import findFilepath from '../fs/findFilepath.js';
|
|
@@ -13,6 +13,7 @@ import { installPackage } from '../utils/installPackage.js';
|
|
|
13
13
|
import { createOrUpdateConfig } from '../fs/config/setupConfig.js';
|
|
14
14
|
import { loadConfig } from '../fs/config/loadConfig.js';
|
|
15
15
|
import { addVitePlugin } from '../react/parse/addVitePlugin/index.js';
|
|
16
|
+
import { exitSync } from '../console/logging.js';
|
|
16
17
|
export async function handleSetupReactCommand(options) {
|
|
17
18
|
// Ask user for confirmation using inquirer
|
|
18
19
|
const answer = await promptConfirm({
|
|
@@ -24,8 +25,8 @@ Make sure you have committed or stashed any changes. Do you want to continue?`),
|
|
|
24
25
|
cancelMessage: 'Operation cancelled. You can re-run this wizard with: npx gtx-cli setup',
|
|
25
26
|
});
|
|
26
27
|
if (!answer) {
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
logger.info('Operation cancelled. You can re-run this wizard with: npx gtx-cli setup');
|
|
29
|
+
exitSync(0);
|
|
29
30
|
}
|
|
30
31
|
const frameworkType = await promptSelect({
|
|
31
32
|
message: 'What framework are you using?',
|
|
@@ -41,9 +42,9 @@ Make sure you have committed or stashed any changes. Do you want to continue?`),
|
|
|
41
42
|
defaultValue: 'next-app',
|
|
42
43
|
});
|
|
43
44
|
if (frameworkType === 'other') {
|
|
44
|
-
|
|
45
|
+
logger.error(`Sorry, other React frameworks are not currently supported.
|
|
45
46
|
Please let us know what you would like to see supported at https://github.com/generaltranslation/gt/issues`);
|
|
46
|
-
|
|
47
|
+
exitSync(0);
|
|
47
48
|
}
|
|
48
49
|
// ----- Create a starter gt.config.json file -----
|
|
49
50
|
await createOrUpdateConfig(options.config || 'gt.config.json', {
|
|
@@ -51,14 +52,14 @@ Please let us know what you would like to see supported at https://github.com/ge
|
|
|
51
52
|
});
|
|
52
53
|
const packageJson = await getPackageJson();
|
|
53
54
|
if (!packageJson) {
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
logger.error(chalk.red('No package.json found in the current directory. Please run this command from the root of your project.'));
|
|
56
|
+
exitSync(1);
|
|
56
57
|
}
|
|
57
58
|
// Check if gt-next or gt-react is installed
|
|
58
59
|
if (frameworkType === 'next-app' &&
|
|
59
60
|
!isPackageInstalled('gt-next', packageJson)) {
|
|
60
61
|
const packageManager = await getPackageManager();
|
|
61
|
-
const spinner = createSpinner('timer');
|
|
62
|
+
const spinner = logger.createSpinner('timer');
|
|
62
63
|
spinner.start(`Installing gt-next with ${packageManager.name}...`);
|
|
63
64
|
await installPackage('gt-next', packageManager);
|
|
64
65
|
spinner.stop(chalk.green('Automatically installed gt-next.'));
|
|
@@ -66,7 +67,7 @@ Please let us know what you would like to see supported at https://github.com/ge
|
|
|
66
67
|
else if (['next-pages', 'react', 'redwood', 'vite', 'gatsby'].includes(frameworkType) &&
|
|
67
68
|
!isPackageInstalled('gt-react', packageJson)) {
|
|
68
69
|
const packageManager = await getPackageManager();
|
|
69
|
-
const spinner = createSpinner('timer');
|
|
70
|
+
const spinner = logger.createSpinner('timer');
|
|
70
71
|
spinner.start(`Installing gt-react with ${packageManager.name}...`);
|
|
71
72
|
await installPackage('gt-react', packageManager);
|
|
72
73
|
spinner.stop(chalk.green('Automatically installed gt-react.'));
|
|
@@ -86,8 +87,8 @@ Please let us know what you would like to see supported at https://github.com/ge
|
|
|
86
87
|
'./next.config.mts',
|
|
87
88
|
]);
|
|
88
89
|
if (!nextConfigPath) {
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
logger.error('No next.config.[js|ts|mjs|mts] file found.');
|
|
91
|
+
exitSync(1);
|
|
91
92
|
}
|
|
92
93
|
const mergeOptions = {
|
|
93
94
|
...options,
|
|
@@ -96,7 +97,7 @@ Please let us know what you would like to see supported at https://github.com/ge
|
|
|
96
97
|
skipTs: true,
|
|
97
98
|
addGTProvider: true,
|
|
98
99
|
};
|
|
99
|
-
const spinner = createSpinner();
|
|
100
|
+
const spinner = logger.createSpinner();
|
|
100
101
|
spinner.start('Wrapping JSX content with <T> tags...');
|
|
101
102
|
// Wrap all JSX elements in the src directory with a <T> tag, with unique ids
|
|
102
103
|
const { filesUpdated: filesUpdatedNext } = await wrapContentNext(mergeOptions, 'gt-next', errors, warnings);
|
|
@@ -104,7 +105,7 @@ Please let us know what you would like to see supported at https://github.com/ge
|
|
|
104
105
|
spinner.stop(chalk.green(`Success! Updated ${chalk.bold.cyan(filesUpdated.length)} files:\n`) + filesUpdated.map((file) => `${chalk.green('-')} ${file}`).join('\n'));
|
|
105
106
|
// Add the withGTConfig() function to the next.config.js file
|
|
106
107
|
await handleInitGT(nextConfigPath, errors, warnings, filesUpdated, packageJson, tsconfigJson);
|
|
107
|
-
|
|
108
|
+
logger.step(chalk.green(`Added withGTConfig() to your ${nextConfigPath} file.`));
|
|
108
109
|
}
|
|
109
110
|
// Add gt compiler plugin
|
|
110
111
|
if (frameworkType === 'vite') {
|
|
@@ -117,10 +118,10 @@ Please let us know what you would like to see supported at https://github.com/ge
|
|
|
117
118
|
});
|
|
118
119
|
}
|
|
119
120
|
if (errors.length > 0) {
|
|
120
|
-
|
|
121
|
+
logger.error(chalk.red('Failed to write files:\n') + errors.join('\n'));
|
|
121
122
|
}
|
|
122
123
|
if (warnings.length > 0) {
|
|
123
|
-
|
|
124
|
+
logger.warn(chalk.yellow('Warnings encountered:') +
|
|
124
125
|
'\n' +
|
|
125
126
|
warnings.map((warning) => `${chalk.yellow('-')} ${warning}`).join('\n'));
|
|
126
127
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
|
-
import {
|
|
2
|
+
import { logger } from '../console/logger.js';
|
|
3
3
|
import loadJSON from '../fs/loadJSON.js';
|
|
4
4
|
import { createDictionaryUpdates } from '../react/parse/createDictionaryUpdates.js';
|
|
5
5
|
import { createInlineUpdates } from '../react/parse/createInlineUpdates.js';
|
|
6
6
|
import createESBuildConfig from '../react/config/createESBuildConfig.js';
|
|
7
7
|
import chalk from 'chalk';
|
|
8
|
+
import { exitSync } from '../console/logging.js';
|
|
8
9
|
/**
|
|
9
10
|
* Searches for gt-react or gt-next dictionary files and creates updates for them,
|
|
10
11
|
* as well as inline updates for <T> tags and useGT()/getGT() calls
|
|
@@ -33,8 +34,8 @@ export async function createUpdates(options, src, sourceDictionary, pkg, validat
|
|
|
33
34
|
if (options.jsconfig) {
|
|
34
35
|
const jsconfig = loadJSON(options.jsconfig);
|
|
35
36
|
if (!jsconfig) {
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
logger.error(`Failed to resolve jsconfig.json or tsconfig.json at provided filepath: "${options.jsconfig}"`);
|
|
38
|
+
exitSync(1);
|
|
38
39
|
}
|
|
39
40
|
esbuildConfig = createESBuildConfig(jsconfig);
|
|
40
41
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { logErrorAndExit } from '../console/logging.js';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import findFilepath from '../fs/findFilepath.js';
|
|
4
|
-
import {
|
|
4
|
+
import { logger } from '../console/logger.js';
|
|
5
5
|
import { createUpdates } from './parse.js';
|
|
6
6
|
export async function aggregateReactTranslations(options, settings, library) {
|
|
7
7
|
if (!options.dictionary) {
|
|
@@ -17,14 +17,14 @@ export async function aggregateReactTranslations(options, settings, library) {
|
|
|
17
17
|
// ---- CREATING UPDATES ---- //
|
|
18
18
|
const { updates, errors, warnings } = await createUpdates(options, settings.src, options.dictionary, library, false, settings.parsingOptions);
|
|
19
19
|
if (warnings.length > 0) {
|
|
20
|
-
|
|
20
|
+
logger.warn(chalk.yellow(`CLI tool encountered ${warnings.length} warnings while scanning for translatable content.\n` +
|
|
21
21
|
warnings
|
|
22
22
|
.map((warning) => chalk.yellow('• Warning: ') + chalk.white(warning))
|
|
23
23
|
.join('\n')));
|
|
24
24
|
}
|
|
25
25
|
if (errors.length > 0) {
|
|
26
26
|
if (options.ignoreErrors) {
|
|
27
|
-
|
|
27
|
+
logger.warn(chalk.yellow(`Warning: CLI tool encountered ${errors.length} syntax errors while scanning for translatable content. These components will not be translated.\n` +
|
|
28
28
|
errors
|
|
29
29
|
.map((error) => chalk.yellow('• ') + chalk.white(error) + '\n')
|
|
30
30
|
.join('')));
|
|
@@ -37,7 +37,7 @@ export async function aggregateReactTranslations(options, settings, library) {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
if (updates.length == 0) {
|
|
40
|
-
|
|
40
|
+
logger.error(chalk.red(`No in-line content or dictionaries were found for ${chalk.green(library)}. Are you sure you're running this command in the right directory?`));
|
|
41
41
|
return updates;
|
|
42
42
|
}
|
|
43
43
|
return updates;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { logErrorAndExit
|
|
1
|
+
import { logErrorAndExit } from '../console/logging.js';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import findFilepath from '../fs/findFilepath.js';
|
|
4
|
-
import {
|
|
4
|
+
import { logger } from '../console/logger.js';
|
|
5
5
|
import { createUpdates } from './parse.js';
|
|
6
6
|
import { createInlineUpdates } from '../react/parse/createInlineUpdates.js';
|
|
7
7
|
export async function validateProject(settings, pkg, files) {
|
|
@@ -14,7 +14,7 @@ export async function validateProject(settings, pkg, files) {
|
|
|
14
14
|
.map((error) => chalk.red('• ') + chalk.white(error) + '\n')
|
|
15
15
|
.join('')));
|
|
16
16
|
}
|
|
17
|
-
|
|
17
|
+
logger.success(chalk.green(`Success! Found ${updates.length} translatable entries.`));
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
20
20
|
if (!settings.dictionary) {
|
|
@@ -29,7 +29,7 @@ export async function validateProject(settings, pkg, files) {
|
|
|
29
29
|
}
|
|
30
30
|
const { updates, errors, warnings } = await createUpdates(settings, settings.src, settings.dictionary, pkg, true, settings.parsingOptions);
|
|
31
31
|
if (warnings.length > 0) {
|
|
32
|
-
|
|
32
|
+
logger.warn(chalk.yellow(`CLI tool encountered ${warnings.length} warnings while scanning for translatable content.`) +
|
|
33
33
|
'\n' +
|
|
34
34
|
warnings
|
|
35
35
|
.map((warning) => chalk.yellow('• ') + chalk.white(warning))
|
|
@@ -42,9 +42,9 @@ export async function validateProject(settings, pkg, files) {
|
|
|
42
42
|
.join('')));
|
|
43
43
|
}
|
|
44
44
|
if (updates.length === 0) {
|
|
45
|
-
|
|
45
|
+
logger.error(chalk.red(`No in-line content or dictionaries were found for ${chalk.green(pkg)}. Are you sure you're running this command in the right directory?`));
|
|
46
46
|
}
|
|
47
47
|
else {
|
|
48
|
-
|
|
48
|
+
logger.success(chalk.green(`Success! Found ${updates.length} translatable entries for ${chalk.green(pkg)}.`));
|
|
49
49
|
}
|
|
50
50
|
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import remarkMdx from 'remark-mdx';
|
|
|
4
4
|
import remarkFrontmatter from 'remark-frontmatter';
|
|
5
5
|
import remarkStringify from 'remark-stringify';
|
|
6
6
|
import { visit } from 'unist-util-visit';
|
|
7
|
-
import {
|
|
7
|
+
import { logger } from '../console/logger.js';
|
|
8
8
|
import escapeHtmlInTextNodes from 'gt-remark';
|
|
9
9
|
/**
|
|
10
10
|
* Generates a slug from heading text
|
|
@@ -90,7 +90,7 @@ export function addExplicitAnchorIds(translatedContent, sourceHeadingMap, settin
|
|
|
90
90
|
const translatedFile = translatedPath
|
|
91
91
|
? `translated file: ${translatedPath}`
|
|
92
92
|
: 'translated file';
|
|
93
|
-
|
|
93
|
+
logger.warn(`Header count mismatch detected! ${sourceFile} has ${sourceHeadingMap.length} headers but ${translatedFile} has ${translatedHeadings.length} headers. ` +
|
|
94
94
|
`This likely means your source file was edited after translation was requested, causing a mismatch between ` +
|
|
95
95
|
`the number of headers in your source file vs the translated file. Please re-translate this file to resolve the issue.`);
|
|
96
96
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { logErrorAndExit } from '../console/logging.js';
|
|
2
|
+
import { logger } from '../console/logger.js';
|
|
2
3
|
import path from 'node:path';
|
|
3
4
|
import fs from 'node:fs';
|
|
4
5
|
import chalk from 'chalk';
|
|
@@ -10,8 +11,8 @@ export async function retrieveCredentials(settings, keyType) {
|
|
|
10
11
|
await import('open').then((open) => open.default(urlToOpen, {
|
|
11
12
|
wait: false,
|
|
12
13
|
}));
|
|
13
|
-
|
|
14
|
-
const spinner = createSpinner('dots');
|
|
14
|
+
logger.message(`${chalk.dim(`If the browser window didn't open automatically, please open the following link:`)}\n\n${chalk.cyan(urlToOpen)}`);
|
|
15
|
+
const spinner = logger.createSpinner('dots');
|
|
15
16
|
spinner.start('Waiting for response from dashboard...');
|
|
16
17
|
const credentials = await new Promise(async (resolve, reject) => {
|
|
17
18
|
const interval = setInterval(async () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { spawn } from 'child_process';
|
|
3
|
-
import {
|
|
3
|
+
import { logger } from '../console/logger.js';
|
|
4
4
|
export async function installPackage(packageName, packageManager, asDevDependency, cwd = process.cwd()) {
|
|
5
5
|
return new Promise((resolve, reject) => {
|
|
6
6
|
const command = packageManager.name;
|
|
@@ -19,8 +19,8 @@ export async function installPackage(packageName, packageManager, asDevDependenc
|
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
21
|
childProcess.on('error', (error) => {
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
logger.error(chalk.red(`Installation error: ${error.message}`));
|
|
23
|
+
logger.info(`Please manually install ${packageName} with: ${packageManager.name} ${packageManager.installCommand} ${packageName}`);
|
|
24
24
|
reject(error);
|
|
25
25
|
});
|
|
26
26
|
childProcess.on('close', (code) => {
|
|
@@ -28,11 +28,11 @@ export async function installPackage(packageName, packageManager, asDevDependenc
|
|
|
28
28
|
resolve();
|
|
29
29
|
}
|
|
30
30
|
else {
|
|
31
|
-
|
|
31
|
+
logger.error(chalk.red(`Installation failed with exit code ${code}`));
|
|
32
32
|
if (errorOutput) {
|
|
33
|
-
|
|
33
|
+
logger.error(chalk.red(`Error details: ${errorOutput}`));
|
|
34
34
|
}
|
|
35
|
-
|
|
35
|
+
logger.info(`Please manually install ${packageName} with: ${packageManager.name} ${packageManager.installCommand} ${packageName}`);
|
|
36
36
|
reject(new Error(`Process exited with code ${code}`));
|
|
37
37
|
}
|
|
38
38
|
});
|
|
@@ -56,8 +56,8 @@ export async function installPackageGlobal(packageName, version) {
|
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
58
|
childProcess.on('error', (error) => {
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
logger.error(chalk.red(`Installation error: ${error.message}`));
|
|
60
|
+
logger.info(`Please manually install ${packageName} with: npm install -g ${packageName}`);
|
|
61
61
|
reject(error);
|
|
62
62
|
});
|
|
63
63
|
childProcess.on('close', (code) => {
|
|
@@ -65,11 +65,11 @@ export async function installPackageGlobal(packageName, version) {
|
|
|
65
65
|
resolve();
|
|
66
66
|
}
|
|
67
67
|
else {
|
|
68
|
-
|
|
68
|
+
logger.error(chalk.red(`Installation failed with exit code ${code}`));
|
|
69
69
|
if (errorOutput) {
|
|
70
|
-
|
|
70
|
+
logger.error(chalk.red(`Error details: ${errorOutput}`));
|
|
71
71
|
}
|
|
72
|
-
|
|
72
|
+
logger.info(`Please manually install ${packageName} with: npm install -g ${packageName}`);
|
|
73
73
|
reject(new Error(`Process exited with code ${code}`));
|
|
74
74
|
}
|
|
75
75
|
});
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { logger } from '../console/logger.js';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import fs from 'node:fs';
|
|
5
5
|
import { fromPackageRoot } from '../fs/getPackageResource.js';
|
|
6
|
+
import { exitSync } from '../console/logging.js';
|
|
6
7
|
// search for package.json such that we can run init in non-js projects
|
|
7
8
|
export async function searchForPackageJson(cwd = process.cwd()) {
|
|
8
9
|
// Get the current working directory (where the CLI is being run)
|
|
@@ -48,8 +49,8 @@ export async function updatePackageJson(packageJson, cwd = process.cwd()) {
|
|
|
48
49
|
await fs.promises.writeFile(path.join(cwd, 'package.json'), JSON.stringify(packageJson, null, 2));
|
|
49
50
|
}
|
|
50
51
|
catch (error) {
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
logger.error(chalk.red('Error updating package.json: ' + String(error)));
|
|
53
|
+
exitSync(1);
|
|
53
54
|
}
|
|
54
55
|
}
|
|
55
56
|
// check if a package is installed in the package.json file
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { WorkflowStep } from './Workflow.js';
|
|
2
|
-
import {
|
|
2
|
+
import { logErrorAndExit } from '../console/logging.js';
|
|
3
|
+
import { logger } from '../console/logger.js';
|
|
3
4
|
import chalk from 'chalk';
|
|
4
5
|
import { getCurrentBranch, getIncomingBranches, getCheckedOutBranches, } from '../git/branches.js';
|
|
5
6
|
import { ApiError } from 'generaltranslation/errors';
|
|
6
7
|
// Step 1: Resolve the current branch id & update API with branch information
|
|
7
8
|
export class BranchStep extends WorkflowStep {
|
|
8
|
-
spinner = createSpinner('dots');
|
|
9
|
+
spinner = logger.createSpinner('dots');
|
|
9
10
|
branchData;
|
|
10
11
|
settings;
|
|
11
12
|
gt;
|
|
@@ -70,7 +71,7 @@ export class BranchStep extends WorkflowStep {
|
|
|
70
71
|
}
|
|
71
72
|
else {
|
|
72
73
|
if (!current) {
|
|
73
|
-
logErrorAndExit('Failed to determine the current branch. Please specify a custom branch or enable automatic branch detection.');
|
|
74
|
+
return logErrorAndExit('Failed to determine the current branch. Please specify a custom branch or enable automatic branch detection.');
|
|
74
75
|
}
|
|
75
76
|
const currentBranch = branchData.branches.find((b) => b.name === current.currentBranchName);
|
|
76
77
|
if (!currentBranch) {
|
|
@@ -83,7 +84,7 @@ export class BranchStep extends WorkflowStep {
|
|
|
83
84
|
}
|
|
84
85
|
catch (error) {
|
|
85
86
|
if (error instanceof ApiError && error.code === 403) {
|
|
86
|
-
|
|
87
|
+
logger.error('Failed to create branch. To enable branching, please upgrade your plan.');
|
|
87
88
|
// retry with default branch
|
|
88
89
|
const createBranchResult = await this.gt.createBranch({
|
|
89
90
|
branchName: 'main', // name doesn't matter for default branch
|