gtx-cli 2.5.7 → 2.5.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/api/downloadFileBatch.js +5 -5
  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.d.ts +2 -1
  7. package/dist/cli/base.js +36 -30
  8. package/dist/cli/commands/setupProject.d.ts +7 -0
  9. package/dist/cli/commands/setupProject.js +50 -0
  10. package/dist/cli/commands/stage.d.ts +0 -2
  11. package/dist/cli/commands/stage.js +13 -61
  12. package/dist/cli/commands/translate.js +3 -5
  13. package/dist/cli/flags.js +2 -3
  14. package/dist/cli/next.js +1 -0
  15. package/dist/cli/react.d.ts +1 -0
  16. package/dist/cli/react.js +26 -15
  17. package/dist/config/generateSettings.js +2 -2
  18. package/dist/config/validateSettings.d.ts +1 -1
  19. package/dist/config/validateSettings.js +4 -4
  20. package/dist/console/logger.d.ts +35 -0
  21. package/dist/console/logger.js +270 -0
  22. package/dist/console/logging.d.ts +6 -11
  23. package/dist/console/logging.js +40 -55
  24. package/dist/formats/files/collectFiles.d.ts +6 -0
  25. package/dist/formats/files/collectFiles.js +49 -0
  26. package/dist/formats/files/fileMapping.js +1 -1
  27. package/dist/formats/files/save.js +2 -2
  28. package/dist/formats/files/translate.js +8 -8
  29. package/dist/formats/files/upload.js +7 -6
  30. package/dist/formats/gt/save.js +4 -3
  31. package/dist/formats/json/flattenJson.js +3 -3
  32. package/dist/formats/json/mergeJson.js +19 -18
  33. package/dist/formats/json/parseJson.js +14 -13
  34. package/dist/formats/json/utils.js +16 -15
  35. package/dist/formats/yaml/mergeYaml.js +6 -5
  36. package/dist/formats/yaml/parseYaml.js +4 -3
  37. package/dist/formats/yaml/utils.js +4 -3
  38. package/dist/fs/clearLocaleDirs.js +6 -6
  39. package/dist/fs/config/downloadedVersions.js +3 -3
  40. package/dist/fs/config/parseFilesConfig.js +2 -2
  41. package/dist/fs/config/setupConfig.js +2 -2
  42. package/dist/fs/config/updateConfig.js +2 -2
  43. package/dist/fs/config/updateVersions.js +3 -3
  44. package/dist/fs/copyFile.js +2 -2
  45. package/dist/fs/createLoadTranslationsFile.d.ts +1 -1
  46. package/dist/fs/createLoadTranslationsFile.js +11 -4
  47. package/dist/fs/determineFramework.js +3 -3
  48. package/dist/fs/findFilepath.js +5 -4
  49. package/dist/hooks/postProcess.js +9 -9
  50. package/dist/next/parse/handleInitGT.js +2 -2
  51. package/dist/react/parse/addVitePlugin/index.js +4 -3
  52. package/dist/react/parse/addVitePlugin/installCompiler.js +2 -2
  53. package/dist/react/parse/addVitePlugin/updateViteConfig.js +9 -12
  54. package/dist/react/parse/createDictionaryUpdates.js +4 -3
  55. package/dist/react/parse/createInlineUpdates.js +2 -2
  56. package/dist/setup/wizard.js +17 -16
  57. package/dist/translation/parse.js +4 -3
  58. package/dist/translation/stage.js +4 -4
  59. package/dist/translation/validate.js +6 -6
  60. package/dist/types/index.d.ts +1 -0
  61. package/dist/utils/addExplicitAnchorIds.js +2 -2
  62. package/dist/utils/constants.d.ts +2 -0
  63. package/dist/utils/constants.js +3 -0
  64. package/dist/utils/credentials.js +4 -3
  65. package/dist/utils/installPackage.js +11 -11
  66. package/dist/utils/packageJson.js +4 -3
  67. package/dist/workflow/BranchStep.js +5 -4
  68. package/dist/workflow/DownloadStep.js +5 -5
  69. package/dist/workflow/EnqueueStep.js +2 -2
  70. package/dist/workflow/PollJobsStep.js +4 -4
  71. package/dist/workflow/SetupStep.d.ts +1 -1
  72. package/dist/workflow/SetupStep.js +4 -3
  73. package/dist/workflow/UploadStep.js +3 -3
  74. package/dist/workflow/UserEditDiffsStep.js +2 -2
  75. package/dist/workflow/download.js +4 -3
  76. package/dist/workflow/setupProject.d.ts +13 -0
  77. package/dist/workflow/setupProject.js +48 -0
  78. package/dist/workflow/stage.js +4 -21
  79. package/package.json +3 -3
  80. package/dist/utils/SpinnerManager.d.ts +0 -30
  81. package/dist/utils/SpinnerManager.js +0 -73
