-
-
Notifications
You must be signed in to change notification settings - Fork 59
/
i18n.js
131 lines (113 loc) · 3.05 KB
/
i18n.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
import fs from "fs-extra";
import glob from "glob";
import sortBy from "lodash/sortBy";
import uniq from "lodash/uniq";
import prettier from "prettier";
main();
async function main() {
const sourceFileLocations = await globPromise("./lib/**/*.tsx");
const translationKeys = await findTranslations(sourceFileLocations);
await updateTranslations(translationKeys);
await updateTypeDefinitions(translationKeys);
}
//#region Translations
async function findTranslations(sourceFileLocations) {
const files = await getFilesContent(sourceFileLocations);
const translationKeys = [];
files.forEach((item) => {
const contentWithoutLineBreaksOrSpaces = item.content
.split("\n")
.join(" ")
.replace(/\s+/g, "");
/**
* `\b` is for space or beginning of line
* then look for any `t("*")`
* `.*?` is not greedy
*/
const match = contentWithoutLineBreaksOrSpaces.match(/(\b)t\(".*?"\)/gm);
if (match) {
match.forEach((m) => {
/**
* remove `"` `t` `(` and `)`
*/
const formatted = m
.split('"')
.join("")
.split("(")
.join("")
.split(")")
.join("");
const withoutT = formatted.substring(1);
translationKeys.push(withoutT);
});
}
});
return translationKeys;
}
async function updateTranslations(keys) {
const sortedKeys = sortBy(keys, (k) => k);
const files = await importJsonFiles(["./public/locales/en/translation.json"]);
for (const file of files) {
const content = file.content;
const newData = sortedKeys.reduce((acc, curr, index) => {
const existingValue = content[curr];
return {
...acc,
[curr]: existingValue || "",
};
}, {});
const formattedData = prettier.format(JSON.stringify(newData), {
parser: "json",
});
await fs.writeFile(file.location, formattedData);
}
}
async function updateTypeDefinitions(keys) {
const sortedKeys = uniq(sortBy(keys, (k) => k));
const typescript = `
export type ITranslationKeys = ${sortedKeys
.map((k) => `"${k}"`)
.join(" | ")};
`;
const formattedData = prettier.format(typescript, {
parser: "typescript",
});
await fs.writeFile("./lib/locale.ts", formattedData);
}
//#endregion
//#region Glob
async function globPromise(pattern) {
const promise = new Promise((resolve, reject) => {
glob(pattern, {}, function (er, matchingFiles) {
if (er) {
reject(er);
} else {
resolve(matchingFiles);
}
});
});
return promise;
}
async function getFilesContent(locations) {
return Promise.all(
locations.map(async (file) => {
const content = await fs.readFile(file, "utf8");
return {
location: file,
content: content,
};
})
);
}
async function importJsonFiles(translationFilesLocations) {
return Promise.all(
translationFilesLocations.map(async (file) => {
const content = await import(file);
return {
location: file,
content: content,
};
})
);
}
//#endregion