| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- /**
- * i18n-aggregator.ts
- *
- * Aggregates translation files that match a list of prefixes.
- *
- */
- import { promises as fs } from "fs";
- import * as path from "path";
- import { factorioPath, scriptOutputPath } from "./file.helper.ts";
- import { dumpFactorioLocale } from "./command.helper.ts";
- type Translations = Record<string, Record<string, unknown>>;
- export const LOCALE_OF_INTEREST = ["fluid", "item", "recipe", "item-group", "quality", "virtual-signal"];
- export const LOCALE_TO_EXPORT = ["en", "ja", "zh-CH", "de", "fr"];
- /**
- * Aggregates i18n JSON files that match a list of prefixes and writes a single
- * JSON file containing all translations for the specified i18n code.
- *
- * @param prefixes Array of file prefixes to look for. Example: ['app', 'common']
- * @param inputFolder The folder to search for the locale files.
- * @param outputFolder The folder where the aggregated JSON will be written.
- * @param i18nCode The i18n code that will be used as the output file name.
- *
- * The function searches `inputFolder` for files that start with one of the
- * provided prefixes and end with `-locale.json`. Each matching file is
- * parsed as JSON and stored in a `Record<string, any>` where the key is the
- * prefix and the value is the parsed JSON object. The final aggregated
- * object is written to `outputFolder/i18n/<i18nCode>.json`.
- */
- export async function aggregateI18n(
- prefixes: string[],
- inputFolder: string,
- outputFolder: string,
- i18nCode: string,
- ): Promise<void> {
- // Resolve absolute paths
- const inputPath = path.resolve(inputFolder);
- const outputPath = path.resolve(outputFolder, "i18n");
- // Ensure the output directory exists
- await fs.mkdir(outputPath, { recursive: true });
- // Read all files in the input directory
- const allFiles = await fs.readdir(inputPath);
- // Map of prefix => filename
- const prefixToFile: Record<string, string> = {};
- // Find the first file that matches each prefix
- for (const prefix of prefixes) {
- const filename = prefix + "-locale.json";
- const match = allFiles.find((f) => f == filename);
- if (match) {
- prefixToFile[prefix] = match;
- }
- }
- const result: Translations = {};
- // Read and parse each matched file
- for (const [prefix, fileName] of Object.entries(prefixToFile)) {
- const filePath = path.join(inputPath, fileName);
- const data = await fs.readFile(filePath, "utf-8");
- try {
- result[prefix] = JSON.parse(data);
- } catch {
- result[prefix] = {};
- }
- }
- // Write the aggregated JSON to the output folder
- const outputFile = path.join(outputPath, `${i18nCode}.json`);
- await fs.writeFile(outputFile, JSON.stringify(result, null, 2), "utf-8");
- }
- const config_folder = process.platform == "win32" ? "config_w" : "config_l";
- /**
- * Updates the first `locale=` line in a file to the supplied locale code.
- *
- * @param localCode New locale code (e.g. "en-US", "de-DE")
- *
- */
- export async function setLocaleInIni(localCode: string): Promise<void> {
- const resolvedPath = path.resolve(factorioPath, config_folder, "config.ini");
- const content = await fs.readFile(resolvedPath, "utf8");
- await fs.writeFile(resolvedPath, content.replace(/^locale=.*$/m, "locale=" + localCode), "utf8");
- }
- export async function extractLocale(outputFolder: string) {
- for (let i18nCode of LOCALE_TO_EXPORT) {
- console.log("Export i18n for " + i18nCode);
- await setLocaleInIni(i18nCode);
- await dumpFactorioLocale();
- await aggregateI18n(LOCALE_OF_INTEREST, scriptOutputPath, outputFolder, i18nCode);
- }
- }
|