Cleanup & split createType (#1307)
* Cleanup & split createType * createType import * Reduce complexity somewhat * Simplify wrapper check * Revert "Simplify wrapper check" This reverts commit e072c7e05e30e68994152af0b5d7b624dc38bba1. * de-dup getTypeClass * Explicit extraction, cleanup getTypeDef * De-dup subType extraction * createType move
This commit is contained in:
@@ -6,7 +6,7 @@ import '../../injector';
|
||||
|
||||
import extrinsicsFromMeta from '@polkadot/api-metadata/extrinsics/fromMetadata';
|
||||
|
||||
import { createTypeUnsafe } from '../../codec/createType';
|
||||
import { createTypeUnsafe } from '../../codec/create';
|
||||
import Metadata from '../Metadata';
|
||||
import Call from '../../primitive/Generic/Call';
|
||||
import { MetadataInterface } from '../types';
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import { TypeDef, TypeDefInfo, TypeDefExtVecFixed } from '../../codec/types';
|
||||
|
||||
import { getTypeDef } from '../../codec/createType';
|
||||
import { getTypeDef } from '../../codec/create';
|
||||
import flattenUniq from './flattenUniq';
|
||||
import { getTypeRegistry } from '../../codec';
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import '../injector';
|
||||
|
||||
import BN from 'bn.js';
|
||||
|
||||
import createType, { ClassOf } from '../codec/createType';
|
||||
import { createType, ClassOf } from './create';
|
||||
import Moment from './Date';
|
||||
import U32 from '../primitive/U32';
|
||||
import Compact from './Compact';
|
||||
|
||||
@@ -8,7 +8,7 @@ import BN from 'bn.js';
|
||||
import { bnToBn, bnToHex, bnToU8a, isString, isU8a, u8aToBn } from '@polkadot/util';
|
||||
import { blake2AsU8a } from '@polkadot/util-crypto';
|
||||
|
||||
import createType from './createType';
|
||||
import { createType } from './create';
|
||||
import { UIntBitLength } from './AbstractInt';
|
||||
|
||||
const BITLENGTH: UIntBitLength = 64;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import '../injector';
|
||||
|
||||
import { ClassOf } from '../codec/createType';
|
||||
import { ClassOf } from './create';
|
||||
import AccountId from '../primitive/Generic/AccountId';
|
||||
import Text from '../primitive/Text';
|
||||
import U32 from '../primitive/U32';
|
||||
|
||||
@@ -10,7 +10,7 @@ import { CodecTo } from '../types';
|
||||
|
||||
import extrinsics from '@polkadot/api-metadata/extrinsics/static';
|
||||
|
||||
import { ClassOf } from '../codec/createType';
|
||||
import { ClassOf } from './create';
|
||||
import Call from '../primitive/Generic/Call';
|
||||
import Text from '../primitive/Text';
|
||||
import U32 from '../primitive/U32';
|
||||
|
||||
@@ -6,7 +6,7 @@ import { AnyNumber } from '../types';
|
||||
|
||||
import { bnToHex, bnToU8a } from '@polkadot/util';
|
||||
|
||||
import { ClassOf } from './createType';
|
||||
import { ClassOf } from './create';
|
||||
import AbstractInt, { DEFAULT_UINT_BITS, UIntBitLength } from './AbstractInt';
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,7 +10,7 @@ import extrinsics from '@polkadot/api-metadata/extrinsics/static';
|
||||
import AccountId from '../primitive/Generic/AccountId';
|
||||
import Call from '../primitive/Generic/Call';
|
||||
import Text from '../primitive/Text';
|
||||
import { createTypeUnsafe } from './createType';
|
||||
import { createTypeUnsafe } from './create';
|
||||
import Vec from './Vec';
|
||||
import Tuple from './Tuple';
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ export default class VecFixed<T extends Codec> extends AbstractArray<T> {
|
||||
return values;
|
||||
}
|
||||
|
||||
public static with<O extends Codec> (Type: Constructor<O>, length: number): Constructor<VecFixed<O>> {
|
||||
public static with<O extends Codec> (Type: Constructor<O> | InterfaceTypes, length: number): Constructor<VecFixed<O>> {
|
||||
return class extends VecFixed<O> {
|
||||
public constructor (value?: any[]) {
|
||||
super(Type, length, value);
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// Copyright 2017-2019 @polkadot/types authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import '../../injector';
|
||||
|
||||
import { createClass } from '.';
|
||||
|
||||
describe('createClass', (): void => {
|
||||
it('should memoize from strings', (): void => {
|
||||
const a = createClass('BabeWeight');
|
||||
const b = createClass('BabeWeight');
|
||||
|
||||
expect(a).toBe(b);
|
||||
});
|
||||
|
||||
it('should return equivalents for Bytes & Vec<u8>', (): void => {
|
||||
const A = createClass('Vec<u8>');
|
||||
const B = createClass('Bytes');
|
||||
|
||||
expect(new A() instanceof B).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright 2017-2019 @polkadot/types authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Codec, Constructor, InterfaceTypes } from '../../types';
|
||||
import { FromReg } from './types';
|
||||
|
||||
import { InterfaceRegistry } from '../../interfaceRegistry';
|
||||
import { getTypeClass } from './getTypeClass';
|
||||
import { getTypeDef } from './getTypeDef';
|
||||
|
||||
export function createClass<T extends Codec = Codec, K extends string = string> (
|
||||
type: K
|
||||
): Constructor<FromReg<T, K>> {
|
||||
return getTypeClass<FromReg<T, K>>(getTypeDef(type));
|
||||
}
|
||||
|
||||
// An unsafe version of the `createType` below. It's unsafe because the `type`
|
||||
// argument here can be any string, which, if not parseable, will yield a
|
||||
// runtime error.
|
||||
export function ClassOfUnsafe<T extends Codec = Codec, K extends string = string> (name: K): Constructor<FromReg<T, K>> {
|
||||
return createClass<T, K>(name);
|
||||
}
|
||||
|
||||
// alias for createClass
|
||||
export function ClassOf<K extends InterfaceTypes> (name: K): Constructor<InterfaceRegistry[K]> {
|
||||
return ClassOfUnsafe<Codec, K>(name) as Constructor<InterfaceRegistry[K]>;
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
// Copyright 2017-2019 @polkadot/types authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import '../../injector';
|
||||
|
||||
import { createClass, createType, createTypeUnsafe, getTypeRegistry, ClassOf } from '.';
|
||||
import CodecSet from '../Set';
|
||||
|
||||
describe('createType', (): void => {
|
||||
it('allows creation of a Struct', (): void => {
|
||||
expect(
|
||||
createTypeUnsafe('{"balance":"Balance","index":"u32"}', [{
|
||||
balance: 1234,
|
||||
index: '0x10'
|
||||
}]).toJSON()
|
||||
).toEqual({
|
||||
balance: 1234,
|
||||
index: 16
|
||||
});
|
||||
});
|
||||
|
||||
it('allows creation of a Tuple', (): void => {
|
||||
expect(
|
||||
createTypeUnsafe('(Balance,u32)', [[1234, 5678]]).toJSON()
|
||||
).toEqual([1234, 5678]);
|
||||
});
|
||||
|
||||
it('allows creation of a Enum (simple)', (): void => {
|
||||
expect(
|
||||
createTypeUnsafe('{"_enum": ["A", "B", "C"]}', [1]).toJSON()
|
||||
).toEqual({ B: null });
|
||||
});
|
||||
|
||||
it('allows creation of a Enum (parametrised)', (): void => {
|
||||
expect(
|
||||
createTypeUnsafe('{"_enum": {"A": null, "B": "u32", "C": null} }', [1]).toJSON()
|
||||
).toEqual({ B: 0 });
|
||||
});
|
||||
|
||||
it('allows creation of a Set', (): void => {
|
||||
expect(
|
||||
createTypeUnsafe<CodecSet>('{"_set": { "A": 1, "B": 2, "C": 4, "D": 8, "E": 16, "G": 32, "H": 64, "I": 128 } }', [1 + 4 + 16 + 64]).strings
|
||||
).toEqual(['A', 'C', 'E', 'H']);
|
||||
});
|
||||
|
||||
it('allows creation of a [u8; 8]', (): void => {
|
||||
expect(
|
||||
createTypeUnsafe('[u8; 8]', [[0x12, 0x00, 0x23, 0x00, 0x45, 0x00, 0x67, 0x00]]).toHex()
|
||||
).toEqual('0x1200230045006700');
|
||||
});
|
||||
|
||||
it('allows creation of a [u16; 4]', (): void => {
|
||||
expect(
|
||||
createTypeUnsafe('[u16; 4]', [[0x1200, 0x2300, 0x4500, 0x6700]]).toU8a()
|
||||
).toEqual(new Uint8Array([0x00, 0x12, 0x00, 0x23, 0x00, 0x45, 0x00, 0x67]));
|
||||
});
|
||||
|
||||
describe('instanceof', (): void => {
|
||||
it('instanceof should work (primitive type)', (): void => {
|
||||
const value = createType('Balance', 1234);
|
||||
|
||||
expect(value instanceof ClassOf('Balance')).toBe(true);
|
||||
});
|
||||
|
||||
it('instanceof should work (srml type)', (): void => {
|
||||
const value = createType('Gas', 1234);
|
||||
const Gas = ClassOf('Gas');
|
||||
|
||||
expect(value instanceof Gas).toBe(true);
|
||||
});
|
||||
|
||||
it('instanceof should work (complex type)', (): void => {
|
||||
getTypeRegistry().register({
|
||||
TestComplex: {
|
||||
balance: 'Balance',
|
||||
accountId: 'AccountId',
|
||||
log: '(u64, u32)',
|
||||
fromSrml: 'Gas'
|
||||
}
|
||||
});
|
||||
|
||||
const value = createTypeUnsafe('TestComplex', [{
|
||||
balance: 123,
|
||||
accountId: '0x1234567812345678123456781234567812345678123456781234567812345678',
|
||||
log: [456, 789],
|
||||
fromSrml: 0
|
||||
}]);
|
||||
|
||||
expect(value instanceof createClass('TestComplex')).toBe(true);
|
||||
});
|
||||
|
||||
it('allows for re-registration of a type', (): void => {
|
||||
const balDef = createType('Balance');
|
||||
|
||||
expect(balDef instanceof ClassOf('Balance'));
|
||||
expect(balDef.bitLength()).toEqual(128);
|
||||
|
||||
getTypeRegistry().register({ Balance: 'u32' });
|
||||
|
||||
const balu32 = createType('Balance');
|
||||
|
||||
expect(balu32 instanceof ClassOf('Balance'));
|
||||
expect(balu32.bitLength()).toEqual(32);
|
||||
});
|
||||
|
||||
it('allows for re-registration of a type (affecting derives)', (): void => {
|
||||
getTypeRegistry().register({
|
||||
Balance: 'u128',
|
||||
TestComplex: {
|
||||
balance: 'Balance',
|
||||
accountId: 'AccountId',
|
||||
log: '(u64, u32)',
|
||||
fromSrml: 'Gas'
|
||||
}
|
||||
});
|
||||
|
||||
const cmpDef: any = createTypeUnsafe('TestComplex');
|
||||
|
||||
expect(cmpDef.balance.bitLength()).toEqual(128);
|
||||
|
||||
getTypeRegistry().register({ Balance: 'u32' });
|
||||
|
||||
const cmpu32: any = createTypeUnsafe('TestComplex');
|
||||
|
||||
expect(cmpu32.balance.bitLength()).toEqual(32);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,61 @@
|
||||
// Copyright 2017-2019 @polkadot/types authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Codec, Constructor, InterfaceTypes } from '../../types';
|
||||
import { FromReg } from './types';
|
||||
|
||||
import { InterfaceRegistry } from '../../interfaceRegistry';
|
||||
import { createClass } from './createClass';
|
||||
|
||||
// With isPedantic, actually check that the encoding matches that supplied. This
|
||||
// is much slower, but verifies that we have the correct types defined
|
||||
function checkInstance<T extends Codec = Codec, K extends string = string> (value: any, created: FromReg<T, K>): void {
|
||||
const inHex = value.toHex(true);
|
||||
const crHex = created.toHex(true);
|
||||
const hasMatch = (inHex === crHex) || (value.toU8a(true).toString() === (
|
||||
created instanceof Uint8Array
|
||||
// strip the input length
|
||||
? created.toU8a().toString()
|
||||
// compare raw. without additions
|
||||
: created.toU8a(true).toString()
|
||||
));
|
||||
|
||||
if (!hasMatch) {
|
||||
console.warn(`${created.toRawType()}:: Input doesn't match output, received ${inHex}, created ${crHex}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Initializes a type with a value. This also checks for fallbacks and in the cases
|
||||
// where isPedantic is specified (storage decoding), also check the format/structure
|
||||
function initType<T extends Codec = Codec, K extends string = string> (Type: Constructor<FromReg<T, K>>, params: any[] = [], isPedantic?: boolean): FromReg<T, K> {
|
||||
const created = new Type(...params);
|
||||
const [value] = params;
|
||||
|
||||
if (isPedantic && value && value.toU8a && !value.isEmpty) {
|
||||
checkInstance(value, created);
|
||||
}
|
||||
|
||||
return created;
|
||||
}
|
||||
|
||||
// An unsafe version of the `createType` below. It's unsafe because the `type`
|
||||
// argument here can be any string, which, if not parseable, will yield a
|
||||
// runtime error.
|
||||
export function createTypeUnsafe<T extends Codec = Codec, K extends string = string> (type: K, params: any[] = [], isPedantic?: boolean): FromReg<T, K> {
|
||||
try {
|
||||
return initType(createClass<T, K>(type), params, isPedantic);
|
||||
} catch (error) {
|
||||
throw new Error(`createType(${type}):: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of a `type` with a given `params`.
|
||||
* @param type - A recognizable string representing the type to create an
|
||||
* instance from
|
||||
* @param params - The value to instantiate the type with
|
||||
*/
|
||||
export function createType<K extends InterfaceTypes> (type: K, ...params: any[]): InterfaceRegistry[K] {
|
||||
return createTypeUnsafe<Codec, K>(type, params) as InterfaceRegistry[K];
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright 2017-2019 @polkadot/types authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import '../../injector';
|
||||
|
||||
import { Codec, Constructor } from '../../types';
|
||||
|
||||
import { getTypeClass } from '.';
|
||||
|
||||
describe('getTypeClass', (): void => {
|
||||
it('does not allow invalid types', (): void => {
|
||||
expect(
|
||||
(): Constructor<Codec> => getTypeClass('SomethingInvalid' as any)
|
||||
).toThrow(/determine type/);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,130 @@
|
||||
// Copyright 2017-2019 @polkadot/types authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Codec, Constructor, InterfaceTypes } from '../../types';
|
||||
import { TypeDef, TypeDefExtVecFixed, TypeDefInfo } from './types';
|
||||
|
||||
import { assert } from '@polkadot/util';
|
||||
|
||||
import Compact from '../Compact';
|
||||
import Enum from '../Enum';
|
||||
import Linkage from '../Linkage';
|
||||
import Option from '../Option';
|
||||
import CodecSet from '../Set';
|
||||
import Struct from '../Struct';
|
||||
import Tuple from '../Tuple';
|
||||
import U8aFixed, { BitLength as U8aFixedBitLength } from '../U8aFixed';
|
||||
import Vec from '../Vec';
|
||||
import VecFixed from '../VecFixed';
|
||||
import { ClassOf } from './createClass';
|
||||
import { getTypeRegistry } from './registry';
|
||||
|
||||
function getSubDefArray (value: TypeDef): TypeDef[] {
|
||||
assert(value.sub && Array.isArray(value.sub), `Expected subtype as TypeDef[] in ${JSON.stringify(value)}`);
|
||||
|
||||
return value.sub as TypeDef[];
|
||||
}
|
||||
|
||||
function getSubDef (value: TypeDef): TypeDef {
|
||||
assert(value.sub && !Array.isArray(value.sub), `Expected subtype as TypeDef in ${JSON.stringify(value)}`);
|
||||
|
||||
return value.sub as TypeDef;
|
||||
}
|
||||
|
||||
function getSubType (value: TypeDef): InterfaceTypes {
|
||||
return getSubDef(value).type as InterfaceTypes;
|
||||
}
|
||||
|
||||
// create a maps of type string constructors from the input
|
||||
function getTypeClassMap (value: TypeDef): Record<string, InterfaceTypes> {
|
||||
const result: Record<string, InterfaceTypes> = {};
|
||||
|
||||
return getSubDefArray(value).reduce((result, sub): Record<string, InterfaceTypes> => {
|
||||
result[sub.name as string] = sub.type as any;
|
||||
|
||||
return result;
|
||||
}, result);
|
||||
}
|
||||
|
||||
// create an array of type string constructors from the input
|
||||
function getTypeClassArray (value: TypeDef): (InterfaceTypes)[] {
|
||||
return getSubDefArray(value).map(({ type }): InterfaceTypes =>
|
||||
type as InterfaceTypes
|
||||
);
|
||||
}
|
||||
|
||||
const infoMapping: Record<TypeDefInfo, (value: TypeDef) => Constructor> = {
|
||||
[TypeDefInfo.Compact]: (value: TypeDef): Constructor => Compact.with(getSubType(value)),
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
[TypeDefInfo.DoubleMap]: (value: TypeDef): Constructor => getTypeClass(getSubDef(value)),
|
||||
|
||||
[TypeDefInfo.Enum]: (value: TypeDef): Constructor => Enum.with(getTypeClassMap(value)),
|
||||
|
||||
[TypeDefInfo.Linkage]: (value: TypeDef): Constructor => Linkage.withKey(getSubType(value)),
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
[TypeDefInfo.Null]: (value: TypeDef): Constructor => ClassOf('Null'),
|
||||
|
||||
[TypeDefInfo.Option]: (value: TypeDef): Constructor => Option.with(getSubType(value)),
|
||||
|
||||
[TypeDefInfo.Plain]: (value: TypeDef): Constructor => {
|
||||
throw new Error(`Unable to find plain type for ${JSON.stringify(value)}`);
|
||||
},
|
||||
|
||||
[TypeDefInfo.Set]: (value: TypeDef): Constructor => {
|
||||
const result: Record<string, number> = {};
|
||||
|
||||
return CodecSet.with(
|
||||
getSubDefArray(value).reduce((result, { name, index }): Record<string, number> => {
|
||||
result[name as string] = index as number;
|
||||
|
||||
return result;
|
||||
}, result)
|
||||
);
|
||||
},
|
||||
|
||||
[TypeDefInfo.Struct]: (value: TypeDef): Constructor => Struct.with(getTypeClassMap(value)),
|
||||
|
||||
[TypeDefInfo.Tuple]: (value: TypeDef): Constructor => Tuple.with(getTypeClassArray(value)),
|
||||
|
||||
[TypeDefInfo.Vec]: (value: TypeDef): Constructor => {
|
||||
const subType = getSubType(value);
|
||||
|
||||
return (
|
||||
subType === 'u8'
|
||||
? ClassOf('Bytes')
|
||||
: Vec.with(subType)
|
||||
);
|
||||
},
|
||||
|
||||
[TypeDefInfo.VecFixed]: (value: TypeDef): Constructor => {
|
||||
assert(value.ext, 'Expected length & type information for fixed vector');
|
||||
|
||||
const ext = value.ext as TypeDefExtVecFixed;
|
||||
|
||||
return (
|
||||
ext.type === 'u8'
|
||||
? U8aFixed.with((ext.length * 8) as U8aFixedBitLength)
|
||||
: VecFixed.with(ext.type as InterfaceTypes, ext.length)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// Returns the type Class for construction
|
||||
export function getTypeClass<T extends Codec = Codec> (value: TypeDef): Constructor<T> {
|
||||
const Type = getTypeRegistry().get<T>(value.type);
|
||||
|
||||
if (Type) {
|
||||
return Type;
|
||||
}
|
||||
|
||||
const getFn = infoMapping[value.info];
|
||||
|
||||
if (!getFn) {
|
||||
throw new Error(`Unable to determine type from ${JSON.stringify(value)}`);
|
||||
}
|
||||
|
||||
return getFn(value) as Constructor<T>;
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
// Copyright 2017-2019 @polkadot/types authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import '../../injector';
|
||||
|
||||
import { TypeDef, TypeDefInfo } from '../types';
|
||||
|
||||
import { getTypeDef } from '.';
|
||||
|
||||
describe('getTypeDef', (): void => {
|
||||
it('does not allow invalid tuples, end )', (): void => {
|
||||
expect(
|
||||
(): TypeDef => getTypeDef('(u64, u32')
|
||||
).toThrow(/Expected '\(' closing with '\)'/);
|
||||
});
|
||||
|
||||
it('does not allow invalid vectors, end >', (): void => {
|
||||
expect(
|
||||
(): TypeDef => getTypeDef('Vec<u64')
|
||||
).toThrow(/Expected 'Vec<' closing with '>'/);
|
||||
});
|
||||
|
||||
it('returns a type structure', (): void => {
|
||||
expect(
|
||||
getTypeDef('(u32, Compact<u32>, Vec<u64>, Option<u128>, DoubleMap<u128>, (Text, Vec<(Bool, u128)>))')
|
||||
).toEqual({
|
||||
info: TypeDefInfo.Tuple,
|
||||
type: '(u32, Compact<u32>, Vec<u64>, Option<u128>, DoubleMap<u128>, (Text, Vec<(Bool, u128)>))',
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u32'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Compact,
|
||||
type: 'Compact<u32>',
|
||||
sub: {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u32'
|
||||
}
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Vec,
|
||||
type: 'Vec<u64>',
|
||||
sub: {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u64'
|
||||
}
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Option,
|
||||
type: 'Option<u128>',
|
||||
sub: {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u128'
|
||||
}
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.DoubleMap,
|
||||
type: 'DoubleMap<u128>',
|
||||
sub: {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u128'
|
||||
}
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Tuple,
|
||||
type: '(Text, Vec<(Bool, u128)>)',
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Vec,
|
||||
type: 'Vec<(Bool, u128)>',
|
||||
sub: {
|
||||
info: TypeDefInfo.Tuple,
|
||||
type: '(Bool, u128)',
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'Bool'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u128'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
it('returns a type structure (actual)', (): void => {
|
||||
expect(
|
||||
getTypeDef('Vec<(PropIndex, Proposal, AccountId)>')
|
||||
).toEqual({
|
||||
info: TypeDefInfo.Vec,
|
||||
type: 'Vec<(PropIndex, Proposal, AccountId)>',
|
||||
sub: {
|
||||
info: TypeDefInfo.Tuple,
|
||||
type: '(PropIndex, Proposal, AccountId)',
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'PropIndex'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'Proposal'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'AccountId'
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('returns an actual Struct', (): void => {
|
||||
expect(
|
||||
getTypeDef('{"balance":"Balance","account_id":"AccountId","log":"(u64, Signature)"}')
|
||||
).toEqual({
|
||||
info: TypeDefInfo.Struct,
|
||||
type: '{"balance":"Balance","account_id":"AccountId","log":"(u64, Signature)"}',
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
name: 'balance',
|
||||
type: 'Balance'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
name: 'account_id',
|
||||
type: 'AccountId'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Tuple,
|
||||
name: 'log',
|
||||
type: '(u64, Signature)',
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u64'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'Signature'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,143 @@
|
||||
// Copyright 2017-2019 @polkadot/types authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { TypeDef, TypeDefExtVecFixed, TypeDefInfo } from './types';
|
||||
|
||||
import { assert } from '@polkadot/util';
|
||||
|
||||
import { typeSplit } from './typeSplit';
|
||||
|
||||
// decode an enum of either of the following forms
|
||||
// { _enum: ['A', 'B', 'C'] }
|
||||
// { _enum: { A: AccountId, B: Balance, C: u32 } }
|
||||
function _decodeEnum (value: TypeDef, details: string[] | Record<string, string>): TypeDef {
|
||||
value.info = TypeDefInfo.Enum;
|
||||
|
||||
// not as pretty, but remain compatible with oo7 for both struct and Array types
|
||||
value.sub = Array.isArray(details)
|
||||
? details.map((name): TypeDef => ({
|
||||
info: TypeDefInfo.Plain,
|
||||
name,
|
||||
type: 'Null'
|
||||
}))
|
||||
: Object.entries(details).map(([name, type]): TypeDef =>
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
getTypeDef(type || 'Null', name)
|
||||
);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// decode a set of the form
|
||||
// { _set: { A: 0b0001, B: 0b0010, C: 0b0100 } }
|
||||
function _decodeSet (value: TypeDef, details: Record<string, number>): TypeDef {
|
||||
value.info = TypeDefInfo.Set;
|
||||
value.sub = Object.entries(details).map(([name, index]): TypeDef => ({
|
||||
index,
|
||||
info: TypeDefInfo.Plain,
|
||||
name,
|
||||
type: name
|
||||
}));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// decode a struct, set or enum
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
function _decodeStruct (value: TypeDef, type: string, subType: string): TypeDef {
|
||||
const parsed = JSON.parse(type);
|
||||
const keys = Object.keys(parsed);
|
||||
|
||||
if (keys.length === 1 && keys[0] === '_enum') {
|
||||
return _decodeEnum(value, parsed[keys[0]]);
|
||||
} else if (keys.length === 1 && keys[0] === '_set') {
|
||||
return _decodeSet(value, parsed[keys[0]]);
|
||||
}
|
||||
|
||||
value.info = TypeDefInfo.Struct;
|
||||
value.sub = keys.map((name): TypeDef =>
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
getTypeDef(parsed[name], name)
|
||||
);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// decode a fixed vector, e.g. [u8;32]
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
function _decodeFixedVec (value: TypeDef, type: string, subType: string): TypeDef {
|
||||
const [vecType, _vecLen] = type.substr(1, type.length - 2).split(';');
|
||||
const vecLen = parseInt(_vecLen.trim(), 10);
|
||||
|
||||
// as a first round, only u8 via u8aFixed, we can add more support
|
||||
assert(vecLen <= 256, `${type}: Only support for [Type; <length>], where length <= 256`);
|
||||
|
||||
value.info = TypeDefInfo.VecFixed;
|
||||
value.ext = { length: vecLen, type: vecType } as unknown as TypeDefExtVecFixed;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// decode a tuple
|
||||
function _decodeTuple (value: TypeDef, type: string, subType: string): TypeDef {
|
||||
value.info = TypeDefInfo.Tuple;
|
||||
value.sub = typeSplit(subType).map((inner): TypeDef =>
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
getTypeDef(inner)
|
||||
);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
function hasWrapper (type: string, [start, end]: [string, string, any]): boolean {
|
||||
if (type.substr(0, start.length) !== start) {
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(type[type.length - 1] === end, `Expected '${start}' closing with '${end}'`);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const nestedExtraction: [string, string, (value: TypeDef, type: string, subType: string) => TypeDef][] = [
|
||||
['[', ']', _decodeFixedVec],
|
||||
['{', '}', _decodeStruct],
|
||||
['(', ')', _decodeTuple]
|
||||
];
|
||||
|
||||
const wrappedExtraction: [string, string, TypeDefInfo][] = [
|
||||
['Compact<', '>', TypeDefInfo.Compact],
|
||||
['Option<', '>', TypeDefInfo.Option],
|
||||
['Vec<', '>', TypeDefInfo.Vec],
|
||||
['Linkage<', '>', TypeDefInfo.Linkage],
|
||||
['DoubleMap<', '>', TypeDefInfo.DoubleMap]
|
||||
];
|
||||
|
||||
function extractSubType (type: string, [start, end]: [string, string, any]): string {
|
||||
return type.substr(start.length, type.length - start.length - end.length);
|
||||
}
|
||||
|
||||
export function getTypeDef (_type: string, name?: string): TypeDef {
|
||||
const type = _type.toString().trim();
|
||||
const value: TypeDef = { info: TypeDefInfo.Plain, name, type };
|
||||
|
||||
const nested = nestedExtraction.find((nested): boolean =>
|
||||
hasWrapper(type, nested)
|
||||
);
|
||||
|
||||
if (nested) {
|
||||
return nested[2](value, type, extractSubType(type, nested));
|
||||
}
|
||||
|
||||
const wrapped = wrappedExtraction.find((wrapped): boolean =>
|
||||
hasWrapper(type, wrapped)
|
||||
);
|
||||
|
||||
if (wrapped) {
|
||||
value.info = wrapped[2];
|
||||
value.sub = getTypeDef(extractSubType(type, wrapped));
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright 2017-2019 @polkadot/types authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { createType } from './createType';
|
||||
|
||||
export * from './createClass';
|
||||
export * from './createType';
|
||||
export * from './getTypeClass';
|
||||
export * from './getTypeDef';
|
||||
export * from './registry';
|
||||
export * from './typeSplit';
|
||||
|
||||
export default createType;
|
||||
+6
-6
@@ -2,14 +2,14 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import '../injector';
|
||||
import '../../injector';
|
||||
|
||||
import { Constructor } from '../types';
|
||||
import { Constructor } from '../../types';
|
||||
|
||||
import { TypeRegistry } from './typeRegistry';
|
||||
import Struct from '../codec/Struct';
|
||||
import Text from '../primitive/Text';
|
||||
import U32 from '../primitive/U32';
|
||||
import { TypeRegistry } from './registry';
|
||||
import Struct from '../Struct';
|
||||
import Text from '../../primitive/Text';
|
||||
import U32 from '../../primitive/U32';
|
||||
|
||||
// Copied from interfacesTs
|
||||
function isChildClass (Parent: Constructor<any>, Child?: Constructor<any>): boolean {
|
||||
+3
-3
@@ -2,11 +2,11 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Codec, Constructor, RegistryTypes } from '../types';
|
||||
import { Codec, Constructor, RegistryTypes } from '../../types';
|
||||
|
||||
import { isFunction, isString, isUndefined } from '@polkadot/util';
|
||||
|
||||
import { createClass } from './createType';
|
||||
import { createClass } from './createClass';
|
||||
|
||||
export class TypeRegistry {
|
||||
public static readonly defaultRegistry: TypeRegistry = new TypeRegistry();
|
||||
@@ -99,6 +99,6 @@ export class TypeRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
export default function getDefaultRegistry (): TypeRegistry {
|
||||
export function getTypeRegistry (): TypeRegistry {
|
||||
return TypeRegistry.defaultRegistry;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// Copyright 2017-2019 @polkadot/types authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import '../../injector';
|
||||
|
||||
import { typeSplit } from '.';
|
||||
|
||||
describe('typeSplit', (): void => {
|
||||
it('splits simple types into an array', (): void => {
|
||||
expect(
|
||||
typeSplit('Text, u32, u64')
|
||||
).toEqual(['Text', 'u32', 'u64']);
|
||||
});
|
||||
|
||||
it('splits nested combinations', (): void => {
|
||||
expect(
|
||||
typeSplit('Text, (u32), Vec<u64>')
|
||||
).toEqual(['Text', '(u32)', 'Vec<u64>']);
|
||||
});
|
||||
|
||||
it('keeps nested tuples together', (): void => {
|
||||
expect(
|
||||
typeSplit('Text, (u32, u128), Vec<u64>')
|
||||
).toEqual(['Text', '(u32, u128)', 'Vec<u64>']);
|
||||
});
|
||||
|
||||
it('keeps nested vector tuples together', (): void => {
|
||||
expect(
|
||||
typeSplit('Text, (u32, u128), Vec<(u64, u32)>')
|
||||
).toEqual(['Text', '(u32, u128)', 'Vec<(u64, u32)>']);
|
||||
});
|
||||
|
||||
it('allows for deep nesting', (): void => {
|
||||
expect(
|
||||
typeSplit('Text, (u32, (u128, u8)), Vec<(u64, (u32, u32))>')
|
||||
).toEqual(['Text', '(u32, (u128, u8))', 'Vec<(u64, (u32, u32))>']);
|
||||
});
|
||||
|
||||
it('checks for unclosed vec', (): void => {
|
||||
expect(
|
||||
(): string[] => typeSplit('Text, Vec<u64')
|
||||
).toThrow(/Invalid defintion/);
|
||||
});
|
||||
|
||||
it('checks for unclosed tuple', (): void => {
|
||||
expect(
|
||||
(): string[] => typeSplit('Text, (u64, u32')
|
||||
).toThrow(/Invalid defintion/);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,51 @@
|
||||
// Copyright 2017-2019 @polkadot/types authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { assert } from '@polkadot/util';
|
||||
|
||||
function isNotNested (...counters: number[]): boolean {
|
||||
return !counters.some((counter): boolean => counter !== 0);
|
||||
}
|
||||
|
||||
// safely split a string on ', ' while taking care of any nested occurences
|
||||
export function typeSplit (type: string): string[] {
|
||||
let [cDepth, fDepth, sDepth, tDepth, start] = [0, 0, 0, 0, 0];
|
||||
const result = [];
|
||||
const extract = (index: number): void => {
|
||||
if (isNotNested(cDepth, fDepth, sDepth, tDepth)) {
|
||||
result.push(type.substr(start, index - start).trim());
|
||||
start = index + 1;
|
||||
}
|
||||
};
|
||||
|
||||
for (let index = 0; index < type.length; index++) {
|
||||
switch (type[index]) {
|
||||
// if we are not nested, add the type
|
||||
case ',': extract(index); break;
|
||||
|
||||
// adjust compact/vec (and friends) depth
|
||||
case '<': cDepth++; break;
|
||||
case '>': cDepth--; break;
|
||||
|
||||
// adjust fixed vec depths
|
||||
case '[': fDepth++; break;
|
||||
case ']': fDepth--; break;
|
||||
|
||||
// adjust struct depth
|
||||
case '{': sDepth++; break;
|
||||
case '}': sDepth--; break;
|
||||
|
||||
// adjust tuple depth
|
||||
case '(': tDepth++; break;
|
||||
case ')': tDepth--; break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(isNotNested(cDepth, fDepth, sDepth, tDepth), `Invalid defintion (missing terminators) found in ${type}`);
|
||||
|
||||
// the final leg of the journey
|
||||
result.push(type.substr(start, type.length - start).trim());
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright 2017-2019 @polkadot/types authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Codec, InterfaceTypes } from '../../types';
|
||||
|
||||
import { InterfaceRegistry } from '../../interfaceRegistry';
|
||||
|
||||
// Type which says: if `K` is in the InterfaceRegistry, then return InterfaceRegistry[K], else fallback to T
|
||||
export type FromReg<T extends Codec, K extends string> = K extends InterfaceTypes
|
||||
? InterfaceRegistry[K]
|
||||
: T;
|
||||
|
||||
export enum TypeDefInfo {
|
||||
Compact,
|
||||
DoubleMap,
|
||||
Enum,
|
||||
Linkage,
|
||||
Option,
|
||||
Plain,
|
||||
Set,
|
||||
Struct,
|
||||
Tuple,
|
||||
Vec,
|
||||
VecFixed,
|
||||
// anything not fully supported (keep this as the last entry)
|
||||
Null
|
||||
}
|
||||
|
||||
export interface TypeDefExtVecFixed {
|
||||
length: number;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface TypeDef {
|
||||
info: TypeDefInfo;
|
||||
index?: number;
|
||||
ext?: TypeDefExtVecFixed; // add additional here as required
|
||||
name?: string;
|
||||
type: string;
|
||||
sub?: TypeDef | TypeDef[];
|
||||
}
|
||||
@@ -1,353 +0,0 @@
|
||||
// Copyright 2017-2019 @polkadot/types authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import '../injector';
|
||||
|
||||
import { Codec, Constructor } from '../types';
|
||||
import { TypeDef, TypeDefInfo } from './types';
|
||||
|
||||
import createType, { createClass, createTypeUnsafe, getTypeClass, getTypeDef, typeSplit, ClassOf } from './createType';
|
||||
import getTypeRegistry from './typeRegistry';
|
||||
import CodecSet from './Set';
|
||||
|
||||
describe('typeSplit', (): void => {
|
||||
it('splits simple types into an array', (): void => {
|
||||
expect(
|
||||
typeSplit('Text, u32, u64')
|
||||
).toEqual(['Text', 'u32', 'u64']);
|
||||
});
|
||||
|
||||
it('splits nested combinations', (): void => {
|
||||
expect(
|
||||
typeSplit('Text, (u32), Vec<u64>')
|
||||
).toEqual(['Text', '(u32)', 'Vec<u64>']);
|
||||
});
|
||||
|
||||
it('keeps nested tuples together', (): void => {
|
||||
expect(
|
||||
typeSplit('Text, (u32, u128), Vec<u64>')
|
||||
).toEqual(['Text', '(u32, u128)', 'Vec<u64>']);
|
||||
});
|
||||
|
||||
it('keeps nested vector tuples together', (): void => {
|
||||
expect(
|
||||
typeSplit('Text, (u32, u128), Vec<(u64, u32)>')
|
||||
).toEqual(['Text', '(u32, u128)', 'Vec<(u64, u32)>']);
|
||||
});
|
||||
|
||||
it('allows for deep nesting', (): void => {
|
||||
expect(
|
||||
typeSplit('Text, (u32, (u128, u8)), Vec<(u64, (u32, u32))>')
|
||||
).toEqual(['Text', '(u32, (u128, u8))', 'Vec<(u64, (u32, u32))>']);
|
||||
});
|
||||
|
||||
it('checks for unclosed vec', (): void => {
|
||||
expect(
|
||||
(): string[] => typeSplit('Text, Vec<u64')
|
||||
).toThrow(/Invalid defintion/);
|
||||
});
|
||||
|
||||
it('checks for unclosed tuple', (): void => {
|
||||
expect(
|
||||
(): string[] => typeSplit('Text, (u64, u32')
|
||||
).toThrow(/Invalid defintion/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTypeValue', (): void => {
|
||||
it('does not allow invalid tuples, end )', (): void => {
|
||||
expect(
|
||||
(): TypeDef => getTypeDef('(u64, u32')
|
||||
).toThrow(/Expected '\(' closing with '\)'/);
|
||||
});
|
||||
|
||||
it('does not allow invalid vectors, end >', (): void => {
|
||||
expect(
|
||||
(): TypeDef => getTypeDef('Vec<u64')
|
||||
).toThrow(/Expected 'Vec<' closing with '>'/);
|
||||
});
|
||||
|
||||
it('returns a type structure', (): void => {
|
||||
expect(
|
||||
getTypeDef('(u32, Compact<u32>, Vec<u64>, Option<u128>, DoubleMap<u128>, (Text, Vec<(Bool, u128)>))')
|
||||
).toEqual({
|
||||
info: TypeDefInfo.Tuple,
|
||||
type: '(u32, Compact<u32>, Vec<u64>, Option<u128>, DoubleMap<u128>, (Text, Vec<(Bool, u128)>))',
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u32'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Compact,
|
||||
type: 'Compact<u32>',
|
||||
sub: {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u32'
|
||||
}
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Vec,
|
||||
type: 'Vec<u64>',
|
||||
sub: {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u64'
|
||||
}
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Option,
|
||||
type: 'Option<u128>',
|
||||
sub: {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u128'
|
||||
}
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.DoubleMap,
|
||||
type: 'DoubleMap<u128>',
|
||||
sub: {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u128'
|
||||
}
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Tuple,
|
||||
type: '(Text, Vec<(Bool, u128)>)',
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Vec,
|
||||
type: 'Vec<(Bool, u128)>',
|
||||
sub: {
|
||||
info: TypeDefInfo.Tuple,
|
||||
type: '(Bool, u128)',
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'Bool'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u128'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
it('returns a type structure (actual)', (): void => {
|
||||
expect(
|
||||
getTypeDef('Vec<(PropIndex, Proposal, AccountId)>')
|
||||
).toEqual({
|
||||
info: TypeDefInfo.Vec,
|
||||
type: 'Vec<(PropIndex, Proposal, AccountId)>',
|
||||
sub: {
|
||||
info: TypeDefInfo.Tuple,
|
||||
type: '(PropIndex, Proposal, AccountId)',
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'PropIndex'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'Proposal'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'AccountId'
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('returns an actual Struct', (): void => {
|
||||
expect(
|
||||
getTypeDef('{"balance":"Balance","account_id":"AccountId","log":"(u64, Signature)"}')
|
||||
).toEqual({
|
||||
info: TypeDefInfo.Struct,
|
||||
type: '{"balance":"Balance","account_id":"AccountId","log":"(u64, Signature)"}',
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
name: 'balance',
|
||||
type: 'Balance'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
name: 'account_id',
|
||||
type: 'AccountId'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Tuple,
|
||||
name: 'log',
|
||||
type: '(u64, Signature)',
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u64'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'Signature'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTypeClass', (): void => {
|
||||
it('does not allow invalid types', (): void => {
|
||||
expect(
|
||||
(): Constructor<Codec> => getTypeClass('SomethingInvalid' as any)
|
||||
).toThrow(/determine type/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createClass', (): void => {
|
||||
it('should memoize from strings', (): void => {
|
||||
const a = createClass('BabeWeight');
|
||||
const b = createClass('BabeWeight');
|
||||
|
||||
expect(a).toBe(b);
|
||||
});
|
||||
|
||||
it('should return equivalents for Bytes & Vec<u8>', (): void => {
|
||||
const A = createClass('Vec<u8>');
|
||||
const B = createClass('Bytes');
|
||||
|
||||
expect(new A() instanceof B).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createType', (): void => {
|
||||
it('allows creation of a Struct', (): void => {
|
||||
expect(
|
||||
createTypeUnsafe('{"balance":"Balance","index":"u32"}', [{
|
||||
balance: 1234,
|
||||
index: '0x10'
|
||||
}]).toJSON()
|
||||
).toEqual({
|
||||
balance: 1234,
|
||||
index: 16
|
||||
});
|
||||
});
|
||||
|
||||
it('allows creation of a Tuple', (): void => {
|
||||
expect(
|
||||
createTypeUnsafe('(Balance,u32)', [[1234, 5678]]).toJSON()
|
||||
).toEqual([1234, 5678]);
|
||||
});
|
||||
|
||||
it('allows creation of a Enum (simple)', (): void => {
|
||||
expect(
|
||||
createTypeUnsafe('{"_enum": ["A", "B", "C"]}', [1]).toJSON()
|
||||
).toEqual({ B: null });
|
||||
});
|
||||
|
||||
it('allows creation of a Enum (parametrised)', (): void => {
|
||||
expect(
|
||||
createTypeUnsafe('{"_enum": {"A": null, "B": "u32", "C": null} }', [1]).toJSON()
|
||||
).toEqual({ B: 0 });
|
||||
});
|
||||
|
||||
it('allows creation of a Set', (): void => {
|
||||
expect(
|
||||
createTypeUnsafe<CodecSet>('{"_set": { "A": 1, "B": 2, "C": 4, "D": 8, "E": 16, "G": 32, "H": 64, "I": 128 } }', [1 + 4 + 16 + 64]).strings
|
||||
).toEqual(['A', 'C', 'E', 'H']);
|
||||
});
|
||||
|
||||
it('allows creation of a [u8; 8]', (): void => {
|
||||
expect(
|
||||
createTypeUnsafe('[u8; 8]', [[0x12, 0x00, 0x23, 0x00, 0x45, 0x00, 0x67, 0x00]]).toHex()
|
||||
).toEqual('0x1200230045006700');
|
||||
});
|
||||
|
||||
it('allows creation of a [u16; 4]', (): void => {
|
||||
expect(
|
||||
createTypeUnsafe('[u16; 4]', [[0x1200, 0x2300, 0x4500, 0x6700]]).toU8a()
|
||||
).toEqual(new Uint8Array([0x00, 0x12, 0x00, 0x23, 0x00, 0x45, 0x00, 0x67]));
|
||||
});
|
||||
|
||||
describe('instanceof', (): void => {
|
||||
it('instanceof should work (primitive type)', (): void => {
|
||||
const value = createType('Balance', 1234);
|
||||
|
||||
expect(value instanceof ClassOf('Balance')).toBe(true);
|
||||
});
|
||||
|
||||
it('instanceof should work (srml type)', (): void => {
|
||||
const value = createType('Gas', 1234);
|
||||
const Gas = ClassOf('Gas');
|
||||
|
||||
expect(value instanceof Gas).toBe(true);
|
||||
});
|
||||
|
||||
it('instanceof should work (complex type)', (): void => {
|
||||
getTypeRegistry().register({
|
||||
TestComplex: {
|
||||
balance: 'Balance',
|
||||
accountId: 'AccountId',
|
||||
log: '(u64, u32)',
|
||||
fromSrml: 'Gas'
|
||||
}
|
||||
});
|
||||
|
||||
const value = createTypeUnsafe('TestComplex', [{
|
||||
balance: 123,
|
||||
accountId: '0x1234567812345678123456781234567812345678123456781234567812345678',
|
||||
log: [456, 789],
|
||||
fromSrml: 0
|
||||
}]);
|
||||
|
||||
expect(value instanceof createClass('TestComplex')).toBe(true);
|
||||
});
|
||||
|
||||
it('allows for re-registration of a type', (): void => {
|
||||
const balDef = createType('Balance');
|
||||
|
||||
expect(balDef instanceof ClassOf('Balance'));
|
||||
expect(balDef.bitLength()).toEqual(128);
|
||||
|
||||
getTypeRegistry().register({ Balance: 'u32' });
|
||||
|
||||
const balu32 = createType('Balance');
|
||||
|
||||
expect(balu32 instanceof ClassOf('Balance'));
|
||||
expect(balu32.bitLength()).toEqual(32);
|
||||
});
|
||||
|
||||
it('allows for re-registration of a type (affecting derives)', (): void => {
|
||||
getTypeRegistry().register({
|
||||
Balance: 'u128',
|
||||
TestComplex: {
|
||||
balance: 'Balance',
|
||||
accountId: 'AccountId',
|
||||
log: '(u64, u32)',
|
||||
fromSrml: 'Gas'
|
||||
}
|
||||
});
|
||||
|
||||
const cmpDef: any = createTypeUnsafe('TestComplex');
|
||||
|
||||
expect(cmpDef.balance.bitLength()).toEqual(128);
|
||||
|
||||
getTypeRegistry().register({ Balance: 'u32' });
|
||||
|
||||
const cmpu32: any = createTypeUnsafe('TestComplex');
|
||||
|
||||
expect(cmpu32.balance.bitLength()).toEqual(32);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,359 +0,0 @@
|
||||
// Copyright 2017-2019 @polkadot/types authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Codec, Constructor, InterfaceTypes } from '../types';
|
||||
import { TypeDef, TypeDefInfo, TypeDefExtVecFixed } from './types';
|
||||
|
||||
import { assert } from '@polkadot/util';
|
||||
|
||||
import { InterfaceRegistry } from '../interfaceRegistry';
|
||||
import Compact from './Compact';
|
||||
import Enum from './Enum';
|
||||
import Linkage from './Linkage';
|
||||
import Option from './Option';
|
||||
import CodecSet from './Set';
|
||||
import Struct from './Struct';
|
||||
import Tuple from './Tuple';
|
||||
import U8aFixed, { BitLength as U8aFixedBitLength } from './U8aFixed';
|
||||
import Vec from './Vec';
|
||||
import VecFixed from './VecFixed';
|
||||
import getTypeRegistry from './typeRegistry';
|
||||
|
||||
// Type which says: if `K` is in the InterfaceRegistry, then return InterfaceRegistry[K], else fallback to T
|
||||
type FromReg<T extends Codec, K extends string> = K extends InterfaceTypes ? InterfaceRegistry[K] : T
|
||||
|
||||
// safely split a string on ', ' while taking care of any nested occurences
|
||||
export function typeSplit (type: string): string[] {
|
||||
let [cDepth, fDepth, sDepth, tDepth, start] = [0, 0, 0, 0, 0];
|
||||
const result = [];
|
||||
|
||||
for (let index = 0; index < type.length; index++) {
|
||||
switch (type[index]) {
|
||||
case ',':
|
||||
// we are not nested, add the type
|
||||
if (cDepth === 0 && fDepth === 0 && sDepth === 0 && tDepth === 0) {
|
||||
result.push(type.substr(start, index - start).trim());
|
||||
start = index + 1;
|
||||
}
|
||||
break;
|
||||
|
||||
// adjust compact/vec (and friends) depth
|
||||
case '<': cDepth++; break;
|
||||
case '>': cDepth--; break;
|
||||
|
||||
// adjust fixed vec depths
|
||||
case '[': fDepth++; break;
|
||||
case ']': fDepth--; break;
|
||||
|
||||
// adjust struct depth
|
||||
case '{': sDepth++; break;
|
||||
case '}': sDepth--; break;
|
||||
|
||||
// adjust tuple depth
|
||||
case '(': tDepth++; break;
|
||||
case ')': tDepth--; break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(!cDepth && !fDepth && !sDepth && !tDepth, `Invalid defintion (missing terminators) found in ${type}`);
|
||||
|
||||
// the final leg of the journey
|
||||
result.push(type.substr(start, type.length - start).trim());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// decode an enum of either of the following forms
|
||||
// { _enum: ['A', 'B', 'C'] }
|
||||
// { _enum: { A: AccountId, B: Balance, C: u32 } }
|
||||
function _decodeEnum (value: TypeDef, details: string[] | Record<string, string>): TypeDef {
|
||||
value.info = TypeDefInfo.Enum;
|
||||
|
||||
// not as pretty, but remain compatible with oo7 for both struct and Array types
|
||||
value.sub = Array.isArray(details)
|
||||
? details.map((name): TypeDef => ({
|
||||
info: TypeDefInfo.Plain,
|
||||
name,
|
||||
type: 'Null'
|
||||
}))
|
||||
: Object.entries(details).map(([name, type]): TypeDef =>
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
getTypeDef(type || 'Null', name)
|
||||
);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// decode a set of the form
|
||||
// { _set: { A: 0b0001, B: 0b0010, C: 0b0100 } }
|
||||
function _decodeSet (value: TypeDef, details: Record<string, number>): TypeDef {
|
||||
value.info = TypeDefInfo.Set;
|
||||
value.sub = Object.entries(details).map(([name, index]): TypeDef => ({
|
||||
index,
|
||||
info: TypeDefInfo.Plain,
|
||||
name,
|
||||
type: name
|
||||
}));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// decode a struct, set or enum
|
||||
function _decodeStruct (type: string, value: TypeDef): TypeDef {
|
||||
const parsed = JSON.parse(type);
|
||||
const keys = Object.keys(parsed);
|
||||
|
||||
if (keys.length === 1 && keys[0] === '_enum') {
|
||||
return _decodeEnum(value, parsed[keys[0]]);
|
||||
} else if (keys.length === 1 && keys[0] === '_set') {
|
||||
return _decodeSet(value, parsed[keys[0]]);
|
||||
}
|
||||
|
||||
value.info = TypeDefInfo.Struct;
|
||||
value.sub = keys.map((name): TypeDef =>
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
getTypeDef(parsed[name], name)
|
||||
);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// decode a fixed vector, e.g. [u8;32]
|
||||
function _decodeFixedVec (type: string, value: TypeDef): TypeDef {
|
||||
const [vecType, _vecLen] = type.substr(1, type.length - 2).split(';');
|
||||
const vecLen = parseInt(_vecLen.trim(), 10);
|
||||
|
||||
// as a first round, only u8 via u8aFixed, we can add more support
|
||||
assert(vecLen <= 256, `${type}: Only support for [Type; <length>], where length <= 256`);
|
||||
|
||||
value.info = TypeDefInfo.VecFixed;
|
||||
value.ext = { length: vecLen, type: vecType } as unknown as TypeDefExtVecFixed;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// decode a tuple
|
||||
function _decodeTuple (subType: string, value: TypeDef): TypeDef {
|
||||
value.info = TypeDefInfo.Tuple;
|
||||
value.sub = typeSplit(subType).map((inner): TypeDef =>
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
getTypeDef(inner)
|
||||
);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
const simpleExtraction: [string, string, TypeDefInfo][] = [
|
||||
['Compact<', '>', TypeDefInfo.Compact],
|
||||
['Option<', '>', TypeDefInfo.Option],
|
||||
['Vec<', '>', TypeDefInfo.Vec],
|
||||
['Linkage<', '>', TypeDefInfo.Linkage],
|
||||
['DoubleMap<', '>', TypeDefInfo.DoubleMap]
|
||||
];
|
||||
|
||||
export function getTypeDef (_type: string, name?: string): TypeDef {
|
||||
const type = _type.toString().trim();
|
||||
const value: TypeDef = { info: TypeDefInfo.Plain, name, type };
|
||||
let subType = '';
|
||||
|
||||
const _hasWrapper = (type: string, start: string, end: string): boolean => {
|
||||
if (type.substr(0, start.length) !== start) {
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(type[type.length - 1] === end, `Expected '${start}' closing with '${end}'`);
|
||||
|
||||
subType = type.substr(start.length, type.length - start.length - 1);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
if (_hasWrapper(type, '[', ']')) {
|
||||
return _decodeFixedVec(type, value);
|
||||
} else if (_hasWrapper(type, '{', '}')) {
|
||||
return _decodeStruct(type, value);
|
||||
} else if (_hasWrapper(type, '(', ')')) {
|
||||
return _decodeTuple(subType, value);
|
||||
}
|
||||
|
||||
const extracted = simpleExtraction.find(([start, end]): boolean => _hasWrapper(type, start, end));
|
||||
|
||||
if (extracted) {
|
||||
value.info = extracted[2];
|
||||
value.sub = getTypeDef(subType);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
export function createClass<T extends Codec = Codec, K extends string = string> (
|
||||
type: K
|
||||
): Constructor<FromReg<T, K>> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
return getTypeClass<FromReg<T, K>>(getTypeDef(type));
|
||||
}
|
||||
|
||||
// An unsafe version of the `createType` below. It's unsafe because the `type`
|
||||
// argument here can be any string, which, if not parseable, will yield a
|
||||
// runtime error.
|
||||
export function ClassOfUnsafe<T extends Codec = Codec, K extends string = string> (name: K): Constructor<FromReg<T, K>> {
|
||||
return createClass<T, K>(name);
|
||||
}
|
||||
|
||||
// alias for createClass
|
||||
export function ClassOf<K extends InterfaceTypes> (name: K): Constructor<InterfaceRegistry[K]> {
|
||||
return ClassOfUnsafe<Codec, K>(name) as Constructor<InterfaceRegistry[K]>;
|
||||
}
|
||||
|
||||
// create a maps of type string constructors from the input
|
||||
export function getTypeClassMap (defs: TypeDef[]): Record<string, InterfaceTypes> {
|
||||
return defs.reduce((result, sub): Record<string, InterfaceTypes> => {
|
||||
result[sub.name as string] = sub.type as any;
|
||||
|
||||
return result;
|
||||
}, {} as unknown as Record<string, InterfaceTypes>);
|
||||
}
|
||||
|
||||
// create an array of type string constructors from the input
|
||||
export function getTypeClassArray (defs: TypeDef[]): (InterfaceTypes)[] {
|
||||
return defs.map(({ type }): InterfaceTypes =>
|
||||
type as any
|
||||
);
|
||||
}
|
||||
|
||||
// Returns the type Class for construction
|
||||
export function getTypeClass<T extends Codec = Codec> (value: TypeDef): Constructor<T> {
|
||||
const Type = getTypeRegistry().get<T>(value.type);
|
||||
|
||||
if (Type) {
|
||||
return Type;
|
||||
}
|
||||
|
||||
switch (value.info) {
|
||||
case TypeDefInfo.Compact:
|
||||
assert(value.sub && !Array.isArray(value.sub), 'Expected subtype for Compact');
|
||||
return Compact.with(
|
||||
(value.sub as TypeDef).type as any
|
||||
) as unknown as Constructor<T>;
|
||||
|
||||
case TypeDefInfo.Enum:
|
||||
assert(value.sub && Array.isArray(value.sub), 'Expected subtype for Enum');
|
||||
return Enum.with(
|
||||
getTypeClassMap(value.sub as TypeDef[]) as any
|
||||
) as unknown as Constructor<T>;
|
||||
|
||||
case TypeDefInfo.Option:
|
||||
assert(value.sub && !Array.isArray(value.sub), 'Expected subtype for Option');
|
||||
return Option.with(
|
||||
(value.sub as TypeDef).type as any
|
||||
) as unknown as Constructor<T>;
|
||||
|
||||
case TypeDefInfo.Set:
|
||||
assert(Array.isArray(value.sub), 'Expected nested info for Set');
|
||||
return CodecSet.with(
|
||||
(value.sub as TypeDef[]).reduce((result, { name, index }): Record<string, number> => {
|
||||
result[name as string] = index as number;
|
||||
|
||||
return result;
|
||||
}, {} as unknown as Record<string, number>)
|
||||
) as unknown as Constructor<T>;
|
||||
|
||||
case TypeDefInfo.Struct:
|
||||
assert(Array.isArray(value.sub), 'Expected nested subtypes for Struct');
|
||||
return Struct.with(
|
||||
getTypeClassMap(value.sub as TypeDef[])
|
||||
) as unknown as Constructor<T>;
|
||||
|
||||
case TypeDefInfo.Tuple:
|
||||
assert(Array.isArray(value.sub), 'Expected nested subtypes for Tuple');
|
||||
return Tuple.with(
|
||||
getTypeClassArray(value.sub as TypeDef[])
|
||||
) as unknown as Constructor<T>;
|
||||
|
||||
case TypeDefInfo.Vec:
|
||||
assert(value.sub && !Array.isArray(value.sub), 'Expected subtype for Vec');
|
||||
|
||||
const vsub = value.sub as TypeDef;
|
||||
|
||||
return (
|
||||
vsub.type === 'u8'
|
||||
? ClassOf('Bytes')
|
||||
: Vec.with(vsub.type as any)
|
||||
) as unknown as Constructor<T>;
|
||||
|
||||
case TypeDefInfo.VecFixed:
|
||||
assert(value.ext, 'Expected length & type information for fixed vector');
|
||||
|
||||
const ext = value.ext as TypeDefExtVecFixed;
|
||||
|
||||
return (
|
||||
ext.type === 'u8'
|
||||
? U8aFixed.with((ext.length * 8) as U8aFixedBitLength)
|
||||
: VecFixed.with(ext.type as any, ext.length)
|
||||
) as unknown as Constructor<T>;
|
||||
|
||||
case TypeDefInfo.Linkage:
|
||||
assert(value.sub && !Array.isArray(value.sub), 'Expected subtype for Linkage');
|
||||
return Linkage.withKey(
|
||||
(value.sub as TypeDef).type as any
|
||||
) as unknown as Constructor<T>;
|
||||
|
||||
case TypeDefInfo.DoubleMap:
|
||||
assert(value.sub && !Array.isArray(value.sub), 'Expected subtype for DoubleMap');
|
||||
return getTypeClass(value.sub as TypeDef);
|
||||
|
||||
case TypeDefInfo.Null:
|
||||
return ClassOf('Null') as unknown as Constructor<T>;
|
||||
}
|
||||
|
||||
throw new Error(`Unable to determine type from ${JSON.stringify(value)}`);
|
||||
}
|
||||
|
||||
// Initializes a type with a value. This also checks for fallbacks and in the cases
|
||||
// where isPedantic is specified (storage decoding), also check the format/structure
|
||||
function initType<T extends Codec = Codec, K extends string = string> (Type: Constructor<FromReg<T, K>>, params: any[] = [], isPedantic?: boolean): FromReg<T, K> {
|
||||
const created = new Type(...params);
|
||||
const [value] = params;
|
||||
|
||||
// With isPedantic, actually check that the encoding matches that supplied. This
|
||||
// is much slower, but verifies that we have the correct types defined
|
||||
if (isPedantic && value && value.toU8a && !value.isEmpty) {
|
||||
const inHex = value.toHex(true);
|
||||
const crHex = created.toHex(true);
|
||||
const hasMatch = inHex === crHex || (
|
||||
created instanceof Uint8Array
|
||||
// strip the input length
|
||||
? (value.toU8a(true).toString() === created.toU8a().toString())
|
||||
// compare raw. without additions
|
||||
: (value.toU8a(true).toString() === created.toU8a(true).toString())
|
||||
);
|
||||
|
||||
if (!hasMatch) {
|
||||
console.warn(`${created.toRawType()}:: Input doesn't match output, received ${inHex}, created ${crHex}`);
|
||||
}
|
||||
}
|
||||
|
||||
return created;
|
||||
}
|
||||
|
||||
// An unsafe version of the `createType` below. It's unsafe because the `type`
|
||||
// argument here can be any string, which, if not parseable, will yield a
|
||||
// runtime error.
|
||||
export function createTypeUnsafe<T extends Codec = Codec, K extends string = string> (type: K, params: any[] = [], isPedantic?: boolean): FromReg<T, K> {
|
||||
try {
|
||||
return initType(createClass<T, K>(type), params, isPedantic);
|
||||
} catch (error) {
|
||||
throw new Error(`createType(${type}):: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of a `type` with a given `params`.
|
||||
* @param type - A recognizable string representing the type to create an
|
||||
* instance from
|
||||
* @param params - The value to instantiate the type with
|
||||
*/
|
||||
export default function createType<K extends InterfaceTypes> (type: K, ...params: any[]): InterfaceRegistry[K] {
|
||||
return createTypeUnsafe<Codec, K>(type, params) as InterfaceRegistry[K];
|
||||
}
|
||||
@@ -24,5 +24,4 @@ export { default as U8a } from './U8a';
|
||||
export { default as UInt } from './UInt';
|
||||
|
||||
// Type management helper functions
|
||||
export { default as createType, createClass, getTypeClass, getTypeDef, ClassOf } from './createType';
|
||||
export { default as getTypeRegistry } from './typeRegistry';
|
||||
export * from './create';
|
||||
|
||||
@@ -2,32 +2,4 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
export enum TypeDefInfo {
|
||||
Compact,
|
||||
DoubleMap,
|
||||
Enum,
|
||||
Linkage,
|
||||
Option,
|
||||
Plain,
|
||||
Set,
|
||||
Struct,
|
||||
Tuple,
|
||||
Vec,
|
||||
VecFixed,
|
||||
// anything not fully supported (keep this as the last entry)
|
||||
Null
|
||||
}
|
||||
|
||||
export interface TypeDefExtVecFixed {
|
||||
length: number;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface TypeDef {
|
||||
info: TypeDefInfo;
|
||||
index?: number;
|
||||
ext?: TypeDefExtVecFixed; // add additional here as required
|
||||
name?: string;
|
||||
type: string;
|
||||
sub?: TypeDef | TypeDef[];
|
||||
}
|
||||
export * from './create/types';
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Codec, Constructor, InterfaceTypes } from '../../types';
|
||||
|
||||
import { isString } from '@polkadot/util';
|
||||
|
||||
import { ClassOf } from '../createType';
|
||||
import { ClassOf } from '../create';
|
||||
|
||||
export function typeToConstructor <T = Codec> (type: InterfaceTypes | Constructor<T>): Constructor<T> {
|
||||
return (
|
||||
|
||||
@@ -6,7 +6,7 @@ import './injector';
|
||||
|
||||
import extrinsics from '@polkadot/api-metadata/extrinsics/static';
|
||||
|
||||
import { createTypeUnsafe } from './codec/createType';
|
||||
import { createTypeUnsafe } from './codec/create';
|
||||
import GenericCall from './primitive/Generic/Call';
|
||||
import { Codec } from './types';
|
||||
import * as exported from './index.types';
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import getTypeRegistry from './codec/typeRegistry';
|
||||
import { getTypeRegistry } from './codec/create';
|
||||
import * as definitions from './interfaces/definitions';
|
||||
import * as baseTypes from './index.types';
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import '../../injector';
|
||||
|
||||
import createType from '../../codec/createType';
|
||||
import { createType } from '../../codec/create';
|
||||
|
||||
describe('ChainProperties', (): void => {
|
||||
it('decodes from a null value', (): void => {
|
||||
|
||||
@@ -6,7 +6,7 @@ import '../../injector';
|
||||
|
||||
import { ExtrinsicStatus } from './types';
|
||||
|
||||
import createType from '../../codec/createType';
|
||||
import { createType } from '../../codec/create';
|
||||
import rpc from '../../json/ExtrinsicStatus.001.json';
|
||||
|
||||
describe('ExtrinsicStatus', (): void => {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import '../../injector';
|
||||
|
||||
import createType from '../../codec/createType';
|
||||
import { createType } from '../../codec/create';
|
||||
|
||||
describe('KeyValueOption', (): void => {
|
||||
it('exposes the properties for key/value', (): void => {
|
||||
|
||||
@@ -6,7 +6,7 @@ import '../../injector';
|
||||
|
||||
import { RuntimeVersion } from './types';
|
||||
|
||||
import createType from '../../codec/createType';
|
||||
import { createType } from '../../codec/create';
|
||||
import rpc from '../../json/RuntimeVersion.002.json';
|
||||
|
||||
describe('RuntimeVersion', (): void => {
|
||||
|
||||
@@ -6,7 +6,7 @@ import '../../injector';
|
||||
|
||||
import BN from 'bn.js';
|
||||
|
||||
import createType from '../../codec/createType';
|
||||
import { createType } from '../../codec/create';
|
||||
import json1 from '../../json/Header.001.json';
|
||||
import json2 from '../../json/Header.002.json';
|
||||
import json3 from '../../json/Header.003.json';
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import '../../injector';
|
||||
|
||||
import createType from '../../codec/createType';
|
||||
import { createType } from '../../codec/create';
|
||||
|
||||
describe('KeyValue', (): void => {
|
||||
it('decodes KeyValue from u8a', (): void => {
|
||||
|
||||
@@ -6,7 +6,7 @@ import '../../injector';
|
||||
|
||||
import extrinsics from '@polkadot/api-metadata/extrinsics/static';
|
||||
|
||||
import createType from '../../codec/createType';
|
||||
import { createType } from '../../codec/create';
|
||||
import Call from '../../primitive/Generic/Call';
|
||||
import events from '../../json/SignedBlock.002.json';
|
||||
import immortalTxs from '../../json/SignedBlock.004.immortal.json';
|
||||
|
||||
@@ -6,7 +6,7 @@ import '../../injector';
|
||||
|
||||
import { EventRecord } from './types';
|
||||
|
||||
import createType from '../../codec/createType';
|
||||
import { createType } from '../../codec/create';
|
||||
import Vec from '../../codec/Vec';
|
||||
import json1 from '../../json/EventRecord.001.json';
|
||||
import json3 from '../../json/EventRecord.003.json';
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Codec, IHash } from '../types';
|
||||
import { isU8a, u8aToHex } from '@polkadot/util';
|
||||
import { blake2AsU8a } from '@polkadot/util-crypto';
|
||||
|
||||
import createType from '../codec/createType';
|
||||
import { createType } from '../codec/create';
|
||||
|
||||
/**
|
||||
* @name Bool
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import '../injector';
|
||||
|
||||
import createType from '../codec/createType';
|
||||
import { createType } from '../codec/create';
|
||||
import Bytes from './Bytes';
|
||||
|
||||
describe('Bytes', (): void => {
|
||||
|
||||
@@ -6,7 +6,7 @@ import { AnyU8a } from '../types';
|
||||
|
||||
import { assert, isString, isU8a, u8aToU8a } from '@polkadot/util';
|
||||
|
||||
import { ClassOf } from '../codec/createType';
|
||||
import { ClassOf } from '../codec/create';
|
||||
import Compact from '../codec/Compact';
|
||||
import U8a from '../codec/U8a';
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { ExtrinsicPayloadValue, IKeyringPair } from '../../types';
|
||||
|
||||
import { u8aToHex } from '@polkadot/util';
|
||||
|
||||
import createType from '../../codec/createType';
|
||||
import { createType } from '../../codec/create';
|
||||
import Base from '../../codec/Base';
|
||||
import Compact from '../../codec/Compact';
|
||||
import U8a from '../../codec/U8a';
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Address, Balance, Index, Signature } from '../../../interfaces/runtime'
|
||||
import { ExtrinsicPayloadValue, IExtrinsicSignature, IKeyringPair, SignatureOptions } from '../../../types';
|
||||
import { ExtrinsicSignatureOptions } from '../types';
|
||||
|
||||
import createType from '../../../codec/createType';
|
||||
import { createType } from '../../../codec/create';
|
||||
import Compact from '../../../codec/Compact';
|
||||
import Struct from '../../../codec/Struct';
|
||||
import Call from '../../Generic/Call';
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Address, Balance, Index, Signature } from '../../../interfaces/runtime'
|
||||
import { ExtrinsicPayloadValue, IExtrinsicSignature, IKeyringPair, SignatureOptions } from '../../../types';
|
||||
import { ExtrinsicSignatureOptions } from '../types';
|
||||
|
||||
import createType from '../../../codec/createType';
|
||||
import { createType } from '../../../codec/create';
|
||||
import Compact from '../../../codec/Compact';
|
||||
import Struct from '../../../codec/Struct';
|
||||
import Call from '../../Generic/Call';
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Address, Balance, Index, Signature } from '../../../interfaces/runtime'
|
||||
import { ExtrinsicPayloadValue, IExtrinsicSignature, IKeyringPair, SignatureOptions } from '../../../types';
|
||||
import { ExtrinsicSignatureOptions } from '../types';
|
||||
|
||||
import createType from '../../../codec/createType';
|
||||
import { createType } from '../../../codec/create';
|
||||
import Compact from '../../../codec/Compact';
|
||||
import Struct from '../../../codec/Struct';
|
||||
import Call from '../../Generic/Call';
|
||||
|
||||
@@ -6,7 +6,7 @@ import '../../injector';
|
||||
|
||||
import { setAddressPrefix } from '@polkadot/util-crypto';
|
||||
|
||||
import createType from '../../codec/createType';
|
||||
import { createType } from '../../codec/create';
|
||||
import U8a from '../../codec/U8a';
|
||||
import jsonVec from '../../json/AccountIdVec.001.json';
|
||||
import AccountId from './AccountId';
|
||||
|
||||
@@ -6,7 +6,7 @@ import '../../injector';
|
||||
|
||||
import BN from 'bn.js';
|
||||
|
||||
import createType from '../../codec/createType';
|
||||
import { createType } from '../../codec/create';
|
||||
import AccountIndex from './AccountIndex';
|
||||
|
||||
describe('AccountIndex', (): void => {
|
||||
|
||||
@@ -8,7 +8,7 @@ import BN from 'bn.js';
|
||||
import { bnToBn, isBn, isNumber, isU8a, isHex } from '@polkadot/util';
|
||||
import { decodeAddress, encodeAddress } from '@polkadot/util-crypto';
|
||||
|
||||
import createType from '../../codec/createType';
|
||||
import { createType } from '../../codec/create';
|
||||
import U32 from '../U32';
|
||||
|
||||
export const ENUMSET_SIZE = new BN(64);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import '../../injector';
|
||||
|
||||
import createType from '../../codec/createType';
|
||||
import { createType } from '../../codec/create';
|
||||
import AccountId from './AccountId';
|
||||
import AccountIndex from './AccountIndex';
|
||||
import Address from './Address';
|
||||
|
||||
@@ -6,7 +6,7 @@ import BN from 'bn.js';
|
||||
import { isBn, isHex, isNumber, isU8a, u8aConcat, u8aToHex, u8aToU8a, u8aToBn } from '@polkadot/util';
|
||||
import { decodeAddress } from '@polkadot/util-crypto';
|
||||
|
||||
import createType from '../../codec/createType';
|
||||
import { createType } from '../../codec/create';
|
||||
import Base from '../../codec/Base';
|
||||
import AccountId from './AccountId';
|
||||
import AccountIndex from './AccountIndex';
|
||||
|
||||
@@ -7,7 +7,7 @@ import { AnyNumber, AnyU8a } from '../../types';
|
||||
|
||||
import { blake2AsU8a } from '@polkadot/util-crypto';
|
||||
|
||||
import createType from '../../codec/createType';
|
||||
import { createType } from '../../codec/create';
|
||||
import Extrinsic from '../Extrinsic/Extrinsic';
|
||||
import Struct from '../../codec/Struct';
|
||||
import Vec from '../../codec/Vec';
|
||||
|
||||
@@ -6,7 +6,7 @@ import { AnyU8a, ArgsDef, CallFunction, Codec, IMethod, ModulesWithCalls } from
|
||||
|
||||
import { assert, isHex, isObject, isU8a, hexToU8a } from '@polkadot/util';
|
||||
|
||||
import { getTypeDef, getTypeClass } from '../../codec/createType';
|
||||
import { getTypeDef, getTypeClass } from '../../codec/create';
|
||||
import Struct from '../../codec/Struct';
|
||||
import U8aFixed from '../../codec/U8aFixed';
|
||||
import { FunctionMetadata as FunctionMetadataV7, FunctionArgumentMetadata } from '../../Metadata/v7/Calls';
|
||||
|
||||
@@ -7,7 +7,7 @@ import { AccountId } from '../../interfaces/runtime';
|
||||
import BN from 'bn.js';
|
||||
import { bnToBn } from '@polkadot/util';
|
||||
|
||||
import createType from '../../codec/createType';
|
||||
import { createType } from '../../codec/create';
|
||||
import Bytes from '../Bytes';
|
||||
import U32 from '../U32';
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Constructor, Codec } from '../../types';
|
||||
|
||||
import { assert, isUndefined, stringCamelCase, u8aToHex } from '@polkadot/util';
|
||||
|
||||
import { getTypeClass, getTypeDef } from '../../codec/createType';
|
||||
import { getTypeClass, getTypeDef } from '../../codec/create';
|
||||
import Struct from '../../codec/Struct';
|
||||
import Tuple from '../../codec/Tuple';
|
||||
import Metadata from '../../Metadata';
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Conviction } from '../../interfaces/democracy';
|
||||
|
||||
import { isBoolean, isNumber, isObject, isU8a, isUndefined } from '@polkadot/util';
|
||||
|
||||
import createType from '../../codec/createType';
|
||||
import { createType } from '../../codec/create';
|
||||
import U8aFixed from '../../codec/U8aFixed';
|
||||
import Bool from '../Bool';
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { AnyU8a, Codec, IHash } from '../types';
|
||||
import { assert, hexToU8a, isHex, isString, stringToU8a, u8aToString, u8aToHex } from '@polkadot/util';
|
||||
import { blake2AsU8a } from '@polkadot/util-crypto';
|
||||
|
||||
import createType from '../codec/createType';
|
||||
import { createType } from '../codec/create';
|
||||
import Compact from '../codec/Compact';
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,7 +9,7 @@ import fs from 'fs';
|
||||
import { isString, stringCamelCase, stringUpperFirst } from '@polkadot/util';
|
||||
|
||||
import interfaces from '../../../type-jsonrpc/src';
|
||||
import { ClassOfUnsafe, getTypeDef } from '../codec/createType';
|
||||
import { ClassOfUnsafe, getTypeDef } from '../codec/create';
|
||||
import * as codecClasses from '../codec';
|
||||
import AbstractInt from '../codec/AbstractInt';
|
||||
import UInt from '../codec/UInt';
|
||||
|
||||
Reference in New Issue
Block a user