gtx-cli 2.1.5 → 2.1.6

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 (60) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/api/checkFileTranslations.d.ts +1 -4
  3. package/dist/api/checkFileTranslations.js +32 -35
  4. package/dist/api/downloadFileBatch.d.ts +1 -0
  5. package/dist/api/sendFiles.d.ts +2 -13
  6. package/dist/api/sendFiles.js +15 -8
  7. package/dist/cli/base.d.ts +5 -17
  8. package/dist/cli/base.js +48 -68
  9. package/dist/cli/commands/stage.d.ts +5 -0
  10. package/dist/cli/commands/stage.js +100 -0
  11. package/dist/cli/commands/translate.d.ts +6 -0
  12. package/dist/cli/commands/translate.js +54 -0
  13. package/dist/cli/flags.d.ts +3 -0
  14. package/dist/cli/flags.js +37 -0
  15. package/dist/cli/next.js +0 -1
  16. package/dist/cli/react.d.ts +2 -5
  17. package/dist/cli/react.js +13 -153
  18. package/dist/config/generateSettings.js +11 -6
  19. package/dist/console/index.d.ts +1 -0
  20. package/dist/console/index.js +1 -0
  21. package/dist/console/logging.d.ts +1 -0
  22. package/dist/console/logging.js +3 -0
  23. package/dist/formats/files/fileMapping.d.ts +2 -1
  24. package/dist/formats/files/fileMapping.js +6 -0
  25. package/dist/formats/files/translate.d.ts +4 -13
  26. package/dist/formats/files/translate.js +30 -142
  27. package/dist/formats/files/upload.js +1 -75
  28. package/dist/formats/gt/save.d.ts +1 -2
  29. package/dist/formats/gt/save.js +2 -5
  30. package/dist/fs/config/setupConfig.d.ts +1 -0
  31. package/dist/fs/config/setupConfig.js +1 -0
  32. package/dist/fs/config/updateConfig.d.ts +1 -2
  33. package/dist/fs/config/updateConfig.js +1 -1
  34. package/dist/fs/config/updateVersions.d.ts +10 -0
  35. package/dist/fs/config/updateVersions.js +30 -0
  36. package/dist/fs/copyFile.d.ts +1 -2
  37. package/dist/translation/parse.d.ts +2 -2
  38. package/dist/translation/parse.js +4 -6
  39. package/dist/translation/stage.d.ts +2 -5
  40. package/dist/translation/stage.js +13 -55
  41. package/dist/types/files.d.ts +1 -0
  42. package/dist/types/files.js +1 -0
  43. package/dist/types/index.d.ts +27 -3
  44. package/dist/utils/flattenJsonFiles.d.ts +2 -2
  45. package/dist/utils/hash.d.ts +6 -0
  46. package/dist/utils/hash.js +11 -0
  47. package/dist/utils/localizeStaticImports.d.ts +2 -2
  48. package/dist/utils/localizeStaticUrls.d.ts +2 -2
  49. package/dist/utils/localizeStaticUrls.js +2 -2
  50. package/package.json +2 -2
  51. package/dist/api/downloadFile.d.ts +0 -9
  52. package/dist/api/downloadFile.js +0 -74
  53. package/dist/api/fetchTranslations.d.ts +0 -7
  54. package/dist/api/fetchTranslations.js +0 -18
  55. package/dist/api/sendUpdates.d.ts +0 -19
  56. package/dist/api/sendUpdates.js +0 -48
  57. package/dist/api/waitForUpdates.d.ts +0 -9
  58. package/dist/api/waitForUpdates.js +0 -89
  59. package/dist/translation/translate.d.ts +0 -2
  60. package/dist/translation/translate.js +0 -18
@@ -1,9 +1,6 @@
1
1
  import { noSupportedFormatError, noDefaultLocaleError, noApiKeyError, noProjectIdError, devApiKeyError, } from '../../console/index.js';
2
- import { logErrorAndExit, createSpinner, logError, } from '../../console/logging.js';
2
+ import { logErrorAndExit, logError } from '../../console/logging.js';
3
3
  import { getRelative, readFile } from '../../fs/findFilepath.js';