package/dist/cli/react.js CHANGED
@@ -1,4 +1,5 @@
1
- import { displayHeader, endCommand, logError, logStep, logSuccess, logWarning, promptConfirm, } from '../console/logging.js';
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';
@@ -20,6 +21,7 @@ export class ReactCLI extends BaseCLI {
20
21
  super(command, library, additionalModules);
21
22
  }
22
23
  init() {
24
+ this.setupSetupProjectCommand();
23
25
  this.setupStageCommand();
24
26
  this.setupTranslateCommand();
25
27
  this.setupGenerateSourceCommand();
@@ -31,13 +33,22 @@ export class ReactCLI extends BaseCLI {
31
33
  wrapContent(options, framework, errors, warnings) {
32
34
  return wrapContentReact(options, pkg, framework, errors, warnings);
33
35
  }
36
+ setupSetupProjectCommand() {
37
+ attachAdditionalReactTranslateFlags(attachTranslateFlags(this.program
38
+ .command('setup')
39
+ .description('Upload source files and setup the project for translation'))).action(async (options) => {
40
+ displayHeader('Uploading source files and setting up project...');
41
+ await this.handleSetupProject(options);
42
+ logger.endCommand('Done!');
43
+ });
44
+ }
34
45
  setupStageCommand() {
35
46
  attachAdditionalReactTranslateFlags(attachTranslateFlags(this.program
36
47
  .command('stage')
37
48
  .description('Submits the project to the General Translation API for translation. Translations created using this command will require human approval.'))).action(async (options) => {
38
49
  displayHeader('Staging project for translation with approval required...');
39
50
  await this.handleStage(options);
40
- endCommand('Done!');
51
+ logger.endCommand('Done!');
41
52
  });
42
53
  }
43
54
  setupTranslateCommand() {
@@ -46,7 +57,7 @@ export class ReactCLI extends BaseCLI {
46
57
  .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
58
  displayHeader('Translating project...');
48
59
  await this.handleTranslate(options);
49
- endCommand('Done!');
60
+ logger.endCommand('Done!');
50
61
  });
51
62
  }
52
63
  setupValidateCommand() {
@@ -62,7 +73,7 @@ export class ReactCLI extends BaseCLI {
62
73
  // intro here since we don't want to show the ascii title
63
74
  intro(chalk.cyan('Validating project...'));
64
75
  await this.handleValidate(options, files);
65
- endCommand('Done!');
76
+ logger.endCommand('Done!');
66
77
  });
67
78
  }
68
79
  setupGenerateSourceCommand() {
@@ -71,7 +82,7 @@ export class ReactCLI extends BaseCLI {
71
82
  .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
83
  displayHeader('Generating source templates...');
73
84
  await this.handleGenerateSourceCommand(initOptions);
74
- endCommand('Done!');
85
+ logger.endCommand('Done!');
75
86
  });
76
87
  }
