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.
Files changed (67) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/api/downloadFileBatch.js +6 -6
  3. package/dist/api/saveLocalEdits.js +4 -3
  4. package/dist/api/uploadFiles.d.ts +1 -1
  5. package/dist/api/uploadFiles.js +5 -4
  6. package/dist/cli/base.js +17 -16
  7. package/dist/cli/commands/stage.js +8 -7
  8. package/dist/cli/commands/translate.js +3 -5
  9. package/dist/cli/flags.js +2 -3
  10. package/dist/cli/react.js +16 -15
  11. package/dist/config/generateSettings.js +2 -2
  12. package/dist/config/validateSettings.d.ts +1 -1
  13. package/dist/config/validateSettings.js +4 -4
  14. package/dist/console/logger.d.ts +27 -0
  15. package/dist/console/logger.js +255 -0
  16. package/dist/console/logging.d.ts +1 -11
  17. package/dist/console/logging.js +24 -55
  18. package/dist/formats/files/save.js +2 -2
  19. package/dist/formats/files/translate.js +8 -8
  20. package/dist/formats/files/upload.js +7 -6
  21. package/dist/formats/gt/save.js +4 -3
  22. package/dist/formats/json/flattenJson.js +3 -3
  23. package/dist/formats/json/mergeJson.d.ts +1 -1
  24. package/dist/formats/json/mergeJson.js +69 -21
  25. package/dist/formats/json/parseJson.js +14 -13
  26. package/dist/formats/json/utils.js +16 -15
  27. package/dist/formats/yaml/mergeYaml.js +6 -5
  28. package/dist/formats/yaml/parseYaml.js +4 -3
  29. package/dist/formats/yaml/utils.js +4 -3
  30. package/dist/fs/clearLocaleDirs.js +6 -6
  31. package/dist/fs/config/downloadedVersions.js +3 -3
  32. package/dist/fs/config/parseFilesConfig.js +2 -2
  33. package/dist/fs/config/setupConfig.js +2 -2
  34. package/dist/fs/config/updateConfig.js +2 -2
  35. package/dist/fs/config/updateVersions.js +3 -3
  36. package/dist/fs/copyFile.js +2 -2
  37. package/dist/fs/createLoadTranslationsFile.js +3 -3
  38. package/dist/fs/determineFramework.js +3 -3
  39. package/dist/fs/findFilepath.js +5 -4
  40. package/dist/hooks/postProcess.js +9 -9
  41. package/dist/next/parse/handleInitGT.js +2 -2
  42. package/dist/react/parse/addVitePlugin/index.js +4 -3
  43. package/dist/react/parse/addVitePlugin/installCompiler.js +2 -2
  44. package/dist/react/parse/addVitePlugin/updateViteConfig.js +9 -12
  45. package/dist/react/parse/createDictionaryUpdates.js +4 -3
  46. package/dist/react/parse/createInlineUpdates.js +2 -2
  47. package/dist/setup/wizard.js +17 -16
  48. package/dist/translation/parse.js +4 -3
  49. package/dist/translation/stage.js +4 -4
  50. package/dist/translation/validate.js +6 -6
  51. package/dist/types/index.d.ts +1 -0
  52. package/dist/utils/addExplicitAnchorIds.js +2 -2
  53. package/dist/utils/credentials.js +4 -3
  54. package/dist/utils/installPackage.js +11 -11
  55. package/dist/utils/packageJson.js +4 -3
  56. package/dist/workflow/BranchStep.js +5 -4
  57. package/dist/workflow/DownloadStep.js +5 -5
  58. package/dist/workflow/EnqueueStep.js +2 -2
  59. package/dist/workflow/PollJobsStep.js +3 -3
  60. package/dist/workflow/SetupStep.js +2 -2
  61. package/dist/workflow/UploadStep.js +3 -3
  62. package/dist/workflow/UserEditDiffsStep.js +2 -2
  63. package/dist/workflow/download.js +4 -3
  64. package/dist/workflow/stage.js +5 -4
  65. package/package.json +2 -2
  66. package/dist/utils/SpinnerManager.d.ts +0 -30
  67. 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 exit(code: number): never;
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;
@@ -1,45 +1,22 @@
1
- import { log, spinner, intro, outro, text, select, confirm, isCancel, cancel, multiselect, progress, } from '@clack/prompts';
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
- // Basic logging functions
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
- log.error(message);
25
- exit(1);
6
+ logger.error(message);
7
+ return exitSync(1);
26
8
  }
