UNPKG

@tryforge/forgescript

Version:

ForgeScript is a comprehensive package that empowers you to effortlessly interact with Discord's API. It ensures scripting remains easy to learn and consistently effective.

154 lines 7.29 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.translateData = void 0; const structures_1 = require("../structures"); const fs_1 = require("fs"); const crypto_1 = require("crypto"); const constants_1 = require("../constants"); const generateBar_1 = require("./generateBar"); const path_1 = require("path"); const thread_1 = require("./thread"); const os_1 = require("os"); const weirdWords = [ ["guild", "server"], ["role", "role id"], ["hex", "hexadecimal"], ["param", "parameter"], ["perm", "permission"] ]; function hash(str) { return (0, crypto_1.createHash)("sha256").update(str).digest().toString("hex"); } async function translateObjectTo(worker, obj, to, existing = {}) { for (const key of Object.keys(obj)) { const value = obj[key]; if (typeof value === "string") { const keyHash = `${key}Hash`; const oldHash = existing[keyHash]; const nowHash = hash(value); if (oldHash !== nowHash) { existing[keyHash] = nowHash; existing[key] = await translate(worker, value, to); } } else { existing[key] = await translateObjectTo(worker, value, to, existing[key]); } } return existing; } async function translate(worker, str, to) { weirdWords.forEach(data => str = str.toLowerCase().includes(data[1]) ? str : str.replaceAll(data[0], data[1])); return (0, thread_1.postMessage)(worker, { locale: to, text: str }); } async function translateEventTo(worker, event, lang, existing = {}) { const newDescriptionHash = hash(event.description); if (newDescriptionHash !== existing.descriptionHash) { existing.descriptionHash = newDescriptionHash; existing.description = await translate(worker, event.description, lang); } return existing; } async function translateFunctionTo(worker, fn, lang, existing = {}) { const newDescriptionHash = hash(fn.description); if (newDescriptionHash !== existing.descriptionHash) { existing.descriptionHash = newDescriptionHash; existing.description = await translate(worker, fn.description, lang); } existing.fields ??= []; for (let i = 0, len = fn.args?.length ?? 0; i < len; i++) { const field = fn.args[i]; const cached = existing.fields[i] ?? {}; const newNameHash = hash(field.name); const newDescriptionHash = hash(field.description); if (newNameHash !== cached.nameHash) { cached.nameHash = newNameHash; cached.name = await translate(worker, field.name, lang); } if (newDescriptionHash !== cached.descriptionHash) { cached.descriptionHash = newDescriptionHash; cached.description = await translate(worker, field.description, lang); } existing.fields[i] = cached; } if (existing.fields.length === 0) delete existing.fields; return existing; } const metaPath = (0, path_1.join)("metadata", "translations"); const docsPath = (0, path_1.join)(metaPath, "docs"); const docsEnPath = (0, path_1.join)(docsPath, "en.json"); const docs = (0, fs_1.existsSync)(docsEnPath) ? JSON.parse((0, fs_1.readFileSync)(docsEnPath, "utf-8")) : null; // For every 300mb available, 1 thread. const threadCount = Math.floor((((0, os_1.totalmem)() - (0, os_1.freemem)()) / (1024 ** 2)) / 300) || 1; async function translateData(options) { const workers = new Array(); structures_1.Logger.info("Spawning " + threadCount + " threads..."); for (let i = 0; i < threadCount; i++) { workers[i] = await (0, thread_1.spawn)("translationThread"); } structures_1.Logger.info("Successfully spawned threads."); if (!(0, fs_1.existsSync)(metaPath)) (0, fs_1.mkdirSync)(metaPath); for (const lang of options.languages) { if (docs) { const resultPath = (0, path_1.join)(docsPath, `${lang}.json`); const cached = (0, fs_1.existsSync)(resultPath) ? JSON.parse((0, fs_1.readFileSync)(resultPath, "utf-8")) : {}; structures_1.Logger.infoUpdate(`Translating docs to ${lang}...`); void await translateObjectTo(workers[0], docs, lang, cached); (0, fs_1.writeFileSync)(resultPath, JSON.stringify(cached), "utf-8"); } const resultPath = (0, path_1.join)(metaPath, `${lang}.json`); const cached = (0, fs_1.existsSync)(resultPath) ? JSON.parse((0, fs_1.readFileSync)(resultPath, "utf-8")) : {}; cached.events ??= {}; cached.functions ??= {}; const functionsStartedAt = Date.now(); for (let x = 0, len = options.functions.length; x < len; x += workers.length) { const promises = new Array(); for (let i = x - workers.length; i < x; i++) { const worker = workers[i % workers.length]; const fn = options.functions[i]; if (!fn) break; const existing = (cached.functions[fn.name] ?? {}); // eslint-disable-next-line no-async-promise-executor promises.push(new Promise(async (resolve) => { cached.functions[fn.name] = await translateFunctionTo(worker, fn, lang, existing); resolve(); })); } await Promise.all(promises); const elapsed = Date.now() - functionsStartedAt; const timeLeft = Math.floor((elapsed / x) * (len - x)); structures_1.Logger.infoUpdate(`[${lang.toUpperCase()} TRANSLATION/FUNCTIONS] [${(0, generateBar_1.generateBar)(x, len, 20)} ${(x * 100 / len).toFixed(2)}%] (${constants_1.TimeParser.parseToString(timeLeft, { limit: 1 })} left)`); } const eventsStartedAt = Date.now(); for (let x = 0, len = options.events.length; x < len; x += workers.length) { const promises = new Array(); for (let i = x - workers.length; i < x; i++) { const worker = workers[i % workers.length]; const ev = options.events[i]; if (!ev) break; const existing = (cached.events[ev.name] ?? {}); // eslint-disable-next-line no-async-promise-executor promises.push(new Promise(async (resolve) => { cached.events[ev.name] = await translateEventTo(worker, ev, lang, existing); resolve(); })); } await Promise.all(promises); const elapsed = Date.now() - eventsStartedAt; const timeLeft = Math.floor((elapsed / x) * (len - x)); structures_1.Logger.infoUpdate(`[${lang.toUpperCase()} TRANSLATION/EVENTS] [${(0, generateBar_1.generateBar)(x, len, 20)} ${(x * 100 / len).toFixed(2)}%] (${constants_1.TimeParser.parseToString(timeLeft, { limit: 1 })} left)`); } (0, fs_1.writeFileSync)(resultPath, JSON.stringify(cached), "utf-8"); structures_1.Logger.infoUpdate("Translations saved, now terminating threads..."); await (0, thread_1.terminate)(...workers); } } exports.translateData = translateData; //# sourceMappingURL=translate.js.map