gtx-cli 1.2.30-alpha.35 → 1.2.31-alpha.1

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 (52) hide show
  1. package/CHANGELOG.md +0 -18
  2. package/dist/api/sendFiles.d.ts +2 -9
  3. package/dist/api/sendFiles.js +2 -2
  4. package/dist/cli/base.js +14 -14
  5. package/dist/cli/react.js +8 -21
  6. package/dist/config/generateSettings.d.ts +0 -1
  7. package/dist/config/generateSettings.js +21 -31
  8. package/dist/console/index.d.ts +2 -1
  9. package/dist/console/index.js +2 -1
  10. package/dist/formats/files/supportedFiles.d.ts +1 -1
  11. package/dist/formats/files/supportedFiles.js +1 -1
  12. package/dist/formats/files/translate.d.ts +1 -4
  13. package/dist/formats/files/translate.js +7 -8
  14. package/dist/fs/config/loadConfig.d.ts +1 -1
  15. package/dist/fs/config/loadConfig.js +1 -1
  16. package/dist/fs/config/parseFilesConfig.js +12 -13
  17. package/dist/fs/config/setupConfig.d.ts +0 -1
  18. package/dist/fs/config/setupConfig.js +0 -1
  19. package/dist/fs/findJsxFilepath.d.ts +7 -0
  20. package/dist/fs/findJsxFilepath.js +30 -0
  21. package/dist/next/parse/wrapContent.js +4 -4
  22. package/dist/react/data-_gt/addGTIdentifierToSyntaxTree.d.ts +1 -8
  23. package/dist/react/data-_gt/addGTIdentifierToSyntaxTree.js +63 -90
  24. package/dist/react/jsx/parse/parseStringFunction.d.ts +12 -0
  25. package/dist/react/jsx/parse/parseStringFunction.js +80 -0
  26. package/dist/react/jsx/utils/constants.d.ts +0 -2
  27. package/dist/react/jsx/utils/constants.js +0 -8
  28. package/dist/react/jsx/utils/parseJsx.d.ts +1 -8
  29. package/dist/react/jsx/utils/parseJsx.js +14 -26
  30. package/dist/react/jsx/utils/parseStringFunction.d.ts +1 -0
  31. package/dist/react/jsx/utils/parseStringFunction.js +8 -7
  32. package/dist/react/parse/createDictionaryUpdates.d.ts +2 -2
  33. package/dist/react/parse/createDictionaryUpdates.js +13 -112
  34. package/dist/react/parse/createInlineUpdates.js +34 -7
  35. package/dist/react/parse/wrapContent.js +4 -5
  36. package/dist/react/utils/getVariableName.d.ts +1 -24
  37. package/dist/react/utils/getVariableName.js +7 -31
  38. package/dist/translation/parse.js +2 -2
  39. package/dist/translation/stage.js +1 -1
  40. package/dist/types/data.d.ts +1 -1
  41. package/dist/types/index.d.ts +4 -7
  42. package/package.json +2 -2
  43. package/dist/config/resolveConfig.d.ts +0 -4
  44. package/dist/config/resolveConfig.js +0 -19
  45. package/dist/fs/matchFiles.d.ts +0 -2
  46. package/dist/fs/matchFiles.js +0 -10
  47. package/dist/utils/flattenJsonFiles.d.ts +0 -2
  48. package/dist/utils/flattenJsonFiles.js +0 -36
  49. package/dist/utils/localizeStaticUrls.d.ts +0 -15
  50. package/dist/utils/localizeStaticUrls.js +0 -78
  51. package/dist/utils/sanitizeFileContent.d.ts +0 -6
  52. package/dist/utils/sanitizeFileContent.js +0 -29
package/CHANGELOG.md CHANGED
@@ -1,23 +1,5 @@
1
1
  # gtx-cli
2
2
 
