From 304785a5530cbfe8802af67013b44237df2ff17f Mon Sep 17 00:00:00 2001 From: Adrian Date: Wed, 9 Oct 2024 15:18:34 -0400 Subject: [PATCH] Changes to src/utils.ts to ensure correct importing by Vite plugins and extraction of the amespaceMap constant to its own file. --- src/plugins/i18n.ts | 13 +----- src/plugins/namespacemap.ts | 14 +++++++ src/plugins/vite/namespaces-i18n-plugin.ts | 21 +++++----- src/utils.ts | 46 +++++++++++++++++----- 4 files changed, 63 insertions(+), 31 deletions(-) create mode 100644 src/plugins/namespacemap.ts diff --git a/src/plugins/i18n.ts b/src/plugins/i18n.ts index e488b62af45..25e56e05e1e 100644 --- a/src/plugins/i18n.ts +++ b/src/plugins/i18n.ts @@ -4,6 +4,7 @@ import LanguageDetector from "i18next-browser-languagedetector"; import HttpBackend from "i18next-http-backend"; import processor, { KoreanPostpositionProcessor } from "i18next-korean-postposition-processor"; import pkg from "../../package.json"; +import { namespaceMap } from "./namespacemap"; //#region Interfaces/Types @@ -72,18 +73,6 @@ const fonts: Array = [ }, ]; -/** maps namespaces that deviate from the file-name */ -const namespaceMap = { - titles: "trainer-titles", - moveTriggers: "move-trigger", - abilityTriggers: "ability-trigger", - battlePokemonForm: "pokemon-form-battle", - miscDialogue: "dialogue-misc", - battleSpecDialogue: "dialogue-final-boss", - doubleBattleDialogue: "dialogue-double-battle", - splashMessages: "splash-texts", - mysteryEncounterMessages: "mystery-encounter-texts", -}; //#region Functions diff --git a/src/plugins/namespacemap.ts b/src/plugins/namespacemap.ts new file mode 100644 index 00000000000..00e9b4dcda2 --- /dev/null +++ b/src/plugins/namespacemap.ts @@ -0,0 +1,14 @@ +// When changing the file, the server restarts because of the namespaces-18n-plugin.ts + +/** maps namespaces that deviate from the file-name */ +export const namespaceMap = { + titles: "trainer-titles", + moveTriggers: "move-trigger", + abilityTriggers: "ability-trigger", + battlePokemonForm: "pokemon-form-battle", + miscDialogue: "dialogue-misc", + battleSpecDialogue: "dialogue-final-boss", + doubleBattleDialogue: "dialogue-double-battle", + splashMessages: "splash-texts", + mysteryEncounterMessages: "mystery-encounter-texts", +}; diff --git a/src/plugins/vite/namespaces-i18n-plugin.ts b/src/plugins/vite/namespaces-i18n-plugin.ts index 24e7734b94c..17de7c55c06 100644 --- a/src/plugins/vite/namespaces-i18n-plugin.ts +++ b/src/plugins/vite/namespaces-i18n-plugin.ts @@ -1,15 +1,10 @@ import { normalizePath, type Plugin as VitePlugin } from "vite"; import fs from "fs"; import path from "path"; +import { namespaceMap } from "../namespacemap"; +import { kebabCaseToCamelCase, objectSwap } from "../../utils"; -function kebabCaseToCamelCase(str: string): string { - return str.split("-").map((text, index) => { - if (index > 0) { - return text.split("").map((char, i) => i === 0 ? char.toUpperCase() : char).join(""); - } - return text; - }).join(""); -} +const namespaceMapSwap = objectSwap(namespaceMap); function getNameSpaces(dir: string) { const namespace: string[] = []; @@ -23,13 +18,19 @@ function getNameSpaces(dir: string) { const subnamespace = getNameSpaces(filePath); for (let i = 0; i < subnamespace.length; i++) { let ns = subnamespace[i]; - if (kebabCaseToCamelCase(file).replace(".json", "").startsWith("mysteryEncounters")) { + if (namespaceMapSwap[file.replace(".json", "")]) { + ns = namespaceMapSwap[file.replace(".json", "")]; + } else if (kebabCaseToCamelCase(file).replace(".json", "").startsWith("mysteryEncounters")) { ns = subnamespace[i].replace(/Dialogue$/, ""); } namespace.push(`${kebabCaseToCamelCase(file).replace(".json", "")}/${ns}`); } } else if (path.extname(file) === ".json") { - namespace.push(kebabCaseToCamelCase(file).replace(".json", "")); + let ns = kebabCaseToCamelCase(file).replace(".json", ""); + if (namespaceMapSwap[file.replace(".json", "")]) { + ns = namespaceMapSwap[file.replace(".json", "")]; + } + namespace.push(ns); } } diff --git a/src/utils.ts b/src/utils.ts index 9cc95b00826..e50cac59c88 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,5 +1,7 @@ -import { MoneyFormat } from "#enums/money-format"; -import { Moves } from "#enums/moves"; +// So that the utils.ts is also accessible to plugins/vite, it's important that the paths are relative and not aliases .. +// Although, due to this, any change made to the file will cause a server restart +import { MoneyFormat } from "./enums/money-format"; +import { Moves } from "./enums/moves"; import i18next from "i18next"; export type nil = null | undefined; @@ -270,23 +272,23 @@ export function executeIf(condition: boolean, promiseFunc: () => Promise): export const sessionIdKey = "pokerogue_sessionId"; // Check if the current hostname is 'localhost' or an IP address, and ensure a port is specified export const isLocal = ( - (window.location.hostname === "localhost" || - /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/.test(window.location.hostname)) && - window.location.port !== "") || window.location.hostname === ""; + (globalThis.location?.hostname === "localhost" || + /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/.test(globalThis.location?.hostname)) && + globalThis.location?.port !== "") || globalThis.location?.hostname === ""; -export const localServerUrl = import.meta.env.VITE_SERVER_URL ?? `http://${window.location.hostname}:${window.location.port + 1}`; +export const localServerUrl = import.meta.env?.VITE_SERVER_URL ?? `http://${globalThis.location?.hostname}:${globalThis.location?.port + 1}`; // Set the server URL based on whether it's local or not export const apiUrl = localServerUrl ?? "https://api.pokerogue.net"; // used to disable api calls when isLocal is true and a server is not found export let isLocalServerConnected = true; -export const isBeta = import.meta.env.MODE === "beta"; // this checks to see if the env mode is development. Technically this gives the same value for beta AND for dev envs +export const isBeta = import.meta.env?.MODE === "beta"; // this checks to see if the env mode is development. Technically this gives the same value for beta AND for dev envs export function setCookie(cName: string, cValue: string): void { const expiration = new Date(); expiration.setTime(new Date().getTime() + 3600000 * 24 * 30 * 3/*7*/); - document.cookie = `${cName}=${cValue};Secure;SameSite=Strict;Domain=${window.location.hostname};Path=/;Expires=${expiration.toUTCString()}`; + document.cookie = `${cName}=${cValue};Secure;SameSite=Strict;Domain=${globalThis.location.hostname};Path=/;Expires=${expiration.toUTCString()}`; } export function removeCookie(cName: string): void { @@ -294,7 +296,7 @@ export function removeCookie(cName: string): void { document.cookie = `${cName}=;Secure;SameSite=Strict;Domain=pokerogue.net;Path=/;Max-Age=-1`; // we need to remove the cookie from the main domain as well } - document.cookie = `${cName}=;Secure;SameSite=Strict;Domain=${window.location.hostname};Path=/;Max-Age=-1`; + document.cookie = `${cName}=;Secure;SameSite=Strict;Domain=${globalThis.location.hostname};Path=/;Max-Age=-1`; document.cookie = `${cName}=;Secure;SameSite=Strict;Path=/;Max-Age=-1`; // legacy cookie without domain, for older cookies to prevent a login loop } @@ -651,3 +653,29 @@ export function animationFileName(move: Moves): string { export function camelCaseToKebabCase(str: string): string { return str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, (s, o) => (o ? "-" : "") + s.toLowerCase()); } + +/** + * Transforms a kebab-case string into a camelCase string + * @param str The kebabCase string + * @returns A camelCase string + * + * @source {@link https://stackoverflow.com/a/23013726} + */ +export function kebabCaseToCamelCase(str: string): string { + return str.replace(/-./g, (x)=> x[1].toUpperCase()); +} + +/** + * Swap the value with the key and the key with the value + * @param json type {[key: string]: string} + * @returns [value]: key + * + * @source {@link https://stackoverflow.com/a/23013726} + */ +export function objectSwap(json: {[key: string]: string}): {[value: string]: string} { + const ret = {}; + for (const key in json) { + ret[json[key]] = key; + } + return ret; +}