// Copyright 2017-2026 @pezkuwi/react-params authors & contributors // SPDX-License-Identifier: Apache-2.0 import type { Vec } from '@pezkuwi/types'; import type { KeyValue as Pair } from '@pezkuwi/types/interfaces'; import type { Props, RawParam } from '../types.js'; import React, { useCallback, useState } from 'react'; import { assert, isHex, u8aToHex, u8aToString } from '@pezkuwi/util'; import { useTranslation } from '../translate.js'; import Base from './Base.js'; import Bytes from './Bytes.js'; import File from './File.js'; import { createParam } from './KeyValue.js'; interface Parsed { isValid: boolean; value: [Uint8Array, Uint8Array][]; } const BYTES_TYPE = { info: 0, type: 'Bytes' }; function parseFile (raw: Uint8Array): Parsed { const json = JSON.parse(u8aToString(raw)) as Record; const keys = Object.keys(json); let isValid = keys.length !== 0; const value = keys.map((key): [Uint8Array, Uint8Array] => { const value = json[key]; assert(isHex(key) && isHex(value), `Non-hex key/value pair found in ${key.toString()} => ${value.toString()}`); const encKey = createParam(key); const encValue = createParam(value, true); isValid = isValid && encKey.isValid && encValue.isValid; return [encKey.u8a, encValue.u8a]; }); return { isValid, value }; } function KeyValueArray ({ className = '', defaultValue, isDisabled, isError, label, onChange, onEnter, onEscape, registry, withLabel }: Props): React.ReactElement { const { t } = useTranslation(); const [placeholder, setPlaceholder] = useState(t('click to select or drag and drop JSON key/value (hex-encoded) file')); const _onChange = useCallback( (raw: Uint8Array): void => { let encoded: Parsed = { isValid: false, value: [] }; try { encoded = parseFile(raw); setPlaceholder(t('{{count}} key/value pairs encoded for submission', { replace: { count: encoded.value.length } })); } catch (error) { console.error('Error converting json k/v', error); setPlaceholder(t('click to select or drag and drop JSON key/value (hex-encoded) file')); } onChange && onChange(encoded); }, [onChange, t] ); if (isDisabled) { const pairs = defaultValue.value as Vec; return ( <>
{pairs.map(([key, value]): React.ReactNode => { const keyHex = u8aToHex(key.toU8a(true)); return ( ); })}
); } return ( ); } export default React.memo(KeyValueArray);