gtx-cli 2.1.16 → 2.1.18

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,17 @@
1
1
  # gtx-cli
2
2
 
3
+ ## 2.1.18
4
+
5
+ ### Patch Changes
6
+
7
+ - [#637](https://github.com/generaltranslation/gt/pull/637) [`9c40a3c`](https://github.com/generaltranslation/gt/commit/9c40a3c729bf690381959679078c11c9c29bcdf2) Thanks [@fernando-aviles](https://github.com/fernando-aviles)! - Skipping over empty files when sending for translation
8
+
9
+ ## 2.1.17
10
+
11
+ ### Patch Changes
12
+
13
+ - [#635](https://github.com/generaltranslation/gt/pull/635) [`10aa051`](https://github.com/generaltranslation/gt/commit/10aa051592cea43f772615da200c8615d4dd1a78) Thanks [@brian-lou](https://github.com/brian-lou)! - Create dictionary with uuid to reduce flakiness
14
+
3
15
  ## 2.1.16
4
16
 
5
17
  ### Patch Changes
@@ -35,30 +35,46 @@ export async function aggregateFiles(settings) {
35
35
  else {
36
36
  dataFormat = 'JSX';
37
37
  }
38
- const jsonFiles = filePaths.json.map((filePath) => {
38
+ const jsonFiles = filePaths.json
39
+ .map((filePath) => {
39
40
  const content = readFile(filePath);
40
- const parsedJson = parseJson(content, filePath, settings.options || {}, settings.defaultLocale);
41
41
  const relativePath = getRelative(filePath);
42
+ const parsedJson = parseJson(content, filePath, settings.options || {}, settings.defaultLocale);
42
43
  return {
43
44
  content: parsedJson,
44
45
  fileName: relativePath,
45
46
  fileFormat: 'JSON',
46
47
  dataFormat,
47
48
  };
49
+ })
50
+ .filter((file) => {
51
+ if (!file || typeof file.content !== 'string' || !file.content.trim()) {
52
+ logWarning(`Skipping ${file?.fileName ?? 'unknown'}: JSON file is empty`);
53
+ return false;
54
+ }
55
+ return true;
48
56
  });
49
57
  allFiles.push(...jsonFiles);
50
58
  }
51
59
  // Process YAML files
52
60
  if (filePaths.yaml) {
53
- const yamlFiles = filePaths.yaml.map((filePath) => {
61
+ const yamlFiles = filePaths.yaml
62
+ .map((filePath) => {
54
63
  const content = readFile(filePath);
55
- const { content: parsedYaml, fileFormat } = parseYaml(content, filePath, settings.options || {});
56
64
  const relativePath = getRelative(filePath);
65
+ const { content: parsedYaml, fileFormat } = parseYaml(content, filePath, settings.options || {});
57
66
  return {
58
67
  content: parsedYaml,
59
68
  fileName: relativePath,
60
69
  fileFormat,
61
70
  };
71
+ })
72
+ .filter((file) => {
73
+ if (!file || typeof file.content !== 'string' || !file.content.trim()) {
74
+ logWarning(`Skipping ${file?.fileName ?? 'unknown'}: YAML file is empty`);
75
+ return false;
76
+ }
77
+ return true;
62
78
  });
63
79
  allFiles.push(...yamlFiles);
64
80
  }
@@ -73,8 +89,7 @@ export async function aggregateFiles(settings) {
73
89
  if (fileType === 'mdx') {
74
90
  const validation = isValidMdx(content, filePath);
75
91
  if (!validation.isValid) {
76
- const errorMsg = validation.error ? `: ${validation.error}` : '';
77
- logWarning(`Skipping ${relativePath}: MDX file is not AST parsable${errorMsg}`);
92
+ logWarning(`Skipping ${relativePath}: MDX file is not AST parsable${validation.error ? `: ${validation.error}` : ''}`);
78
93
  return null;
79
94
  }
80
95
  }
@@ -85,7 +100,15 @@ export async function aggregateFiles(settings) {
85
100
  fileFormat: fileType.toUpperCase(),
86
101
  };
87
102
  })
88
- .filter((file) => file !== null);
103
+ .filter((file) => {
104
+ if (!file ||
105
+ typeof file.content !== 'string' ||
106
+ !file.content.trim()) {
107
+ logWarning(`Skipping ${file?.fileName ?? 'unknown'}: File is empty after sanitization`);
108
+ return false;
109
+ }
110
+ return true;
111
+ });
89
112
  allFiles.push(...files);
90
113
  }
91
114
  }
@@ -7,6 +7,7 @@ import loadJSON from '../../fs/loadJSON.js';
7
7
  import { hashSource } from 'generaltranslation/id';
8
8
  import getEntryAndMetadata from '../utils/getEntryAndMetadata.js';
9
9
  import { logError } from '../../console/logging.js';
10
+ import { randomUUID } from 'node:crypto';
10
11
  export async function createDictionaryUpdates(dictionaryPath, esbuildConfig) {
11
12
  let dictionary;
12
13
  // ---- HANDLE JSON STRING DICTIONARY ----- //
@@ -21,7 +22,7 @@ export async function createDictionaryUpdates(dictionaryPath, esbuildConfig) {
21
22
  write: false,
22
23
  });
23
24
  const bundledCode = result.outputFiles[0].text;
24
- const tempFilePath = path.join(os.tmpdir(), 'bundled-dictionary.js');
25
+ const tempFilePath = path.join(os.tmpdir(), `bundled-dictionary-${randomUUID()}.js`);
25
26
  await fs.promises.writeFile(tempFilePath, bundledCode);
26
27
  // Load the module using dynamic import
27
28
  let dictionaryModule;
@@ -8,17 +8,6 @@ import remarkMdx from 'remark-mdx';
8
8
  import remarkFrontmatter from 'remark-frontmatter';
9
9
  import { visit } from 'unist-util-visit';
10
10
  const { isMatch } = micromatch;
11
- /**
12
- * Checks if a file exists at the given path
13
- */
14
- function fileExists(filePath) {
15
- try {
16
- return fs.existsSync(filePath);
17
- }
18
- catch {
19
- return false;
20
- }
21
- }
22
11
  /**
23
12
  * Localizes static imports in content files.
24
13
  * Currently only supported for md and mdx files. (/docs/ -> /[locale]/docs/)
@@ -55,6 +44,10 @@ export default async function localizeStaticImports(settings) {
55
44
  }
56
45
  if (defaultLocaleFiles.length > 0) {
57
46
  const defaultPromise = Promise.all(defaultLocaleFiles.map(async (filePath) => {
47
+ // Check if file exists before processing
48
+ if (!fs.existsSync(filePath)) {
49
+ return;
50
+ }
58
51
  // Get file content
59
52
  const fileContent = await fs.promises.readFile(filePath, 'utf8');
60
53
  // Localize the file using default locale
@@ -72,6 +65,10 @@ export default async function localizeStaticImports(settings) {
72
65
  const targetFiles = Object.values(filesMap).filter((path) => path.endsWith('.md') || path.endsWith('.mdx'));
73
66
  // Replace the placeholder path with the target path
74
67
  await Promise.all(targetFiles.map(async (filePath) => {
68
+ // Check if file exists before processing
69
+ if (!fs.existsSync(filePath)) {
70
+ return;
71
+ }
75
72
  // Get file content
76
73
  const fileContent = await fs.promises.readFile(filePath, 'utf8');
77
74
  // Localize the file
@@ -211,8 +208,7 @@ function transformImportPath(fullPath, patternHead, targetLocale, defaultLocale,
211
208
  const currentDir = path.dirname(currentFilePath);
212
209
  resolvedPath = path.resolve(currentDir, newPath);
213
210
  }
214
- const pathExists = fileExists(resolvedPath);
215
- if (!pathExists) {
211
+ if (!fs.existsSync(resolvedPath)) {
216
212
  return null;
217
213
  }
218
214
  }
@@ -49,6 +49,10 @@ export default async function localizeStaticUrls(settings, targetLocales) {
49
49
  }
50
50
  if (defaultLocaleFiles.length > 0) {
51
51
  const defaultPromise = Promise.all(defaultLocaleFiles.map(async (filePath) => {
52
+ // Check if file exists before processing
53
+ if (!fs.existsSync(filePath)) {
54
+ return;
55
+ }
52
56
  // Get file content
53
57
  const fileContent = await fs.promises.readFile(filePath, 'utf8');
54
58
  // Localize the file using default locale
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gtx-cli",
3
- "version": "2.1.16",
3
+ "version": "2.1.18",
4
4
  "main": "dist/index.js",
5
5
  "bin": "dist/main.js",
6
6
  "files": [