| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- /**
- * 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");
- }
- /**
- * 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", "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);
- }
- }
|