-
Notifications
You must be signed in to change notification settings - Fork 754
/
Copy pathgenerateLangTypes.ts
71 lines (56 loc) · 2.69 KB
/
generateLangTypes.ts
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
import { readFileSync, writeFileSync } from 'fs';
import readStrings from '../src/util/data/readStrings';
const TOP_COMMENT = '// This file is generated by dev/generateLangTypes.ts. Do not edit it manually.\n';
const LANG_KEY_TYPE = `
export type RegularLangKey = keyof LangPair;
export type RegularLangKeyWithVariables = keyof LangPairWithVariables;
export type PluralLangKey = keyof LangPairPlural;
export type PluralLangKeyWithVariables = keyof LangPairPluralWithVariables;
export type LangKey = RegularLangKey | RegularLangKeyWithVariables | PluralLangKey | PluralLangKeyWithVariables;
type LangVariable = string | number | undefined;
`.trim();
const data = readFileSync('./src/assets/localization/fallback.strings', 'utf8');
const parsed = readStrings(data);
const regularKeysWithVars: Record<string, string[]> = {};
const pluralKeysWithVars: Record<string, string[]> = {};
Object.entries(parsed).forEach(([keyWithSuffix, value]) => {
const [key, pluralSuffix] = keyWithSuffix.split('_');
const variables = extractVariables(value);
const acc = pluralSuffix ? pluralKeysWithVars : regularKeysWithVars;
const previousVariables = acc[key] || [];
previousVariables.push(...variables);
acc[key] = previousVariables;
});
const regularTypes = formatKeyWithVariables(false, regularKeysWithVars);
const pluralTypes = formatKeyWithVariables(true, pluralKeysWithVars);
const text = `${TOP_COMMENT}\n${regularTypes}\n${pluralTypes}${LANG_KEY_TYPE}\n`;
writeFileSync('./src/types/language.d.ts', text, 'utf8');
// eslint-disable-next-line no-console
console.log(`Language types generated
${Object.keys(regularKeysWithVars).length} simple keys
${Object.keys(pluralKeysWithVars).length} plural keys
`);
function extractVariables(value: string) {
const matches = value.match(/(?<!\\){[^{}]+}/g);
if (!matches) return [];
return matches.map((match) => match.slice(1, -1));
}
function wrapInQuotes(value: string) {
return `'${value}'`;
}
function formatKeyWithVariables(isPlural: boolean, keysWithVars: Record<string, string[]>) {
let entries = '';
let variableEntries = '';
Object.entries(keysWithVars).forEach(([key, variables]) => {
const uniqueVariables = variables.length ? Array.from(new Set(variables)) : undefined;
if (uniqueVariables) {
const type = `{\n ${uniqueVariables.map((v) => `${wrapInQuotes(v)}: V;`).join('\n ')}\n };\n`;
variableEntries += ` ${wrapInQuotes(key)}: ${type}`;
} else {
entries += ` ${wrapInQuotes(key)}: undefined;\n`;
}
});
const typeName = isPlural ? 'LangPairPlural' : 'LangPair';
return `export interface ${typeName} {\n${entries}}\n
export interface ${typeName}WithVariables<V extends unknown = LangVariable> {\n${variableEntries}}\n`;
}