77
88
  async handleGenerateSourceCommand(initOptions) {
@@ -93,11 +104,11 @@ export class ReactCLI extends BaseCLI {
93
104
  if (settings.files && settings.files.placeholderPaths.gt) {
94
105
  const translationFiles = resolveLocaleFiles(settings.files.placeholderPaths, settings.defaultLocale);
95
106
  if (!translationFiles.gt) {
96
- logError(noFilesError);
97
- process.exit(1);
107
+ logger.error(noFilesError);
108
+ exitSync(1);
98
109
  }
99
110
  await saveJSON(translationFiles.gt, newData);
100
- logStep('Source file saved successfully!');
111
+ logger.step('Source file saved successfully!');
101
112
  // Also save translations (after merging with existing translations)
102
113
  for (const locale of settings.locales) {
103
114
  const translationsFile = resolveLocaleFiles(settings.files.placeholderPaths, locale);
@@ -113,7 +124,7 @@ export class ReactCLI extends BaseCLI {
113
124
  const filteredTranslations = Object.fromEntries(Object.entries(mergedTranslations).filter(([key]) => newData[key]));
114
125
  await saveJSON(translationsFile.gt, filteredTranslations);
115
126
  }
116
- logStep('Merged translations successfully!');
127
+ logger.step('Merged translations successfully!');
117
128
  }
118
129
  }
119
130
  async handleScanCommand(options) {
@@ -123,8 +134,8 @@ export class ReactCLI extends BaseCLI {
123
134
  defaultValue: true,
124
135
  });
125
136
  if (!answer) {
126
- logError('Operation cancelled.');
127
- process.exit(0);
137
+ logger.error('Operation cancelled.');
138
+ exitSync(0);
128
139
  }
129
140
  // ----- Create a starter gt.config.json file -----
130
141
  await generateSettings(options);
@@ -139,18 +150,18 @@ export class ReactCLI extends BaseCLI {
139
150
  // Wrap all JSX elements in the src directory with a <T> tag, with unique ids
140
151
  const { filesUpdated } = await this.wrapContent(options, 'react', errors, warnings);
141
152
  if (errors.length > 0) {
142
- logError(chalk.red('Failed to write files:\n') + errors.join('\n'));
153
+ logger.error(chalk.red('Failed to write files:\n') + errors.join('\n'));
143
154
  }
144
155
  // Format updated files if formatters are available
145
156
  if (!options.disableFormatting)
146
157
  await formatFiles(filesUpdated);
147
- logSuccess(`Success! Added <T> tags and updated ${chalk.bold.cyan(filesUpdated.length)} files:\n` +
158
+ logger.success(`Success! Added <T> tags and updated ${chalk.bold.cyan(filesUpdated.length)} files:\n` +
148
159
  filesUpdated.map((file) => `${chalk.green('-')} ${file}`).join('\n'));
149
160
  if (filesUpdated.length > 0) {
150
- logStep(chalk.green('Please verify the changes before committing.'));
161
+ logger.step(chalk.green('Please verify the changes before committing.'));
151
162
  }
152
163
  if (warnings.length > 0) {
153
- logWarning(chalk.yellow('Warnings encountered:') +
164
+ logger.warn(chalk.yellow('Warnings encountered:') +
154
165
  '\n' +
155
166
  warnings
156
167
  .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
- process.exit(1);
49
+ exitSync(1);
50
50
  }
51
51
  const projectIdEnv = resolveProjectId();
52
52
  // Resolve mismatched projectIds
@@ -1,3 +1,3 @@
1
1
  import { Settings } from '../types/index.js';
2
- export declare function validateSettings(settings: Settings): void;
2
+ export declare function validateSettings(settings: Settings): undefined;
3
3
  export declare function validateConfigExists(): string;
@@ -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,35 @@
1
+ import type { SpinnerResult, ProgressResult } from '@clack/prompts';
2
+ export type LogFormat = 'default' | 'json';
3
+ /**
4
+ * GT_LOG_FORMAT: default | json.
5
+ * - If default, logs will be pretty-printed using @clack/prompts.
6
+ * - If json, logs will be written in JSON format to the console.
7
+ * GT_LOG_FILE: If specified, logs will be written to the file.
8
+ * GT_LOG_LEVEL: The level of logs to write. If not specified, defaults to 'info'.
9
+ * - Valid levels: debug, info, warn, error.
10
+ */
11
+ declare class Logger {
12
+ private static instance;
13
+ private pinoLogger;
14
+ private fileLogger;
15
+ private logFormat;
16
+ private constructor();
17
+ static getInstance(): Logger;
18
+ trace(message: string): void;
19
+ debug(message: string): void;
20
+ info(message: string): void;
21
+ warn(message: string): void;
22
+ error(message: string): void;
23
+ fatal(message: string): void;
24
+ silent(message: string): void;
25
+ success(message: string): void;
26
+ step(message: string): void;
27
+ message(message: string, symbol?: string): void;
28
+ createSpinner(indicator?: 'dots' | 'timer'): SpinnerResult;
29
+ createProgressBar(total: number): ProgressResult;
30
+ startCommand(message: string): void;
31
+ endCommand(message: string): void;
32
+ flush(): void;
33
+ }
34
+ export declare const logger: Logger;
35
+ export {};
@@ -0,0 +1,270 @@
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
+ /**
63
+ * GT_LOG_FORMAT: default | json.
64
+ * - If default, logs will be pretty-printed using @clack/prompts.
65
+ * - If json, logs will be written in JSON format to the console.
66
+ * GT_LOG_FILE: If specified, logs will be written to the file.
67
+ * GT_LOG_LEVEL: The level of logs to write. If not specified, defaults to 'info'.
68
+ * - Valid levels: debug, info, warn, error.
69
+ */
70
+ class Logger {
71
+ static instance;
72
+ pinoLogger = null;
73
+ fileLogger = null;
74
+ logFormat;
75
+ constructor() {
76
+ // Read configuration from environment variables
77
+ const format = (process.env.GT_LOG_FORMAT || 'default').toLowerCase();
78
+ const logFile = process.env.GT_LOG_FILE;
79
+ const logLevel = process.env.GT_LOG_LEVEL || 'info';
80
+ if (format !== 'default' && format !== 'json') {
81
+ console.error('Invalid log format');
82
+ process.exit(1);
83
+ }
84
+ if (logLevel !== 'debug' &&
85
+ logLevel !== 'info' &&
86
+ logLevel !== 'warn' &&
87
+ logLevel !== 'error') {
88
+ console.error('Invalid log level');
89
+ process.exit(1);
90
+ }
91
+ this.logFormat = format;
92
+ const transports = [];
93
+ // Console output (stdout)
94
+ if (format === 'json') {
95
+ // JSON formatted console output
96
+ transports.push({
97
+ level: logLevel,
98
+ target: 'pino/file',
99
+ options: { destination: 1 }, // stdout
100
+ });
101
+ }
102
+ // For 'default' format, we don't add a console transport - we'll use @clack/prompts directly
103
+ // Create console logger if we have console transports
104
+ if (transports.length > 0) {
105
+ this.pinoLogger = pino({
106
+ level: logLevel,
107
+ mixin: () => ({
108
+ logId: randomUUID(),
109
+ }),
110
+ }, transport({
111
+ targets: transports,
112
+ }));
113
+ }
114
+ // File output (if specified) - always JSON format
115
+ if (logFile) {
116
+ this.fileLogger = pino({
117
+ level: logLevel,
118
+ mixin: () => ({
119
+ logId: randomUUID(),
120
+ }),
121
+ }, transport({
122
+ targets: [
123
+ {
124
+ level: logLevel,
125
+ target: 'pino/file',
126
+ options: { destination: logFile },
127
+ },
128
+ ],
129
+ }));
130
+ }
131
+ }
132
+ static getInstance() {
133
+ if (!Logger.instance) {
134
+ Logger.instance = new Logger();
135
+ }
136
+ return Logger.instance;
137
+ }
138
+ // Standard logging methods
139
+ trace(message) {
140
+ if (this.logFormat === 'default') {
141
+ // @clack/prompts doesn't have trace, use message
142
+ clackLog.message(message, { symbol: chalk.dim('•') });
143
+ }
144
+ else {
145
+ this.pinoLogger?.trace(message);
146
+ }
147
+ this.fileLogger?.trace(message);
148
+ }
149
+ debug(message) {
150
+ if (this.logFormat === 'default') {
151
+ // @clack/prompts doesn't have debug, use message
152
+ clackLog.message(message, { symbol: chalk.dim('◆') });
153
+ }
154
+ else {
155
+ this.pinoLogger?.debug(message);
156
+ }
157
+ this.fileLogger?.debug(message);
158
+ }
159
+ info(message) {
160
+ if (this.logFormat === 'default') {
161
+ clackLog.info(message);
162
+ }
163
+ else {
164
+ this.pinoLogger?.info(message);
165
+ }
166
+ this.fileLogger?.info(message);
167
+ }
168
+ warn(message) {
169
+ if (this.logFormat === 'default') {
170
+ clackLog.warn(message);
171
+ }
172
+ else {
173
+ this.pinoLogger?.warn(message);
174
+ }
175
+ this.fileLogger?.warn(message);
176
+ }
177
+ error(message) {
178
+ if (this.logFormat === 'default') {
179
+ clackLog.error(message);
180
+ }
181
+ else {
182
+ this.pinoLogger?.error(message);
183
+ }
184
+ this.fileLogger?.error(message);
185
+ }
186
+ fatal(message) {
187
+ if (this.logFormat === 'default') {
188
+ clackLog.error(message); // @clack/prompts doesn't have fatal, use error
189
+ }
190
+ else {
191
+ this.pinoLogger?.fatal(message);
192
+ }
193
+ this.fileLogger?.fatal(message);
194
+ }
195
+ silent(message) {
196
+ // Silent doesn't log to console, only to file
197
+ this.fileLogger?.silent(message);
198
+ }
199
+ // @clack/prompts specific methods (for 'default' format)
200
+ success(message) {
201
+ if (this.logFormat === 'default') {
202
+ clackLog.success(message);
203
+ }
204
+ else {
205
+ this.pinoLogger?.info(message); // Map to info for non-default formats
206
+ }
207
+ this.fileLogger?.info(message);
208
+ }
209
+ step(message) {
210
+ if (this.logFormat === 'default') {
211
+ clackLog.step(message);
212
+ }
213
+ else {
214
+ this.pinoLogger?.info(message); // Map to info for non-default formats
215
+ }
216
+ this.fileLogger?.info(message);
217
+ }
218
+ message(message, symbol) {
219
+ if (this.logFormat === 'default') {
220
+ clackLog.message(message, symbol ? { symbol } : undefined);
221
+ }
222
+ else {
223
+ this.pinoLogger?.info(message); // Map to info for non-default formats
224
+ }
225
+ this.fileLogger?.info(message);
226
+ }
227
+ // Spinner functionality
228
+ createSpinner(indicator = 'timer') {
229
+ if (this.logFormat === 'default') {
230
+ return spinner({ indicator });
231
+ }
232
+ else {
233
+ return new MockSpinner(this);
234
+ }
235
+ }
236
+ // Progress bar functionality
237
+ createProgressBar(total) {
238
+ if (this.logFormat === 'default') {
239
+ return progress({ max: total });
240
+ }
241
+ else {
242
+ return new MockProgress(total, this);
243
+ }
244
+ }
245
+ // Command start/end markers
246
+ startCommand(message) {
247
+ if (this.logFormat === 'default') {
248
+ intro(chalk.cyan(message));
249
+ }
250
+ else {
251
+ this.info(`╭─ ${message}`);
252
+ }
253
+ this.fileLogger?.info(`[START] ${message}`);
254
+ }
255
+ endCommand(message) {
256
+ if (this.logFormat === 'default') {
257
+ outro(chalk.cyan(message));
258
+ }
259
+ else {
260
+ this.info(`╰─ ${message}`);
261
+ }
262
+ this.fileLogger?.info(`[END] ${message}`);
263
+ }
264
+ // Flush logs to ensure they're written before process exit
265
+ flush() {
266
+ this.pinoLogger?.flush();
267
+ this.fileLogger?.flush();
268
+ }
269
+ }
270
+ export const logger = Logger.getInstance();
@@ -1,21 +1,12 @@
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;
1
+ import { FileToUpload } from 'generaltranslation/types';
7
2
  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;
3
+ export declare function exitSync(code: number): never;
11
4
  export declare function displayHeader(introString?: string): void;
12
5
  export declare function displayProjectId(projectId: string): void;
13
6
  export declare function displayResolvedPaths(resolvedPaths: [string, string][]): void;
14
7
  export declare function displayCreatedConfigFile(configFilepath: string): void;
15
8
  export declare function displayUpdatedConfigFile(configFilepath: string): void;
16
9
  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
10
  export declare function promptText({ message, defaultValue, validate, }: {
20
11
  message: string;
21
12
  defaultValue?: string;
@@ -51,3 +42,7 @@ export declare function warnHasUnwrappedExpression(file: string, id: string, unw
51
42
  export declare function warnNonStaticExpression(file: string, attrName: string, value: string): void;
52
43
  export declare function warnTemplateLiteral(file: string, value: string): void;
53
44
  export declare function warnTernary(file: string): void;
45
+ /**
46
+ * Helper: Log all collected files
47
+ */
48
+ export declare function logCollectedFiles(files: FileToUpload[], reactComponents?: number): void;