gtx-cli 2.3.13 → 2.3.14

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,11 @@
1
1
  # gtx-cli
2
2
 
3
+ ## 2.3.14
4
+
5
+ ### Patch Changes
6
+
7
+ - [#739](https://github.com/generaltranslation/gt/pull/739) [`7afed0b`](https://github.com/generaltranslation/gt/commit/7afed0bda5be08d83bbe75cca9fb657ff5a50dae) Thanks [@fernando-aviles](https://github.com/fernando-aviles)! - Only post-process files downloaded by gtx-cli on current run
8
+
3
9
  ## 2.3.13
4
10
 
5
11
  ### Patch Changes
@@ -7,6 +7,7 @@ import { validateYamlSchema } from '../formats/yaml/utils.js';
7
7
  import { mergeJson } from '../formats/json/mergeJson.js';
8
8
  import mergeYaml from '../formats/yaml/mergeYaml.js';
9
9
  import { getDownloadedVersions, saveDownloadedVersions, } from '../fs/config/downloadedVersions.js';
10
+ import { recordDownloaded } from '../state/recentDownloads.js';
10
11
  /**
11
12
  * Downloads multiple translation files in a single batch request
12
13
  * @param files - Array of files to download with their output paths
@@ -97,6 +98,8 @@ export async function downloadFileBatch(files, options, maxRetries = 3, retryDel
97
98
  }
98
99
  // Write the file to disk
99
100
  await fs.promises.writeFile(outputPath, data);
101
+ // Track as downloaded
102
+ recordDownloaded(outputPath);
100
103
  result.successful.push(translationId);
101
104
  if (versionId) {
102
105
  downloadedVersions.entries[downloadedKey] = {
package/dist/cli/base.js CHANGED
@@ -17,6 +17,7 @@ import { upload } from '../formats/files/upload.js';
17
17
  import { attachTranslateFlags } from './flags.js';
18
18
  import { handleStage } from './commands/stage.js';
19
19
  import { handleDownload, handleTranslate, postProcessTranslations, } from './commands/translate.js';
20
+ import { getDownloaded, clearDownloaded } from '../state/recentDownloads.js';
20
21
  import updateConfig from '../fs/config/updateConfig.js';
21
22
  import { createLoadTranslationsFile } from '../fs/createLoadTranslationsFile.js';
22
23
  export class BaseCLI {
@@ -86,7 +87,12 @@ export class BaseCLI {
86
87
  else {
87
88
  await handleDownload(initOptions, settings);
88
89
  }
89
- await postProcessTranslations(settings);
90
+ // Only postprocess files downloaded in this run
91
+ const include = getDownloaded();
92
+ if (include.size > 0) {
93
+ await postProcessTranslations(settings, include);
94
+ }
95
+ clearDownloaded();
90
96
  }
91
97
  setupUploadCommand() {
92
98
  this.program
@@ -3,4 +3,4 @@ import { TranslateFlags } from '../../types/index.js';
3
3
  import { Settings } from '../../types/index.js';
4
4
  export declare function handleTranslate(options: TranslateFlags, settings: Settings, filesTranslationResponse: SendFilesResult | undefined): Promise<void>;
5
5
  export declare function handleDownload(options: TranslateFlags, settings: Settings): Promise<void>;
6
- export declare function postProcessTranslations(settings: Settings): Promise<void>;
6
+ export declare function postProcessTranslations(settings: Settings, includeFiles?: Set<string>): Promise<void>;
@@ -36,25 +36,25 @@ export async function handleDownload(options, settings) {
36
36
  await checkFileTranslations(stagedVersionData, settings.locales, options.timeout, (sourcePath, locale) => fileMapping[locale][sourcePath] ?? null, settings, false, // force is not applicable for downloading staged translations
37
37
  options.forceDownload);
38
38
  }
39
- export async function postProcessTranslations(settings) {
39
+ export async function postProcessTranslations(settings, includeFiles) {
40
40
  // Localize static urls (/docs -> /[locale]/docs) and preserve anchor IDs for non-default locales
41
41
  // Default locale is processed earlier in the flow in base.ts
42
42
  if (settings.options?.experimentalLocalizeStaticUrls) {
43
43
  const nonDefaultLocales = settings.locales.filter((locale) => locale !== settings.defaultLocale);
44
44
  if (nonDefaultLocales.length > 0) {
45
- await localizeStaticUrls(settings, nonDefaultLocales);
45
+ await localizeStaticUrls(settings, nonDefaultLocales, includeFiles);
46
46
  }
47
47
  // Add explicit anchor IDs to translated MDX/MD files to preserve navigation
48
48
  // Uses inline {#id} format by default, or div wrapping if experimentalAddHeaderAnchorIds is 'mintlify'
49
- await processAnchorIds(settings);
49
+ await processAnchorIds(settings, includeFiles);
50
50
  }
51
51
  // Localize static imports (import Snippet from /snippets/file.mdx -> import Snippet from /snippets/[locale]/file.mdx)
52
52
  if (settings.options?.experimentalLocalizeStaticImports) {
53
- await localizeStaticImports(settings);
53
+ await localizeStaticImports(settings, includeFiles);
54
54
  }
55
55
  // Flatten json files into a single file
56
56
  if (settings.options?.experimentalFlattenJsonFiles) {
57
- await flattenJsonFiles(settings);
57
+ await flattenJsonFiles(settings, includeFiles);
58
58
  }
59
59
  // Copy files to the target locale
60
60
  if (settings.options?.copyFiles) {
@@ -0,0 +1,3 @@
1
+ export declare function recordDownloaded(filePath: string): void;
2
+ export declare function getDownloaded(): Set<string>;
3
+ export declare function clearDownloaded(): void;
@@ -0,0 +1,10 @@
1
+ const recent = new Set();
2
+ export function recordDownloaded(filePath) {
3
+ recent.add(filePath);
4
+ }
5
+ export function getDownloaded() {
6
+ return recent;
7
+ }
8
+ export function clearDownloaded() {
9
+ recent.clear();
10
+ }
@@ -1,2 +1,2 @@
1
1
  import { Settings } from '../types/index.js';
2
- export default function flattenJsonFiles(settings: Settings): Promise<void>;
2
+ export default function flattenJsonFiles(settings: Settings, includeFiles?: Set<string>): Promise<void>;
@@ -1,6 +1,6 @@
1
1
  import { createFileMapping } from '../formats/files/fileMapping.js';
2
2
  import fs from 'node:fs';
3
- export default async function flattenJsonFiles(settings) {
3
+ export default async function flattenJsonFiles(settings, includeFiles) {
4
4
  if (!settings.files ||
5
5
  (Object.keys(settings.files.placeholderPaths).length === 1 &&
6
6
  settings.files.placeholderPaths.gt)) {
@@ -9,7 +9,7 @@ export default async function flattenJsonFiles(settings) {
9
9
  const { resolvedPaths: sourceFiles } = settings.files;
10
10
  const fileMapping = createFileMapping(sourceFiles, settings.files.placeholderPaths, settings.files.transformPaths, settings.locales, settings.defaultLocale);
11
11
  await Promise.all(Object.values(fileMapping).map(async (filesMap) => {
12
- const targetFiles = Object.values(filesMap).filter((path) => path.endsWith('.json'));
12
+ const targetFiles = Object.values(filesMap).filter((p) => p.endsWith('.json') && (!includeFiles || includeFiles.has(p)));
13
13
  await Promise.all(targetFiles.map(async (file) => {
14
14
  // Read each json file
15
15
  const json = JSON.parse(fs.readFileSync(file, 'utf8'));
@@ -12,4 +12,4 @@ import { Settings } from '../types/index.js';
12
12
  * - Support more file types
13
13
  * - Support more complex paths
14
14
  */
15
- export default function localizeStaticImports(settings: Settings): Promise<void>;
15
+ export default function localizeStaticImports(settings: Settings, includeFiles?: Set<string>): Promise<void>;
@@ -21,7 +21,7 @@ const { isMatch } = micromatch;
21
21
  * - Support more file types
22
22
  * - Support more complex paths
23
23
  */
24
- export default async function localizeStaticImports(settings) {
24
+ export default async function localizeStaticImports(settings, includeFiles) {
25
25
  if (!settings.files ||
26
26
  (Object.keys(settings.files.placeholderPaths).length === 1 &&
27
27
  settings.files.placeholderPaths.gt)) {
@@ -33,7 +33,7 @@ export default async function localizeStaticImports(settings) {
33
33
  const processPromises = [];
34
34
  // First, process default locale files (from source files)
35
35
  // This is needed because they might not be in the fileMapping if they're not being translated
36
- if (!fileMapping[settings.defaultLocale]) {
36
+ if (!fileMapping[settings.defaultLocale] && !includeFiles) {
37
37
  const defaultLocaleFiles = [];
38
38
  // Collect all .md and .mdx files from sourceFiles
39
39
  if (sourceFiles.md) {
@@ -62,7 +62,8 @@ export default async function localizeStaticImports(settings) {
62
62
  // Then process all other locales from fileMapping
63
63
  const mappingPromises = Object.entries(fileMapping).map(async ([locale, filesMap]) => {
64
64
  // Get all files that are md or mdx
65
- const targetFiles = Object.values(filesMap).filter((path) => path.endsWith('.md') || path.endsWith('.mdx'));
65
+ const targetFiles = Object.values(filesMap).filter((p) => (p.endsWith('.md') || p.endsWith('.mdx')) &&
66
+ (!includeFiles || includeFiles.has(p)));
66
67
  // Replace the placeholder path with the target path
67
68
  await Promise.all(targetFiles.map(async (filePath) => {
68
69
  // Check if file exists before processing
@@ -12,7 +12,7 @@ import { Settings } from '../types/index.js';
12
12
  * - Support more file types
13
13
  * - Support more complex paths
14
14
  */
15
- export default function localizeStaticUrls(settings: Settings, targetLocales?: string[]): Promise<void>;
15
+ export default function localizeStaticUrls(settings: Settings, targetLocales?: string[], includeFiles?: Set<string>): Promise<void>;
16
16
  /**
17
17
  * Main URL transformation function that delegates to specific scenarios
18
18
  */
@@ -22,7 +22,7 @@ const { isMatch } = micromatch;
22
22
  * - Support more file types
23
23
  * - Support more complex paths
24
24
  */
25
- export default async function localizeStaticUrls(settings, targetLocales) {
25
+ export default async function localizeStaticUrls(settings, targetLocales, includeFiles) {
26
26
  if (!settings.files ||
27
27
  (Object.keys(settings.files.placeholderPaths).length === 1 &&
28
28
  settings.files.placeholderPaths.gt)) {
@@ -39,7 +39,9 @@ export default async function localizeStaticUrls(settings, targetLocales) {
39
39
  // This is needed because they might not be in the fileMapping if they're not being translated
40
40
  // Only process default locale if it's in the target locales filter
41
41
  if (!fileMapping[settings.defaultLocale] &&
42
- locales.includes(settings.defaultLocale)) {
42
+ locales.includes(settings.defaultLocale) &&
43
+ !includeFiles // when filtering, skip default-locale pass
44
+ ) {
43
45
  const defaultLocaleFiles = [];
44
46
  // Collect all .md and .mdx files from sourceFiles
45
47
  if (sourceFiles.md) {
@@ -72,7 +74,8 @@ export default async function localizeStaticUrls(settings, targetLocales) {
72
74
  .filter(([locale, filesMap]) => locales.includes(locale)) // Filter by target locales
73
75
  .map(async ([locale, filesMap]) => {
74
76
  // Get all files that are md or mdx
75
- const targetFiles = Object.values(filesMap).filter((path) => path.endsWith('.md') || path.endsWith('.mdx'));
77
+ const targetFiles = Object.values(filesMap).filter((p) => (p.endsWith('.md') || p.endsWith('.mdx')) &&
78
+ (!includeFiles || includeFiles.has(p)));
76
79
  // Replace the placeholder path with the target path
77
80
  await Promise.all(targetFiles.map(async (filePath) => {
78
81
  // Check if file exists before processing
@@ -3,4 +3,4 @@ import { Settings } from '../types/index.js';
3
3
  * Processes all translated MD/MDX files to add explicit anchor IDs
4
4
  * This preserves navigation links when headings are translated
5
5
  */
6
- export default function processAnchorIds(settings: Settings): Promise<void>;
6
+ export default function processAnchorIds(settings: Settings, includeFiles?: Set<string>): Promise<void>;
@@ -6,7 +6,7 @@ import * as fs from 'fs';
6
6
  * Processes all translated MD/MDX files to add explicit anchor IDs
7
7
  * This preserves navigation links when headings are translated
8
8
  */
9
- export default async function processAnchorIds(settings) {
9
+ export default async function processAnchorIds(settings, includeFiles) {
10
10
  if (!settings.files)
11
11
  return;
12
12
  const { resolvedPaths, placeholderPaths, transformPaths } = settings.files;
@@ -16,7 +16,9 @@ export default async function processAnchorIds(settings) {
16
16
  .filter(([locale, filesMap]) => locale !== settings.defaultLocale) // Skip default locale
17
17
  .map(async ([locale, filesMap]) => {
18
18
  // Get all translated files that are md or mdx
19
- const translatedFiles = Object.values(filesMap).filter((path) => path && (path.endsWith('.md') || path.endsWith('.mdx')));
19
+ const translatedFiles = Object.values(filesMap).filter((p) => p &&
20
+ (p.endsWith('.md') || p.endsWith('.mdx')) &&
21
+ (!includeFiles || includeFiles.has(p)));
20
22
  for (const translatedPath of translatedFiles) {
21
23
  try {
22
24
  // Check if translated file exists before processing
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gtx-cli",
3
- "version": "2.3.13",
3
+ "version": "2.3.14",
4
4
  "main": "dist/index.js",
5
5
  "bin": "dist/main.js",
6
6
  "files": [