diff --git a/README.md b/README.md index 7695ecf..5f2ae9e 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,22 @@ This command will translate all the keys in your `en/*.json` file to `es/*. json`. It will use the OpenAI API to translate the keys. You will need to add a valid OpenAI API key in the `.env.local` file of your Makerkit repository. +#### Translating Specific Files + +You can now specify which files to translate using the `--files` option: + +``` +> npx @makerkit/cli@latest i18n translate en es --files=common.json,errors.json +``` + +or + +``` +> npx @makerkit/cli@latest i18n translate en es --files=common.json --files=errors.json +``` + +This will only translate the specified files instead of all `.json` files in the locale folder. + ### Verifying To verify that your i18n files are in sync, you can use the `i18n verify` command: diff --git a/package-lock.json b/package-lock.json index 92e154e..69e769c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@makerkit/cli", - "version": "1.2.10", + "version": "1.3.13", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@makerkit/cli", - "version": "1.2.10", + "version": "1.3.13", "license": "ISC", "dependencies": { "@types/fs-extra": "^11.0.1", diff --git a/src/commands/i18n/i18n-service.ts b/src/commands/i18n/i18n-service.ts index bbc5129..9f22e39 100644 --- a/src/commands/i18n/i18n-service.ts +++ b/src/commands/i18n/i18n-service.ts @@ -59,8 +59,9 @@ export class I18nService { * @description Translates the locale files from source to target * @param source * @param target + * @param files */ - static async translate(source: string, target: string) { + static async translate(source: string, target: string, files: string[]) { const kit = await Workspace.getKitMeta(); const client = getOpenAIClient(); @@ -73,13 +74,23 @@ export class I18nService { throw new Error(`Source locale at ${sourceLocalePath} not found`); } - const files = fs.readdirSync(sourceLocalePath).filter((file) => { - return file.endsWith('.json'); - }); + // Get all JSON files in the source locale path + let availableFiles = fs + .readdirSync(sourceLocalePath) + .filter((file) => file.endsWith('.json')); - console.log(`Found the following files: ${files.join(', ')}`); + // If specific files were passed, filter only those + if (files.length > 0) { + availableFiles = availableFiles.filter((file) => files.includes(file)); - for (const file of files) { + if (availableFiles.length === 0) { + throw new Error( + `None of the specified files exist in ${sourceLocalePath}` + ); + } + } + + for (const file of availableFiles) { const data: Record> = {}; @@ -96,11 +107,13 @@ export class I18nService { console.log(chalk.green(`File "${file}" successfully translated!`)); console.log(chalk.cyan(`Writing file "${file}" to ${targetJsonPath}`)); - // check if targetJsonPath exists, if not, create it - (await fs.exists(targetJsonPath)) || (await fs.mkdir(targetJsonPath)); + // Ensure target directory exists + if (!(await fs.exists(targetJsonPath))) { + await fs.mkdir(targetJsonPath, { recursive: true }); + } - // write file to targetJsonPath - await fs.writeJSON(join(targetJsonPath, file), data, {}); + // Write translated JSON file + await fs.writeJSON(join(targetJsonPath, file), data, { spaces: 2 }); console.log(chalk.green(`File "${file}" successfully written!`)); } diff --git a/src/commands/i18n/translate/translate.command.ts b/src/commands/i18n/translate/translate.command.ts index 68b5cdb..ab48034 100644 --- a/src/commands/i18n/translate/translate.command.ts +++ b/src/commands/i18n/translate/translate.command.ts @@ -8,11 +8,24 @@ export function createTranslateI18nCommand(parentCommand: Command) { .command('translate') .argument('[source-locale]', 'Source Locale') .argument('[target-locale]', 'Target Locale') + .option( + '--files ', + 'Specify files to translate (comma-separated or repeated usage)', + (value, previous: string[]) => { + // Split comma-separated input and merge with previous array (to handle repeated usage) + return previous.concat(value.split(',')); + }, + [] + ) .description('Translate i18n files from source locale to target locale') - .action(async (sourceLocale, targetLocale) => { + .action(async (sourceLocale, targetLocale, options) => { const locales = await promptLocales(sourceLocale, targetLocale); - await I18nService.translate(locales.sourceLocale, locales.targetLocale); + await I18nService.translate( + locales.sourceLocale, + locales.targetLocale, + options.files + ); }); }