Skip to content

Add --files option to i18n translate command #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 23 additions & 10 deletions src/commands/i18n/i18n-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -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<string, string | Record<string, string | NestedKey>> =
{};

Expand All @@ -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!`));
}
Expand Down
17 changes: 15 additions & 2 deletions src/commands/i18n/translate/translate.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,24 @@ export function createTranslateI18nCommand(parentCommand: Command) {
.command('translate')
.argument('[source-locale]', 'Source Locale')
.argument('[target-locale]', 'Target Locale')
.option(
'--files <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
);
});
}

Expand Down