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
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import { pino, transport } from 'pino';
|
|
4
|
+
import { log as clackLog, spinner, progress, intro, outro, } from '@clack/prompts';
|
|
5
|
+
// Mock spinner that logs to console instead of updating terminal UI
|
|
6
|
+
class MockSpinner {
|
|
7
|
+
currentMessage = '';
|
|
8
|
+
logger;
|
|
9
|
+
isCancelled = false;
|
|
10
|
+
constructor(logger) {
|
|
11
|
+
this.logger = logger;
|
|
12
|
+
}
|
|
13
|
+
start(message) {
|
|
14
|
+
if (message) {
|
|
15
|
+
this.currentMessage = message;
|
|
16
|
+
this.logger.info(`[Spinner] ${message}`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
stop(message) {
|
|
20
|
+
const msg = message || this.currentMessage;
|
|
21
|
+
if (msg) {
|
|
22
|
+
this.logger.info(`[Spinner] ${msg}`);
|
|
23
|
+
}
|
|
24
|
+
this.currentMessage = '';
|
|
25
|
+
}
|
|
26
|
+
message(message) {
|
|
27
|
+
if (message) {
|
|
28
|
+
this.currentMessage = message;
|
|
29
|
+
this.logger.info(`[Spinner] ${message}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Mock progress bar that logs to console instead of updating terminal UI
|
|
34
|
+
class MockProgress {
|
|
35
|
+
max;
|
|
36
|
+
current = 0;
|
|
37
|
+
logger;
|
|
38
|
+
isCancelled = false;
|
|
39
|
+
constructor(max, logger) {
|
|
40
|
+
this.max = max;
|
|
41
|
+
this.logger = logger;
|
|
42
|
+
}
|
|
43
|
+
start(message) {
|
|
44
|
+
const msg = message || 'Starting progress';
|
|
45
|
+
this.logger.info(`[Progress] ${msg} (0/${this.max})`);
|
|
46
|
+
}
|
|
47
|
+
stop(message) {
|
|
48
|
+
const msg = message || 'Complete';
|
|
49
|
+
this.logger.info(`[Progress] ${msg} (${this.current}/${this.max})`);
|
|
50
|
+
}
|
|
51
|
+
message(message) {
|
|
52
|
+
if (message) {
|
|
53
|
+
this.logger.info(`[Progress] ${message} (${this.current}/${this.max})`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
advance(amount, message) {
|
|
57
|
+
this.current += amount;
|
|
58
|
+
const msg = message || 'Progress';
|
|
59
|
+
this.logger.info(`[Progress] ${msg} (${this.current}/${this.max})`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
class Logger {
|
|
63
|
+
static instance;
|
|
64
|
+
pinoLogger = null;
|
|
65
|
+
fileLogger = null;
|
|
66
|
+
logFormat;
|
|
67
|
+
constructor() {
|
|
68
|
+
// Read configuration from environment variables
|
|
69
|
+
const format = (process.env.GT_LOG_FORMAT || 'default').toLowerCase();
|
|
70
|
+
if (format !== 'default' && format !== 'json') {
|
|
71
|
+
console.error('Invalid log format');
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
const logFile = process.env.GT_LOG_FILE;
|
|
75
|
+
const logLevel = process.env.GT_LOG_LEVEL || 'info';
|
|
76
|
+
this.logFormat = format;
|
|
77
|
+
const transports = [];
|
|
78
|
+
// Console output (stdout)
|
|
79
|
+
if (format === 'json') {
|
|
80
|
+
// JSON formatted console output
|
|
81
|
+
transports.push({
|
|
82
|
+
level: logLevel,
|
|
83
|
+
target: 'pino/file',
|
|
84
|
+
options: { destination: 1 }, // stdout
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
// For 'default' format, we don't add a console transport - we'll use @clack/prompts directly
|
|
88
|
+
// Create console logger if we have console transports
|
|
89
|
+
if (transports.length > 0) {
|
|
90
|
+
this.pinoLogger = pino({
|
|
91
|
+
level: logLevel,
|
|
92
|
+
mixin: () => ({
|
|
93
|
+
logId: randomUUID(),
|
|
94
|
+
}),
|
|
95
|
+
}, transport({
|
|
96
|
+
targets: transports,
|
|
97
|
+
}));
|
|
98
|
+
}
|
|
99
|
+
// File output (if specified) - always JSON format
|
|
100
|
+
if (logFile) {
|
|
101
|
+
this.fileLogger = pino({
|
|
102
|
+
level: logLevel,
|
|
103
|
+
mixin: () => ({
|
|
104
|
+
logId: randomUUID(),
|
|
105
|
+
}),
|
|
106
|
+
}, transport({
|
|
107
|
+
targets: [
|
|
108
|
+
{
|
|
109
|
+
level: logLevel,
|
|
110
|
+
target: 'pino/file',
|
|
111
|
+
options: { destination: logFile },
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
static getInstance() {
|
|
118
|
+
if (!Logger.instance) {
|
|
119
|
+
Logger.instance = new Logger();
|
|
120
|
+
}
|
|
121
|
+
return Logger.instance;
|
|
122
|
+
}
|
|
123
|
+
// Standard logging methods
|
|
124
|
+
trace(message) {
|
|
125
|
+
if (this.logFormat === 'default') {
|
|
126
|
+
// @clack/prompts doesn't have trace, use message
|
|
127
|
+
clackLog.message(message, { symbol: chalk.dim('•') });
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
this.pinoLogger?.trace(message);
|
|
131
|
+
}
|
|
132
|
+
this.fileLogger?.trace(message);
|
|
133
|
+
}
|
|
134
|
+
debug(message) {
|
|
135
|
+
if (this.logFormat === 'default') {
|
|
136
|
+
// @clack/prompts doesn't have debug, use message
|
|
137
|
+
clackLog.message(message, { symbol: chalk.dim('◆') });
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
this.pinoLogger?.debug(message);
|
|
141
|
+
}
|
|
142
|
+
this.fileLogger?.debug(message);
|
|
143
|
+
}
|
|
144
|
+
info(message) {
|
|
145
|
+
if (this.logFormat === 'default') {
|
|
146
|
+
clackLog.info(message);
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
this.pinoLogger?.info(message);
|
|
150
|
+
}
|
|
151
|
+
this.fileLogger?.info(message);
|
|
152
|
+
}
|
|
153
|
+
warn(message) {
|
|
154
|
+
if (this.logFormat === 'default') {
|
|
155
|
+
clackLog.warn(message);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
this.pinoLogger?.warn(message);
|
|
159
|
+
}
|
|
160
|
+
this.fileLogger?.warn(message);
|
|
161
|
+
}
|
|
162
|
+
error(message) {
|
|
163
|
+
if (this.logFormat === 'default') {
|
|
164
|
+
clackLog.error(message);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
this.pinoLogger?.error(message);
|
|
168
|
+
}
|
|
169
|
+
this.fileLogger?.error(message);
|
|
170
|
+
}
|
|
171
|
+
fatal(message) {
|
|
172
|
+
if (this.logFormat === 'default') {
|
|
173
|
+
clackLog.error(message); // @clack/prompts doesn't have fatal, use error
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
this.pinoLogger?.fatal(message);
|
|
177
|
+
}
|
|
178
|
+
this.fileLogger?.fatal(message);
|
|
179
|
+
}
|
|
180
|
+
silent(message) {
|
|
181
|
+
// Silent doesn't log to console, only to file
|
|
182
|
+
this.fileLogger?.silent(message);
|
|
183
|
+
}
|
|
184
|
+
// @clack/prompts specific methods (for 'default' format)
|
|
185
|
+
success(message) {
|
|
186
|
+
if (this.logFormat === 'default') {
|
|
187
|
+
clackLog.success(message);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
this.pinoLogger?.info(message); // Map to info for non-default formats
|
|
191
|
+
}
|
|
192
|
+
this.fileLogger?.info(message);
|
|
193
|
+
}
|
|
194
|
+
step(message) {
|
|
195
|
+
if (this.logFormat === 'default') {
|
|
196
|
+
clackLog.step(message);
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
this.pinoLogger?.info(message); // Map to info for non-default formats
|
|
200
|
+
}
|
|
201
|
+
this.fileLogger?.info(message);
|
|
202
|
+
}
|
|
203
|
+
message(message, symbol) {
|
|
204
|
+
if (this.logFormat === 'default') {
|
|
205
|
+
clackLog.message(message, symbol ? { symbol } : undefined);
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
this.pinoLogger?.info(message); // Map to info for non-default formats
|
|
209
|
+
}
|
|
210
|
+
this.fileLogger?.info(message);
|
|
211
|
+
}
|
|
212
|
+
// Spinner functionality
|
|
213
|
+
createSpinner(indicator = 'timer') {
|
|
214
|
+
if (this.logFormat === 'default') {
|
|
215
|
+
return spinner({ indicator });
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
return new MockSpinner(this);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// Progress bar functionality
|
|
222
|
+
createProgressBar(total) {
|
|
223
|
+
if (this.logFormat === 'default') {
|
|
224
|
+
return progress({ max: total });
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
return new MockProgress(total, this);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
// Command start/end markers
|
|
231
|
+
startCommand(message) {
|
|
232
|
+
if (this.logFormat === 'default') {
|
|
233
|
+
intro(chalk.cyan(message));
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
this.info(`╭─ ${message}`);
|
|
237
|
+
}
|
|
238
|
+
this.fileLogger?.info(`[START] ${message}`);
|
|
239
|
+
}
|
|
240
|
+
endCommand(message) {
|
|
241
|
+
if (this.logFormat === 'default') {
|
|
242
|
+
outro(chalk.cyan(message));
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
this.info(`╰─ ${message}`);
|
|
246
|
+
}
|
|
247
|
+
this.fileLogger?.info(`[END] ${message}`);
|
|
248
|
+
}
|
|
249
|
+
// Flush logs to ensure they're written before process exit
|
|
250
|
+
flush() {
|
|
251
|
+
this.pinoLogger?.flush();
|
|
252
|
+
this.fileLogger?.flush();
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
export const logger = Logger.getInstance();
|
|
@@ -1,21 +1,11 @@
|
|
|
1
|
-
export declare function logInfo(message: string): void;
|
|
2
|
-
export declare function logWarning(message: string): void;
|
|
3
|
-
export declare function logError(message: string): void;
|
|
4
|
-
export declare function logSuccess(message: string): void;
|
|
5
|
-
export declare function logStep(message: string): void;
|
|
6
|
-
export declare function logMessage(message: string): void;
|
|
7
1
|
export declare function logErrorAndExit(message: string): never;
|
|
8
|
-
export declare function
|
|
9
|
-
export declare function startCommand(message: string): void;
|
|
10
|
-
export declare function endCommand(message: string): void;
|
|
2
|
+
export declare function exitSync(code: number): never;
|
|
11
3
|
export declare function displayHeader(introString?: string): void;
|
|
12
4
|
export declare function displayProjectId(projectId: string): void;
|
|
13
5
|
export declare function displayResolvedPaths(resolvedPaths: [string, string][]): void;
|
|
14
6
|
export declare function displayCreatedConfigFile(configFilepath: string): void;
|
|
15
7
|
export declare function displayUpdatedConfigFile(configFilepath: string): void;
|
|
16
8
|
export declare function displayUpdatedVersionsFile(versionFilepath: string): void;
|
|
17
|
-
export declare function createSpinner(indicator?: 'dots' | 'timer'): import("@clack/prompts").SpinnerResult;
|
|
18
|
-
export declare function createProgressBar(total: number): import("@clack/prompts").ProgressResult;
|
|
19
9
|
export declare function promptText({ message, defaultValue, validate, }: {
|
|
20
10
|
message: string;
|
|
21
11
|
defaultValue?: string;
|
package/dist/console/logging.js
CHANGED
|
@@ -1,45 +1,22 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { text, select, confirm, isCancel, cancel, multiselect, } from '@clack/prompts';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import { getCLIVersion } from '../utils/packageJson.js';
|
|
4
|
-
|
|
5
|
-
export function logInfo(message) {
|
|
6
|
-
log.info(message);
|
|
7
|
-
}
|
|
8
|
-
export function logWarning(message) {
|
|
9
|
-
log.warn(message);
|
|
10
|
-
}
|
|
11
|
-
export function logError(message) {
|
|
12
|
-
log.error(message);
|
|
13
|
-
}
|
|
14
|
-
export function logSuccess(message) {
|
|
15
|
-
log.success(message);
|
|
16
|
-
}
|
|
17
|
-
export function logStep(message) {
|
|
18
|
-
log.step(message);
|
|
19
|
-
}
|
|
20
|
-
export function logMessage(message) {
|
|
21
|
-
log.message(message, { symbol: chalk.cyan('~') });
|
|
22
|
-
}
|
|
4
|
+
import { logger } from './logger.js';
|
|
23
5
|
export function logErrorAndExit(message) {
|
|
24
|
-
|
|
25
|
-
|
|
6
|
+
logger.error(message);
|
|
7
|
+
return exitSync(1);
|
|
26
8
|
}
|
|
27
|
-
export function
|
|
9
|
+
export function exitSync(code) {
|
|
10
|
+
// Flush logs before exit
|
|
11
|
+
logger.flush();
|
|
28
12
|
process.exit(code);
|
|
29
13
|
}
|
|
30
|
-
// Clack prompts
|
|
31
|
-
export function startCommand(message) {
|
|
32
|
-
intro(chalk.cyan(message));
|
|
33
|
-
}
|
|
34
|
-
export function endCommand(message) {
|
|
35
|
-
outro(chalk.cyan(message));
|
|
36
|
-
}
|
|
37
14
|
// GT specific logging
|
|
38
15
|
export function displayHeader(introString) {
|
|
39
16
|
displayAsciiTitle();
|
|
40
17
|
displayInitializingText();
|
|
41
18
|
if (introString) {
|
|
42
|
-
startCommand(introString);
|
|
19
|
+
logger.startCommand(introString);
|
|
43
20
|
}
|
|
44
21
|
}
|
|
45
22
|
function displayAsciiTitle() {
|
|
@@ -59,30 +36,22 @@ ${chalk.dim('https://generaltranslation.com/docs')}
|
|
|
59
36
|
${chalk.dim(`CLI Version: ${version}\n`)}`);
|
|
60
37
|
}
|
|
61
38
|
export function displayProjectId(projectId) {
|
|
62
|
-
|
|
39
|
+
logger.message(chalk.dim(`Project ID: ${chalk.bold(projectId)}`), chalk.cyan('~'));
|
|
63
40
|
}
|
|
64
41
|
export function displayResolvedPaths(resolvedPaths) {
|
|
65
42
|
const paths = resolvedPaths.map(([key, resolvedPath]) => {
|
|
66
43
|
return chalk.dim(`'${chalk.white(key)}' → '${chalk.green(resolvedPath)}'`);
|
|
67
44
|
});
|
|
68
|
-
|
|
45
|
+
logger.step(`Resolved path aliases:\n${paths.join('\n')}`);
|
|
69
46
|
}
|
|
70
47
|
export function displayCreatedConfigFile(configFilepath) {
|
|
71
|
-
|
|
48
|
+
logger.step(`Created config file ${chalk.cyan(configFilepath)}`);
|
|
72
49
|
}
|
|
73
50
|
export function displayUpdatedConfigFile(configFilepath) {
|
|
74
|
-
|
|
51
|
+
logger.success(`Updated config file ${chalk.cyan(configFilepath)}`);
|
|
75
52
|
}
|
|
76
53
|
export function displayUpdatedVersionsFile(versionFilepath) {
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
// Spinner functionality
|
|
80
|
-
export function createSpinner(indicator = 'timer') {
|
|
81
|
-
return spinner({ indicator });
|
|
82
|
-
}
|
|
83
|
-
// Spinner functionality
|
|
84
|
-
export function createProgressBar(total) {
|
|
85
|
-
return progress({ max: total });
|
|
54
|
+
logger.success(`Updated versions file ${chalk.cyan(versionFilepath)}`);
|
|
86
55
|
}
|
|
87
56
|
// Input prompts
|
|
88
57
|
export async function promptText({ message, defaultValue, validate, }) {
|
|
@@ -98,7 +67,7 @@ export async function promptText({ message, defaultValue, validate, }) {
|
|
|
98
67
|
});
|
|
99
68
|
if (isCancel(result)) {
|
|
100
69
|
cancel('Operation cancelled');
|
|
101
|
-
|
|
70
|
+
return exitSync(0);
|
|
102
71
|
}
|
|
103
72
|
return result;
|
|
104
73
|
}
|
|
@@ -116,7 +85,7 @@ export async function promptSelect({ message, options, defaultValue, }) {
|
|
|
116
85
|
});
|
|
117
86
|
if (isCancel(result)) {
|
|
118
87
|
cancel('Operation cancelled');
|
|
119
|
-
|
|
88
|
+
return exitSync(0);
|
|
120
89
|
}
|
|
121
90
|
return result;
|
|
122
91
|
}
|
|
@@ -134,7 +103,7 @@ export async function promptMultiSelect({ message, options, required = true, })
|
|
|
134
103
|
});
|
|
135
104
|
if (isCancel(result)) {
|
|
136
105
|
cancel('Operation cancelled');
|
|
137
|
-
|
|
106
|
+
return exitSync(0);
|
|
138
107
|
}
|
|
139
108
|
return result;
|
|
140
109
|
}
|
|
@@ -145,25 +114,25 @@ export async function promptConfirm({ message, defaultValue = true, cancelMessag
|
|
|
145
114
|
});
|
|
146
115
|
if (isCancel(result)) {
|
|
147
116
|
cancel(cancelMessage);
|
|
148
|
-
|
|
117
|
+
return exitSync(0);
|
|
149
118
|
}
|
|
150
119
|
return result;
|
|
151
120
|
}
|
|
152
121
|
// Warning display functions
|
|
153
122
|
export function warnApiKeyInConfig(optionsFilepath) {
|
|
154
|
-
|
|
123
|
+
logger.warn(`Found ${chalk.cyan('apiKey')} in "${chalk.green(optionsFilepath)}". ` +
|
|
155
124
|
chalk.white('Your API key is exposed! Please remove it from the file and include it as an environment variable.'));
|
|
156
125
|
}
|
|
157
126
|
export function warnVariableProp(file, attrName, value) {
|
|
158
|
-
|
|
127
|
+
logger.warn(`Found ${chalk.green('<T>')} component in ${chalk.cyan(file)} with variable ${attrName}: "${chalk.white(value)}". ` +
|
|
159
128
|
`Change "${attrName}" to ensure this content is translated.`);
|
|
160
129
|
}
|
|
161
130
|
export function warnNoId(file) {
|
|
162
|
-
|
|
131
|
+
logger.warn(`Found ${chalk.green('<T>')} component in ${chalk.cyan(file)} with no id. ` +
|
|
163
132
|
chalk.white('Add an id to ensure the content is translated.'));
|
|
164
133
|
}
|
|
165
134
|
export function warnHasUnwrappedExpression(file, id, unwrappedExpressions) {
|
|
166
|
-
|
|
135
|
+
logger.warn(`${chalk.green('<T>')} with id "${id}" in ${chalk.cyan(file)} has children: ${unwrappedExpressions.join(', ')} that could change at runtime. ` +
|
|
167
136
|
chalk.white('Use a variable component like ') +
|
|
168
137
|
chalk.green('<Var>') +
|
|
169
138
|
chalk.white(' (') +
|
|
@@ -171,14 +140,14 @@ export function warnHasUnwrappedExpression(file, id, unwrappedExpressions) {
|
|
|
171
140
|
chalk.white(') to translate this properly.'));
|
|
172
141
|
}
|
|
173
142
|
export function warnNonStaticExpression(file, attrName, value) {
|
|
174
|
-
|
|
143
|
+
logger.warn(`Found non-static expression in ${chalk.cyan(file)} for attribute ${attrName}: "${chalk.white(value)}". ` +
|
|
175
144
|
`Change "${attrName}" to ensure this content is translated.`);
|
|
176
145
|
}
|
|
177
146
|
export function warnTemplateLiteral(file, value) {
|
|
178
|
-
|
|
147
|
+
logger.warn(`Found template literal with quasis (${value}) in ${chalk.cyan(file)}. ` +
|
|
179
148
|
chalk.white('Change the template literal to a string to ensure this content is translated.'));
|
|
180
149
|
}
|
|
181
150
|
export function warnTernary(file) {
|
|
182
|
-
|
|
151
|
+
logger.warn(`Found ternary expression in ${chalk.cyan(file)}. ` +
|
|
183
152
|
chalk.white('A Branch component may be more appropriate here.'));
|
|
184
153
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from 'fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import {
|
|
3
|
+
import { logger } from '../../console/logger.js';
|
|
4
4
|
/**
|
|
5
5
|
* Saves translated MDX/MD file content to the appropriate location
|
|
6
6
|
*/
|
|
@@ -12,6 +12,6 @@ export async function saveTranslatedFile(translatedContent, outputDir, fileName,
|
|
|
12
12
|
// Save the translated file with the appropriate extension
|
|
13
13
|
const outputPath = path.join(localeDir, fileName);
|
|
14
14
|
await fs.writeFile(outputPath, translatedContent);
|
|
15
|
-
|
|
15
|
+
logger.success(`Saved translated ${dataFormat} file to: ${outputPath}`);
|
|
16
16
|
}
|
|
17
17
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { logger } from '../../console/logger.js';
|
|
2
2
|
import { getRelative, readFile } from '../../fs/findFilepath.js';
|
|
3
3
|
import { SUPPORTED_FILE_EXTENSIONS } from './supportedFiles.js';
|
|
4
4
|
import sanitizeFileContent from '../../utils/sanitizeFileContent.js';
|
|
@@ -46,7 +46,7 @@ export async function aggregateFiles(settings) {
|
|
|
46
46
|
JSON.parse(content);
|
|
47
47
|
}
|
|
48
48
|
catch (e) {
|
|
49
|
-
|
|
49
|
+
logger.warn(`Skipping ${relativePath}: JSON file is not parsable`);
|
|
50
50
|
return null;
|
|
51
51
|
}
|
|
52
52
|
const parsedJson = parseJson(content, filePath, settings.options || {}, settings.defaultLocale);
|
|
@@ -63,7 +63,7 @@ export async function aggregateFiles(settings) {
|
|
|
63
63
|
if (!file)
|
|
64
64
|
return false;
|
|
65
65
|
if (typeof file.content !== 'string' || !file.content.trim()) {
|
|
66
|
-
|
|
66
|
+
logger.warn(`Skipping ${file.fileName}: JSON file is empty`);
|
|
67
67
|
return false;
|
|
68
68
|
}
|
|
69
69
|
return true;
|
|
@@ -81,7 +81,7 @@ export async function aggregateFiles(settings) {
|
|
|
81
81
|
YAML.parse(content);
|
|
82
82
|
}
|
|
83
83
|
catch (e) {
|
|
84
|
-
|
|
84
|
+
logger.warn(`Skipping ${relativePath}: YAML file is not parsable`);
|
|
85
85
|
return null;
|
|
86
86
|
}
|
|
87
87
|
const { content: parsedYaml, fileFormat } = parseYaml(content, filePath, settings.options || {});
|
|
@@ -95,7 +95,7 @@ export async function aggregateFiles(settings) {
|
|
|
95
95
|
})
|
|
96
96
|
.filter((file) => {
|
|
97
97
|
if (!file || typeof file.content !== 'string' || !file.content.trim()) {
|
|
98
|
-
|
|
98
|
+
logger.warn(`Skipping ${file?.fileName ?? 'unknown'}: YAML file is empty`);
|
|
99
99
|
return false;
|
|
100
100
|
}
|
|
101
101
|
return true;
|
|
@@ -113,7 +113,7 @@ export async function aggregateFiles(settings) {
|
|
|
113
113
|
if (fileType === 'mdx') {
|
|
114
114
|
const validation = isValidMdx(content, filePath);
|
|
115
115
|
if (!validation.isValid) {
|
|
116
|
-
|
|
116
|
+
logger.warn(`Skipping ${relativePath}: MDX file is not AST parsable${validation.error ? `: ${validation.error}` : ''}`);
|
|
117
117
|
return null;
|
|
118
118
|
}
|
|
119
119
|
}
|
|
@@ -130,7 +130,7 @@ export async function aggregateFiles(settings) {
|
|
|
130
130
|
if (!file ||
|
|
131
131
|
typeof file.content !== 'string' ||
|
|
132
132
|
!file.content.trim()) {
|
|
133
|
-
|
|
133
|
+
logger.warn(`Skipping ${file?.fileName ?? 'unknown'}: File is empty after sanitization`);
|
|
134
134
|
return false;
|
|
135
135
|
}
|
|
136
136
|
return true;
|
|
@@ -139,7 +139,7 @@ export async function aggregateFiles(settings) {
|
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
141
|
if (allFiles.length === 0 && !settings.publish) {
|
|
142
|
-
|
|
142
|
+
logger.error('No files to translate were found. Please check your configuration and try again.');
|
|
143
143
|
}
|
|
144
144
|
return allFiles;
|
|
145
145
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { noSupportedFormatError, noDefaultLocaleError, noApiKeyError, noProjectIdError, devApiKeyError, } from '../../console/index.js';
|
|
2
|
-
import { logErrorAndExit
|
|
2
|
+
import { logErrorAndExit } from '../../console/logging.js';
|
|
3
|
+
import { logger } from '../../console/logger.js';
|
|
3
4
|
import { getRelative, readFile } from '../../fs/findFilepath.js';
|
|
4
5
|
import { SUPPORTED_FILE_EXTENSIONS } from './supportedFiles.js';
|
|
5
6
|
import sanitizeFileContent from '../../utils/sanitizeFileContent.js';
|
|
@@ -80,20 +81,20 @@ export async function upload(filePaths, placeholderPaths, transformPaths, dataFo
|
|
|
80
81
|
}
|
|
81
82
|
}
|
|
82
83
|
if (allFiles.length === 0) {
|
|
83
|
-
|
|
84
|
+
logger.error('No files to upload were found. Please check your configuration and try again.');
|
|
84
85
|
return;
|
|
85
86
|
}
|
|
86
87
|
if (!options.defaultLocale) {
|
|
87
|
-
logErrorAndExit(noDefaultLocaleError);
|
|
88
|
+
return logErrorAndExit(noDefaultLocaleError);
|
|
88
89
|
}
|
|
89
90
|
if (!options.apiKey) {
|
|
90
|
-
logErrorAndExit(noApiKeyError);
|
|
91
|
+
return logErrorAndExit(noApiKeyError);
|
|
91
92
|
}
|
|
92
93
|
if (options.apiKey.startsWith('gtx-dev-')) {
|
|
93
|
-
logErrorAndExit(devApiKeyError);
|
|
94
|
+
return logErrorAndExit(devApiKeyError);
|
|
94
95
|
}
|
|
95
96
|
if (!options.projectId) {
|
|
96
|
-
logErrorAndExit(noProjectIdError);
|
|
97
|
+
return logErrorAndExit(noProjectIdError);
|
|
97
98
|
}
|
|
98
99
|
const locales = options.locales || [];
|
|
99
100
|
// Create file mapping for all file types
|
package/dist/formats/gt/save.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import {
|
|
3
|
+
import { logger } from '../../console/logger.js';
|
|
4
|
+
import { exitSync } from '../../console/logging.js';
|
|
4
5
|
import { noFilesError } from '../../console/index.js';
|
|
5
6
|
import { resolveLocaleFiles } from '../../fs/config/parseFilesConfig.js';
|
|
6
7
|
/**
|
|
@@ -14,8 +15,8 @@ export async function saveTranslations(translations, placeholderPaths) {
|
|
|
14
15
|
const locale = translation.locale;
|
|
15
16
|
const translationFiles = resolveLocaleFiles(placeholderPaths, locale);
|
|
16
17
|
if (!translationFiles.gt) {
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
logger.error(noFilesError);
|
|
19
|
+
exitSync(1);
|
|
19
20
|
}
|
|
20
21
|
const filepath = translationFiles.gt;
|
|
21
22
|
const translationData = translation.translation;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { JSONPath } from 'jsonpath-plus';
|
|
2
|
-
import {
|
|
2
|
+
import { logger } from '../../console/logger.js';
|
|
3
3
|
/**
|
|
4
4
|
* Flattens a JSON object according to a list of JSON paths.
|
|
5
5
|
* @param json - The JSON object to flatten
|
|
@@ -25,7 +25,7 @@ export function flattenJson(json, jsonPaths) {
|
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
27
|
catch (error) {
|
|
28
|
-
|
|
28
|
+
logger.error(`Error with JSONPath pattern: ${jsonPath}`);
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
return extractedJson;
|
|
@@ -57,7 +57,7 @@ export function flattenJsonWithStringFilter(json, jsonPaths) {
|
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
59
|
catch {
|
|
60
|
-
|
|
60
|
+
logger.error(`Error with JSONPath pattern: ${jsonPath}`);
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
return extractedJson;
|