4
- import chalk from 'chalk';
5
- import { downloadFile } from '../../api/downloadFile.js';
6
- import { downloadFileBatch } from '../../api/downloadFileBatch.js';
7
4
  import { SUPPORTED_FILE_EXTENSIONS } from './supportedFiles.js';
8
5
  import sanitizeFileContent from '../../utils/sanitizeFileContent.js';
9
6
  import { parseJson } from '../json/parseJson.js';
@@ -139,74 +136,3 @@ export async function upload(filePaths, placeholderPaths, transformPaths, dataFo
139
136
  logErrorAndExit(`Error uploading files: ${error}`);
140
137
  }
141
138
  }
142
- /**
143
- * Processes translations that were already completed and returned with the initial API response
144
- * @returns Set of downloaded file+locale combinations
145
- */
146
- async function processInitialTranslations(translations = [], fileMapping, options) {
147
- const downloadStatus = {
148
- downloaded: new Set(),
149
- failed: new Set(),
150
- };
151
- if (!translations || translations.length === 0) {
152
- return downloadStatus;
153
- }
154
- // Filter for ready translations
155
- const readyTranslations = translations.filter((translation) => translation.isReady && translation.fileName);
156
- if (readyTranslations.length > 0) {
157
- const spinner = createSpinner('dots');
158
- spinner.start('Downloading translations...');
159
- // Prepare batch download data
160
- const batchFiles = readyTranslations
161
- .map((translation) => {
162
- const { locale, fileName, id } = translation;
163
- const outputPath = fileMapping[locale][fileName];
164
- if (!outputPath) {
165
- return null;
166
- }
167
- return {
168
- translationId: id,
169
- outputPath,
170
- inputPath: fileName,
171
- fileLocale: `${fileName}:${locale}`,
172
- locale,
173
- };
174
- })
175
- .filter(Boolean);
176
- if (batchFiles.length === 0 || batchFiles[0] === null) {
177
- return downloadStatus;
178
- }
179
- // Use batch download if there are multiple files
180
- if (batchFiles.length > 1) {
181
- const batchResult = await downloadFileBatch(batchFiles.map(({ translationId, outputPath, inputPath, locale }) => ({
182
- translationId,
183
- outputPath,
184
- inputPath,
185
- locale,
186
- })), options);
187
- // Process results
188
- batchFiles.forEach((file) => {
189
- const { translationId, fileLocale } = file;
190
- if (batchResult.successful.includes(translationId)) {
191
- downloadStatus.downloaded.add(fileLocale);
192
- }
193
- else if (batchResult.failed.includes(translationId)) {
194
- downloadStatus.failed.add(fileLocale);
195
- }
196
- });
197
- }
198
- else if (batchFiles.length === 1) {
199
- // For a single file, use the original downloadFile method
200
- const file = batchFiles[0];
201
- const result = await downloadFile(file.translationId, file.outputPath, file.inputPath, file.locale, options);
202
- if (result) {
203
- downloadStatus.downloaded.add(file.fileLocale);
204
- }
205
- else {
206
- downloadStatus.failed.add(file.fileLocale);
207
- }
208
- }
209
- spinner.stop(chalk.green('Downloaded cached translations'));
210
- }
211
- return downloadStatus;
212
- }
@@ -1,10 +1,9 @@
1
1
  import { RetrievedTranslations } from 'generaltranslation/types';
2
2
  import { ResolvedFiles } from '../../types/index.js';
3
- import { DataFormat } from '../../types/data.js';
4
3
  /**
5
4
  * Saves translations to a local directory
6
5
  * @param translations - The translations to save
7
6
  * @param translationsDir - The directory to save the translations to
8
7
  * @param fileType - The file type to save the translations as (file extension)
9
8
  */
10
- export declare function saveTranslations(translations: RetrievedTranslations, placeholderPaths: ResolvedFiles, dataFormat: DataFormat): Promise<void>;
9
+ export declare function saveTranslations(translations: RetrievedTranslations, placeholderPaths: ResolvedFiles): Promise<void>;
@@ -9,7 +9,7 @@ import { resolveLocaleFiles } from '../../fs/config/parseFilesConfig.js';
9
9
  * @param translationsDir - The directory to save the translations to
