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
This commit is contained in:
@@ -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<Null | ImplicitCandidateSignat
|
||||
}
|
||||
}
|
||||
|
||||
export class ValidityVote extends Tuple.with([SessionKey, ValidityAttestation]) {
|
||||
export class ValidityVote extends Tuple.with({ SessionKey, ValidityAttestation }) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,10 +19,10 @@ export type BftAuthoritySignatureValue = [AnyU8a, AnyU8a];
|
||||
*/
|
||||
export class BftAuthoritySignature extends Tuple {
|
||||
constructor (value?: BftAuthoritySignatureValue | Uint8Array) {
|
||||
super(
|
||||
[AuthorityId, Signature],
|
||||
value
|
||||
);
|
||||
super({
|
||||
AuthorityId,
|
||||
Signature
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,10 +50,10 @@ export type BftHashSignatureValue = [AnyU8a, AnyU8a];
|
||||
*/
|
||||
export class BftHashSignature extends Tuple {
|
||||
constructor (value?: BftHashSignatureValue | Uint8Array) {
|
||||
super([
|
||||
super({
|
||||
Hash,
|
||||
Signature
|
||||
], value);
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -43,10 +43,10 @@ export class Other extends Bytes {
|
||||
*/
|
||||
export class Seal extends Tuple {
|
||||
constructor (value: any) {
|
||||
super([
|
||||
super({
|
||||
U64,
|
||||
Signature
|
||||
], value);
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,5 +9,5 @@ import Tuple from './codec/Tuple';
|
||||
* @description
|
||||
* Describes the offline-reporting extrinsic
|
||||
*/
|
||||
export default class InherentOfflineReport extends Tuple.with([]) {
|
||||
export default class InherentOfflineReport extends Tuple.with({}) {
|
||||
}
|
||||
|
||||
@@ -57,10 +57,10 @@ export type KeyValueOptionValue = [AnyU8a, AnyU8a?];
|
||||
*/
|
||||
export class KeyValueOption extends Tuple {
|
||||
constructor (value?: KeyValueOptionValue | Uint8Array) {
|
||||
super([
|
||||
super({
|
||||
StorageKey,
|
||||
Option.with(StorageData)
|
||||
], value);
|
||||
'Option<StorageData>': Option.with(StorageData)
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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<EventMetadata>': Vector.with(EventMetadata)
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,10 +34,10 @@ type RuntimeVersionApiValue = {
|
||||
*/
|
||||
export class RuntimeVersionApi extends Tuple {
|
||||
constructor (value?: RuntimeVersionApiValue | Uint8Array) {
|
||||
super([
|
||||
super({
|
||||
ApiId,
|
||||
U32
|
||||
], value);
|
||||
}, value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)]);
|
||||
});
|
||||
|
||||
@@ -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<Constructor> | {
|
||||
[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<Constructor> = Array<Constructor>
|
||||
> extends Array<Codec> implements Codec {
|
||||
private _Types: S;
|
||||
export default class Tuple extends Array<Codec> 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<Constructor>
|
||||
> (Types: S, value: AnyU8a | string | Array<AnyU8a | AnyNumber | AnyString | undefined | null>): Array<Codec> {
|
||||
private static decodeTuple (_Types: TupleConstructors, value: AnyU8a | string | Array<AnyU8a | AnyNumber | AnyString | undefined | null>): Array<Codec> {
|
||||
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<Constructor> = Array.isArray(_Types)
|
||||
? _Types
|
||||
: Object.values(_Types);
|
||||
|
||||
return Types.map((Type, index) => {
|
||||
return new Type(value && value[index]);
|
||||
});
|
||||
}
|
||||
|
||||
static with<
|
||||
S extends Array<Constructor>
|
||||
> (Types: S): Constructor<Tuple<S>> {
|
||||
return class extends Tuple<S> {
|
||||
static with (Types: TupleConstructors): Constructor<Tuple> {
|
||||
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<string> {
|
||||
return this._Types.map(({ name }) => name);
|
||||
return Array.isArray(this._Types)
|
||||
? this._Types.map(({ name }) => name)
|
||||
: Object.keys(this._Types);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 [];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user