From 8b836020bf9344f45c7c64d156b37fcf8619e0c4 Mon Sep 17 00:00:00 2001 From: Sainan Date: Fri, 24 Jan 2025 14:27:10 +0100 Subject: [PATCH] chore: turn getJSONfromString into a template/generic function (#836) --- src/controllers/api/activateRandomModController.ts | 2 +- src/controllers/api/addFriendImageController.ts | 2 +- src/controllers/api/arcaneCommonController.ts | 2 +- src/controllers/api/artifactsController.ts | 2 +- .../api/claimCompletedRecipeController.ts | 2 +- src/controllers/api/createGuildController.ts | 2 +- src/controllers/api/endlessXpController.ts | 2 +- src/controllers/api/evolveWeaponController.ts | 2 +- src/controllers/api/fishmongerController.ts | 2 +- src/controllers/api/genericUpdateController.ts | 2 +- .../api/getVoidProjectionRewardsController.ts | 2 +- src/controllers/api/gildWeaponController.ts | 2 +- .../api/giveKeyChainTriggeredItemsController.ts | 4 ++-- src/controllers/api/infestedFoundryController.ts | 14 +++++++------- .../api/missionInventoryUpdateController.ts | 2 +- .../api/modularWeaponCraftingController.ts | 2 +- src/controllers/api/nameWeaponController.ts | 2 +- src/controllers/api/playerSkillsController.ts | 2 +- src/controllers/api/rerollRandomModController.ts | 2 +- .../api/setEquippedInstrumentController.ts | 2 +- .../api/setWeaponSkillTreeController.ts | 2 +- src/controllers/api/startRecipeController.ts | 2 +- .../api/syndicateSacrificeController.ts | 2 +- src/controllers/api/trainingResultController.ts | 2 +- .../api/updateChallengeProgressController.ts | 2 +- src/controllers/api/updateQuestController.ts | 2 +- src/controllers/api/updateThemeController.ts | 2 +- src/helpers/stringHelpers.ts | 4 ++-- 28 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/controllers/api/activateRandomModController.ts b/src/controllers/api/activateRandomModController.ts index a0ef4745..cb84feba 100644 --- a/src/controllers/api/activateRandomModController.ts +++ b/src/controllers/api/activateRandomModController.ts @@ -9,7 +9,7 @@ import { ExportUpgrades } from "warframe-public-export-plus"; export const activateRandomModController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); const inventory = await getInventory(accountId); - const request = getJSONfromString(String(req.body)) as IActiveRandomModRequest; + const request = getJSONfromString(String(req.body)); addMods(inventory, [ { ItemType: request.ItemType, diff --git a/src/controllers/api/addFriendImageController.ts b/src/controllers/api/addFriendImageController.ts index 3242234c..3772f7ef 100644 --- a/src/controllers/api/addFriendImageController.ts +++ b/src/controllers/api/addFriendImageController.ts @@ -6,7 +6,7 @@ import { getInventory } from "@/src/services/inventoryService"; const addFriendImageController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); - const json = getJSONfromString(String(req.body)) as IUpdateGlyphRequest; + const json = getJSONfromString(String(req.body)); const inventory = await getInventory(accountId); inventory.ActiveAvatarImageType = json.AvatarImageType; await inventory.save(); diff --git a/src/controllers/api/arcaneCommonController.ts b/src/controllers/api/arcaneCommonController.ts index 1028fc3f..2448140b 100644 --- a/src/controllers/api/arcaneCommonController.ts +++ b/src/controllers/api/arcaneCommonController.ts @@ -6,7 +6,7 @@ import { IOid } from "@/src/types/commonTypes"; export const arcaneCommonController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); - const json = getJSONfromString(String(req.body)) as IArcaneCommonRequest; + const json = getJSONfromString(String(req.body)); const inventory = await getInventory(accountId); const upgrade = inventory.Upgrades.id(json.arcane.ItemId.$oid); if (json.newRank == -1) { diff --git a/src/controllers/api/artifactsController.ts b/src/controllers/api/artifactsController.ts index 564d222a..e9f8d582 100644 --- a/src/controllers/api/artifactsController.ts +++ b/src/controllers/api/artifactsController.ts @@ -7,7 +7,7 @@ import { config } from "@/src/services/configService"; export const artifactsController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); - const artifactsData = getJSONfromString(String(req.body)) as IArtifactsRequest; + const artifactsData = getJSONfromString(String(req.body)); const { Upgrade, LevelDiff, Cost, FusionPointCost } = artifactsData; diff --git a/src/controllers/api/claimCompletedRecipeController.ts b/src/controllers/api/claimCompletedRecipeController.ts index 21beb6c0..779f4587 100644 --- a/src/controllers/api/claimCompletedRecipeController.ts +++ b/src/controllers/api/claimCompletedRecipeController.ts @@ -21,7 +21,7 @@ export interface IClaimCompletedRecipeRequest { } export const claimCompletedRecipeController: RequestHandler = async (req, res) => { - const claimCompletedRecipeRequest = getJSONfromString(String(req.body)) as IClaimCompletedRecipeRequest; + const claimCompletedRecipeRequest = getJSONfromString(String(req.body)); const accountId = await getAccountIdForRequest(req); if (!accountId) throw new Error("no account id"); diff --git a/src/controllers/api/createGuildController.ts b/src/controllers/api/createGuildController.ts index d5ad31e9..8bc34408 100644 --- a/src/controllers/api/createGuildController.ts +++ b/src/controllers/api/createGuildController.ts @@ -6,7 +6,7 @@ import { Guild } from "@/src/models/guildModel"; export const createGuildController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); - const payload = getJSONfromString(String(req.body)) as ICreateGuildRequest; + const payload = getJSONfromString(String(req.body)); // Create guild on database const guild = new Guild({ diff --git a/src/controllers/api/endlessXpController.ts b/src/controllers/api/endlessXpController.ts index 855c5f22..656ebb05 100644 --- a/src/controllers/api/endlessXpController.ts +++ b/src/controllers/api/endlessXpController.ts @@ -7,7 +7,7 @@ import { TEndlessXpCategory } from "@/src/types/inventoryTypes/inventoryTypes"; export const endlessXpController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); const inventory = await getInventory(accountId); - const payload = getJSONfromString(String(req.body)) as IEndlessXpRequest; + const payload = getJSONfromString(String(req.body)); inventory.EndlessXP ??= []; const entry = inventory.EndlessXP.find(x => x.Category == payload.Category); diff --git a/src/controllers/api/evolveWeaponController.ts b/src/controllers/api/evolveWeaponController.ts index 3e70922c..3b2550bb 100644 --- a/src/controllers/api/evolveWeaponController.ts +++ b/src/controllers/api/evolveWeaponController.ts @@ -8,7 +8,7 @@ import { EquipmentFeatures } from "@/src/types/inventoryTypes/commonInventoryTyp export const evolveWeaponController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); const inventory = await getInventory(accountId); - const payload = getJSONfromString(String(req.body)) as IEvolveWeaponRequest; + const payload = getJSONfromString(String(req.body)); const recipe = getRecipe(payload.Recipe)!; if (payload.Action == "EWA_INSTALL") { diff --git a/src/controllers/api/fishmongerController.ts b/src/controllers/api/fishmongerController.ts index 37951333..898f5e4c 100644 --- a/src/controllers/api/fishmongerController.ts +++ b/src/controllers/api/fishmongerController.ts @@ -9,7 +9,7 @@ import { ExportResources, ExportSyndicates } from "warframe-public-export-plus"; export const fishmongerController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); const inventory = await getInventory(accountId); - const body = getJSONfromString(String(req.body)) as IFishmongerRequest; + const body = getJSONfromString(String(req.body)); const miscItemChanges: IMiscItem[] = []; let syndicateTag: string | undefined; let gainedStanding = 0; diff --git a/src/controllers/api/genericUpdateController.ts b/src/controllers/api/genericUpdateController.ts index a8060981..79b6ba44 100644 --- a/src/controllers/api/genericUpdateController.ts +++ b/src/controllers/api/genericUpdateController.ts @@ -9,7 +9,7 @@ import { IGenericUpdate } from "@/src/types/genericUpdate"; const genericUpdateController: RequestHandler = async (request, response) => { const accountId = await getAccountIdForRequest(request); - const update = getJSONfromString(String(request.body)) as IGenericUpdate; + const update = getJSONfromString(String(request.body)); await updateGeneric(update, accountId); response.json(update); }; diff --git a/src/controllers/api/getVoidProjectionRewardsController.ts b/src/controllers/api/getVoidProjectionRewardsController.ts index 9a956a20..eecbdc51 100644 --- a/src/controllers/api/getVoidProjectionRewardsController.ts +++ b/src/controllers/api/getVoidProjectionRewardsController.ts @@ -10,7 +10,7 @@ import { ExportRelics, ExportRewards, TRarity } from "warframe-public-export-plu export const getVoidProjectionRewardsController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); - const data = getJSONfromString(String(req.body)) as IVoidProjectionRewardRequest; + const data = getJSONfromString(String(req.body)); const response: IVoidProjectionRewardResponse = { CurrentWave: data.CurrentWave, ParticipantInfo: data.ParticipantInfo, diff --git a/src/controllers/api/gildWeaponController.ts b/src/controllers/api/gildWeaponController.ts index 5a89415f..ea4f1194 100644 --- a/src/controllers/api/gildWeaponController.ts +++ b/src/controllers/api/gildWeaponController.ts @@ -26,7 +26,7 @@ interface IGildWeaponRequest { export const gildWeaponController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); - const data = getJSONfromString(String(req.body)) as IGildWeaponRequest; + const data = getJSONfromString(String(req.body)); data.ItemId = String(req.query.ItemId); if (!modularWeaponCategory.includes(req.query.Category as WeaponTypeInternal | "Hoverboards")) { throw new Error(`Unknown modular weapon Category: ${String(req.query.Category)}`); diff --git a/src/controllers/api/giveKeyChainTriggeredItemsController.ts b/src/controllers/api/giveKeyChainTriggeredItemsController.ts index 9437e75a..e8f0dda6 100644 --- a/src/controllers/api/giveKeyChainTriggeredItemsController.ts +++ b/src/controllers/api/giveKeyChainTriggeredItemsController.ts @@ -5,9 +5,9 @@ import { addKeyChainItems, getInventory } from "@/src/services/inventoryService" export const giveKeyChainTriggeredItemsController: RequestHandler = async (req, res) => { const accountId = parseString(req.query.accountId); - const keyChainTriggeredItemsRequest = getJSONfromString( + const keyChainTriggeredItemsRequest = getJSONfromString( (req.body as string).toString() - ) as IGiveKeyChainTriggeredItemsRequest; + ); const inventory = await getInventory(accountId); const inventoryChanges = await addKeyChainItems(inventory, keyChainTriggeredItemsRequest); diff --git a/src/controllers/api/infestedFoundryController.ts b/src/controllers/api/infestedFoundryController.ts index 61a74982..5e27f1c9 100644 --- a/src/controllers/api/infestedFoundryController.ts +++ b/src/controllers/api/infestedFoundryController.ts @@ -22,7 +22,7 @@ export const infestedFoundryController: RequestHandler = async (req, res) => { switch (req.query.mode) { case "s": { // shard installation - const request = getJSONfromString(String(req.body)) as IShardInstallRequest; + const request = getJSONfromString(String(req.body)); const inventory = await getInventory(accountId); const suit = inventory.Suits.find(suit => suit._id.toString() == request.SuitId.$oid)!; if (!suit.ArchonCrystalUpgrades || suit.ArchonCrystalUpgrades.length != 5) { @@ -50,7 +50,7 @@ export const infestedFoundryController: RequestHandler = async (req, res) => { case "x": { // shard removal - const request = getJSONfromString(String(req.body)) as IShardUninstallRequest; + const request = getJSONfromString(String(req.body)); const inventory = await getInventory(accountId); const suit = inventory.Suits.find(suit => suit._id.toString() == request.SuitId.$oid)!; @@ -88,7 +88,7 @@ export const infestedFoundryController: RequestHandler = async (req, res) => { case "n": { // name the beast - const request = getJSONfromString(String(req.body)) as IHelminthNameRequest; + const request = getJSONfromString(String(req.body)); const inventory = await getInventory(accountId); inventory.InfestedFoundry ??= {}; inventory.InfestedFoundry.Name = request.newName; @@ -105,7 +105,7 @@ export const infestedFoundryController: RequestHandler = async (req, res) => { case "c": { // consume items - const request = getJSONfromString(String(req.body)) as IHelminthFeedRequest; + const request = getJSONfromString(String(req.body)); const inventory = await getInventory(accountId); inventory.InfestedFoundry ??= {}; inventory.InfestedFoundry.Resources ??= []; @@ -201,7 +201,7 @@ export const infestedFoundryController: RequestHandler = async (req, res) => { case "o": { // offerings update - const request = getJSONfromString(String(req.body)) as IHelminthOfferingsUpdate; + const request = getJSONfromString(String(req.body)); const inventory = await getInventory(accountId); inventory.InfestedFoundry ??= {}; inventory.InfestedFoundry.InvigorationIndex = request.OfferingsIndex; @@ -220,7 +220,7 @@ export const infestedFoundryController: RequestHandler = async (req, res) => { case "a": { // subsume warframe - const request = getJSONfromString(String(req.body)) as IHelminthSubsumeRequest; + const request = getJSONfromString(String(req.body)); const inventory = await getInventory(accountId); const recipe = getRecipe(request.Recipe)!; for (const ingredient of recipe.secretIngredients!) { @@ -283,7 +283,7 @@ export const infestedFoundryController: RequestHandler = async (req, res) => { } case "u": { - const request = getJSONfromString(String(req.body)) as IHelminthInvigorationRequest; + const request = getJSONfromString(String(req.body)); const inventory = await getInventory(accountId); const suit = inventory.Suits.id(request.SuitId.$oid)!; const upgradesExpiry = new Date(new Date().getTime() + 7 * 24 * 60 * 60 * 1000); diff --git a/src/controllers/api/missionInventoryUpdateController.ts b/src/controllers/api/missionInventoryUpdateController.ts index 49203095..f24172c4 100644 --- a/src/controllers/api/missionInventoryUpdateController.ts +++ b/src/controllers/api/missionInventoryUpdateController.ts @@ -52,7 +52,7 @@ import { getInventory } from "@/src/services/inventoryService"; export const missionInventoryUpdateController: RequestHandler = async (req, res): Promise => { const accountId = await getAccountIdForRequest(req); - const missionReport = getJSONfromString((req.body as string).toString()) as IMissionInventoryUpdateRequest; + const missionReport = getJSONfromString((req.body as string).toString()); if (missionReport.MissionStatus !== "GS_SUCCESS") { console.log(`Mission failed: ${missionReport.RewardInfo?.node}`); diff --git a/src/controllers/api/modularWeaponCraftingController.ts b/src/controllers/api/modularWeaponCraftingController.ts index 3eb27310..d70f48ca 100644 --- a/src/controllers/api/modularWeaponCraftingController.ts +++ b/src/controllers/api/modularWeaponCraftingController.ts @@ -29,7 +29,7 @@ interface IModularCraftRequest { export const modularWeaponCraftingController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); - const data = getJSONfromString(String(req.body)) as IModularCraftRequest; + const data = getJSONfromString(String(req.body)); if (!(data.WeaponType in modularWeaponTypes)) { throw new Error(`unknown modular weapon type: ${data.WeaponType}`); } diff --git a/src/controllers/api/nameWeaponController.ts b/src/controllers/api/nameWeaponController.ts index 2a3f4236..843feeb9 100644 --- a/src/controllers/api/nameWeaponController.ts +++ b/src/controllers/api/nameWeaponController.ts @@ -11,7 +11,7 @@ interface INameWeaponRequest { export const nameWeaponController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); const inventory = await getInventory(accountId); - const body = getJSONfromString(String(req.body)) as INameWeaponRequest; + const body = getJSONfromString(String(req.body)); const item = inventory[req.query.Category as string as TEquipmentKey].find( item => item._id.toString() == (req.query.ItemId as string) )!; diff --git a/src/controllers/api/playerSkillsController.ts b/src/controllers/api/playerSkillsController.ts index 2610183f..de7ab4c8 100644 --- a/src/controllers/api/playerSkillsController.ts +++ b/src/controllers/api/playerSkillsController.ts @@ -7,7 +7,7 @@ import { RequestHandler } from "express"; export const playerSkillsController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); const inventory = await getInventory(accountId); - const request = getJSONfromString(String(req.body)) as IPlayerSkillsRequest; + const request = getJSONfromString(String(req.body)); const oldRank: number = inventory.PlayerSkills[request.Skill as keyof IPlayerSkills]; const cost = (request.Pool == "LPP_DRIFTER" ? drifterCosts[oldRank] : 1 << oldRank) * 1000; diff --git a/src/controllers/api/rerollRandomModController.ts b/src/controllers/api/rerollRandomModController.ts index ba72dc43..71bc8f1c 100644 --- a/src/controllers/api/rerollRandomModController.ts +++ b/src/controllers/api/rerollRandomModController.ts @@ -7,7 +7,7 @@ import { getRandomElement } from "@/src/services/rngService"; export const rerollRandomModController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); - const request = getJSONfromString(String(req.body)) as RerollRandomModRequest; + const request = getJSONfromString(String(req.body)); if ("ItemIds" in request) { const inventory = await getInventory(accountId, "Upgrades MiscItems"); const upgrade = inventory.Upgrades.id(request.ItemIds[0])!; diff --git a/src/controllers/api/setEquippedInstrumentController.ts b/src/controllers/api/setEquippedInstrumentController.ts index 0781825a..5b4b9800 100644 --- a/src/controllers/api/setEquippedInstrumentController.ts +++ b/src/controllers/api/setEquippedInstrumentController.ts @@ -6,7 +6,7 @@ import { getJSONfromString } from "@/src/helpers/stringHelpers"; export const setEquippedInstrumentController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); const inventory = await getInventory(accountId); - const body = getJSONfromString(String(req.body)) as ISetEquippedInstrumentRequest; + const body = getJSONfromString(String(req.body)); inventory.EquippedInstrument = body.Instrument; await inventory.save(); res.end(); diff --git a/src/controllers/api/setWeaponSkillTreeController.ts b/src/controllers/api/setWeaponSkillTreeController.ts index d4557f45..98fe7652 100644 --- a/src/controllers/api/setWeaponSkillTreeController.ts +++ b/src/controllers/api/setWeaponSkillTreeController.ts @@ -7,7 +7,7 @@ import { WeaponTypeInternal } from "@/src/services/itemDataService"; export const setWeaponSkillTreeController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); const inventory = await getInventory(accountId); - const payload = getJSONfromString(String(req.body)) as ISetWeaponSkillTreeRequest; + const payload = getJSONfromString(String(req.body)); const item = inventory[req.query.Category as WeaponTypeInternal].find( item => item._id.toString() == (req.query.ItemId as string) diff --git a/src/controllers/api/startRecipeController.ts b/src/controllers/api/startRecipeController.ts index 06ce6d90..642d0cfc 100644 --- a/src/controllers/api/startRecipeController.ts +++ b/src/controllers/api/startRecipeController.ts @@ -14,7 +14,7 @@ interface IStartRecipeRequest { } export const startRecipeController: RequestHandler = async (req, res) => { - const startRecipeRequest = getJSONfromString(String(req.body)) as IStartRecipeRequest; + const startRecipeRequest = getJSONfromString(String(req.body)); logger.debug("StartRecipe Request", { startRecipeRequest }); const accountId = await getAccountIdForRequest(req); diff --git a/src/controllers/api/syndicateSacrificeController.ts b/src/controllers/api/syndicateSacrificeController.ts index e1be3510..9d7ece71 100644 --- a/src/controllers/api/syndicateSacrificeController.ts +++ b/src/controllers/api/syndicateSacrificeController.ts @@ -9,7 +9,7 @@ import { IInventoryChanges } from "@/src/types/purchaseTypes"; export const syndicateSacrificeController: RequestHandler = async (request, response) => { const accountId = await getAccountIdForRequest(request); const inventory = await getInventory(accountId); - const data = getJSONfromString(String(request.body)) as ISyndicateSacrificeRequest; + const data = getJSONfromString(String(request.body)); let syndicate = inventory.Affiliations.find(x => x.Tag == data.AffiliationTag); if (!syndicate) { diff --git a/src/controllers/api/trainingResultController.ts b/src/controllers/api/trainingResultController.ts index eeab95b5..022d6c10 100644 --- a/src/controllers/api/trainingResultController.ts +++ b/src/controllers/api/trainingResultController.ts @@ -19,7 +19,7 @@ interface ITrainingResultsResponse { const trainingResultController: RequestHandler = async (req, res): Promise => { const accountId = await getAccountIdForRequest(req); - const trainingResults = getJSONfromString(String(req.body)) as ITrainingResultsRequest; + const trainingResults = getJSONfromString(String(req.body)); const inventory = await getInventory(accountId); diff --git a/src/controllers/api/updateChallengeProgressController.ts b/src/controllers/api/updateChallengeProgressController.ts index d665a6fb..2889a333 100644 --- a/src/controllers/api/updateChallengeProgressController.ts +++ b/src/controllers/api/updateChallengeProgressController.ts @@ -5,7 +5,7 @@ import { updateChallengeProgress } from "@/src/services/inventoryService"; import { IUpdateChallengeProgressRequest } from "@/src/types/requestTypes"; const updateChallengeProgressController: RequestHandler = async (req, res) => { - const payload = getJSONfromString(String(req.body)) as IUpdateChallengeProgressRequest; + const payload = getJSONfromString(String(req.body)); const accountId = await getAccountIdForRequest(req); await updateChallengeProgress(payload, accountId); diff --git a/src/controllers/api/updateQuestController.ts b/src/controllers/api/updateQuestController.ts index 2b30a3d1..dbfdb499 100644 --- a/src/controllers/api/updateQuestController.ts +++ b/src/controllers/api/updateQuestController.ts @@ -9,7 +9,7 @@ import { addItem, combineInventoryChanges, getInventory } from "@/src/services/i // eslint-disable-next-line @typescript-eslint/no-misused-promises export const updateQuestController: RequestHandler = async (req, res) => { const accountId = parseString(req.query.accountId); - const updateQuestRequest = getJSONfromString((req.body as string).toString()) as IUpdateQuestRequest; + const updateQuestRequest = getJSONfromString((req.body as string).toString()); // updates should be made only to one quest key per request if (updateQuestRequest.QuestKeys.length > 1) { diff --git a/src/controllers/api/updateThemeController.ts b/src/controllers/api/updateThemeController.ts index 17730064..ccb4ab57 100644 --- a/src/controllers/api/updateThemeController.ts +++ b/src/controllers/api/updateThemeController.ts @@ -9,7 +9,7 @@ const updateThemeController: RequestHandler = async (request, response) => { const body = String(request.body); try { - const json = getJSONfromString(body) as IThemeUpdateRequest; + const json = getJSONfromString(body); if (typeof json !== "object") { throw new Error("Invalid data format"); } diff --git a/src/helpers/stringHelpers.ts b/src/helpers/stringHelpers.ts index 89a3ae9d..6ab13851 100644 --- a/src/helpers/stringHelpers.ts +++ b/src/helpers/stringHelpers.ts @@ -1,6 +1,6 @@ -export const getJSONfromString = (str: string): any => { +export const getJSONfromString = (str: string): T => { const jsonSubstring = str.substring(0, str.lastIndexOf("}") + 1); - return JSON.parse(jsonSubstring); + return JSON.parse(jsonSubstring) as T; }; export const getSubstringFromKeyword = (str: string, keyword: string): string => {