From 8260a37121d40e2d139537e1d56ede91f8e21e2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=A7=81Ash=C3=BB=EA=A7=82?= <30575805+Ashu11-A@users.noreply.github.com> Date: Thu, 20 Jun 2024 17:35:08 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=86=95=20Create=20setLanguage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lang is now a class Remove ` in translate pt-BR --- core/locales/pt-BR/translation.json | 2 +- core/src/app.ts | 3 +- core/src/controller/auth.ts | 2 +- core/src/controller/crypt.ts | 7 +-- core/src/controller/database.ts | 2 +- core/src/controller/events.ts | 2 +- core/src/controller/lang.ts | 70 +++++++++++++++++++++++++++++ core/src/controller/license.ts | 2 +- core/src/controller/plugins.ts | 2 +- core/src/controller/socket.ts | 2 +- core/src/discord/base/Client.ts | 2 +- core/src/discord/commands/lang.ts | 2 +- core/src/lang.ts | 57 ----------------------- 13 files changed, 83 insertions(+), 72 deletions(-) create mode 100644 core/src/controller/lang.ts delete mode 100644 core/src/lang.ts diff --git a/core/locales/pt-BR/translation.json b/core/locales/pt-BR/translation.json index f3df8e41..3ec7f5b1 100644 --- a/core/locales/pt-BR/translation.json +++ b/core/locales/pt-BR/translation.json @@ -3,7 +3,7 @@ "start": "📌 Iniciando Discord", "create": "💡 Criando o client do Discord", "close": "💥 Destruindo conexão com o Discord", - "connected": "📡 Connected with {{botName}}`", + "connected": "📡 Connected with {{botName}}", "isConnected": "⛔ Desculpe, mas já estou conectado ao Discord!", "commands": "📝 {{length}} Comandos definidos com sucesso!", "token_send": "⚠️ Token{{isEncrypted}} sendo enviado para: {{pluginId}}", diff --git a/core/src/app.ts b/core/src/app.ts index add5cc78..97871094 100644 --- a/core/src/app.ts +++ b/core/src/app.ts @@ -13,6 +13,7 @@ import { SocketController } from './controller/socket.js' import { generatePort } from './functions/port.js' import { PKG_MODE } from './index.js' import { config } from 'dotenv' +import { Lang } from './controller/lang.js' interface Args { command: string @@ -30,7 +31,7 @@ const argsList: Args[] = [ prompts.override(yargs().argv) config() - await import('./lang.js') + await new Lang().register() await new License().checker() await new Crypt().checker() await new Auth().checker() diff --git a/core/src/controller/auth.ts b/core/src/controller/auth.ts index fe0fd84a..451953a6 100644 --- a/core/src/controller/auth.ts +++ b/core/src/controller/auth.ts @@ -5,7 +5,7 @@ import { CronJob } from 'cron' import { rm } from 'fs/promises' import prompts, { Choice, PromptObject } from 'prompts' import { credentials, Crypt } from './crypt.js' -import { i18 } from '@/lang.js' +import { i18 } from '@/controller/lang.js' const emailRegex = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/g const crypt = new Crypt() diff --git a/core/src/controller/crypt.ts b/core/src/controller/crypt.ts index 778a8087..bf8193ce 100644 --- a/core/src/controller/crypt.ts +++ b/core/src/controller/crypt.ts @@ -1,15 +1,14 @@ +import { i18, Lang } from '@/controller/lang.js'; import { exists } from "@/functions/fs-extra.js"; import { isJson } from "@/functions/validate.js"; import { RootPATH } from "@/index.js"; import { DataCrypted } from "@/interfaces/crypt.js"; -import { i18 } from "@/lang.js"; import * as argon2 from "argon2"; import { passwordStrength } from 'check-password-strength'; import { watch } from 'chokidar'; import { randomBytes } from 'crypto'; import CryptoJS from 'crypto-js'; import { readFile, rm, writeFile } from "fs/promises"; -import i18next from "i18next"; import forge from 'node-forge'; import prompts from "prompts"; @@ -144,9 +143,7 @@ export class Crypt { const outputData = JSON.parse(AESCrypt) as DataCrypted - if (outputData.language !== undefined) { - i18next.changeLanguage(outputData.language) - } + if (outputData.language !== undefined) new Lang().setLanguage(outputData.language) for (const [key, value] of Object.entries(outputData) as Array<[string, string | object | boolean | number]>) { diff --git a/core/src/controller/database.ts b/core/src/controller/database.ts index 8328cfa9..7bfd24b1 100644 --- a/core/src/controller/database.ts +++ b/core/src/controller/database.ts @@ -3,7 +3,7 @@ import { join } from 'path' import { Socket } from 'socket.io' import { DataSource, FindOptionsWhere, ObjectId, type BaseEntity, type DataSourceOptions } from 'typeorm' import { RootPATH } from '@/index.js' -import { i18 } from '@/lang.js' +import { i18 } from '@/controller/lang.js' export interface EntityImport { default: T } diff --git a/core/src/controller/events.ts b/core/src/controller/events.ts index 69fbf876..8ba91da1 100644 --- a/core/src/controller/events.ts +++ b/core/src/controller/events.ts @@ -5,7 +5,7 @@ import { Config } from './config.js' import { credentials, Crypt } from './crypt.js' import { Database } from './database.js' import { Plugins } from './plugins.js' -import { i18 } from '@/lang.js' +import { i18 } from '@/controller/lang.js' interface EventOptions { client: Socket diff --git a/core/src/controller/lang.ts b/core/src/controller/lang.ts new file mode 100644 index 00000000..6c3c9214 --- /dev/null +++ b/core/src/controller/lang.ts @@ -0,0 +1,70 @@ +import { RootPATH } from '@/index.js' +import { watch } from 'chokidar' +import { mkdir, readFile, writeFile } from 'fs/promises' +import { glob } from 'glob' +import i18next from 'i18next' +import Backend, { FsBackendOptions } from 'i18next-fs-backend' +import { dirname, join } from 'path' +import { exists } from '@/functions/fs-extra.js' +import { __dirname } from '@/index.js' + +export class Lang { + /** + * Recriar os arquivos de lang externamente (do PKG) para possibilitar customizações + */ + async register () { + const path = join(__dirname, '..', 'locales') + const internalLangs = await glob('**/*.json', { cwd: path }) + const wather = watch(path) + const cache = new Map() + void wather.on('all', async (action, path) => { + const language = path.split('/')[path.split('/').length - 2] + + if (cache.get(path)) return + switch (action) { + case 'add': { + i18next.options.backend = { + backend: join(RootPATH, 'locales', '{{lng}}', '{{ns}}.json'), + } + break + } + case 'change': + cache.set(path, true) + await i18next.reloadResources(language).finally(() => setTimeout(() => cache.delete(path), 5000)) + break + } + }) + for (const lang of internalLangs) { + const content = await readFile(join(path, lang), { encoding: 'utf8' }) + const externalDir = join(RootPATH, 'locales', dirname(lang.split('/')[0])) + const externalPath = join(externalDir, lang) + + if (!(await exists(externalPath))) { + await mkdir(externalDir, { recursive: true }).catch(() => undefined) + await writeFile(externalPath, content, { encoding: 'utf8' }) + } + } + } + async setLanguage (lang: string) { + const path = join(RootPATH, 'locales', lang) + if (!(await exists(path))) { + console.log(`⛔ The selected language (${lang}) does not exist, using English by default`) + i18next.changeLanguage('en') + return + } + await i18next.changeLanguage(lang) + } +} + + + +/** + * Inicializar i18 + */ +export const i18 = await i18next.use(Backend).init({ + debug: false, + lng: 'en', + backend: { + loadPath: join(RootPATH, 'locales', '{{lng}}', '{{ns}}.json'), + } +}) diff --git a/core/src/controller/license.ts b/core/src/controller/license.ts index 76cad7ff..32e78800 100644 --- a/core/src/controller/license.ts +++ b/core/src/controller/license.ts @@ -7,7 +7,7 @@ import { existsSync } from "fs"; import { readFile, writeFile } from "fs/promises"; import { join } from "path"; import { __dirname } from '@/index.js' -import { i18 } from "@/lang.js"; +import { i18 } from '@/controller/lang.js'; let watched = false diff --git a/core/src/controller/plugins.ts b/core/src/controller/plugins.ts index 2d9d244e..9c5c5950 100644 --- a/core/src/controller/plugins.ts +++ b/core/src/controller/plugins.ts @@ -15,7 +15,7 @@ import { Config, ConfigOptions } from './config.js' import { Database, EntityImport } from './database.js' import { fileURLToPath } from 'url' import { createVerify } from 'crypto' -import { i18 } from '@/lang.js' +import { i18 } from '@/controller/lang.js' const __dirname = dirname(fileURLToPath(import.meta.url)) const cacheWatcher = new Map() diff --git a/core/src/controller/socket.ts b/core/src/controller/socket.ts index 59b39ed7..c0875bac 100644 --- a/core/src/controller/socket.ts +++ b/core/src/controller/socket.ts @@ -4,7 +4,7 @@ import { Server } from 'socket.io' import ws from 'ws' import { Event } from './events.js' import eiows from 'eiows' -import { i18 } from '@/lang.js' +import { i18 } from '@/controller/lang.js' export class SocketController { protected readonly app: Application diff --git a/core/src/discord/base/Client.ts b/core/src/discord/base/Client.ts index 92a5916c..f3228c8a 100644 --- a/core/src/discord/base/Client.ts +++ b/core/src/discord/base/Client.ts @@ -1,6 +1,6 @@ import { Config } from '@/controller/config.js' import { credentials } from '@/controller/crypt.js' -import { i18 } from '@/lang.js' +import { i18 } from '@/controller/lang.js' import { ApplicationCommandType, AutocompleteInteraction, type BitFieldResolvable, ChatInputCommandInteraction, Client, CommandInteraction, type GatewayIntentsString, IntentsBitField, MessageContextMenuCommandInteraction, Partials, PermissionsBitField, UserContextMenuCommandInteraction } from 'discord.js' import { glob } from 'glob' import { dirname, join } from 'path' diff --git a/core/src/discord/commands/lang.ts b/core/src/discord/commands/lang.ts index 2afa4008..876ed9cf 100644 --- a/core/src/discord/commands/lang.ts +++ b/core/src/discord/commands/lang.ts @@ -4,7 +4,7 @@ import { glob } from "glob"; import i18next from "i18next"; import { Command } from "../base/Commands.js"; import { Crypt } from "@/controller/crypt.js"; -import { i18 } from "@/lang.js"; +import { i18 } from '@/controller/lang.js'; new Command({ name: 'language', diff --git a/core/src/lang.ts b/core/src/lang.ts deleted file mode 100644 index ff9266e7..00000000 --- a/core/src/lang.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { RootPATH } from '@/index.js' -import { watch } from 'chokidar' -import { mkdir, readFile, writeFile } from 'fs/promises' -import { glob } from 'glob' -import i18next from 'i18next' -import Backend, { FsBackendOptions } from 'i18next-fs-backend' -import { dirname, join } from 'path' -import { exists } from './functions/fs-extra.js' -import { __dirname } from './index.js' - -/** - * Recriar os arquivos de lang externamente (do PKG) para possibilitar customizações - */ -const path = join(__dirname, '..', 'locales') -const internalLangs = await glob('**/*.json', { cwd: path }) -const wather = watch(path) -const cache = new Map() -void wather.on('all', async (action, path) => { - const language = path.split('/')[path.split('/').length - 2] - - if (cache.get(path)) return - switch (action) { - case 'add': { - i18next.options.backend = { - backend: join(RootPATH, 'locales', '{{lng}}', '{{ns}}.json'), - } - break - } - case 'change': - cache.set(path, true) - await i18next.reloadResources(language).finally(() => setTimeout(() => cache.delete(path), 5000)) - break - } - -}) - -for (const lang of internalLangs) { - const content = await readFile(join(path, lang), { encoding: 'utf8' }) - const externalDir = join(RootPATH, 'locales', dirname(lang.split('/')[0])) - const externalPath = join(externalDir, lang) - - if (!(await exists(externalPath))) { - await mkdir(externalDir, { recursive: true }).catch(() => undefined) - await writeFile(externalPath, content, { encoding: 'utf8' }) - } -} - -/** - * Inicializar i18 - */ -export const i18 = await i18next.use(Backend).init({ - debug: false, - lng: 'en', - backend: { - loadPath: join(RootPATH, 'locales', '{{lng}}', '{{ns}}.json'), - } -})