-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
280 lines (232 loc) · 7.95 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
'use strict';
const consola = require('consola');
const readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
const fs = require('fs');
let localePath = null;
// Prompt the user with a question and return their answer as a promise
function question(q) {
return new Promise(resolve => readline.question(q, answ => resolve(answ)));
}
// Add a new translation sentence to a specific locale file
async function addToLocale(locale, key) {
let value = await question(`Add translation for ${locale} locale or type 'update' to modify an existing one: `);
if (value.toLowerCase() === 'update') {
value = await question(`Enter new value for ${key} in ${locale} locale: `);
consola.ready(`New value: ${value}`);
await updateLocaleSentence(locale, key, value);
return;
}
consola.ready(`Value: ${value}`);
const filePath = `${localePath}/${locale}.json`;
// Read the contents of the locale file as JSON data
let localeJson;
try {
const fileData = await fs.promises.readFile(filePath);
localeJson = JSON.parse(fileData);
} catch (err) {
consola.error(`Unable to read file: ${err}`);
return;
}
// Check if the translation key already exists in the locale file
if (localeJson.hasOwnProperty(key)) {
consola.warn(`Translation key ${key} already exists in ${locale} locale`);
return;
}
// Add the translation key-value pair to the locale JSON data
localeJson[key] = value;
// Convert the JSON data to a formatted string
const data = JSON.stringify(localeJson, null, 2);
// Write the updated JSON data to the locale file
try {
await fs.promises.writeFile(filePath, data);
consola.success('Translation added to locale');
} catch (err) {
consola.error(`Unable to write file: ${err}`);
}
}
// Get a list of locales and prompt the user to add a translation sentence to each one
async function addTranslationSentence() {
if (!localePath) {
localePath = await question('Enter the folder path where the locale files are located: ');
}
const key = await question('Enter the key of the new translation sentence: ');
consola.ready(`Key: ${key}`);
// Read the list of files in the specified folder
let files;
try {
files = await fs.promises.readdir(localePath);
} catch (err) {
consola.error(`Unable to read directory: ${err}`);
return;
}
// Loop through each file in the folder and prompt the user to add a translation sentence
for (const file of files) {
await addToLocale(file.replace('.json', ''), key);
}
consola.success('Translation added to all locales');
}
async function updateLocaleSentence(locale, key, value) {
const filePath = `${localePath}/${locale}.json`;
// Read the contents of the locale file as JSON data
let localeJson;
try {
const fileData = await fs.promises.readFile(filePath);
localeJson = JSON.parse(fileData);
} catch (err) {
consola.error(`Unable to read file: ${err}`);
return;
}
// Check if the translation key exists in the locale file
if (!localeJson.hasOwnProperty(key)) {
consola.warn(`Translation key ${key} does not exist in ${locale} locale`);
return;
}
// Update the translation value in the locale JSON data
localeJson[key] = value;
// Convert the JSON data to a formatted string
const data = JSON.stringify(localeJson, null, 2);
// Write the updated JSON data to the locale file
try {
await fs.promises.writeFile(filePath, data);
consola.success('Translation updated in locale');
} catch (err) {
consola.error(`Unable to write file: ${err}`);
}
}
// Delete a translation sentence from a specific locale file
async function deleteFromLocale() {
if (!localePath) {
localePath = await question('Enter the folder path where the locale files are located: ');
}
const key = await question('Enter the key of the translation sentence to delete: ');
const files = await fs.promises.readdir(localePath);
let deleted = false;
// Loop through each file in the folder and delete the translation key
for (const file of files) {
const locale = file.replace('.json', '');
const filePath = `${localePath}/${file}`;
// Read the contents of the locale file as JSON data
let localeJson;
try {
const fileData = await fs.promises.readFile(filePath);
localeJson = JSON.parse(fileData);
} catch (err) {
consola.error(`Unable to read file: ${err}`);
continue;
}
// Delete the translation key from the locale JSON data
if (localeJson.hasOwnProperty(key)) {
delete localeJson[key];
deleted = true;
}
// Convert the JSON data to a formatted string
const data = JSON.stringify(localeJson, null, 2);
// Write the updated JSON data to the locale file
try {
await fs.promises.writeFile(filePath, data);
} catch (err) {
consola.error(`Unable to write file: ${err}`);
continue;
}
}
if (deleted) {
consola.success(`Translation key '${key}' deleted from all locales`);
} else {
consola.warn(`Translation key '${key}' not found in any locales`);
}
}
// Generate a CSV file from all locales
async function generateCSV() {
if (!localePath) {
localePath = await question('Enter the folder path where the locale files are located: ');
}
// Read the list of files in the specified folder
let files;
try {
files = await fs.promises.readdir(localePath);
} catch (err) {
consola.error(`Unable to read directory: ${err}`);
return;
}
const csvData = {};
// Loop through each file in the folder and add its contents to the CSV data
for (const file of files) {
const locale = file.replace('.json', '');
const filePath = `${localePath}/${file}`;
// Read the contents of the locale file as JSON data
let localeJson;
try {
const fileData = await fs.promises.readFile(filePath);
localeJson = JSON.parse(fileData);
} catch (err) {
consola.error(`Unable to read file: ${err}`);
continue;
}
// Loop through each translation key in the locale JSON data and add it to the CSV data
for (const key in localeJson) {
if (!csvData[key]) {
csvData[key] = {};
}
csvData[key][locale] = localeJson[key];
}
}
// Extract keys and locales from the CSV data
const keys = Object.keys(csvData);
const locales = Object.keys(csvData[keys[0]]);
// Create the header row of the CSV data
const header = ['key', ...locales];
// Create the data rows of the CSV data
const rows = keys.map(key => {
const values = locales.map(locale => csvData[key][locale] || '');
return [key, ...values];
});
// Concatenate the header row and data rows into the final CSV data
const csv = [header, ...rows].map(row => row.join(";")).join('\n');
// Write the CSV data to a file
try {
await fs.promises.writeFile('locales.csv', csv);
consola.success('CSV generated successfully');
} catch (err) {
consola.error(`Unable to write file: ${err}`);
}
}
// Prompt the user to choose an option and handle their selection
async function askOption() {
consola.info('Please choose an option:');
console.log('1 -> Add Translation Sentence');
console.log('2 -> Delete Translation Sentence');
console.log('3 -> Generate CSV extract');
console.log('4 -> Exit');
const option = await question('Option: ');
console.log(`Selected option: ${option}`); // await the promise before printing to the console
switch (parseInt(option)) {
case 1:
await addTranslationSentence();
await askOption();
break;
case 2:
await deleteFromLocale();
await askOption();
break;
case 3:
await generateCSV()
await askOption();
break;
case 4:
consola.info('Exiting...');
process.exit();
default:
consola.error('Invalid option, please choose again');
await askOption();
break;
}
}
// Start the CLI tool
async function i18ncli() {
consola.info('Running i18n editor');
await askOption();
}
module.exports = i18ncli;