From 4115b8a4cc64a3c4667c3f0ef9670aeada51e9d2 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Wed, 14 Aug 2019 14:06:45 +0200 Subject: [PATCH] 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 --- CHANGELOG.md | 1 + .../src/consts/fromMetadata/index.ts | 2 +- .../storage/fromMetadata/createFunction.ts | 2 +- packages/api/src/checkTypes.manual.ts | 6 +- packages/rpc-core/src/index.ts | 2 +- packages/types/src/Metadata/util/testUtil.ts | 2 +- .../types/src/Metadata/util/validateTypes.ts | 2 +- packages/types/src/codec/Compact.spec.ts | 2 +- packages/types/src/codec/Date.ts | 2 +- packages/types/src/codec/Struct.spec.ts | 2 +- packages/types/src/codec/Tuple.spec.ts | 2 +- packages/types/src/codec/UInt.ts | 2 +- packages/types/src/codec/Vec.spec.ts | 2 +- packages/types/src/codec/VecFixed.ts | 2 +- .../src/codec/create/createClass.spec.ts | 23 ++ .../types/src/codec/create/createClass.ts | 28 ++ .../types/src/codec/create/createType.spec.ts | 129 +++++++ packages/types/src/codec/create/createType.ts | 61 +++ .../src/codec/create/getTypeClass.spec.ts | 17 + .../types/src/codec/create/getTypeClass.ts | 130 +++++++ .../types/src/codec/create/getTypeDef.spec.ts | 161 ++++++++ packages/types/src/codec/create/getTypeDef.ts | 143 +++++++ packages/types/src/codec/create/index.ts | 14 + .../registry.spec.ts} | 12 +- .../{typeRegistry.ts => create/registry.ts} | 6 +- .../types/src/codec/create/typeSplit.spec.ts | 51 +++ packages/types/src/codec/create/typeSplit.ts | 51 +++ packages/types/src/codec/create/types.ts | 42 ++ packages/types/src/codec/createType.spec.ts | 353 ----------------- packages/types/src/codec/createType.ts | 359 ------------------ packages/types/src/codec/index.ts | 3 +- packages/types/src/codec/types.ts | 30 +- .../types/src/codec/utils/mapToTypeMap.ts | 2 +- packages/types/src/index.spec.ts | 2 +- packages/types/src/injector.ts | 2 +- .../interfaces/rpc/ChainProperties.spec.ts | 2 +- .../interfaces/rpc/ExtrinsicStatus.spec.ts | 2 +- .../src/interfaces/rpc/KeyValueOption.spec.ts | 2 +- .../src/interfaces/rpc/RuntimeVersion.spec.ts | 2 +- .../src/interfaces/runtime/Header.spec.ts | 2 +- .../src/interfaces/runtime/KeyValue.spec.ts | 2 +- .../interfaces/runtime/SignedBlock.spec.ts | 2 +- .../src/interfaces/system/EventRecord.spec.ts | 2 +- packages/types/src/primitive/Bool.ts | 2 +- packages/types/src/primitive/Bytes.spec.ts | 2 +- packages/types/src/primitive/Bytes.ts | 2 +- .../primitive/Extrinsic/ExtrinsicPayload.ts | 2 +- .../Extrinsic/v1/ExtrinsicSignature.ts | 2 +- .../Extrinsic/v2/ExtrinsicSignature.ts | 2 +- .../Extrinsic/v3/ExtrinsicSignature.ts | 2 +- .../src/primitive/Generic/AccountId.spec.ts | 2 +- .../primitive/Generic/AccountIndex.spec.ts | 2 +- .../src/primitive/Generic/AccountIndex.ts | 2 +- .../src/primitive/Generic/Address.spec.ts | 2 +- .../types/src/primitive/Generic/Address.ts | 2 +- packages/types/src/primitive/Generic/Block.ts | 2 +- packages/types/src/primitive/Generic/Call.ts | 2 +- .../primitive/Generic/ConsensusEngineId.ts | 2 +- packages/types/src/primitive/Generic/Event.ts | 2 +- packages/types/src/primitive/Generic/Vote.ts | 2 +- packages/types/src/primitive/Text.ts | 2 +- packages/types/src/scripts/interfacesTs.ts | 2 +- 62 files changed, 907 insertions(+), 797 deletions(-) create mode 100644 packages/types/src/codec/create/createClass.spec.ts create mode 100644 packages/types/src/codec/create/createClass.ts create mode 100644 packages/types/src/codec/create/createType.spec.ts create mode 100644 packages/types/src/codec/create/createType.ts create mode 100644 packages/types/src/codec/create/getTypeClass.spec.ts create mode 100644 packages/types/src/codec/create/getTypeClass.ts create mode 100644 packages/types/src/codec/create/getTypeDef.spec.ts create mode 100644 packages/types/src/codec/create/getTypeDef.ts create mode 100644 packages/types/src/codec/create/index.ts rename packages/types/src/codec/{TypeRegistry.spec.ts => create/registry.spec.ts} (90%) rename packages/types/src/codec/{typeRegistry.ts => create/registry.ts} (94%) create mode 100644 packages/types/src/codec/create/typeSplit.spec.ts create mode 100644 packages/types/src/codec/create/typeSplit.ts create mode 100644 packages/types/src/codec/create/types.ts delete mode 100644 packages/types/src/codec/createType.spec.ts delete mode 100644 packages/types/src/codec/createType.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ac383a0c0..af941b9250 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ If you are upgrading form an older version, use the CHANGELOG hand-in-hand with - `usize` is now a blacklisted type that will throw on construction. Since it is platform-specific, it creates incompatibilities between native (generally `u64`) and WASM (always `u32`) code. Use one of the `u32` or `u64` types explicitly. - Support substrate v7 metadata - The `Method.findFunction(callIndex)` (allowing decoding of raw data), is now available on `api.findCall(callIndex)`. To keep backwards compatibility, it is still available on `GenericCall.findMethod` but the `api.findCall` is recommended and suggested. +- The `types/codec/createType` has been moved to `types/codec/create` with the same exports. If you explicitly imported from here (and not doing the suggested `import { createType } from '@polkadot/types`), the reference needs to be updated # 0.82.0-beta.x diff --git a/packages/api-metadata/src/consts/fromMetadata/index.ts b/packages/api-metadata/src/consts/fromMetadata/index.ts index edfef63720..b9633264dd 100644 --- a/packages/api-metadata/src/consts/fromMetadata/index.ts +++ b/packages/api-metadata/src/consts/fromMetadata/index.ts @@ -4,7 +4,7 @@ import { Constants, ConstantCodec, ModuleConstants } from '../types'; -import { createTypeUnsafe } from '@polkadot/types/codec/createType'; +import { createTypeUnsafe } from '@polkadot/types/codec'; import Metadata from '@polkadot/types/Metadata'; import { stringCamelCase } from '@polkadot/util'; diff --git a/packages/api-metadata/src/storage/fromMetadata/createFunction.ts b/packages/api-metadata/src/storage/fromMetadata/createFunction.ts index a7f7c5bb4c..61510df7f4 100644 --- a/packages/api-metadata/src/storage/fromMetadata/createFunction.ts +++ b/packages/api-metadata/src/storage/fromMetadata/createFunction.ts @@ -6,7 +6,7 @@ import { Codec } from '@polkadot/types/types'; import BN from 'bn.js'; import { Bytes, Compact, StorageKey, U8a } from '@polkadot/types'; -import { createTypeUnsafe } from '@polkadot/types/codec/createType'; +import { createTypeUnsafe } from '@polkadot/types/codec'; import { PlainType, StorageEntryMetadata, StorageEntryModifier, StorageEntryType } from '@polkadot/types/Metadata/v6/Storage'; import { StorageEntry } from '@polkadot/types/primitive/StorageKey'; import { assert, isNull, isUndefined, stringLowerFirst, stringToU8a, u8aConcat } from '@polkadot/util'; diff --git a/packages/api/src/checkTypes.manual.ts b/packages/api/src/checkTypes.manual.ts index 2c2bc1910c..0c5c1f5549 100644 --- a/packages/api/src/checkTypes.manual.ts +++ b/packages/api/src/checkTypes.manual.ts @@ -4,14 +4,14 @@ // Simple non-runnable checks to test type definitions in the editor itself +import { ConstantCodec } from '@polkadot/api-metadata/consts/types'; import { Balance, Header, Index } from '@polkadot/types/interfaces'; +import { IExtrinsic, IMethod } from '@polkadot/types/types'; import { ApiPromise } from '@polkadot/api'; import { HeaderExtended } from '@polkadot/api-derive'; -import { ConstantCodec } from '@polkadot/api-metadata/consts/types'; import testKeyring, { TestKeyringMap } from '@polkadot/keyring/testingPairs'; -import { IExtrinsic, IMethod } from '@polkadot/types/types'; -import createType, { createTypeUnsafe } from '@polkadot/types/codec/createType'; +import { createType, createTypeUnsafe } from '@polkadot/types/codec'; import { SubmittableResult } from './'; diff --git a/packages/rpc-core/src/index.ts b/packages/rpc-core/src/index.ts index 828f0d8b7c..1a8775f69e 100644 --- a/packages/rpc-core/src/index.ts +++ b/packages/rpc-core/src/index.ts @@ -14,7 +14,7 @@ import { combineLatest, from, Observable, Observer, of, throwError } from 'rxjs' import { catchError, map, publishReplay, refCount, switchMap } from 'rxjs/operators'; import interfaces from '@polkadot/jsonrpc'; import { ClassOf, Option, StorageData, StorageKey, Vec, createClass } from '@polkadot/types'; -import { createTypeUnsafe } from '@polkadot/types/codec/createType'; +import { createTypeUnsafe } from '@polkadot/types/codec'; import { ExtError, assert, isFunction, isNull, isNumber, logger } from '@polkadot/util'; const l = logger('rpc-core'); diff --git a/packages/types/src/Metadata/util/testUtil.ts b/packages/types/src/Metadata/util/testUtil.ts index 4a33d918f3..eda5a403ab 100644 --- a/packages/types/src/Metadata/util/testUtil.ts +++ b/packages/types/src/Metadata/util/testUtil.ts @@ -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'; diff --git a/packages/types/src/Metadata/util/validateTypes.ts b/packages/types/src/Metadata/util/validateTypes.ts index 96c3167b87..1687ac241e 100644 --- a/packages/types/src/Metadata/util/validateTypes.ts +++ b/packages/types/src/Metadata/util/validateTypes.ts @@ -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'; diff --git a/packages/types/src/codec/Compact.spec.ts b/packages/types/src/codec/Compact.spec.ts index ea239c8841..17f718ff65 100644 --- a/packages/types/src/codec/Compact.spec.ts +++ b/packages/types/src/codec/Compact.spec.ts @@ -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'; diff --git a/packages/types/src/codec/Date.ts b/packages/types/src/codec/Date.ts index 330b06c9f4..d8c6edeb66 100644 --- a/packages/types/src/codec/Date.ts +++ b/packages/types/src/codec/Date.ts @@ -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; diff --git a/packages/types/src/codec/Struct.spec.ts b/packages/types/src/codec/Struct.spec.ts index 49cd9a17cb..5557307be3 100644 --- a/packages/types/src/codec/Struct.spec.ts +++ b/packages/types/src/codec/Struct.spec.ts @@ -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'; diff --git a/packages/types/src/codec/Tuple.spec.ts b/packages/types/src/codec/Tuple.spec.ts index 75a8eb0dd6..7fecaec01a 100644 --- a/packages/types/src/codec/Tuple.spec.ts +++ b/packages/types/src/codec/Tuple.spec.ts @@ -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'; diff --git a/packages/types/src/codec/UInt.ts b/packages/types/src/codec/UInt.ts index 1448f23565..e800b63c2a 100644 --- a/packages/types/src/codec/UInt.ts +++ b/packages/types/src/codec/UInt.ts @@ -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'; /** diff --git a/packages/types/src/codec/Vec.spec.ts b/packages/types/src/codec/Vec.spec.ts index 3a45430182..c10962b565 100644 --- a/packages/types/src/codec/Vec.spec.ts +++ b/packages/types/src/codec/Vec.spec.ts @@ -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'; diff --git a/packages/types/src/codec/VecFixed.ts b/packages/types/src/codec/VecFixed.ts index 970ee43b36..38b529b3d2 100644 --- a/packages/types/src/codec/VecFixed.ts +++ b/packages/types/src/codec/VecFixed.ts @@ -42,7 +42,7 @@ export default class VecFixed extends AbstractArray { return values; } - public static with (Type: Constructor, length: number): Constructor> { + public static with (Type: Constructor | InterfaceTypes, length: number): Constructor> { return class extends VecFixed { public constructor (value?: any[]) { super(Type, length, value); diff --git a/packages/types/src/codec/create/createClass.spec.ts b/packages/types/src/codec/create/createClass.spec.ts new file mode 100644 index 0000000000..a958c5db2c --- /dev/null +++ b/packages/types/src/codec/create/createClass.spec.ts @@ -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', (): void => { + const A = createClass('Vec'); + const B = createClass('Bytes'); + + expect(new A() instanceof B).toBe(true); + }); +}); diff --git a/packages/types/src/codec/create/createClass.ts b/packages/types/src/codec/create/createClass.ts new file mode 100644 index 0000000000..0455e931c6 --- /dev/null +++ b/packages/types/src/codec/create/createClass.ts @@ -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 ( + type: K +): Constructor> { + return getTypeClass>(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 (name: K): Constructor> { + return createClass(name); +} + +// alias for createClass +export function ClassOf (name: K): Constructor { + return ClassOfUnsafe(name) as Constructor; +} diff --git a/packages/types/src/codec/create/createType.spec.ts b/packages/types/src/codec/create/createType.spec.ts new file mode 100644 index 0000000000..4bf2c1aa7c --- /dev/null +++ b/packages/types/src/codec/create/createType.spec.ts @@ -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('{"_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); + }); + }); +}); diff --git a/packages/types/src/codec/create/createType.ts b/packages/types/src/codec/create/createType.ts new file mode 100644 index 0000000000..3a180dcf35 --- /dev/null +++ b/packages/types/src/codec/create/createType.ts @@ -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 (value: any, created: FromReg): 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 (Type: Constructor>, params: any[] = [], isPedantic?: boolean): FromReg { + 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 (type: K, params: any[] = [], isPedantic?: boolean): FromReg { + try { + return initType(createClass(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 (type: K, ...params: any[]): InterfaceRegistry[K] { + return createTypeUnsafe(type, params) as InterfaceRegistry[K]; +} diff --git a/packages/types/src/codec/create/getTypeClass.spec.ts b/packages/types/src/codec/create/getTypeClass.spec.ts new file mode 100644 index 0000000000..e53eed7318 --- /dev/null +++ b/packages/types/src/codec/create/getTypeClass.spec.ts @@ -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 => getTypeClass('SomethingInvalid' as any) + ).toThrow(/determine type/); + }); +}); diff --git a/packages/types/src/codec/create/getTypeClass.ts b/packages/types/src/codec/create/getTypeClass.ts new file mode 100644 index 0000000000..000b4f5689 --- /dev/null +++ b/packages/types/src/codec/create/getTypeClass.ts @@ -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 { + const result: Record = {}; + + return getSubDefArray(value).reduce((result, sub): Record => { + 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 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 = {}; + + return CodecSet.with( + getSubDefArray(value).reduce((result, { name, index }): Record => { + 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 (value: TypeDef): Constructor { + const Type = getTypeRegistry().get(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; +} diff --git a/packages/types/src/codec/create/getTypeDef.spec.ts b/packages/types/src/codec/create/getTypeDef.spec.ts new file mode 100644 index 0000000000..c17e96711a --- /dev/null +++ b/packages/types/src/codec/create/getTypeDef.spec.ts @@ -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'/); + }); + + it('returns a type structure', (): void => { + expect( + getTypeDef('(u32, Compact, Vec, Option, DoubleMap, (Text, Vec<(Bool, u128)>))') + ).toEqual({ + info: TypeDefInfo.Tuple, + type: '(u32, Compact, Vec, Option, DoubleMap, (Text, Vec<(Bool, u128)>))', + sub: [ + { + info: TypeDefInfo.Plain, + type: 'u32' + }, + { + info: TypeDefInfo.Compact, + type: 'Compact', + sub: { + info: TypeDefInfo.Plain, + type: 'u32' + } + }, + { + info: TypeDefInfo.Vec, + type: 'Vec', + sub: { + info: TypeDefInfo.Plain, + type: 'u64' + } + }, + { + info: TypeDefInfo.Option, + type: 'Option', + sub: { + info: TypeDefInfo.Plain, + type: 'u128' + } + }, + { + info: TypeDefInfo.DoubleMap, + type: 'DoubleMap', + 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' + } + ] + } + ] + }); + }); +}); diff --git a/packages/types/src/codec/create/getTypeDef.ts b/packages/types/src/codec/create/getTypeDef.ts new file mode 100644 index 0000000000..6980fde915 --- /dev/null +++ b/packages/types/src/codec/create/getTypeDef.ts @@ -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): 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): 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; ], 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; +} diff --git a/packages/types/src/codec/create/index.ts b/packages/types/src/codec/create/index.ts new file mode 100644 index 0000000000..aeb454dea5 --- /dev/null +++ b/packages/types/src/codec/create/index.ts @@ -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; diff --git a/packages/types/src/codec/TypeRegistry.spec.ts b/packages/types/src/codec/create/registry.spec.ts similarity index 90% rename from packages/types/src/codec/TypeRegistry.spec.ts rename to packages/types/src/codec/create/registry.spec.ts index 0df1723c7a..9321aff2c8 100644 --- a/packages/types/src/codec/TypeRegistry.spec.ts +++ b/packages/types/src/codec/create/registry.spec.ts @@ -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, Child?: Constructor): boolean { diff --git a/packages/types/src/codec/typeRegistry.ts b/packages/types/src/codec/create/registry.ts similarity index 94% rename from packages/types/src/codec/typeRegistry.ts rename to packages/types/src/codec/create/registry.ts index 0ff960cd05..e1f676ada2 100644 --- a/packages/types/src/codec/typeRegistry.ts +++ b/packages/types/src/codec/create/registry.ts @@ -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; } diff --git a/packages/types/src/codec/create/typeSplit.spec.ts b/packages/types/src/codec/create/typeSplit.spec.ts new file mode 100644 index 0000000000..bd026b83e5 --- /dev/null +++ b/packages/types/src/codec/create/typeSplit.spec.ts @@ -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') + ).toEqual(['Text', '(u32)', 'Vec']); + }); + + it('keeps nested tuples together', (): void => { + expect( + typeSplit('Text, (u32, u128), Vec') + ).toEqual(['Text', '(u32, u128)', 'Vec']); + }); + + 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 { + expect( + (): string[] => typeSplit('Text, (u64, u32') + ).toThrow(/Invalid defintion/); + }); +}); diff --git a/packages/types/src/codec/create/typeSplit.ts b/packages/types/src/codec/create/typeSplit.ts new file mode 100644 index 0000000000..c9cc0bba0f --- /dev/null +++ b/packages/types/src/codec/create/typeSplit.ts @@ -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; +} diff --git a/packages/types/src/codec/create/types.ts b/packages/types/src/codec/create/types.ts new file mode 100644 index 0000000000..ca08f2ea82 --- /dev/null +++ b/packages/types/src/codec/create/types.ts @@ -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 = 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[]; +} diff --git a/packages/types/src/codec/createType.spec.ts b/packages/types/src/codec/createType.spec.ts deleted file mode 100644 index 016296aaf4..0000000000 --- a/packages/types/src/codec/createType.spec.ts +++ /dev/null @@ -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') - ).toEqual(['Text', '(u32)', 'Vec']); - }); - - it('keeps nested tuples together', (): void => { - expect( - typeSplit('Text, (u32, u128), Vec') - ).toEqual(['Text', '(u32, u128)', 'Vec']); - }); - - 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 { - 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'/); - }); - - it('returns a type structure', (): void => { - expect( - getTypeDef('(u32, Compact, Vec, Option, DoubleMap, (Text, Vec<(Bool, u128)>))') - ).toEqual({ - info: TypeDefInfo.Tuple, - type: '(u32, Compact, Vec, Option, DoubleMap, (Text, Vec<(Bool, u128)>))', - sub: [ - { - info: TypeDefInfo.Plain, - type: 'u32' - }, - { - info: TypeDefInfo.Compact, - type: 'Compact', - sub: { - info: TypeDefInfo.Plain, - type: 'u32' - } - }, - { - info: TypeDefInfo.Vec, - type: 'Vec', - sub: { - info: TypeDefInfo.Plain, - type: 'u64' - } - }, - { - info: TypeDefInfo.Option, - type: 'Option', - sub: { - info: TypeDefInfo.Plain, - type: 'u128' - } - }, - { - info: TypeDefInfo.DoubleMap, - type: 'DoubleMap', - 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 => 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', (): void => { - const A = createClass('Vec'); - 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('{"_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); - }); - }); -}); diff --git a/packages/types/src/codec/createType.ts b/packages/types/src/codec/createType.ts deleted file mode 100644 index e5660e1f05..0000000000 --- a/packages/types/src/codec/createType.ts +++ /dev/null @@ -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 = 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): 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): 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; ], 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 ( - type: K -): Constructor> { - // eslint-disable-next-line @typescript-eslint/no-use-before-define - return getTypeClass>(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 (name: K): Constructor> { - return createClass(name); -} - -// alias for createClass -export function ClassOf (name: K): Constructor { - return ClassOfUnsafe(name) as Constructor; -} - -// create a maps of type string constructors from the input -export function getTypeClassMap (defs: TypeDef[]): Record { - return defs.reduce((result, sub): Record => { - result[sub.name as string] = sub.type as any; - - return result; - }, {} as unknown as Record); -} - -// 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 (value: TypeDef): Constructor { - const Type = getTypeRegistry().get(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; - - 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; - - 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; - - 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 => { - result[name as string] = index as number; - - return result; - }, {} as unknown as Record) - ) as unknown as Constructor; - - 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; - - 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; - - 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; - - 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; - - 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; - - 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; - } - - 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 (Type: Constructor>, params: any[] = [], isPedantic?: boolean): FromReg { - 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 (type: K, params: any[] = [], isPedantic?: boolean): FromReg { - try { - return initType(createClass(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 (type: K, ...params: any[]): InterfaceRegistry[K] { - return createTypeUnsafe(type, params) as InterfaceRegistry[K]; -} diff --git a/packages/types/src/codec/index.ts b/packages/types/src/codec/index.ts index a0e7da736d..0cce6f7c4e 100644 --- a/packages/types/src/codec/index.ts +++ b/packages/types/src/codec/index.ts @@ -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'; diff --git a/packages/types/src/codec/types.ts b/packages/types/src/codec/types.ts index d22c07b845..1541d1fc1c 100644 --- a/packages/types/src/codec/types.ts +++ b/packages/types/src/codec/types.ts @@ -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'; diff --git a/packages/types/src/codec/utils/mapToTypeMap.ts b/packages/types/src/codec/utils/mapToTypeMap.ts index 3b6597dd1d..00d9f9488b 100644 --- a/packages/types/src/codec/utils/mapToTypeMap.ts +++ b/packages/types/src/codec/utils/mapToTypeMap.ts @@ -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 (type: InterfaceTypes | Constructor): Constructor { return ( diff --git a/packages/types/src/index.spec.ts b/packages/types/src/index.spec.ts index 822964651d..124d905946 100644 --- a/packages/types/src/index.spec.ts +++ b/packages/types/src/index.spec.ts @@ -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'; diff --git a/packages/types/src/injector.ts b/packages/types/src/injector.ts index 6a2fc91255..57054e7e97 100644 --- a/packages/types/src/injector.ts +++ b/packages/types/src/injector.ts @@ -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'; diff --git a/packages/types/src/interfaces/rpc/ChainProperties.spec.ts b/packages/types/src/interfaces/rpc/ChainProperties.spec.ts index fae7f8a7cd..3d237a71bc 100644 --- a/packages/types/src/interfaces/rpc/ChainProperties.spec.ts +++ b/packages/types/src/interfaces/rpc/ChainProperties.spec.ts @@ -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 => { diff --git a/packages/types/src/interfaces/rpc/ExtrinsicStatus.spec.ts b/packages/types/src/interfaces/rpc/ExtrinsicStatus.spec.ts index 4d98d92e2e..bd70ff808c 100644 --- a/packages/types/src/interfaces/rpc/ExtrinsicStatus.spec.ts +++ b/packages/types/src/interfaces/rpc/ExtrinsicStatus.spec.ts @@ -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 => { diff --git a/packages/types/src/interfaces/rpc/KeyValueOption.spec.ts b/packages/types/src/interfaces/rpc/KeyValueOption.spec.ts index 5c53ade4e3..d9bafa043f 100644 --- a/packages/types/src/interfaces/rpc/KeyValueOption.spec.ts +++ b/packages/types/src/interfaces/rpc/KeyValueOption.spec.ts @@ -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 => { diff --git a/packages/types/src/interfaces/rpc/RuntimeVersion.spec.ts b/packages/types/src/interfaces/rpc/RuntimeVersion.spec.ts index 6bcca5a327..6cb5316ec7 100644 --- a/packages/types/src/interfaces/rpc/RuntimeVersion.spec.ts +++ b/packages/types/src/interfaces/rpc/RuntimeVersion.spec.ts @@ -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 => { diff --git a/packages/types/src/interfaces/runtime/Header.spec.ts b/packages/types/src/interfaces/runtime/Header.spec.ts index 4877b58b1a..3ac3c26341 100644 --- a/packages/types/src/interfaces/runtime/Header.spec.ts +++ b/packages/types/src/interfaces/runtime/Header.spec.ts @@ -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'; diff --git a/packages/types/src/interfaces/runtime/KeyValue.spec.ts b/packages/types/src/interfaces/runtime/KeyValue.spec.ts index 0eef7d33ba..929118e79b 100644 --- a/packages/types/src/interfaces/runtime/KeyValue.spec.ts +++ b/packages/types/src/interfaces/runtime/KeyValue.spec.ts @@ -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 => { diff --git a/packages/types/src/interfaces/runtime/SignedBlock.spec.ts b/packages/types/src/interfaces/runtime/SignedBlock.spec.ts index a1ecf75eb4..70dc07d39c 100644 --- a/packages/types/src/interfaces/runtime/SignedBlock.spec.ts +++ b/packages/types/src/interfaces/runtime/SignedBlock.spec.ts @@ -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'; diff --git a/packages/types/src/interfaces/system/EventRecord.spec.ts b/packages/types/src/interfaces/system/EventRecord.spec.ts index 7bc5446037..bbf5212640 100644 --- a/packages/types/src/interfaces/system/EventRecord.spec.ts +++ b/packages/types/src/interfaces/system/EventRecord.spec.ts @@ -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'; diff --git a/packages/types/src/primitive/Bool.ts b/packages/types/src/primitive/Bool.ts index 869b1b3177..6e7cb1cbd6 100644 --- a/packages/types/src/primitive/Bool.ts +++ b/packages/types/src/primitive/Bool.ts @@ -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 diff --git a/packages/types/src/primitive/Bytes.spec.ts b/packages/types/src/primitive/Bytes.spec.ts index 5ac979cbae..05e4b45b5d 100644 --- a/packages/types/src/primitive/Bytes.spec.ts +++ b/packages/types/src/primitive/Bytes.spec.ts @@ -4,7 +4,7 @@ import '../injector'; -import createType from '../codec/createType'; +import { createType } from '../codec/create'; import Bytes from './Bytes'; describe('Bytes', (): void => { diff --git a/packages/types/src/primitive/Bytes.ts b/packages/types/src/primitive/Bytes.ts index bb38de4388..139526a1c1 100644 --- a/packages/types/src/primitive/Bytes.ts +++ b/packages/types/src/primitive/Bytes.ts @@ -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'; diff --git a/packages/types/src/primitive/Extrinsic/ExtrinsicPayload.ts b/packages/types/src/primitive/Extrinsic/ExtrinsicPayload.ts index cb0911ed85..d73005142c 100644 --- a/packages/types/src/primitive/Extrinsic/ExtrinsicPayload.ts +++ b/packages/types/src/primitive/Extrinsic/ExtrinsicPayload.ts @@ -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'; diff --git a/packages/types/src/primitive/Extrinsic/v1/ExtrinsicSignature.ts b/packages/types/src/primitive/Extrinsic/v1/ExtrinsicSignature.ts index 6b9cc9770f..353b17d6af 100644 --- a/packages/types/src/primitive/Extrinsic/v1/ExtrinsicSignature.ts +++ b/packages/types/src/primitive/Extrinsic/v1/ExtrinsicSignature.ts @@ -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'; diff --git a/packages/types/src/primitive/Extrinsic/v2/ExtrinsicSignature.ts b/packages/types/src/primitive/Extrinsic/v2/ExtrinsicSignature.ts index acbc3016c8..7a0fa2e336 100644 --- a/packages/types/src/primitive/Extrinsic/v2/ExtrinsicSignature.ts +++ b/packages/types/src/primitive/Extrinsic/v2/ExtrinsicSignature.ts @@ -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'; diff --git a/packages/types/src/primitive/Extrinsic/v3/ExtrinsicSignature.ts b/packages/types/src/primitive/Extrinsic/v3/ExtrinsicSignature.ts index 925e1c3871..4978c676cc 100644 --- a/packages/types/src/primitive/Extrinsic/v3/ExtrinsicSignature.ts +++ b/packages/types/src/primitive/Extrinsic/v3/ExtrinsicSignature.ts @@ -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'; diff --git a/packages/types/src/primitive/Generic/AccountId.spec.ts b/packages/types/src/primitive/Generic/AccountId.spec.ts index aa323a19c6..7b47d7b21d 100644 --- a/packages/types/src/primitive/Generic/AccountId.spec.ts +++ b/packages/types/src/primitive/Generic/AccountId.spec.ts @@ -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'; diff --git a/packages/types/src/primitive/Generic/AccountIndex.spec.ts b/packages/types/src/primitive/Generic/AccountIndex.spec.ts index 9ac344d6b8..d7bb9dc711 100644 --- a/packages/types/src/primitive/Generic/AccountIndex.spec.ts +++ b/packages/types/src/primitive/Generic/AccountIndex.spec.ts @@ -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 => { diff --git a/packages/types/src/primitive/Generic/AccountIndex.ts b/packages/types/src/primitive/Generic/AccountIndex.ts index e3c6e386f9..4f21ea0d9d 100644 --- a/packages/types/src/primitive/Generic/AccountIndex.ts +++ b/packages/types/src/primitive/Generic/AccountIndex.ts @@ -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); diff --git a/packages/types/src/primitive/Generic/Address.spec.ts b/packages/types/src/primitive/Generic/Address.spec.ts index b6d2ec3281..4f5d359869 100644 --- a/packages/types/src/primitive/Generic/Address.spec.ts +++ b/packages/types/src/primitive/Generic/Address.spec.ts @@ -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'; diff --git a/packages/types/src/primitive/Generic/Address.ts b/packages/types/src/primitive/Generic/Address.ts index a36da26d2c..cf0b8468d1 100644 --- a/packages/types/src/primitive/Generic/Address.ts +++ b/packages/types/src/primitive/Generic/Address.ts @@ -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'; diff --git a/packages/types/src/primitive/Generic/Block.ts b/packages/types/src/primitive/Generic/Block.ts index 6c1849d255..7e7172fa65 100644 --- a/packages/types/src/primitive/Generic/Block.ts +++ b/packages/types/src/primitive/Generic/Block.ts @@ -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'; diff --git a/packages/types/src/primitive/Generic/Call.ts b/packages/types/src/primitive/Generic/Call.ts index aa0be0fa42..b1c43ed868 100644 --- a/packages/types/src/primitive/Generic/Call.ts +++ b/packages/types/src/primitive/Generic/Call.ts @@ -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'; diff --git a/packages/types/src/primitive/Generic/ConsensusEngineId.ts b/packages/types/src/primitive/Generic/ConsensusEngineId.ts index 6f61ae4d34..1ca8e85a6f 100644 --- a/packages/types/src/primitive/Generic/ConsensusEngineId.ts +++ b/packages/types/src/primitive/Generic/ConsensusEngineId.ts @@ -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'; diff --git a/packages/types/src/primitive/Generic/Event.ts b/packages/types/src/primitive/Generic/Event.ts index 9310fe903c..10d5f466b2 100644 --- a/packages/types/src/primitive/Generic/Event.ts +++ b/packages/types/src/primitive/Generic/Event.ts @@ -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'; diff --git a/packages/types/src/primitive/Generic/Vote.ts b/packages/types/src/primitive/Generic/Vote.ts index 50acae2d59..6c22ab4fd8 100644 --- a/packages/types/src/primitive/Generic/Vote.ts +++ b/packages/types/src/primitive/Generic/Vote.ts @@ -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'; diff --git a/packages/types/src/primitive/Text.ts b/packages/types/src/primitive/Text.ts index 9dc306ceb6..0c9170862d 100644 --- a/packages/types/src/primitive/Text.ts +++ b/packages/types/src/primitive/Text.ts @@ -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'; /** diff --git a/packages/types/src/scripts/interfacesTs.ts b/packages/types/src/scripts/interfacesTs.ts index c7a7edb827..57da55932e 100644 --- a/packages/types/src/scripts/interfacesTs.ts +++ b/packages/types/src/scripts/interfacesTs.ts @@ -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';