27
- export function exit(code) {
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
- logMessage(chalk.dim(`Project ID: ${chalk.bold(projectId)}`));
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
- log.step(`Resolved path aliases:\n${paths.join('\n')}`);
45
+ logger.step(`Resolved path aliases:\n${paths.join('\n')}`);
69
46
  }
70
47
  export function displayCreatedConfigFile(configFilepath) {
71
- log.step(`Created config file ${chalk.cyan(configFilepath)}`);
48
+ logger.step(`Created config file ${chalk.cyan(configFilepath)}`);
72
49
  }
73
50
  export function displayUpdatedConfigFile(configFilepath) {
74
- log.success(`Updated config file ${chalk.cyan(configFilepath)}`);
51
+ logger.success(`Updated config file ${chalk.cyan(configFilepath)}`);
75
52
  }
76
53
  export function displayUpdatedVersionsFile(versionFilepath) {
77
- log.success(`Updated versions file ${chalk.cyan(versionFilepath)}`);
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
- process.exit(0);
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
- process.exit(0);
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
- process.exit(0);
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
- process.exit(0);
117
+ return exitSync(0);
149
118
  }
150
119
  return result;
151
120
  }
152
121
  // Warning display functions
153
122
  export function warnApiKeyInConfig(optionsFilepath) {
154
- log.warn(`Found ${chalk.cyan('apiKey')} in "${chalk.green(optionsFilepath)}". ` +
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
- log.warn(`Found ${chalk.green('<T>')} component in ${chalk.cyan(file)} with variable ${attrName}: "${chalk.white(value)}". ` +
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
- log.warn(`Found ${chalk.green('<T>')} component in ${chalk.cyan(file)} with no id. ` +
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
- log.warn(`${chalk.green('<T>')} with id "${id}" in ${chalk.cyan(file)} has children: ${unwrappedExpressions.join(', ')} that could change at runtime. ` +
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
- log.warn(`Found non-static expression in ${chalk.cyan(file)} for attribute ${attrName}: "${chalk.white(value)}". ` +
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
- log.warn(`Found template literal with quasis (${value}) in ${chalk.cyan(file)}. ` +
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
- log.warn(`Found ternary expression in ${chalk.cyan(file)}. ` +
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 { logSuccess } from '../../console/logging.js';
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
- logSuccess(`Saved translated ${dataFormat} file to: ${outputPath}`);
15
+ logger.success(`Saved translated ${dataFormat} file to: ${outputPath}`);
16
16
  }
17
17
  }
@@ -1,4 +1,4 @@
1
- import { logError, logWarning } from '../../console/logging.js';
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
- logWarning(`Skipping ${relativePath}: JSON file is not parsable`);
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
- logWarning(`Skipping ${file.fileName}: JSON file is empty`);
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
- logWarning(`Skipping ${relativePath}: YAML file is not parsable`);
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
- logWarning(`Skipping ${file?.fileName ?? 'unknown'}: YAML file is empty`);
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
- logWarning(`Skipping ${relativePath}: MDX file is not AST parsable${validation.error ? `: ${validation.error}` : ''}`);
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
- logWarning(`Skipping ${file?.fileName ?? 'unknown'}: File is empty after sanitization`);
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
- logError('No files to translate were found. Please check your configuration and try again.');
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, logError } from '../../console/logging.js';
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
- logError('No files to upload were found. Please check your configuration and try again.');
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
@@ -1,6 +1,7 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
- import { logError } from '../../console/logging.js';
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
- logError(noFilesError);
18
- process.exit(1);
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 { logError } from '../../console/logging.js';
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
- logError(`Error with JSONPath pattern: ${jsonPath}`);
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
- logError(`Error with JSONPath pattern: ${jsonPath}`);
60
+ logger.error(`Error with JSONPath pattern: ${jsonPath}`);
61
61
  }
62
62
  }
63
63
  return extractedJson;
@@ -2,7 +2,7 @@ import { AdditionalOptions, SourceObjectOptions } from '../../types/index.js';
2
2
  export declare function mergeJson(originalContent: string, inputPath: string, options: AdditionalOptions, targets: {
3
3
  translatedContent: string;
4
4
  targetLocale: string;
5
- }[], defaultLocale: string): string[];
5
+ }[], defaultLocale: string, localeOrder?: string[]): string[];
6
6
  /**
7
7
  * Apply transformations to the sourceItem in-place
8
8
  * @param sourceItem - The source item to apply transformations to