10
10
  * @param fileType - The file type to save the translations as (file extension)
11
11
  */
12
- export async function saveTranslations(translations, placeholderPaths, dataFormat) {
12
+ export async function saveTranslations(translations, placeholderPaths) {
13
13
  for (const translation of translations) {
14
14
  const locale = translation.locale;
15
15
  const translationFiles = resolveLocaleFiles(placeholderPaths, locale);
@@ -21,9 +21,6 @@ export async function saveTranslations(translations, placeholderPaths, dataForma
21
21
  const translationData = translation.translation;
22
22
  // Ensure directory exists
23
23
  await fs.promises.mkdir(path.dirname(filepath), { recursive: true });
24
- // Handle different file types
25
- if (dataFormat === 'JSX') {
26
- await fs.promises.writeFile(filepath, JSON.stringify(translationData, null, 2));
27
- }
24
+ await fs.promises.writeFile(filepath, JSON.stringify(translationData, null, 2));
28
25
  }
29
26
  }
@@ -13,4 +13,5 @@ export declare function createOrUpdateConfig(configFilepath: string, options: {
13
13
  files?: FilesOptions;
14
14
  framework?: SupportedFrameworks;
15
15
  baseUrl?: string;
16
+ publish?: boolean;
16
17
  }): Promise<string>;
@@ -17,6 +17,7 @@ export async function createOrUpdateConfig(configFilepath, options) {
17
17
  ...(options.files && { files: options.files }),
18
18
  ...(options.framework && { framework: options.framework }),
19
19
  ...(options.baseUrl && { baseUrl: options.baseUrl }),
20
+ ...(options.publish && { publish: options.publish }),
20
21
  };
21
22
  try {
22
23
  // if file exists
@@ -2,10 +2,9 @@
2
2
  * Update the config file version id, locales, and projectId (if necessary)
3
3
  * @param {Record<string, any>} configObject - The config object to write if the file does not exist.
4
4
  */
5
- export default function updateConfig({ configFilepath, projectId, _versionId, locales, stageTranslations, }: {
5
+ export default function updateConfig({ configFilepath, projectId, _versionId, stageTranslations, }: {
6
6
  configFilepath: string;
7
7
  projectId?: string;
8
8
  _versionId?: string;
9
- locales?: string[];
10
9
  stageTranslations?: boolean;
11
10
  }): Promise<void>;
@@ -5,7 +5,7 @@ import { logError } from '../../console/logging.js';
5
5
  * Update the config file version id, locales, and projectId (if necessary)
6
6
  * @param {Record<string, any>} configObject - The config object to write if the file does not exist.
7
7
  */
8
- export default async function updateConfig({ configFilepath, projectId, _versionId, locales, stageTranslations, }) {
8
+ export default async function updateConfig({ configFilepath, projectId, _versionId, stageTranslations, }) {
9
9
  // Filter out empty string values from the config object
10
10
  const newContent = {
11
11
  ...(projectId && { projectId }),
@@ -0,0 +1,10 @@
1
+ type StagedVersionData = Record<string, {
2
+ fileName: string;
3
+ versionId: string;
4
+ }>;
5
+ export declare function updateVersions({ configDirectory, versionData, }: {
6
+ configDirectory: string;
7
+ versionData: StagedVersionData;
8
+ }): Promise<void>;
9
+ export declare function getStagedVersions(configDirectory: string): Promise<StagedVersionData>;
10
+ export {};
@@ -0,0 +1,30 @@
1
+ import fs from 'node:fs';
2
+ import { displayUpdatedVersionsFile } from '../../console/logging.js';
3
+ import { logError } from '../../console/logging.js';
4
+ import path from 'node:path';
5
+ const STAGED_VERSIONS_FILE = 'staged-versions.json';
6
+ // Update the versions.json file with the new version ids
7
+ // of the translations that were sent to the API
8
+ export async function updateVersions({ configDirectory, versionData, }) {
9
+ const versionFilepath = path.join(configDirectory, STAGED_VERSIONS_FILE);
10
+ try {
11
+ fs.mkdirSync(configDirectory, { recursive: true });
12
+ fs.writeFileSync(versionFilepath, JSON.stringify(versionData, null, 2));
13
+ // show update in console
14
+ displayUpdatedVersionsFile(versionFilepath);
15
+ }
16
+ catch (error) {
17
+ logError(`An error occurred while updating ${versionFilepath}: ${error}`);
18
+ }
19
+ }
20
+ export async function getStagedVersions(configDirectory) {
21
+ try {
22
+ const versionFilepath = path.join(configDirectory, STAGED_VERSIONS_FILE);
23
+ const versionData = JSON.parse(fs.readFileSync(versionFilepath, 'utf8'));
24
+ return versionData;
25
+ }
26
+ catch (error) {
27
+ logError(`An error occurred while getting staged versions: ${error}`);
28
+ return {};
29
+ }
30
+ }
@@ -1,8 +1,7 @@
1
1
  import { Settings } from '../types/index.js';
2
- import { TranslateOptions } from '../cli/base.js';
3
2
  /**
4
3
  * Copy a file to target locale without translation
5
4
  *
6
5
  * This is a naive approach, does not allow for wild cards
7
6
  */
8
- export default function copyFile(settings: Settings & TranslateOptions): Promise<void>;
7
+ export default function copyFile(settings: Settings): Promise<void>;
@@ -1,4 +1,4 @@
1
- import { Options, GenerateSourceOptions, Updates } from '../types/index.js';
1
+ import { Updates, TranslateFlags } from '../types/index.js';
2
2
  /**
3
3
  * Searches for gt-react or gt-next dictionary files and creates updates for them,
4
4
  * as well as inline updates for <T> tags and useGT()/getGT() calls
@@ -8,7 +8,7 @@ import { Options, GenerateSourceOptions, Updates } from '../types/index.js';
8
8
  * @param pkg - The package name
9
9
  * @returns An object containing the updates and errors
10
10
  */
11
- export declare function createUpdates(options: Options | GenerateSourceOptions, sourceDictionary: string | undefined, pkg: 'gt-react' | 'gt-next', validate: boolean): Promise<{
11
+ export declare function createUpdates(options: TranslateFlags, sourceDictionary: string | undefined, pkg: 'gt-react' | 'gt-next', validate: boolean): Promise<{
12
12
  updates: Updates;
13
13
  errors: string[];
14
14
  warnings: string[];
@@ -48,12 +48,10 @@ export async function createUpdates(options, sourceDictionary, pkg, validate) {
48
48
  }
49
49
  }
50
50
  // Scan through project for <T> tags
51
- if (options.inline) {
52
- const { updates: newUpdates, errors: newErrors, warnings: newWarnings, } = await createInlineUpdates(pkg, validate, options.src);
53
- errors = [...errors, ...newErrors];
54
- warnings = [...warnings, ...newWarnings];
55
- updates = [...updates, ...newUpdates];
56
- }
51
+ const { updates: newUpdates, errors: newErrors, warnings: newWarnings, } = await createInlineUpdates(pkg, validate, options.src);
52
+ errors = [...errors, ...newErrors];
53
+ warnings = [...warnings, ...newWarnings];
54
+ updates = [...updates, ...newUpdates];
57
55
  // Metadata addition and validation
58
56
  const idHashMap = new Map();
59
57
  const duplicateIds = new Set();
@@ -1,5 +1,2 @@
1
- import { Options, Settings } from '../types/index.js';
2
- export declare function stageProject(settings: Options & Settings, pkg: 'gt-react' | 'gt-next'): Promise<{
3
- versionId: string;
4
- locales: string[];
5
- } | null>;
1
+ import { Settings, TranslateFlags, Updates } from '../types/index.js';
2
+ export declare function aggregateReactTranslations(options: TranslateFlags, settings: Settings, library: 'gt-react' | 'gt-next'): Promise<Updates>;
@@ -1,14 +1,11 @@
1
- import { devApiKeyError } from '../console/index.js';
2
1
  import { logErrorAndExit } from '../console/logging.js';
3
2
  import chalk from 'chalk';
4
3
  import findFilepath from '../fs/findFilepath.js';
5
- import { logSuccess, logWarning, logError } from '../console/logging.js';
4
+ import { logWarning, logError } from '../console/logging.js';
6
5
  import { createUpdates } from './parse.js';
7
- import { noLocalesError, noDefaultLocaleError, noProjectIdError, noApiKeyError, } from '../console/index.js';
8
- import { sendUpdates } from '../api/sendUpdates.js';
9
- export async function stageProject(settings, pkg) {
10
- if (!settings.dictionary) {
11
- settings.dictionary = findFilepath([
6
+ export async function aggregateReactTranslations(options, settings, library) {
7
+ if (!options.dictionary) {
8
+ options.dictionary = findFilepath([
12
9
  './dictionary.js',
13
10
  './src/dictionary.js',
14
11
  './dictionary.json',
@@ -17,29 +14,16 @@ export async function stageProject(settings, pkg) {
17
14
  './src/dictionary.ts',
18
15
  ]);
19
16
  }
20
- // Separate defaultLocale from locales
21
- settings.locales = settings.locales.filter((locale) => locale !== settings.defaultLocale);
22
- // validate timeout
23
- const timeout = parseInt(settings.timeout);
24
- if (isNaN(timeout) || timeout < 0) {
25
- logErrorAndExit(`Invalid timeout: ${settings.timeout}. Must be a positive integer.`);
26
- }
27
- settings.timeout = timeout.toString();
28
17
  // ---- CREATING UPDATES ---- //
29
- const { updates, errors, warnings } = await createUpdates(settings, settings.dictionary, pkg, false);
18
+ const { updates, errors, warnings } = await createUpdates(options, options.dictionary, library, false);
30
19
  if (warnings.length > 0) {
31
- if (settings.suppressWarnings) {
32
- logWarning(chalk.yellow(`CLI tool encountered ${warnings.length} warnings while scanning for translatable content. ${chalk.gray('To view these warnings, re-run without the --suppress-warnings flag')}`));
33
- }
34
- else {
35
- logWarning(chalk.yellow(`CLI tool encountered ${warnings.length} warnings while scanning for translatable content. ${chalk.gray('To suppress these warnings, re-run with --suppress-warnings')}\n` +
36
- warnings
37
- .map((warning) => chalk.yellow('• Warning: ') + chalk.white(warning))
38
- .join('\n')));
39
- }
20
+ logWarning(chalk.yellow(`CLI tool encountered ${warnings.length} warnings while scanning for translatable content.\n` +
21
+ warnings
22
+ .map((warning) => chalk.yellow('• Warning: ') + chalk.white(warning))
23
+ .join('\n')));
40
24
  }
41
25
  if (errors.length > 0) {
42
- if (settings.ignoreErrors) {
26
+ if (options.ignoreErrors) {
43
27
  logWarning(chalk.yellow(`Warning: CLI tool encountered ${errors.length} syntax errors while scanning for translatable content. These components will not be translated.\n` +
44
28
  errors
45
29
  .map((error) => chalk.yellow('• ') + chalk.white(error) + '\n')
@@ -52,35 +36,9 @@ export async function stageProject(settings, pkg) {
52
36
  .join('')));
53
37
  }
54
38
  }
55
- if (settings.dryRun) {
56
- logSuccess('Dry run: No translations were sent to General Translation.');
57
- return null;
58
- }
59
39
  if (updates.length == 0) {
60
- logError(chalk.red(`No in-line content or dictionaries were found for ${chalk.green(pkg)}. Are you sure you're running this command in the right directory?`));
61
- return null;
62
- }
63
- // Send updates to General Translation API
64
- if (!settings.locales) {
65
- logErrorAndExit(noLocalesError);
66
- }
67
- if (!settings.defaultLocale) {
68
- logErrorAndExit(noDefaultLocaleError);
69
- }
70
- if (!settings.apiKey) {
71
- logErrorAndExit(noApiKeyError);
72
- }
73
- if (settings.apiKey.startsWith('gtx-dev-')) {
74
- logErrorAndExit(devApiKeyError);
75
- }
76
- if (!settings.projectId) {
77
- logErrorAndExit(noProjectIdError);
40
+ logError(chalk.red(`No in-line content or dictionaries were found for ${chalk.green(library)}. Are you sure you're running this command in the right directory?`));
41
+ return updates;
78
42
  }
79
- const updateResponse = await sendUpdates(updates, {
80
- ...settings,
81
- timeout: settings.timeout,
82
- dataFormat: 'JSX',
83
- }, pkg);
84
- const { versionId, locales } = updateResponse;
85
- return { versionId, locales };
43
+ return updates;
86
44
  }
@@ -0,0 +1 @@
1
+ export type FileMapping = Record<string, Record<string, string>>;
@@ -0,0 +1 @@
1
+ export {};
@@ -15,13 +15,35 @@ export type Options = {
15
15
  ignoreErrors: boolean;
16
16
  suppressWarnings: boolean;
17
17
  dryRun: boolean;
18
- timeout: string;
18
+ timeout: number;
19
19
  stageTranslations?: boolean;
20
20
  experimentalLocalizeStaticUrls?: boolean;
21
21
  experimentalHideDefaultLocale?: boolean;
22
22
  experimentalFlattenJsonFiles?: boolean;
23
23
  experimentalLocalizeStaticImports?: boolean;
24
24
  };
25
+ export type TranslateFlags = {
26
+ config?: string;
27
+ apiKey?: string;
28
+ projectId?: string;
29
+ versionId?: string;
30
+ jsconfig?: string;
31
+ dictionary?: string;
32
+ defaultLocale?: string;
33
+ locales?: string[];
34
+ ignoreErrors?: boolean;
35
+ src?: string[];
36
+ timeout: number;
37
+ dryRun: boolean;
38
+ stageTranslations?: boolean;
39
+ publish?: boolean;
40
+ experimentalLocalizeStaticUrls?: boolean;
41
+ experimentalHideDefaultLocale?: boolean;
42
+ experimentalFlattenJsonFiles?: boolean;
43
+ experimentalLocalizeStaticImports?: boolean;
44
+ excludeStaticUrls?: string[];
45
+ excludeStaticImports?: string[];
46
+ };
25
47
  export type WrapOptions = {
26
48
  src?: string[];
27
49
  config: string;
@@ -80,10 +102,11 @@ export type FilesOptions = {
80
102
  };
81
103
  export type Settings = {
82
104
  config: string;
105
+ configDirectory: string;
83
106
  baseUrl: string;
84
107
  dashboardUrl: string;
85
- apiKey: string;
86
- projectId: string;
108
+ apiKey?: string;
109
+ projectId?: string;
87
110
  defaultLocale: string;
88
111
  locales: string[];
89
112
  files: {
@@ -92,6 +115,7 @@ export type Settings = {
92
115
  transformPaths: TransformFiles;
93
116
  } | undefined;
94
117
  stageTranslations: boolean;
118
+ publish: boolean;
95
119
  _versionId?: string;
96
120
  version?: string;
97
121
  description?: string;
@@ -1,2 +1,2 @@
1
- import { Settings, Options } from '../types/index.js';
2
- export default function flattenJsonFiles(settings: Omit<Settings & Options, 'ignoreErrors' | 'suppressWarnings' | 'timeout'>): Promise<void>;
1
+ import { Settings } from '../types/index.js';
2
+ export default function flattenJsonFiles(settings: Settings): Promise<void>;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Hashes a string using SHA-256 algorithm.
3
+ * @param {string} string - The string to be hashed.
4
+ * @returns {string} The hashed string.
5
+ */
6
+ export declare function hashStringSync(string: string): string;
@@ -0,0 +1,11 @@
1
+ import crypto from 'crypto';
2
+ /**
3
+ * Hashes a string using SHA-256 algorithm.
4
+ * @param {string} string - The string to be hashed.
5
+ * @returns {string} The hashed string.
6
+ */
7
+ export function hashStringSync(string) {
8
+ const hash = crypto.createHash('sha256');
9
+ hash.update(string);
10
+ return hash.digest('hex');
11
+ }
@@ -1,4 +1,4 @@
1
- import { Options, Settings } from '../types/index.js';
1
+ import { Settings } from '../types/index.js';
2
2
  /**
3
3
  * Localizes static imports in content files.
4
4
  * Currently only supported for md and mdx files. (/docs/ -> /[locale]/docs/)
@@ -12,4 +12,4 @@ import { Options, 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: Omit<Settings & Options, 'ignoreErrors' | 'suppressWarnings' | 'timeout'>): Promise<void>;
15
+ export default function localizeStaticImports(settings: Settings): Promise<void>;
@@ -1,4 +1,4 @@
1
- import { Options, Settings } from '../types/index.js';
1
+ import { Settings } from '../types/index.js';
2
2
  /**
3
3
  * Localizes static urls in content files.
4
4
  * Currently only supported for md and mdx files. (/docs/ -> /[locale]/docs/)
@@ -12,4 +12,4 @@ import { Options, 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: Omit<Settings & Options, 'ignoreErrors' | 'suppressWarnings' | 'timeout'>): Promise<void>;
15
+ export default function localizeStaticUrls(settings: Settings): Promise<void>;
@@ -48,7 +48,7 @@ export default async function localizeStaticUrls(settings) {
48
48
  const fileContent = await fs.promises.readFile(filePath, 'utf8');
49
49
  // Localize the file using default locale
50
50
  const localizedFile = localizeStaticUrlsForFile(fileContent, settings.defaultLocale, settings.defaultLocale, // Process as default locale
51
- settings.experimentalHideDefaultLocale || false, settings.options?.docsUrlPattern, settings.options?.excludeStaticUrls);
51
+ settings.options?.experimentalHideDefaultLocale || false, settings.options?.docsUrlPattern, settings.options?.excludeStaticUrls);
52
52
  // Write the localized file back to the same path
53
53
  await fs.promises.writeFile(filePath, localizedFile);
54
54
  }));
@@ -64,7 +64,7 @@ export default async function localizeStaticUrls(settings) {
64
64
  // Get file content
65
65
  const fileContent = await fs.promises.readFile(filePath, 'utf8');
66
66
  // Localize the file (handles both URLs and hrefs in single AST pass)
67
- const localizedFile = localizeStaticUrlsForFile(fileContent, settings.defaultLocale, locale, settings.experimentalHideDefaultLocale || false, settings.options?.docsUrlPattern, settings.options?.excludeStaticUrls);
67
+ const localizedFile = localizeStaticUrlsForFile(fileContent, settings.defaultLocale, locale, settings.options?.experimentalHideDefaultLocale || false, settings.options?.docsUrlPattern, settings.options?.excludeStaticUrls);
68
68
  // Write the localized file to the target path
69
69
  await fs.promises.writeFile(filePath, localizedFile);
70
70
  }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gtx-cli",
3
- "version": "2.1.5",
3
+ "version": "2.1.6",
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.0",
90
+ "generaltranslation": "^7.4.1",
91
91
  "json-pointer": "^0.6.2",
92
92
  "jsonpath-plus": "^10.3.0",
93
93
  "jsonpointer": "^5.0.1",
@@ -1,9 +0,0 @@
1
- import { Settings } from '../types/index.js';
2
- /**
3
- * Downloads a file from the API and saves it to a local directory
4
- * @param translationId - The ID of the translation to download
5
- * @param outputPath - The path to save the file to
6
- * @param maxRetries - The maximum number of retries to attempt
7
- * @param retryDelay - The delay between retries in milliseconds
8
- */
9
- export declare function downloadFile(translationId: string, outputPath: string, inputPath: string, locale: string, options: Settings, maxRetries?: number, retryDelay?: number): Promise<boolean>;
@@ -1,74 +0,0 @@
1
- import * as fs from 'fs';
2
- import * as path from 'path';
3
- import { logError } from '../console/logging.js';
4
- import { gt } from '../utils/gt.js';
5
- import { validateJsonSchema } from '../formats/json/utils.js';
6
- import { mergeJson } from '../formats/json/mergeJson.js';
7
- import { TextDecoder } from 'node:util';
8
- import mergeYaml from '../formats/yaml/mergeYaml.js';
9
- import { validateYamlSchema } from '../formats/yaml/utils.js';
10
- /**
11
- * Downloads a file from the API and saves it to a local directory
12
- * @param translationId - The ID of the translation to download
13
- * @param outputPath - The path to save the file to
14
- * @param maxRetries - The maximum number of retries to attempt
15
- * @param retryDelay - The delay between retries in milliseconds
16
- */
17
- export async function downloadFile(translationId, outputPath, inputPath, locale, options, maxRetries = 3, retryDelay = 1000) {
18
- let retries = 0;
19
- while (retries <= maxRetries) {
20
- try {
21
- // Get the file data as an ArrayBuffer
22
- const fileData = await gt.downloadFile(translationId);
23
- // Ensure the directory exists
24
- const dir = path.dirname(outputPath);
25
- if (!fs.existsSync(dir)) {
26
- fs.mkdirSync(dir, { recursive: true });
27
- }
28
- let data = new TextDecoder().decode(fileData);
29
- if (options.options?.jsonSchema && locale) {
30
- const jsonSchema = validateJsonSchema(options.options, inputPath);
31
- if (jsonSchema) {
32
- const originalContent = fs.readFileSync(inputPath, 'utf8');
33
- if (originalContent) {
34
- data = mergeJson(originalContent, inputPath, options.options, [
35
- {
36
- translatedContent: data,
37
- targetLocale: locale,
38
- },
39
- ], options.defaultLocale)[0];
40
- }
41
- }
42
- }
43
- if (options.options?.yamlSchema && locale) {
44
- const yamlSchema = validateYamlSchema(options.options, inputPath);
45
- if (yamlSchema) {
46
- const originalContent = fs.readFileSync(inputPath, 'utf8');
47
- if (originalContent) {
48
- data = mergeYaml(originalContent, inputPath, options.options, [
49
- {
50
- translatedContent: data,
51
- targetLocale: locale,
52
- },
53
- ])[0];
54
- }
55
- }
56
- }
57
- // Write the file to disk
58
- await fs.promises.writeFile(outputPath, data);
59
- return true;
60
- }
61
- catch (error) {
62
- // If we've retried too many times, log an error and return false
63
- if (retries >= maxRetries) {
64
- logError(`Error downloading file ${outputPath} after ${maxRetries + 1} attempts: ` +
65
- error);
66
- return false;
67
- }
68
- // Increment retry counter and wait before next attempt
69
- retries++;
70
- await new Promise((resolve) => setTimeout(resolve, retryDelay));
71
- }
72
- }
73
- return false;
74
- }
@@ -1,7 +0,0 @@
1
- import { RetrievedTranslations } from 'generaltranslation/types';
2
- /**
3
- * Fetches translations from the API and saves them to a local directory
4
- * @param translationsDir - The directory to save the translations to
5
- * @param fileType - The file type to save the translations as (file extension)
6
- */
7
- export declare function fetchTranslations(versionId: string): Promise<RetrievedTranslations>;
@@ -1,18 +0,0 @@
1
- import chalk from 'chalk';
2
- import { logError } from '../console/logging.js';
3
- import { gt } from '../utils/gt.js';
4
- /**
5
- * Fetches translations from the API and saves them to a local directory
6
- * @param translationsDir - The directory to save the translations to
7
- * @param fileType - The file type to save the translations as (file extension)
8
- */
9
- export async function fetchTranslations(versionId) {
10
- try {
11
- const result = await gt.fetchTranslations(versionId);
12
- return result.translations;
13
- }
14
- catch {
15
- logError(chalk.red('Failed to fetch translations'));
16
- return [];
17
- }
18
- }
@@ -1,19 +0,0 @@
1
- import { Settings, SupportedLibraries, Updates } from '../types/index.js';
2
- import { DataFormat } from '../types/data.js';
3
- export type ApiOptions = Settings & {
4
- timeout: string;
5
- dataFormat: DataFormat;
6
- description?: string;
7
- requireApproval?: boolean;
8
- };
9
- export type SendUpdatesResult = {
10
- versionId: string;
11
- locales: string[];
12
- };
13
- /**
14
- * Sends updates to the API
15
- * @param updates - The updates to send
16
- * @param options - The options for the API call
17
- * @returns The versionId of the updated project
18
- */
19
- export declare function sendUpdates(updates: Updates, options: ApiOptions, library: SupportedLibraries): Promise<SendUpdatesResult>;