3
- ## 1.2.34
4
-
5
- ### Patch Changes
6
-
7
- - [#428](https://github.com/generaltranslation/gt/pull/428) [`54036f5`](https://github.com/generaltranslation/gt/commit/54036f54308bdb9f9e6dcec93871e004dcf1be4c) Thanks [@ErnestM1234](https://github.com/ErnestM1234)! - feat: add experimental options to translate
8
-
9
- ## 1.2.33
10
-
11
- ### Patch Changes
12
-
13
- - [#426](https://github.com/generaltranslation/gt/pull/426) [`ce57545`](https://github.com/generaltranslation/gt/commit/ce575454301185c663cfb93345d3058c9ceb25dd) Thanks [@brian-lou](https://github.com/brian-lou)! - Improve file pattern matching
14
-
15
- ## 1.2.31
16
-
17
- ### Patch Changes
18
-
19
- - [#423](https://github.com/generaltranslation/gt/pull/423) [`0ed08c7`](https://github.com/generaltranslation/gt/commit/0ed08c7bb1e63c99296b74138e4d44b718681fc8) Thanks [@brian-lou](https://github.com/brian-lou)! - Add setting configuration options
20
-
21
3
  ## 1.2.30
22
4
 
23
5
  ### Patch Changes
@@ -1,16 +1,9 @@
1
1
  import { Settings } from '../types/index.js';
2
- import { FileExtension, DataFormat } from '../types/data.js';
3
- /**
4
- * File object structure
5
- * @param content - The content of the file
6
- * @param fileName - The name of the file
7
- * @param fileExtension - The format of the file (JSON, MDX, MD, etc.)
8
- * @param dataFormat - The format of the data within the file
9
- */
2
+ import { FileFormats, DataFormat } from '../types/data.js';
10
3
  export interface FileToTranslate {
11
4
  content: string;
12
5
  fileName: string;
13
- fileExtension: FileExtension;
6
+ fileFormat: FileFormats;
14
7
  dataFormat: DataFormat;
15
8
  }
16
9
  type ApiOptions = Settings & {
@@ -19,8 +19,8 @@ export async function sendFiles(files, options) {
19
19
  // Add each file to the form data
20
20
  files.forEach((file, index) => {
21
21
  formData.append(`file${index}`, new Blob([file.content]), file.fileName);
22
- formData.append(`fileExtension${index}`, file.fileExtension);
23
- formData.append(`dataFormat${index}`, file.dataFormat); // Only used when translating JSON files
22
+ formData.append(`fileFormat${index}`, file.fileFormat);
23
+ formData.append(`fileDataFormat${index}`, file.dataFormat); // Only used when translating JSON files
24
24
  formData.append(`fileName${index}`, file.fileName);
25
25
  });
26
26
  // Add number of files
package/dist/cli/base.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import { createOrUpdateConfig } from '../fs/config/setupConfig.js';
2
- import findFilepath from '../fs/findFilepath.js';
2
+ import findFilepath, { findFilepaths } from '../fs/findFilepath.js';
3
3
  import { displayHeader, promptText, logErrorAndExit, endCommand, promptConfirm, promptMultiSelect, logSuccess, logInfo, startCommand, createSpinner, logMessage, } from '../console/logging.js';
4
4
  import path from 'node:path';
5
5
  import fs from 'node:fs';
6
6
  import { generateSettings } from '../config/generateSettings.js';
7
7
  import chalk from 'chalk';
8
8
  import { translateFiles } from '../formats/files/translate.js';
9
- import { FILE_EXT_TO_EXT_LABEL } from '../formats/files/supportedFiles.js';
9
+ import { FILE_EXT_TO_FORMAT } from '../formats/files/supportedFiles.js';
10
10
  import { handleSetupReactCommand } from '../setup/wizard.js';
11
11
  import { isPackageInstalled, searchForPackageJson, } from '../utils/packageJson.js';
12
12
  import { getDesiredLocales } from '../setup/userInput.js';
@@ -94,7 +94,7 @@ export class BaseCLI {
94
94
  this.program
95
95
  .command('init')
96
96
  .description('Run the setup wizard to configure your project for General Translation')
97
- .option('--src <paths...>', "Space-separated list of glob patterns containing the app's source code, by default 'src/**/*.{js,jsx,ts,tsx}' 'app/**/*.{js,jsx,ts,tsx}' 'pages/**/*.{js,jsx,ts,tsx}' 'components/**/*.{js,jsx,ts,tsx}'")
97
+ .option('--src <paths...>', "Filepath to directory containing the app's source code, by default ./src || ./app || ./pages || ./components", findFilepaths(['./src', './app', './pages', './components']))
98
98
  .option('-c, --config <path>', 'Filepath to config file, by default gt.config.json', findFilepath(['gt.config.json']))
99
99
  .action(async (options) => {
100
100
  displayHeader('Running setup wizard...');
@@ -139,7 +139,7 @@ See the docs for more information: https://generaltranslation.com/docs/react/tut
139
139
  this.program
140
140
  .command('setup')
141
141
  .description('Run the setup to configure your Next.js or React project for General Translation')
142
- .option('--src <paths...>', "Space-separated list of glob patterns containing the app's source code, by default 'src/**/*.{js,jsx,ts,tsx}' 'app/**/*.{js,jsx,ts,tsx}' 'pages/**/*.{js,jsx,ts,tsx}' 'components/**/*.{js,jsx,ts,tsx}'")
142
+ .option('--src <paths...>', "Filepath to directory containing the app's source code, by default ./src || ./app || ./pages || ./components", findFilepaths(['./src', './app', './pages', './components']))
143
143
  .option('-c, --config <path>', 'Filepath to config file, by default gt.config.json', findFilepath(['gt.config.json']))
144
144
  .action(async (options) => {
145
145
  displayHeader('Running React setup wizard...');
@@ -210,24 +210,24 @@ See the docs for more information: https://generaltranslation.com/docs/react/tut
210
210
  const message = !isUsingGT
211
211
  ? 'What is the format of your language resource files? Select as many as applicable.\nAdditionally, you can translate any other files you have in your project.'
212
212
  : `${chalk.dim('(Optional)')} Do you have any separate files you would like to translate? For example, extra Markdown files for docs.`;
213
- const fileExtensions = await promptMultiSelect({
213
+ const dataFormats = await promptMultiSelect({
214
214
  message,
215
215
  options: [
216
- { value: 'json', label: FILE_EXT_TO_EXT_LABEL.json },
217
- { value: 'md', label: FILE_EXT_TO_EXT_LABEL.md },
218
- { value: 'mdx', label: FILE_EXT_TO_EXT_LABEL.mdx },
219
- { value: 'ts', label: FILE_EXT_TO_EXT_LABEL.ts },
220
- { value: 'js', label: FILE_EXT_TO_EXT_LABEL.js },
216
+ { value: 'json', label: 'JSON' },
217
+ { value: 'md', label: 'Markdown' },
218
+ { value: 'mdx', label: 'MDX' },
219
+ { value: 'ts', label: 'TypeScript' },
220
+ { value: 'js', label: 'JavaScript' },
221
221
  ],
222
222
  required: !isUsingGT,
223
223
  });
224
224
  const files = {};
225
- for (const fileExtension of fileExtensions) {
225
+ for (const dataFormat of dataFormats) {
226
226
  const paths = await promptText({
227
- message: `${chalk.cyan(FILE_EXT_TO_EXT_LABEL[fileExtension])}: Please enter a space-separated list of glob patterns matching the location of the ${FILE_EXT_TO_EXT_LABEL[fileExtension]} files you would like to translate.\nMake sure to include [locale] in the patterns.\nSee https://generaltranslation.com/docs/cli/reference/config#include for more information.`,
228
- defaultValue: `./**/[locale]/*.${fileExtension}`,
227
+ message: `${chalk.cyan(FILE_EXT_TO_FORMAT[dataFormat])}: Please enter a space-separated list of glob patterns matching the location of the ${FILE_EXT_TO_FORMAT[dataFormat]} files you would like to translate.\nMake sure to include [locale] in the patterns.\nSee https://generaltranslation.com/docs/cli/reference/config#include for more information.`,
228
+ defaultValue: `./**/[locale]/*.${dataFormat}`,
229
229
  });
230
- files[fileExtension] = {
230
+ files[dataFormat] = {
231
231
  include: paths.split(' '),
232
232
  };
233
233
  }
package/dist/cli/react.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { displayHeader, endCommand, logError, logErrorAndExit, logStep, logSuccess, logWarning, promptConfirm, } from '../console/logging.js';
2
2
  import loadJSON from '../fs/loadJSON.js';
3
- import findFilepath from '../fs/findFilepath.js';
3
+ import findFilepath, { findFilepaths } from '../fs/findFilepath.js';
4
4
  import chalk from 'chalk';
5
5
  import { formatFiles } from '../hooks/postProcess.js';
6
6
  import { BaseCLI } from './base.js';
@@ -16,8 +16,6 @@ import updateConfig from '../fs/config/updateConfig.js';
16
16
  import { validateConfigExists } from '../config/validateSettings.js';
17
17
  import { validateProject } from '../translation/validate.js';
18
18
  import { intro } from '@clack/prompts';
19
- import localizeStaticUrls from '../utils/localizeStaticUrls.js';
20
- import flattenJsonFiles from '../utils/flattenJsonFiles.js';
21
19
  const DEFAULT_TIMEOUT = 600;
22
20
  const pkg = 'gt-react';
23
21
  export class ReactCLI extends BaseCLI {
@@ -47,7 +45,7 @@ export class ReactCLI extends BaseCLI {
47
45
  .option('--version-id <id>', 'Version ID for the translation service')
48
46
  .option('--tsconfig, --jsconfig <path>', 'Path to jsconfig or tsconfig file', findFilepath(['./tsconfig.json', './jsconfig.json']))
49
47
  .option('--dictionary <path>', 'Path to dictionary file')
50
- .option('--src <paths...>', "Space-separated list of glob patterns containing the app's source code, by default 'src/**/*.{js,jsx,ts,tsx}' 'app/**/*.{js,jsx,ts,tsx}' 'pages/**/*.{js,jsx,ts,tsx}' 'components/**/*.{js,jsx,ts,tsx}'")
48
+ .option('--src <paths...>', "Filepath to directory containing the app's source code, by default ./src || ./app || ./pages || ./components")
51
49
  .option('--default-language, --default-locale <locale>', 'Default locale (e.g., en)')
52
50
  .option('--new, --locales <locales...>', 'Space-separated list of locales (e.g., en fr es)')
53
51
  .option('--inline', 'Include inline <T> tags in addition to dictionary file', true)
@@ -70,16 +68,13 @@ export class ReactCLI extends BaseCLI {
70
68
  .option('--version-id <id>', 'Version ID for the translation service')
71
69
  .option('--tsconfig, --jsconfig <path>', 'Path to jsconfig or tsconfig file', findFilepath(['./tsconfig.json', './jsconfig.json']))
72
70
  .option('--dictionary <path>', 'Path to dictionary file')
73
- .option('--src <paths...>', "Space-separated list of glob patterns containing the app's source code, by default 'src/**/*.{js,jsx,ts,tsx}' 'app/**/*.{js,jsx,ts,tsx}' 'pages/**/*.{js,jsx,ts,tsx}' 'components/**/*.{js,jsx,ts,tsx}'")
71
+ .option('--src <paths...>', "Filepath to directory containing the app's source code, by default ./src || ./app || ./pages || ./components")
74
72
  .option('--default-language, --default-locale <locale>', 'Default locale (e.g., en)')
75
73
  .option('--new, --locales <locales...>', 'Space-separated list of locales (e.g., en fr es)')
76
74
  .option('--inline', 'Include inline <T> tags in addition to dictionary file', true)
77
75
  .option('--ignore-errors', 'Ignore errors encountered while scanning for <T> tags', false)
78
76
  .option('--dry-run', 'Dry run, does not send updates to General Translation API', false)
79
77
  .option('--timeout <seconds>', 'Timeout in seconds for waiting for updates to be deployed to the CDN', DEFAULT_TIMEOUT.toString())
80
- .option('--experimental-localize-static-urls', 'Triggering this will run a script after the cli tool that localizes all urls in content files. Currently only supported for md and mdx files.', false)
81
- .option('--experimental-hide-default-locale', 'When localizing static locales, hide the default locale from the path', false)
82
- .option('--experimental-flatten-json-files', 'Triggering this will flatten the json files into a single file. This is useful for projects that have a lot of json files.', false)
83
78
  .action(async (options) => {
84
79
  displayHeader('Translating project...');
85
80
  await this.handleTranslate(options);
@@ -93,7 +88,7 @@ export class ReactCLI extends BaseCLI {
93
88
  .option('-c, --config <path>', 'Filepath to config file, by default gt.config.json', findFilepath(['gt.config.json']))
94
89
  .option('--tsconfig, --jsconfig <path>', 'Path to jsconfig or tsconfig file', findFilepath(['./tsconfig.json', './jsconfig.json']))
95
90
  .option('--dictionary <path>', 'Path to dictionary file')
96
- .option('--src <paths...>', "Space-separated list of glob patterns containing the app's source code, by default 'src/**/*.{js,jsx,ts,tsx}' 'app/**/*.{js,jsx,ts,tsx}' 'pages/**/*.{js,jsx,ts,tsx}' 'components/**/*.{js,jsx,ts,tsx}'")
91
+ .option('--src <paths...>', "Filepath to directory containing the app's source code, by default ./src || ./app || ./pages || ./components")
97
92
  .option('--inline', 'Include inline <T> tags in addition to dictionary file', true)
98
93
  .action(async (options) => {
99
94
  // intro here since we don't want to show the ascii title
@@ -106,7 +101,7 @@ export class ReactCLI extends BaseCLI {
106
101
  this.program
107
102
  .command('generate')
108
103
  .description('Generate a translation file for the source locale. The -t flag must be provided. This command should be used if you are handling your own translations.')
109
- .option('--src <paths...>', "Space-separated list of glob patterns containing the app's source code, by default 'src/**/*.{js,jsx,ts,tsx}' 'app/**/*.{js,jsx,ts,tsx}' 'pages/**/*.{js,jsx,ts,tsx}' 'components/**/*.{js,jsx,ts,tsx}'")
104
+ .option('--src <paths...>', "Filepath to directory containing the app's source code, by default ./src || ./app || ./pages || ./components")
110
105
  .option('--tsconfig, --jsconfig <path>', 'Path to jsconfig or tsconfig file', findFilepath(['./tsconfig.json', './jsconfig.json']))
111
106
  .option('--dictionary <path>', 'Path to dictionary file')
112
107
  .option('--default-language, --default-locale <locale>', 'Source locale (e.g., en)')
@@ -123,7 +118,7 @@ export class ReactCLI extends BaseCLI {
123
118
  this.program
124
119
  .command('scan')
125
120
  .description('Scans the project and wraps all JSX elements in the src directory with a <T> tag, with unique ids')
126
- .option('--src <paths...>', "Space-separated list of glob patterns containing the app's source code, by default 'src/**/*.{js,jsx,ts,tsx}' 'app/**/*.{js,jsx,ts,tsx}' 'pages/**/*.{js,jsx,ts,tsx}' 'components/**/*.{js,jsx,ts,tsx}'")
121
+ .option('--src <paths...>', "Filepath to directory containing the app's source code, by default ./src || ./app || ./pages || ./components", findFilepaths(['./src', './app', './pages', './components']))
127
122
  .option('-c, --config <path>', 'Filepath to config file, by default gt.config.json', findFilepath(['gt.config.json']))
128
123
  .option('--disable-ids', 'Disable id generation for the <T> tags', false)
129
124
  .option('--disable-formatting', 'Disable formatting of edited files', false)
@@ -158,7 +153,7 @@ export class ReactCLI extends BaseCLI {
158
153
  .join('\n')));
159
154
  }
160
155
  else {
161
- logErrorAndExit(chalk.red(`CLI tool encountered errors while scanning for translatable content. ${chalk.gray('To ignore these errors, re-run with --ignore-errors')}\n` +
156
+ logErrorAndExit(chalk.red(`CLI tool encountered errors while scanning for translatable content. ${chalk.dim('To ignore these errors, re-run with --ignore-errors')}\n` +
162
157
  errors
163
158
  .map((error) => chalk.red('• Error: ') + chalk.white(error))
164
159
  .join('\n')));
@@ -267,7 +262,7 @@ export class ReactCLI extends BaseCLI {
267
262
  await super.handleGenericTranslate(options);
268
263
  // If the base class's handleTranslate completes successfully, continue with ReactCLI-specific code
269
264
  }
270
- catch {
265
+ catch (error) {
271
266
  // Continue with ReactCLI-specific code even if base handleTranslate failed
272
267
  }
273
268
  if (!settings.stageTranslations) {
@@ -285,14 +280,6 @@ export class ReactCLI extends BaseCLI {
285
280
  }
286
281
  await translate(options, settings._versionId);
287
282
  }
288
- // Localize static urls (/docs -> /[locale]/docs)
289
- if (options.experimentalLocalizeStaticUrls) {
290
- await localizeStaticUrls(options);
291
- }
292
- // Flatten json files into a single file
293
- if (options.experimentalFlattenJsonFiles) {
294
- await flattenJsonFiles(options);
295
- }
296
283
  }
297
284
  async handleValidate(initOptions) {
298
285
  validateConfigExists();
@@ -1,5 +1,4 @@
1
1
  import { Settings } from '../types/index.js';
2
- export declare const DEFAULT_SRC_PATTERNS: string[];
3
2
  /**
4
3
  * Generates settings from any
5
4
  * @param options - The options to generate settings from
@@ -1,21 +1,14 @@
1
- import { displayProjectId, logErrorAndExit, warnApiKeyInConfig, } from '../console/logging.js';
2
- import { loadConfig } from '../fs/config/loadConfig.js';
1
+ import { displayProjectId, warnApiKeyInConfig } from '../console/logging.js';
2
+ import loadConfig from '../fs/config/loadConfig.js';
3
3
  import { defaultBaseUrl, libraryDefaultLocale, } from 'generaltranslation/internal';
4
4
  import fs from 'node:fs';
5
5
  import { createOrUpdateConfig } from '../fs/config/setupConfig.js';
6
6
  import { resolveFiles } from '../fs/config/parseFilesConfig.js';
7
+ import { findFilepaths } from '../fs/findFilepath.js';
7
8
  import { validateSettings } from './validateSettings.js';
8
9
  import { GT_DASHBOARD_URL } from '../utils/constants.js';
9
10
  import { resolveProjectId } from '../fs/utils.js';
10
11
  import path from 'node:path';
11
- import chalk from 'chalk';
12
- import { resolveConfig } from './resolveConfig.js';
13
- export const DEFAULT_SRC_PATTERNS = [
14
- 'src/**/*.{js,jsx,ts,tsx}',
15
- 'app/**/*.{js,jsx,ts,tsx}',
16
- 'pages/**/*.{js,jsx,ts,tsx}',
17
- 'components/**/*.{js,jsx,ts,tsx}',
18
- ];
19
12
  /**
20
13
  * Generates settings from any
21
14
  * @param options - The options to generate settings from
@@ -31,33 +24,23 @@ export async function generateSettings(options, cwd = process.cwd()) {
31
24
  if (options.config) {
32
25
  gtConfig = loadConfig(options.config);
33
26
  }
27
+ else if (fs.existsSync(path.join(cwd, 'gt.config.json'))) {
28
+ options.config = path.join(cwd, 'gt.config.json');
29
+ gtConfig = loadConfig(options.config);
30
+ }
31
+ else if (fs.existsSync(path.join(cwd, 'src/gt.config.json'))) {
32
+ options.config = path.join(cwd, 'src/gt.config.json');
33
+ gtConfig = loadConfig(options.config);
34
+ }
34
35
  else {
35
- const config = resolveConfig(cwd);
36
- if (config) {
37
- gtConfig = config.config;
38
- options.config = config.path;
39
- }
40
- else {
41
- gtConfig = {};
42
- }
36
+ // If neither config exists, use empty config
37
+ gtConfig = {};
43
38
  }
44
39
  // Warn if apiKey is present in gt.config.json
45
40
  if (gtConfig.apiKey) {
46
41
  warnApiKeyInConfig(options.config);
47
42
  process.exit(1);
48
43
  }
49
- const projectIdEnv = resolveProjectId();
50
- // Resolve mismatched projectIds
51
- if (gtConfig.projectId &&
52
- options.projectId &&
53
- gtConfig.projectId !== options.projectId) {
54
- logErrorAndExit(`Project ID mismatch between ${chalk.green(gtConfig.projectId)} and ${chalk.green(options.projectId)}! Please use the same projectId in all configs.`);
55
- }
56
- else if (gtConfig.projectId &&
57
- projectIdEnv &&
58
- gtConfig.projectId !== projectIdEnv) {
59
- logErrorAndExit(`Project ID mismatch between ${chalk.green(gtConfig.projectId)} and ${chalk.green(projectIdEnv)}! Please use the same projectId in all configs.`);
60
- }
61
44
  // merge options
62
45
  const mergedOptions = { ...gtConfig, ...options };
63
46
  // merge locales
@@ -85,7 +68,14 @@ export async function generateSettings(options, cwd = process.cwd()) {
85
68
  // For human review, always stage the project
86
69
  mergedOptions.stageTranslations = mergedOptions.stageTranslations ?? false;
87
70
  // Populate src if not provided
88
- mergedOptions.src = mergedOptions.src || DEFAULT_SRC_PATTERNS;
71
+ mergedOptions.src =
72
+ mergedOptions.src ||
73
+ findFilepaths([
74
+ path.join(cwd, './src'),
75
+ path.join(cwd, './app'),
76
+ path.join(cwd, './pages'),
77
+ path.join(cwd, './components'),
78
+ ]);
89
79
  // Resolve all glob patterns in the files object
90
80
  mergedOptions.files = mergedOptions.files
91
81
  ? resolveFiles(mergedOptions.files, mergedOptions.defaultLocale, cwd)
@@ -13,7 +13,8 @@ export declare const noLocalesError = "No locales found! Please provide a list o
13
13
  export declare const noDefaultLocaleError = "No default locale found! Please provide a default locale, or specify it in your gt.config.json file.";
14
14
  export declare const noFilesError = "Incorrect or missing files configuration! Please make sure your files are configured correctly in your gt.config.json file.";
15
15
  export declare const noSourceFileError = "No source file found! Please double check your translations directory and default locale.";
16
- export declare const noSupportedFormatError = "Unsupported data format! Please make sure your translationsDir parameter ends with a supported file extension.";
16
+ export declare const noDataFormatError = "No data format found! Please make sure your translationsDir parameter ends with a supported file extension.";
17
+ export declare const noSupportedDataFormatError = "Unsupported data format! Please make sure your translationsDir parameter ends with a supported file extension.";
17
18
  export declare const noApiKeyError = "No API key found! Please provide an API key using the --api-key flag or set the GT_API_KEY environment variable.";
18
19
  export declare const devApiKeyError = "You are using a development API key. Please use a production API key to use the General Translation API.\nYou can generate a production API key with the command: npx gtx-cli auth -t production";
19
20
  export declare const noProjectIdError = "No project ID found! Please provide a project ID using the --project-id flag, specify it in your gt.config.json file, or set the GT_PROJECT_ID environment variable.";
@@ -16,7 +16,8 @@ export const noLocalesError = `No locales found! Please provide a list of locale
16
16
  export const noDefaultLocaleError = `No default locale found! Please provide a default locale, or specify it in your gt.config.json file.`;
17
17
  export const noFilesError = `Incorrect or missing files configuration! Please make sure your files are configured correctly in your gt.config.json file.`;
18
18
  export const noSourceFileError = `No source file found! Please double check your translations directory and default locale.`;
19
- export const noSupportedFormatError = `Unsupported data format! Please make sure your translationsDir parameter ends with a supported file extension.`;
19
+ export const noDataFormatError = `No data format found! Please make sure your translationsDir parameter ends with a supported file extension.`;
20
+ export const noSupportedDataFormatError = `Unsupported data format! Please make sure your translationsDir parameter ends with a supported file extension.`;
20
21
  export const noApiKeyError = `No API key found! Please provide an API key using the --api-key flag or set the GT_API_KEY environment variable.`;
21
22
  export const devApiKeyError = `You are using a development API key. Please use a production API key to use the General Translation API.\nYou can generate a production API key with the command: npx gtx-cli auth -t production`;
22
23
  export const noProjectIdError = `No project ID found! Please provide a project ID using the --project-id flag, specify it in your gt.config.json file, or set the GT_PROJECT_ID environment variable.`;
@@ -1,5 +1,5 @@
1
1
  export declare const SUPPORTED_FILE_EXTENSIONS: readonly ["json", "mdx", "md", "ts", "js"];
2
- export declare const FILE_EXT_TO_EXT_LABEL: {
2
+ export declare const FILE_EXT_TO_FORMAT: {
3
3
  json: string;
4
4
  mdx: string;
5
5
  md: string;
@@ -5,7 +5,7 @@ export const SUPPORTED_FILE_EXTENSIONS = [
5
5
  'ts',
6
6
  'js',
7
7
  ];
8
- export const FILE_EXT_TO_EXT_LABEL = {
8
+ export const FILE_EXT_TO_FORMAT = {
9
9
  json: 'JSON',
10
10
  mdx: 'MDX',
11
11
  md: 'Markdown',
@@ -6,12 +6,9 @@ import { TranslateOptions } from '../../cli/base.js';
6
6
  * @param filePaths - Resolved file paths for different file types
7
7
  * @param placeholderPaths - Placeholder paths for translated files
8
8
  * @param transformPaths - Transform paths for file naming
9
+ * @param fileFormat - Format of the files
9
10
  * @param dataFormat - Format of the data within the files
10
11
  * @param options - Translation options including API settings
11
12
  * @returns Promise that resolves when translation is complete
12
13
  */
13
14
  export declare function translateFiles(filePaths: ResolvedFiles, placeholderPaths: ResolvedFiles, transformPaths: TransformFiles, dataFormat: DataFormat | undefined, options: Settings & TranslateOptions): Promise<void>;
14
- /**
15
- * Creates a mapping between source files and their translated counterparts for each locale
16
- */
17
- export declare function createFileMapping(filePaths: ResolvedFiles, placeholderPaths: ResolvedFiles, transformPaths: TransformFiles, locales: string[]): Record<string, Record<string, string>>;
@@ -1,6 +1,6 @@
1
1
  import { checkFileTranslations } from '../../api/checkFileTranslations.js';
2
2
  import { sendFiles } from '../../api/sendFiles.js';
3
- import { noSupportedFormatError, noLocalesError, noDefaultLocaleError, noApiKeyError, noProjectIdError, devApiKeyError, } from '../../console/index.js';
3
+ import { noSupportedDataFormatError, noLocalesError, noDefaultLocaleError, noApiKeyError, noProjectIdError, devApiKeyError, } from '../../console/index.js';
4
4
  import { logErrorAndExit, createSpinner, logError, logSuccess, } from '../../console/logging.js';
5
5
  import { resolveLocaleFiles } from '../../fs/config/parseFilesConfig.js';
6
6
  import { getRelative, readFile } from '../../fs/findFilepath.js';
@@ -10,13 +10,13 @@ import chalk from 'chalk';
10
10
  import { downloadFile } from '../../api/downloadFile.js';
11
11
  import { downloadFileBatch } from '../../api/downloadFileBatch.js';
12
12
  import { SUPPORTED_FILE_EXTENSIONS } from './supportedFiles.js';
13
- import sanitizeFileContent from '../../utils/sanitizeFileContent.js';
14
13
  const SUPPORTED_DATA_FORMATS = ['JSX', 'ICU', 'I18NEXT'];
15
14
  /**
16
15
  * Sends multiple files to the API for translation
17
16
  * @param filePaths - Resolved file paths for different file types
18
17
  * @param placeholderPaths - Placeholder paths for translated files
19
18
  * @param transformPaths - Transform paths for file naming
19
+ * @param fileFormat - Format of the files
20
20
  * @param dataFormat - Format of the data within the files
21
21
  * @param options - Translation options including API settings
22
22
  * @returns Promise that resolves when translation is complete
@@ -27,7 +27,7 @@ export async function translateFiles(filePaths, placeholderPaths, transformPaths
27
27
  // Process JSON files
28
28
  if (filePaths.json) {
29
29
  if (!SUPPORTED_DATA_FORMATS.includes(dataFormat)) {
30
- logErrorAndExit(noSupportedFormatError);
30
+ logErrorAndExit(noSupportedDataFormatError);
31
31
  }
32
32
  const jsonFiles = filePaths.json.map((filePath) => {
33
33
  const content = readFile(filePath);
@@ -38,7 +38,7 @@ export async function translateFiles(filePaths, placeholderPaths, transformPaths
38
38
  return {
39
39
  content,
40
40
  fileName: relativePath,
41
- fileExtension: 'JSON',
41
+ fileFormat: 'JSON',
42
42
  dataFormat,
43
43
  };
44
44
  });
@@ -50,12 +50,11 @@ export async function translateFiles(filePaths, placeholderPaths, transformPaths
50
50
  if (filePaths[fileType]) {
51
51
  const files = filePaths[fileType].map((filePath) => {
52
52
  const content = readFile(filePath);
53
- const sanitizedContent = sanitizeFileContent(content);
54
53
  const relativePath = getRelative(filePath);
55
54
  return {
56
- content: sanitizedContent,
55
+ content,
57
56
  fileName: relativePath,
58
- fileExtension: fileType.toUpperCase(),
57
+ fileFormat: fileType.toUpperCase(),
59
58
  dataFormat,
60
59
  };
61
60
  });
@@ -110,7 +109,7 @@ export async function translateFiles(filePaths, placeholderPaths, transformPaths
110
109
  /**
111
110
  * Creates a mapping between source files and their translated counterparts for each locale
112
111
  */
113
- export function createFileMapping(filePaths, placeholderPaths, transformPaths, locales) {
112
+ function createFileMapping(filePaths, placeholderPaths, transformPaths, locales) {
114
113
  const fileMapping = {};
115
114
  for (const locale of locales) {
116
115
  const translatedPaths = resolveLocaleFiles(placeholderPaths, locale);
@@ -1 +1 @@
1
- export declare function loadConfig(filepath: string): Record<string, any>;
1
+ export default function loadConfig(filepath: string): Record<string, any>;
@@ -1,5 +1,5 @@
1
1
  import fs from 'node:fs';
2
- export function loadConfig(filepath) {
2
+ export default function loadConfig(filepath) {
3
3
  try {
4
4
  return JSON.parse(fs.readFileSync(filepath, 'utf-8'));
5
5
  }
@@ -92,30 +92,29 @@ function expandGlobPatterns(cwd, includePatterns, excludePatterns, locale, trans
92
92
  resolvedPaths.push(...matches);
93
93
  // For each match, create a version with [locale] in the correct positions
94
94
  matches.forEach((match) => {
95
- // Convert to absolute path to make replacement easier
96
- const absolutePath = path.resolve(cwd, match);
97
- const patternPath = path.resolve(cwd, pattern);
98
- let originalAbsolutePath = absolutePath;
95
+ // Convert to relative path to make replacement easier
96
+ const relativePath = path.relative(cwd, match);
97
+ let originalRelativePath = relativePath;
98
+ // Replace locale with [locale] at each tracked position
99
99
  if (localePositions.length > 0) {
100
- // Replace all instances of [locale]
100
+ // We need to account for path resolution differences
101
+ // This is a simplified approach - we'll replace all instances of the locale
101
102
  // but only in path segments where we expect it based on the original pattern
102
- const pathParts = absolutePath.split(path.sep);
103
- const patternParts = patternPath.split(path.sep);
103
+ const pathParts = relativePath.split(path.sep);
104
+ const patternParts = pattern.split(/[\/\\]/); // Handle both slash types
104
105
  for (let i = 0; i < pathParts.length; i++) {
105
106
  if (i < patternParts.length) {
106
107
  if (patternParts[i].includes(localeTag)) {
107
108
  // This segment should have the locale replaced
108
- // Create regex from pattern to match the actual path structure
109
- const regexPattern = patternParts[i].replace(/\[locale\]/g, `(${locale.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})`);
110
- const regex = new RegExp(regexPattern);
111
- pathParts[i] = pathParts[i].replace(regex, patternParts[i].replace(/\[locale\]/g, localeTag));
109
+ pathParts[i] = pathParts[i].replace(locale, localeTag);
112
110
  }
113
111
  }
114
112
  }
115
- originalAbsolutePath = pathParts.join(path.sep);
113
+ originalRelativePath = pathParts.join(path.sep);
116
114
  }
117
115
  // Convert back to absolute path
118
- placeholderPaths.push(originalAbsolutePath);
116
+ const originalPath = path.resolve(cwd, originalRelativePath);
117
+ placeholderPaths.push(originalPath);
119
118
  });
120
119
  }
121
120
  return { resolvedPaths, placeholderPaths };
@@ -12,5 +12,4 @@ export declare function createOrUpdateConfig(configFilepath: string, options: {
12
12
  locales?: string[];
13
13
  files?: FilesOptions;
14
14
  framework?: SupportedFrameworks;
15
- baseUrl?: string;
16
15
  }): Promise<string>;
@@ -15,7 +15,6 @@ export async function createOrUpdateConfig(configFilepath, options) {
15
15
  ...(options.defaultLocale && { defaultLocale: options.defaultLocale }),
16
16
  ...(options.files && { files: options.files }),
17
17
  ...(options.framework && { framework: options.framework }),
18
- ...(options.baseUrl && { baseUrl: options.baseUrl }),
19
18
  };
20
19
  try {
21
20
  // if file exists
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Recursively scan the directory and collect all files with the specified extensions,
3
+ * excluding files or directories that start with a dot (.)
4
+ * @param dir - The directory to scan
5
+ * @returns An array of file paths
6
+ */
7
+ export declare function getFiles(dir: string): string[];
@@ -0,0 +1,30 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ // Define the file extensions to look for
4
+ const extensions = ['.js', '.jsx', '.tsx'];
5
+ /**
6
+ * Recursively scan the directory and collect all files with the specified extensions,
7
+ * excluding files or directories that start with a dot (.)
8
+ * @param dir - The directory to scan
9
+ * @returns An array of file paths
10
+ */
11
+ export function getFiles(dir) {
12
+ let files = [];
13
+ const items = fs.readdirSync(dir);
14
+ for (const item of items) {
15
+ // Skip hidden files and directories
16
+ if (item.startsWith('.'))
17
+ continue;
18
+ const fullPath = path.join(dir, item);
19
+ const stat = fs.statSync(fullPath);
20
+ if (stat.isDirectory()) {
21
+ // Recursively scan subdirectories
22
+ files = files.concat(getFiles(fullPath));
23
+ }
24
+ else if (extensions.includes(path.extname(item))) {
25
+ // Add files with the specified extensions
26
+ files.push(fullPath);
27
+ }
28
+ }
29
+ return files;
30
+ }
@@ -6,13 +6,12 @@ import generateModule from '@babel/generator';
6
6
  // Handle CommonJS/ESM interop
7
7
  const traverse = traverseModule.default || traverseModule;
8
8
  const generate = generateModule.default || generateModule;
9
+ import { getFiles } from '../../fs/findJsxFilepath.js';
9
10
  import { isMeaningful } from '../../react/jsx/evaluateJsx.js';
10
11
  import { handleJsxElement } from '../../react/jsx/wrapJsx.js';
11
12
  import { getRelativePath } from '../../fs/findFilepath.js';
12
13
  import { isHtmlElement, isBodyElement, hasGTProviderChild, addDynamicLangAttribute, makeParentFunctionAsync, } from '../jsx/utils.js';
13
14
  import { generateImportMap, createImports, } from '../../react/jsx/utils/parseAst.js';
14
- import { matchFiles } from '../../fs/matchFiles.js';
15
- import { DEFAULT_SRC_PATTERNS } from '../../config/generateSettings.js';
16
15
  const IMPORT_MAP = {
17
16
  T: { name: 'T', source: 'gt-next' },
18
17
  Var: { name: 'Var', source: 'gt-next' },
@@ -29,12 +28,13 @@ const IMPORT_MAP = {
29
28
  * @returns An object containing the updates and errors
30
29
  */
31
30
  export async function wrapContentNext(options, pkg, errors, warnings) {
32
- const files = matchFiles(process.cwd(), options.src || DEFAULT_SRC_PATTERNS);
31
+ const srcDirectory = options.src || ['./'];
32
+ const files = srcDirectory.flatMap((dir) => getFiles(dir));
33
33
  const filesUpdated = [];
34
34
  for (const file of files) {
35
35
  const code = await fs.promises.readFile(file, 'utf8');
36
36
  // Create relative path from src directory and remove extension
37
- const relativePath = getRelativePath(file, process.cwd());
37
+ const relativePath = getRelativePath(file, srcDirectory[0]);
38
38
  let ast;
39
39
  try {
40
40
  ast = parse(code, {
@@ -1,8 +1 @@
1
- import { JsxChildren } from 'generaltranslation/types';
2
- /**
3
- * Add GT Identifier and minify the tree (recreates addGTIdentifier and writeChildrenAsObjects)
4
- * @param tree - The tree to add GT identifiers to
5
- * @param startingIndex - The starting index for GT IDs
6
- * @returns The tree with GT identifiers added
7
- */
8
- export default function addGTIdentifierToSyntaxTree(tree: any, startingIndex?: number): JsxChildren;
1
+ export default function addGTIdentifierToSyntaxTree(tree: any, startingIndex?: number): any;