From 1e471e40133afd2ca169cbdc807bafb8df05ce52 Mon Sep 17 00:00:00 2001 From: Chloe <44501120+chloezxyy@users.noreply.github.com> Date: Mon, 27 May 2024 12:57:22 +0800 Subject: [PATCH 01/16] fix: 1. display boolean value --- .../address/_components/contract/ContractMethodResult.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/web/src/pages/address/_components/contract/ContractMethodResult.tsx b/apps/web/src/pages/address/_components/contract/ContractMethodResult.tsx index 06347f5f..9750bd8a 100644 --- a/apps/web/src/pages/address/_components/contract/ContractMethodResult.tsx +++ b/apps/web/src/pages/address/_components/contract/ContractMethodResult.tsx @@ -49,8 +49,7 @@ const formatOutputValue = (output: SmartContractOutputWithValue): string => { if (typeof output.value === "bigint") { return BigInt(output.value).toString(); } - - return output.value; + return output.value.toString(); }; export default function ContractMethodResult({ From f2a74251ad29f0a76750eca96aa85e6a3b03b3af Mon Sep 17 00:00:00 2001 From: Chloe <44501120+chloezxyy@users.noreply.github.com> Date: Mon, 27 May 2024 13:54:40 +0800 Subject: [PATCH 02/16] fix: 2. convert to boolean values when writing to contract --- .../_components/contract/ContractMethodForm.tsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx index fe86765f..ef97dccc 100644 --- a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx +++ b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx @@ -69,8 +69,19 @@ export default function ContractMethodForm({ address: contractId as `0x${string}`, abi: [method], functionName: method.name, - args: method.inputs?.length > 0 ? [...Object.values(userInput)] : [], - ...(dfiValue && { value: parseEther(`${Number(dfiValue)}`) }), + args: method.inputs?.length > 0 ? [...Object.values(userInput)].map(value => { + + // Parse the value to boolean if it is 'true' or 'false' + switch (value) { + case "true": + return true; + case "false": + return false; + default: + return value; + } + }) : [], + ...(dfiValue && { value: parseEther(`${Number(dfiValue)}`) }), // to specify the amount of Ether to send with the contract function call, if any }; if (isWriteOrWriteProxy) { // Write/WriteProxy From 3ee59de6842f422b5d1a0e25d3d58aa97b194826 Mon Sep 17 00:00:00 2001 From: Chloe <44501120+chloezxyy@users.noreply.github.com> Date: Mon, 27 May 2024 14:42:32 +0800 Subject: [PATCH 03/16] fix: 3. include url query param for view transaction CTA --- .../address/_components/contract/ContractMethodForm.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx index ef97dccc..29eefbab 100644 --- a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx +++ b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx @@ -12,6 +12,7 @@ import { StateMutability, } from "@api/types"; import { DFI_TOKEN_SYMBOL } from "shared/constants"; +import { useNetwork } from "@contexts/NetworkContext"; import ContractMethodTextInput from "./ContractMethodTextInput"; import ContractMethodResult from "./ContractMethodResult"; import SubmitButton from "./SubmitButton"; @@ -36,6 +37,7 @@ export default function ContractMethodForm({ const router = useRouter(); const contractId = router.query.aid as string; const { isConnected } = useAccount(); + const { connection } = useNetwork(); // eslint-disable-next-line @typescript-eslint/no-use-before-define const defaultInputValues = getDefaultValues(method.inputs ?? []); @@ -146,13 +148,13 @@ export default function ContractMethodForm({ )} {/* Write result is always hash */} - {writeResult && ( + {writeResult && ( window.open(`/tx/${writeResult}`, "_blank")} + onClick={() => window.open(`/tx/${writeResult}?network=${connection}`, "_blank")} /> - )} + )} {/* Read result */} {(type === ContractMethodType.Read || From 3bed279d97913670d655138669e54bc0a64bba32 Mon Sep 17 00:00:00 2001 From: Chloe <44501120+chloezxyy@users.noreply.github.com> Date: Mon, 27 May 2024 16:20:30 +0800 Subject: [PATCH 04/16] fix: convert uint256 value to ethers for user input and refactor code --- .../contract/ContractMethodForm.tsx | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx index 29eefbab..7e830acb 100644 --- a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx +++ b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx @@ -1,9 +1,9 @@ -import { useEffect, useState } from "react"; -import { useRouter } from "next/router"; -import { useAccount } from "wagmi"; -import { readContract, writeContract } from "@wagmi/core"; -import { parseEther } from "viem"; -import { ConnectKitButton } from "connectkit"; +import {useEffect, useState} from "react"; +import {useRouter} from "next/router"; +import {useAccount} from "wagmi"; +import {readContract, writeContract} from "@wagmi/core"; +import {parseEther} from "viem"; +import {ConnectKitButton} from "connectkit"; import { ContractMethodType, SmartContractInputOutput, @@ -11,8 +11,8 @@ import { SmartContractOutputWithValue, StateMutability, } from "@api/types"; -import { DFI_TOKEN_SYMBOL } from "shared/constants"; -import { useNetwork } from "@contexts/NetworkContext"; +import {DFI_TOKEN_SYMBOL} from "shared/constants"; +import {useNetwork} from "@contexts/NetworkContext"; import ContractMethodTextInput from "./ContractMethodTextInput"; import ContractMethodResult from "./ContractMethodResult"; import SubmitButton from "./SubmitButton"; @@ -64,25 +64,28 @@ export default function ContractMethodForm({ } }, [resetForm]); + // To handle user input values based on the type of method input + function convertUserInputs(input: KeyValue, inputTypes: SmartContractInputOutput[] | []){ + return Object.entries(input).map(([, value], i) => { + const inputType = inputTypes[i].type; + if (inputType === "bool") { + return value === "true"; + } if (inputType === "uint256") { + return parseEther(value); + } + return value; + }) + } + const handleSubmit = async () => { try { + const convertedValue = convertUserInputs(userInput, method.inputs) setIsLoading(true); const config = { address: contractId as `0x${string}`, abi: [method], functionName: method.name, - args: method.inputs?.length > 0 ? [...Object.values(userInput)].map(value => { - - // Parse the value to boolean if it is 'true' or 'false' - switch (value) { - case "true": - return true; - case "false": - return false; - default: - return value; - } - }) : [], + args: method.inputs?.length > 0 ? convertedValue : [], ...(dfiValue && { value: parseEther(`${Number(dfiValue)}`) }), // to specify the amount of Ether to send with the contract function call, if any }; if (isWriteOrWriteProxy) { @@ -113,7 +116,7 @@ export default function ContractMethodForm({ const hasCompletedInput = method.inputs?.length === fieldsWithValue.length; return ( -
+
{isWriteOrWriteProxy && isPayable && ( // `value` is not part of method `inputs`, only display this additional input field when method is payable { '0': "", '1': "" } + * Eg: [{name:"amount", type:"uint256"}, {name:"to", type:"address"}] -> { '0': "", '1': "" } * @param inputs SmartContractInputOutput[] * @returns */ From 1b98d71babc64cbb97feb4cf442a1e626939f05b Mon Sep 17 00:00:00 2001 From: Chloe <44501120+chloezxyy@users.noreply.github.com> Date: Mon, 27 May 2024 16:23:00 +0800 Subject: [PATCH 05/16] code cleanup --- .../pages/address/_components/contract/ContractMethodForm.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx index 7e830acb..a51ffec5 100644 --- a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx +++ b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx @@ -116,7 +116,7 @@ export default function ContractMethodForm({ const hasCompletedInput = method.inputs?.length === fieldsWithValue.length; return ( -
+
{isWriteOrWriteProxy && isPayable && ( // `value` is not part of method `inputs`, only display this additional input field when method is payable Date: Mon, 27 May 2024 16:26:35 +0800 Subject: [PATCH 06/16] fix: prettier --- .../contract/ContractMethodForm.tsx | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx index a51ffec5..0b9e2385 100644 --- a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx +++ b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx @@ -1,9 +1,9 @@ -import {useEffect, useState} from "react"; -import {useRouter} from "next/router"; -import {useAccount} from "wagmi"; -import {readContract, writeContract} from "@wagmi/core"; -import {parseEther} from "viem"; -import {ConnectKitButton} from "connectkit"; +import { useEffect, useState } from "react"; +import { useRouter } from "next/router"; +import { useAccount } from "wagmi"; +import { readContract, writeContract } from "@wagmi/core"; +import { parseEther } from "viem"; +import { ConnectKitButton } from "connectkit"; import { ContractMethodType, SmartContractInputOutput, @@ -11,8 +11,8 @@ import { SmartContractOutputWithValue, StateMutability, } from "@api/types"; -import {DFI_TOKEN_SYMBOL} from "shared/constants"; -import {useNetwork} from "@contexts/NetworkContext"; +import { DFI_TOKEN_SYMBOL } from "shared/constants"; +import { useNetwork } from "@contexts/NetworkContext"; import ContractMethodTextInput from "./ContractMethodTextInput"; import ContractMethodResult from "./ContractMethodResult"; import SubmitButton from "./SubmitButton"; @@ -65,21 +65,25 @@ export default function ContractMethodForm({ }, [resetForm]); // To handle user input values based on the type of method input - function convertUserInputs(input: KeyValue, inputTypes: SmartContractInputOutput[] | []){ + function convertUserInputs( + input: KeyValue, + inputTypes: SmartContractInputOutput[] | [], + ) { return Object.entries(input).map(([, value], i) => { const inputType = inputTypes[i].type; if (inputType === "bool") { return value === "true"; - } if (inputType === "uint256") { + } + if (inputType === "uint256") { return parseEther(value); } return value; - }) + }); } const handleSubmit = async () => { try { - const convertedValue = convertUserInputs(userInput, method.inputs) + const convertedValue = convertUserInputs(userInput, method.inputs); setIsLoading(true); const config = { address: contractId as `0x${string}`, @@ -151,13 +155,15 @@ export default function ContractMethodForm({ )} {/* Write result is always hash */} - {writeResult && ( + {writeResult && ( window.open(`/tx/${writeResult}?network=${connection}`, "_blank")} + onClick={() => + window.open(`/tx/${writeResult}?network=${connection}`, "_blank") + } /> - )} + )}
{/* Read result */} {(type === ContractMethodType.Read || From 3911580b2d3f1fe41840d4299f3e9a7717ef7b32 Mon Sep 17 00:00:00 2001 From: Chloe <44501120+chloezxyy@users.noreply.github.com> Date: Wed, 12 Jun 2024 13:03:37 +0800 Subject: [PATCH 07/16] fix: .toString() error in contracts tab --- .../address/_components/contract/ContractMethodResult.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/web/src/pages/address/_components/contract/ContractMethodResult.tsx b/apps/web/src/pages/address/_components/contract/ContractMethodResult.tsx index 9750bd8a..8842ae7a 100644 --- a/apps/web/src/pages/address/_components/contract/ContractMethodResult.tsx +++ b/apps/web/src/pages/address/_components/contract/ContractMethodResult.tsx @@ -49,7 +49,12 @@ const formatOutputValue = (output: SmartContractOutputWithValue): string => { if (typeof output.value === "bigint") { return BigInt(output.value).toString(); } - return output.value.toString(); + if (typeof output.value === "boolean") { + return JSON.stringify(output.value); + } + + // for outputs like uint256[], int256[], etc + return output.value; }; export default function ContractMethodResult({ From a4b61dbd33994c64dc6524849e316f13802467db Mon Sep 17 00:00:00 2001 From: Chloe <44501120+chloezxyy@users.noreply.github.com> Date: Wed, 12 Jun 2024 13:47:28 +0800 Subject: [PATCH 08/16] fix: parse string back to object for array of values --- .../address/_components/contract/ContractMethodForm.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx index 0b9e2385..79d03f9c 100644 --- a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx +++ b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx @@ -71,6 +71,13 @@ export default function ContractMethodForm({ ) { return Object.entries(input).map(([, value], i) => { const inputType = inputTypes[i].type; + + // Check if input type is an array of uint256 values + if (inputType.endsWith("[]")) { + // parse the string into an array + return JSON.parse(value); + } + if (inputType === "bool") { return value === "true"; } From 01426c03fc151501b5b2cc0f72191a9e27454235 Mon Sep 17 00:00:00 2001 From: Chloe <44501120+chloezxyy@users.noreply.github.com> Date: Wed, 12 Jun 2024 16:16:55 +0800 Subject: [PATCH 09/16] fix: parse output into string when query from read contract --- .../contract/ContractMethodForm.tsx | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx index 79d03f9c..1f04b430 100644 --- a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx +++ b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx @@ -72,18 +72,18 @@ export default function ContractMethodForm({ return Object.entries(input).map(([, value], i) => { const inputType = inputTypes[i].type; - // Check if input type is an array of uint256 values - if (inputType.endsWith("[]")) { + const parsedValue = JSON.parse(value); + + // Check if inputType matches '[]' from uint256[] and checks if user input matches type + if (inputType === "uint256[]" && Array.isArray(parsedValue)) { // parse the string into an array - return JSON.parse(value); + return parsedValue; } if (inputType === "bool") { return value === "true"; } - if (inputType === "uint256") { - return parseEther(value); - } + return value; }); } @@ -108,9 +108,16 @@ export default function ContractMethodForm({ const data = (await readContract(config)) ?? []; const results = method.outputs?.map((output, index) => { const value = typeof data === "object" ? data[index] : data; + // serialize bigint to display in human readable format + if (output.type.endsWith("[]")) { + return { + type: output.type, + value: value.toString(), + }; + } return { type: output.type, - value, + value }; }); setReadResult(results); From 72d2e5284006d9190f3d2fe861ba864bff4f7f5a Mon Sep 17 00:00:00 2001 From: Chloe <44501120+chloezxyy@users.noreply.github.com> Date: Wed, 12 Jun 2024 16:24:39 +0800 Subject: [PATCH 10/16] fix format --- .../_components/contract/ContractMethodForm.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx index 1f04b430..531f276f 100644 --- a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx +++ b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx @@ -109,15 +109,15 @@ export default function ContractMethodForm({ const results = method.outputs?.map((output, index) => { const value = typeof data === "object" ? data[index] : data; // serialize bigint to display in human readable format - if (output.type.endsWith("[]")) { - return { - type: output.type, - value: value.toString(), - }; - } + if (output.type.endsWith("[]")) { + return { + type: output.type, + value: value.toString(), + }; + } return { type: output.type, - value + value, }; }); setReadResult(results); From 81676f2a39a09a90107126e212c2c0e06f4576bb Mon Sep 17 00:00:00 2001 From: Chloe <44501120+chloezxyy@users.noreply.github.com> Date: Wed, 12 Jun 2024 16:52:05 +0800 Subject: [PATCH 11/16] fix: dont convert values to string --- .../address/_components/contract/ContractMethodForm.tsx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx index 531f276f..45327bbf 100644 --- a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx +++ b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx @@ -108,13 +108,6 @@ export default function ContractMethodForm({ const data = (await readContract(config)) ?? []; const results = method.outputs?.map((output, index) => { const value = typeof data === "object" ? data[index] : data; - // serialize bigint to display in human readable format - if (output.type.endsWith("[]")) { - return { - type: output.type, - value: value.toString(), - }; - } return { type: output.type, value, From 7cd1ce423a3fb773f49bf77873fa397316759d8a Mon Sep 17 00:00:00 2001 From: Chloe <44501120+chloezxyy@users.noreply.github.com> Date: Wed, 12 Jun 2024 17:04:01 +0800 Subject: [PATCH 12/16] fix: handle display of object in read contract upon query --- .../address/_components/contract/ContractMethodResult.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/web/src/pages/address/_components/contract/ContractMethodResult.tsx b/apps/web/src/pages/address/_components/contract/ContractMethodResult.tsx index 8842ae7a..40abf3c1 100644 --- a/apps/web/src/pages/address/_components/contract/ContractMethodResult.tsx +++ b/apps/web/src/pages/address/_components/contract/ContractMethodResult.tsx @@ -52,7 +52,11 @@ const formatOutputValue = (output: SmartContractOutputWithValue): string => { if (typeof output.value === "boolean") { return JSON.stringify(output.value); } - + if (typeof output.value === "object") { + return JSON.stringify(output.value, (_, value) => + typeof value === "bigint" ? value.toString() : value, + ); + } // for outputs like uint256[], int256[], etc return output.value; }; From f58a48e2f576522b77bbbbce9d677d6637a77430 Mon Sep 17 00:00:00 2001 From: Chloe <44501120+chloezxyy@users.noreply.github.com> Date: Wed, 12 Jun 2024 18:07:50 +0800 Subject: [PATCH 13/16] fix: put parse in try catch --- .../contract/ContractMethodForm.tsx | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx index 45327bbf..ec5bad86 100644 --- a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx +++ b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx @@ -72,18 +72,21 @@ export default function ContractMethodForm({ return Object.entries(input).map(([, value], i) => { const inputType = inputTypes[i].type; - const parsedValue = JSON.parse(value); - - // Check if inputType matches '[]' from uint256[] and checks if user input matches type - if (inputType === "uint256[]" && Array.isArray(parsedValue)) { - // parse the string into an array - return parsedValue; + // Check if inputType matches is an array + if (inputType.includes("[]")) { + try { + const parsedValue = JSON.parse(value); + if (Array.isArray(parsedValue)) { + // parse the string into an array + return parsedValue; + } + } catch(e) { + // Intentionally empty - ignore JSON parsing errors + } } - if (inputType === "bool") { return value === "true"; } - return value; }); } From f92c6800d1eae5f18e1154699cd54c2cbcc0b03e Mon Sep 17 00:00:00 2001 From: Chloe <44501120+chloezxyy@users.noreply.github.com> Date: Wed, 12 Jun 2024 18:17:59 +0800 Subject: [PATCH 14/16] fix format --- .../pages/address/_components/contract/ContractMethodForm.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx index ec5bad86..91fbbe19 100644 --- a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx +++ b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx @@ -80,7 +80,7 @@ export default function ContractMethodForm({ // parse the string into an array return parsedValue; } - } catch(e) { + } catch (e) { // Intentionally empty - ignore JSON parsing errors } } From 3c2bba0e808ab10f3b2eb94c68e1baa94ef00c33 Mon Sep 17 00:00:00 2001 From: Harsh Date: Thu, 13 Jun 2024 11:13:14 +0530 Subject: [PATCH 15/16] fix tuple[] output --- .../pages/address/_components/contract/ContractMethodForm.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx index 91fbbe19..f5e16224 100644 --- a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx +++ b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx @@ -106,11 +106,12 @@ export default function ContractMethodForm({ // Write/WriteProxy const { hash } = await writeContract(config); setWriteResult(hash); + } else { // Read/ReadProxy const data = (await readContract(config)) ?? []; const results = method.outputs?.map((output, index) => { - const value = typeof data === "object" ? data[index] : data; + const value = (typeof data === "object" && !Array.isArray(data)) ? data[index] : data; return { type: output.type, value, From 9cd3d4e02e06d2c30535ef5344bf26bc6a2e8b9d Mon Sep 17 00:00:00 2001 From: Harsh Date: Thu, 13 Jun 2024 11:21:02 +0530 Subject: [PATCH 16/16] lint fix --- .../address/_components/contract/ContractMethodForm.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx index f5e16224..47278ec4 100644 --- a/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx +++ b/apps/web/src/pages/address/_components/contract/ContractMethodForm.tsx @@ -106,12 +106,14 @@ export default function ContractMethodForm({ // Write/WriteProxy const { hash } = await writeContract(config); setWriteResult(hash); - } else { // Read/ReadProxy const data = (await readContract(config)) ?? []; const results = method.outputs?.map((output, index) => { - const value = (typeof data === "object" && !Array.isArray(data)) ? data[index] : data; + const value = + typeof data === "object" && !Array.isArray(data) + ? data[index] + : data; return { type: output.type, value,