Skip to content

Commit 559156d

Browse files
committed
add command to replace key
1 parent a7c93bb commit 559156d

File tree

8 files changed

+267
-22
lines changed

8 files changed

+267
-22
lines changed

.gitignore

+6-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,9 @@
33
node_modules
44
dist
55

6-
.yarn
6+
.yarn
7+
8+
.env
9+
test.tsx
10+
locales
11+
i18n-magic.js

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "i18n-magic",
3-
"version": "0.1.7",
3+
"version": "0.1.8",
44
"license": "MIT",
55
"author": "BjoernRave",
66
"main": "dist/index.js",
@@ -48,7 +48,7 @@
4848
}
4949
],
5050
"dependencies": {
51-
"@inquirer/input": "^1.2.5",
51+
"@inquirer/prompts": "^3.0.0",
5252
"chalk": "^5.3.0",
5353
"commander": "^11.0.0",
5454
"dotenv": "^16.3.1",

src/commands/replace.ts

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { input } from '@inquirer/prompts';
2+
import { Configuration } from '../lib/types';
3+
import { loadLocalesFile, translateKey, writeLocalesFile } from '../lib/utils';
4+
5+
const getKeyToReplace = async (keys: any) => {
6+
const keyToReplace = await input({
7+
message: 'Enter the key to replace the translation for: ',
8+
});
9+
10+
if (!keys[keyToReplace]) {
11+
console.log(`The key "${keyToReplace}" does not exist.`);
12+
return await getKeyToReplace(keys);
13+
} else {
14+
console.log(`The key "${keyToReplace}" exists.`);
15+
return keyToReplace;
16+
}
17+
};
18+
19+
export const replaceTranslation = async (config: Configuration) => {
20+
const {
21+
loadPath,
22+
savePath,
23+
defaultLocale,
24+
defaultNamespace,
25+
namespaces,
26+
locales,
27+
globPatterns,
28+
context,
29+
openai,
30+
} = config;
31+
32+
const keys = loadLocalesFile(
33+
config.loadPath,
34+
config.defaultLocale,
35+
config.defaultNamespace
36+
);
37+
38+
const keyToReplace = await getKeyToReplace(keys);
39+
40+
console.log(
41+
`The current translation in ${defaultLocale} for "${keyToReplace}" is "${keys[keyToReplace]}".`
42+
);
43+
44+
const newTranslation = await input({
45+
message: `Enter the new translation: `,
46+
});
47+
48+
for (const locale of locales) {
49+
let newValue = '';
50+
if (locale === defaultLocale) {
51+
newValue = newTranslation;
52+
} else {
53+
const translation = await translateKey({
54+
context,
55+
inputLanguage: defaultLocale,
56+
outputLanguage: locale,
57+
object: {
58+
[keyToReplace]: newTranslation,
59+
},
60+
openai,
61+
});
62+
63+
newValue = translation[keyToReplace];
64+
}
65+
66+
const existingKeys = loadLocalesFile(loadPath, locale, defaultNamespace);
67+
68+
existingKeys[keyToReplace] = newValue;
69+
70+
writeLocalesFile(savePath, locale, defaultNamespace, existingKeys);
71+
72+
console.log(
73+
`The new translation for "${keyToReplace}" in ${locale} is "${newValue}".`
74+
);
75+
}
76+
};

src/commands/scan.ts

+10-15
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
import input from '@inquirer/input';
1+
import { input } from '@inquirer/prompts';
22
import glob from 'fast-glob';
33
import fs from 'fs';
44
import { Parser } from 'i18next-scanner';
5-
import OpenAI from 'openai';
65

76
import { Configuration } from '../lib/types';
87
import {
98
getPureKey,
109
loadLocalesFile,
1110
removeDuplicatesFromArray,
1211
translateKey,
12+
writeLocalesFile,
1313
} from '../lib/utils';
1414

1515
export const translateMissing = async ({
@@ -21,11 +21,8 @@ export const translateMissing = async ({
2121
locales,
2222
globPatterns,
2323
context,
24+
openai,
2425
}: Configuration) => {
25-
const openai = new OpenAI({
26-
apiKey: process.env.OPENAI_KEY,
27-
});
28-
2926
const parser = new Parser({
3027
nsSeparator: false,
3128
keySeparator: false,
@@ -69,15 +66,15 @@ export const translateMissing = async ({
6966
}
7067
}
7168

72-
console.log(
73-
`Please provide the values for the following keys in ${defaultLocale}:`
74-
);
75-
7669
if (newKeys.length === 0) {
7770
console.log('No new keys found.');
7871
return;
7972
}
8073

74+
console.log(
75+
`Please provide the values for the following keys in ${defaultLocale}:`
76+
);
77+
8178
const newKeysWithDefaultLocale = [];
8279

8380
for (const newKey of newKeys) {
@@ -127,11 +124,9 @@ export const translateMissing = async ({
127124
existingKeys[key.key] = translatedValues[key.key];
128125
}
129126

130-
const resolvedSavePath = savePath
131-
.replace('{{lng}}', locale)
132-
.replace('{{ns}}', namespace);
133-
134-
fs.writeFileSync(resolvedSavePath, JSON.stringify(existingKeys, null, 2));
127+
writeLocalesFile(savePath, locale, namespace, existingKeys);
135128
}
136129
}
130+
131+
console.log(`Successfully translated ${newKeys.length} keys.`);
137132
};

src/index.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { Command } from 'commander';
2+
import OpenAI from 'openai';
3+
import { replaceTranslation } from './commands/replace';
24
import { translateMissing } from './commands/scan';
35
import { loadConfig } from './lib/utils';
46

@@ -19,6 +21,11 @@ const commands = [
1921
description: 'Scan for missing translations',
2022
action: translateMissing,
2123
},
24+
{
25+
name: 'replace',
26+
description: 'Replace a translation',
27+
action: replaceTranslation,
28+
},
2229
];
2330

2431
for (const command of commands) {
@@ -27,6 +34,9 @@ for (const command of commands) {
2734
.description(command.description)
2835
.action(async () => {
2936
const config = await loadConfig();
37+
const openai = new OpenAI({
38+
apiKey: process.env.OPENAI_KEY,
39+
});
3040

3141
if (!process.env.OPENAI_KEY) {
3242
console.error(
@@ -35,7 +45,7 @@ for (const command of commands) {
3545
process.exit(1);
3646
}
3747

38-
command.action(config);
48+
command.action({ ...config, openai });
3949
});
4050
}
4151

src/lib/types.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import OpenAI from 'openai';
2+
13
export interface Configuration {
24
loadPath: string;
35
savePath: string;
@@ -7,4 +9,5 @@ export interface Configuration {
79
locales: string[];
810
globPatterns: string[];
911
context?: string;
12+
openai: OpenAI;
1013
}

src/lib/utils.ts

+14-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,20 @@ export const loadLocalesFile = (
7676
const content = fs.readFileSync(resolvedPath, 'utf-8');
7777
const json = JSON.parse(content);
7878

79-
return json;
79+
return json as Record<string, string>;
80+
};
81+
82+
export const writeLocalesFile = (
83+
path: string,
84+
locale: string,
85+
namespace: string,
86+
data: Record<string, string>
87+
) => {
88+
const resolvedSavePath = path
89+
.replace('{{lng}}', locale)
90+
.replace('{{ns}}', namespace);
91+
92+
fs.writeFileSync(resolvedSavePath, JSON.stringify(data, null, 2));
8093
};
8194

8295
export const getPureKey = (

0 commit comments

Comments
 (0)