gtx-cli 2.1.13 → 2.1.15

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 CHANGED
@@ -1,5 +1,20 @@
1
1
  # gtx-cli
2
2
 
3
+ ## 2.1.15
4
+
5
+ ### Patch Changes
6
+
7
+ - [#622](https://github.com/generaltranslation/gt/pull/622) [`f5f888d`](https://github.com/generaltranslation/gt/commit/f5f888d79319ac79f3cde12588d1e24ec2003b25) Thanks [@fernando-aviles](https://github.com/fernando-aviles)! - Skipping invalid (cannot be parsed by AST) MDX files when generating translations
8
+
9
+ ## 2.1.14
10
+
11
+ ### Patch Changes
12
+
13
+ - [#623](https://github.com/generaltranslation/gt/pull/623) [`288d2c6`](https://github.com/generaltranslation/gt/commit/288d2c657ff46eb5f4a5cdbc76ecc3f9be85228f) Thanks [@ErnestM1234](https://github.com/ErnestM1234)! - feat: add --force flag for overwriting cached translations
14
+
15
+ - Updated dependencies [[`288d2c6`](https://github.com/generaltranslation/gt/commit/288d2c657ff46eb5f4a5cdbc76ecc3f9be85228f)]:
16
+ - generaltranslation@7.4.2
17
+
3
18
  ## 2.1.13
4
19
 
5
20
  ### Patch Changes
@@ -29,6 +29,7 @@ export async function sendFiles(files, options, settings) {
29
29
  targetLocales: settings.locales,
30
30
  version: settings.version, // not set ATM
31
31
  modelProvider: settings.modelProvider,
32
+ force: options?.force,
32
33
  });
33
34
  // Handle version ID response (for async processing)
34
35
  const { data, message, locales, translations } = responseData;
package/dist/cli/flags.js CHANGED
@@ -23,7 +23,8 @@ export function attachTranslateFlags(command) {
23
23
  .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)
24
24
  .option('--experimental-hide-default-locale', 'When localizing static locales, hide the default locale from the path', false)
25
25
  .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)
26
- .option('--experimental-localize-static-imports', 'Triggering this will run a script after the cli tool that localizes all static imports in content files. Currently only supported for md and mdx files.', false);
26
+ .option('--experimental-localize-static-imports', 'Triggering this will run a script after the cli tool that localizes all static imports in content files. Currently only supported for md and mdx files.', false)
27
+ .option('--force', 'Force a retranslation, invalidating all existing cached translations if they exist.', false);
27
28
  return command;
28
29
  }
29
30
  export function attachAdditionalReactTranslateFlags(command) {
@@ -1,10 +1,11 @@
1
- import { logError } from '../../console/logging.js';
1
+ import { logError, logWarning } from '../../console/logging.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';
5
5
  import { parseJson } from '../json/parseJson.js';
6
6
  import parseYaml from '../yaml/parseYaml.js';
7
7
  import { determineLibrary } from '../../fs/determineFramework.js';
8
+ import { isValidMdx } from '../../utils/validateMdx.js';
8
9
  export const SUPPORTED_DATA_FORMATS = ['JSX', 'ICU', 'I18NEXT'];
9
10
  export async function aggregateFiles(settings) {
10
11
  // Aggregate all files to translate
@@ -65,16 +66,26 @@ export async function aggregateFiles(settings) {
65
66
  if (fileType === 'json' || fileType === 'yaml')
66
67
  continue;
67
68
  if (filePaths[fileType]) {
68
- const files = filePaths[fileType].map((filePath) => {
69
+ const files = filePaths[fileType]
70
+ .map((filePath) => {
69
71
  const content = readFile(filePath);
70
- const sanitizedContent = sanitizeFileContent(content);
71
72
  const relativePath = getRelative(filePath);
73
+ if (fileType === 'mdx') {
74
+ const validation = isValidMdx(content, filePath);
75
+ if (!validation.isValid) {
76
+ const errorMsg = validation.error ? `: ${validation.error}` : '';
77
+ logWarning(`Skipping ${relativePath}: MDX file is not AST parsable${errorMsg}`);
78
+ return null;
79
+ }
80
+ }
81
+ const sanitizedContent = sanitizeFileContent(content);
72
82
  return {
73
83
  content: sanitizedContent,
74
84
  fileName: relativePath,
75
85
  fileFormat: fileType.toUpperCase(),
76
86
  };
77
- });
87
+ })
88
+ .filter((file) => file !== null);
78
89
  allFiles.push(...files);
79
90
  }
80
91
  }
@@ -16,6 +16,7 @@ export type Options = {
16
16
  suppressWarnings: boolean;
17
17
  dryRun: boolean;
18
18
  timeout: number;
19
+ force?: boolean;
19
20
  stageTranslations?: boolean;
20
21
  experimentalLocalizeStaticUrls?: boolean;
21
22
  experimentalHideDefaultLocale?: boolean;
@@ -38,6 +39,7 @@ export type TranslateFlags = {
38
39
  dryRun: boolean;
39
40
  stageTranslations?: boolean;
40
41
  publish?: boolean;
42
+ force?: boolean;
41
43
  experimentalLocalizeStaticUrls?: boolean;
42
44
  experimentalHideDefaultLocale?: boolean;
43
45
  experimentalFlattenJsonFiles?: boolean;
@@ -70,6 +70,10 @@ export default async function localizeStaticUrls(settings, targetLocales) {
70
70
  const targetFiles = Object.values(filesMap).filter((path) => path.endsWith('.md') || path.endsWith('.mdx'));
71
71
  // Replace the placeholder path with the target path
72
72
  await Promise.all(targetFiles.map(async (filePath) => {
73
+ // Check if file exists before processing
74
+ if (!fs.existsSync(filePath)) {
75
+ return;
76
+ }
73
77
  // Get file content
74
78
  const fileContent = await fs.promises.readFile(filePath, 'utf8');
75
79
  // Localize the file (handles both URLs and hrefs in single AST pass)
@@ -19,6 +19,10 @@ export default async function processAnchorIds(settings) {
19
19
  const translatedFiles = Object.values(filesMap).filter((path) => path && (path.endsWith('.md') || path.endsWith('.mdx')));
20
20
  for (const translatedPath of translatedFiles) {
21
21
  try {
22
+ // Check if translated file exists before processing
23
+ if (!fs.existsSync(translatedPath)) {
24
+ continue;
25
+ }
22
26
  // Find the corresponding source file
23
27
  const sourcePath = Object.keys(filesMap).find((key) => filesMap[key] === translatedPath);
24
28
  if (!sourcePath) {
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Validates if an MDX file content can be parsed as a valid AST
3
+ * @param content - The MDX file content to validate
4
+ * @param filePath - The file path for error reporting
5
+ * @returns object with isValid boolean and optional error message
6
+ */
7
+ export declare function isValidMdx(content: string, filePath: string): {
8
+ isValid: boolean;
9
+ error?: string;
10
+ };
@@ -0,0 +1,25 @@
1
+ import { unified } from 'unified';
2
+ import remarkParse from 'remark-parse';
3
+ import remarkMdx from 'remark-mdx';
4
+ import remarkFrontmatter from 'remark-frontmatter';
5
+ /**
6
+ * Validates if an MDX file content can be parsed as a valid AST
7
+ * @param content - The MDX file content to validate
8
+ * @param filePath - The file path for error reporting
9
+ * @returns object with isValid boolean and optional error message
10
+ */
11
+ export function isValidMdx(content, filePath) {
12
+ try {
13
+ const parseProcessor = unified()
14
+ .use(remarkParse)
15
+ .use(remarkFrontmatter, ['yaml', 'toml'])
16
+ .use(remarkMdx);
17
+ const ast = parseProcessor.parse(content);
18
+ parseProcessor.runSync(ast);
19
+ return { isValid: true };
20
+ }
21
+ catch (error) {
22
+ const errorMessage = error instanceof Error ? error.message : String(error);
23
+ return { isValid: false, error: errorMessage };
24
+ }
25
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gtx-cli",
3
- "version": "2.1.13",
3
+ "version": "2.1.15",
4
4
  "main": "dist/index.js",
5
5
  "bin": "dist/main.js",
6
6
  "files": [
@@ -87,7 +87,7 @@
87
87
  "esbuild": "^0.25.4",
88
88
  "fast-glob": "^3.3.3",
89
89
  "form-data": "^4.0.4",
90
- "generaltranslation": "^7.4.1",
90
+ "generaltranslation": "^7.4.2",
91
91
  "json-pointer": "^0.6.2",
92
92
  "jsonpath-plus": "^10.3.0",
93
93
  "jsonpointer": "^5.0.1",