From d9655f8a215332be9fea982e1c8f3c062a36af5f Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Tue, 8 Jan 2019 14:28:07 +0100 Subject: [PATCH] Allow Tuple types defined as struct or Array (#548) * Allow Tuple types defined as struct or Array * Update tests (not requiring injection) * Update KeyValue.ts --- packages/types/src/AttestedCandidate.ts | 8 ++--- packages/types/src/Bft.ts | 12 +++---- packages/types/src/Digest.ts | 4 +-- packages/types/src/InherentOfflineReport.ts | 2 +- packages/types/src/KeyValue.ts | 6 ++-- packages/types/src/Metadata/Events.ts | 6 ++-- packages/types/src/RuntimeVersion.ts | 4 +-- packages/types/src/StoredPendingChange.ts | 4 +-- packages/types/src/codec/Tuple.spec.ts | 8 +++++ packages/types/src/codec/Tuple.ts | 35 ++++++++++++--------- packages/types/src/codec/utils/decodeU8a.ts | 6 +++- 11 files changed, 56 insertions(+), 39 deletions(-) diff --git a/packages/types/src/AttestedCandidate.ts b/packages/types/src/AttestedCandidate.ts index aef9f836e8..ce7efd84dd 100644 --- a/packages/types/src/AttestedCandidate.ts +++ b/packages/types/src/AttestedCandidate.ts @@ -18,10 +18,10 @@ import U64 from './U64'; export class CandidateSignature extends Signature { } -export class BalanceUpload extends Tuple.with([AccountId, U64]) { +export class BalanceUpload extends Tuple.with({ AccountId, U64 }) { } -export class EgressQueueRoot extends Tuple.with([ParaId, Hash]) { +export class EgressQueueRoot extends Tuple.with({ ParaId, Hash }) { } export class HeadData extends Bytes { @@ -42,7 +42,7 @@ export class CandidateReceipt extends Struct { } } -export class AvailabilityVote extends Tuple.with([SessionKey, CandidateSignature]) { +export class AvailabilityVote extends Tuple.with({ SessionKey, CandidateSignature }) { } export class ExplicitCandidateSignature extends CandidateSignature { @@ -63,7 +63,7 @@ export class ValidityAttestation extends EnumType': Option.with(StorageData) + }, value); } /** diff --git a/packages/types/src/Metadata/Events.ts b/packages/types/src/Metadata/Events.ts index 38fcf9827c..4102955685 100644 --- a/packages/types/src/Metadata/Events.ts +++ b/packages/types/src/Metadata/Events.ts @@ -41,10 +41,10 @@ export class EventMetadata extends Struct { export class OuterEventMetadataEvent extends Tuple { constructor (value?: any) { - super([ + super({ Text, - Vector.with(EventMetadata) - ], value); + 'Vec': Vector.with(EventMetadata) + }, value); } /** diff --git a/packages/types/src/RuntimeVersion.ts b/packages/types/src/RuntimeVersion.ts index c3b96cbaec..599626a196 100644 --- a/packages/types/src/RuntimeVersion.ts +++ b/packages/types/src/RuntimeVersion.ts @@ -34,10 +34,10 @@ type RuntimeVersionApiValue = { */ export class RuntimeVersionApi extends Tuple { constructor (value?: RuntimeVersionApiValue | Uint8Array) { - super([ + super({ ApiId, U32 - ], value); + }, value); } /** diff --git a/packages/types/src/StoredPendingChange.ts b/packages/types/src/StoredPendingChange.ts index 8b3328d8a3..85ef90d618 100644 --- a/packages/types/src/StoredPendingChange.ts +++ b/packages/types/src/StoredPendingChange.ts @@ -30,10 +30,10 @@ export type StoredPendingChangeValue = { */ export class NextAuthority extends Tuple { constructor (value?: Uint8Array | NextAuthorityValue) { - super([ + super({ SessionKey, U64 - ], value); + }, value); } get index (): U64 { diff --git a/packages/types/src/codec/Tuple.spec.ts b/packages/types/src/codec/Tuple.spec.ts index 6b9f167d54..212a384943 100644 --- a/packages/types/src/codec/Tuple.spec.ts +++ b/packages/types/src/codec/Tuple.spec.ts @@ -69,6 +69,14 @@ describe('Tuple', () => { expect(tuple.Types).toEqual(['Text', 'U32']); }); + it('exposes the Types (object creation)', () => { + const test = new Tuple({ + BlockNumber, VoteThreshold + }, []); + + expect(test.Types).toEqual(['BlockNumber', 'VoteThreshold']); + }); + it('exposes filter', () => { expect(tuple.filter((v) => v.toJSON() === 69)).toEqual([new U32(69)]); }); diff --git a/packages/types/src/codec/Tuple.ts b/packages/types/src/codec/Tuple.ts index f160fa2a3e..bf1f84731c 100644 --- a/packages/types/src/codec/Tuple.ts +++ b/packages/types/src/codec/Tuple.ts @@ -7,6 +7,10 @@ import { isU8a, u8aConcat, u8aToHex, isHex, hexToU8a } from '@polkadot/util'; import { AnyNumber, AnyU8a, AnyString, Codec, Constructor } from '../types'; import decodeU8a from './utils/decodeU8a'; +type TupleConstructors = Array | { + [index: string]: Constructor +}; + /** * @name Tuple * @description @@ -14,36 +18,35 @@ import decodeU8a from './utils/decodeU8a'; * own type. It extends the base JS `Array` object. * @noInheritDoc */ -export default class Tuple< - S extends Array = Array - > extends Array implements Codec { - private _Types: S; +export default class Tuple extends Array implements Codec { + private _Types: TupleConstructors; - constructor (Types: S, value: any) { + constructor (Types: TupleConstructors, value: any) { super( ...Tuple.decodeTuple(Types, value) ); + this._Types = Types; } - private static decodeTuple< - S extends Array - > (Types: S, value: AnyU8a | string | Array): Array { + private static decodeTuple (_Types: TupleConstructors, value: AnyU8a | string | Array): Array { if (isU8a(value)) { - return decodeU8a(value, Types); + return decodeU8a(value, _Types); } else if (isHex(value)) { - return Tuple.decodeTuple(Types, hexToU8a(value)); + return Tuple.decodeTuple(_Types, hexToU8a(value)); } + const Types: Array = Array.isArray(_Types) + ? _Types + : Object.values(_Types); + return Types.map((Type, index) => { return new Type(value && value[index]); }); } - static with< - S extends Array - > (Types: S): Constructor> { - return class extends Tuple { + static with (Types: TupleConstructors): Constructor { + return class extends Tuple { constructor (value?: any) { super(Types, value); } @@ -63,7 +66,9 @@ export default class Tuple< * @description The types definition of the tuple */ get Types (): Array { - return this._Types.map(({ name }) => name); + return Array.isArray(this._Types) + ? this._Types.map(({ name }) => name) + : Object.keys(this._Types); } /** diff --git a/packages/types/src/codec/utils/decodeU8a.ts b/packages/types/src/codec/utils/decodeU8a.ts index 4db53d462c..50e8629f87 100644 --- a/packages/types/src/codec/utils/decodeU8a.ts +++ b/packages/types/src/codec/utils/decodeU8a.ts @@ -11,7 +11,11 @@ import { Codec, Constructor } from '../../types'; * @param u8a - The u8a to decode. * @param types - The array of Constructor to decode the U8a against. */ -export default function decodeU8a (u8a: Uint8Array, types: Constructor[]): Codec[] { +export default function decodeU8a (u8a: Uint8Array, _types: Constructor[] | { [index: string]: Constructor }): Codec[] { + const types = Array.isArray(_types) + ? _types + : Object.values(_types); + if (!types.length) { return []; }