Detect resulting types from createType (#3849)
* Detect resulting types from createType * Additional detect overrides * additional * Empy (), never for invalids
This commit is contained in:
+2
-1
@@ -6,7 +6,8 @@
|
||||
|
||||
Changes:
|
||||
|
||||
- `createType<T = Codec>('...': K)` now returns `Codec` when `K` is not in the InterfaceRegistry, with `T` override
|
||||
- `createType<T = Codec>('...': K)` now returns `Codec` when `K` is not known
|
||||
- `createType` does basic TypeScript type matching on the input type
|
||||
- Handle `BitSequence` in `PortableRegistry`
|
||||
- Ensure API `isConnected` is set before connect/disconnect events are fired
|
||||
- Move all static test support files into `@polkadot/types-support`
|
||||
|
||||
@@ -8,7 +8,7 @@ import { TypeRegistry } from '@polkadot/types/create';
|
||||
import * as defaultDefinitions from '@polkadot/types/interfaces/definitions';
|
||||
import * as defaultPrimitives from '@polkadot/types/primitive';
|
||||
|
||||
import { createImports, getDerivedTypes, readTemplate, setImports, writeFile } from '../util';
|
||||
import { createImports, readTemplate, setImports, writeFile } from '../util';
|
||||
import { ModuleTypes } from '../util/imports';
|
||||
|
||||
const primitiveClasses = {
|
||||
@@ -35,10 +35,10 @@ export function generateInterfaceTypes (importDefinitions: { [importPath: string
|
||||
Object
|
||||
.keys(primitiveClasses)
|
||||
.filter((name) => !name.includes('Generic'))
|
||||
.forEach((primitiveName) => {
|
||||
.forEach((primitiveName): void => {
|
||||
setImports(definitions, imports, [primitiveName]);
|
||||
|
||||
items.push(...getDerivedTypes(registry, definitions, primitiveName, primitiveName, imports));
|
||||
items.push(primitiveName);
|
||||
});
|
||||
|
||||
const existingTypes: Record<string, boolean> = {};
|
||||
@@ -55,10 +55,10 @@ export function generateInterfaceTypes (importDefinitions: { [importPath: string
|
||||
|
||||
const uniqueTypes = Object.keys(types).filter((type) => !existingTypes[type]);
|
||||
|
||||
uniqueTypes.forEach((type) => {
|
||||
uniqueTypes.forEach((type): void => {
|
||||
existingTypes[type] = true;
|
||||
|
||||
items.push(...getDerivedTypes(registry, definitions, type, types[type] as string, imports));
|
||||
items.push(type);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
declare module '@polkadot/types/types/registry' {
|
||||
export interface InterfaceTypes {
|
||||
{{#each items}}
|
||||
{{{this}}}
|
||||
{{{this}}}: {{{this}}};
|
||||
{{/each}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/typegen authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Constructor } from '@polkadot/types/types';
|
||||
|
||||
import { UInt } from '@polkadot/types/codec';
|
||||
import { isChildClass } from '@polkadot/util';
|
||||
|
||||
/** @internal */
|
||||
export function isCompactEncodable (Child: Constructor<any>): boolean {
|
||||
return isChildClass(UInt, Child);
|
||||
}
|
||||
@@ -11,10 +11,8 @@ import { TypeDefInfo } from '@polkadot/types/create/types';
|
||||
import { GenericAccountId, GenericLookupSource, GenericVote } from '@polkadot/types/generic';
|
||||
import { AllConvictions } from '@polkadot/types/interfaces/democracy/definitions';
|
||||
import { bool, Null } from '@polkadot/types/primitive';
|
||||
import * as primitiveClasses from '@polkadot/types/primitive';
|
||||
import { isChildClass, stringify } from '@polkadot/util';
|
||||
|
||||
import { isCompactEncodable } from './class';
|
||||
import { formatType } from './formatting';
|
||||
import { ModuleTypes, setImports, TypeImports } from './imports';
|
||||
|
||||
@@ -24,46 +22,6 @@ function arrayToStrType (arr: string[]): string {
|
||||
|
||||
const voteConvictions = arrayToStrType(AllConvictions);
|
||||
|
||||
// From `T`, generate `Compact<T>, Option<T>, Vec<T>`
|
||||
/** @internal */
|
||||
export function getDerivedTypes (registry: Registry, definitions: Record<string, ModuleTypes>, type: string, primitiveName: string, imports: TypeImports): string[] {
|
||||
// `primitiveName` represents the actual primitive type our type is mapped to
|
||||
const isCompact = isCompactEncodable(
|
||||
(primitiveClasses as Record<string, any>)[primitiveName] ||
|
||||
registry.createClass(type)
|
||||
);
|
||||
const def = getTypeDef(type);
|
||||
|
||||
setImports(definitions, imports, ['Option', 'Vec', isCompact ? 'Compact' : '']);
|
||||
|
||||
const types = [
|
||||
{
|
||||
info: TypeDefInfo.Option,
|
||||
sub: def,
|
||||
type
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Vec,
|
||||
sub: def,
|
||||
type
|
||||
}
|
||||
];
|
||||
|
||||
if (isCompact) {
|
||||
types.unshift({
|
||||
info: TypeDefInfo.Compact,
|
||||
sub: def,
|
||||
type
|
||||
});
|
||||
}
|
||||
|
||||
const result = types.map((t) => formatType(registry, definitions, t, imports)).map((t) => `'${t}': ${t};`);
|
||||
|
||||
result.unshift(`${type}: ${type};`);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Make types a little bit more flexible
|
||||
// - if param instanceof AbstractInt, then param: u64 | Uint8array | AnyNumber
|
||||
// etc
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,33 +1,65 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { u32 } from './primitive';
|
||||
import type { Registry } from './types/registry';
|
||||
import type { Compact, Option } from './codec';
|
||||
import type { AccountId, BlockAttestations, SessionKeys7 } from './interfaces';
|
||||
import type { Bytes, u32 } from './primitive';
|
||||
|
||||
import { assert } from '@polkadot/util';
|
||||
|
||||
import { TypeRegistry } from './create';
|
||||
|
||||
function registryCheck (registry: Registry): void {
|
||||
// Should be AccountId
|
||||
const aa = registry.createType('AccountId');
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
assert(aa.isAscii, 'All ok');
|
||||
// something that uses overrides
|
||||
const oo0 = registry.createType('Something' as 'u32');
|
||||
const oo1 = registry.createType<BlockAttestations>('u32');
|
||||
const oo2 = registry.createType<SessionKeys7>('u32');
|
||||
const oo3 = registry.createType<u32>('Something');
|
||||
const oo4 = registry.createType<AccountId>('Option<u32>');
|
||||
const oo5 = registry.createType<Option<u32>>('u32');
|
||||
const oo6 = registry.createType<Option<Compact<u32>>>('u32');
|
||||
const oo7 = registry.createType<Bytes>('u64');
|
||||
|
||||
// Should be Codec
|
||||
const bb = registry.createType('Something');
|
||||
assert(oo0.divn(123) && [...oo1.values()] && oo2[6].isAscii && oo3.divn(3) && oo4.isAscii && oo5.unwrap().divn(1) && oo6.unwrap().unwrap().divn(1) && oo7.isAscii, 'All ok');
|
||||
|
||||
assert(bb.toHuman(), 'All ok');
|
||||
// There are in the interface registry
|
||||
const aa0 = registry.createType('AccountId');
|
||||
const aa1 = registry.createType('BlockAttestations');
|
||||
|
||||
// Should be u32
|
||||
const cc = registry.createType('Something' as 'u32');
|
||||
assert(aa0.isAscii && aa1.receipt, 'All ok');
|
||||
|
||||
assert(cc.divn(123), 'All ok');
|
||||
// Should be Codec, we don't know this one
|
||||
const bb = registry.createType('Something');
|
||||
|
||||
// Should be u32
|
||||
const dd = registry.createType<u32>('Something');
|
||||
assert(bb.toHuman(), 'All ok');
|
||||
|
||||
assert(dd.divn(123), 'All ok');
|
||||
}
|
||||
// Should be Vec<Option<Compact<u32>>>
|
||||
const ee = registry.createType('Vec<Option<Compact<u32>>>');
|
||||
// Option<Bytes>
|
||||
const vb = registry.createType('Option<Vec<u8>>');
|
||||
|
||||
registryCheck(new TypeRegistry());
|
||||
assert(ee[0].unwrap().unwrap().divn(123) && vb.unwrap().bitLength(), 'All ok');
|
||||
|
||||
// Should end up as Raw
|
||||
const gg = registry.createType('[u8;678]');
|
||||
|
||||
assert(gg.bitLength, 'All ok');
|
||||
|
||||
// Should end up as VecFixed<u128>
|
||||
const hh = registry.createType('[u128; 32]');
|
||||
|
||||
assert(hh[0].bitLength(), 'All ok');
|
||||
|
||||
// tuple! ITuple<[u32, Compact<u64>, u128, Codec]>
|
||||
const tt1 = registry.createType('(u32, Compact<u64>,u128, Something)');
|
||||
// unwraps into a u32
|
||||
const tt2 = registry.createType('(u32)');
|
||||
// max number of params
|
||||
const tt3 = registry.createType('(u8,u16,u32,u64,u128)');
|
||||
// lots and lots of params
|
||||
const tt4 = registry.createType('(u8,u16,u32,u64,u8,u16,u32,u64,u8,u16,u32,u64,u8,u16,u32,u64)');
|
||||
// empty
|
||||
const tt5 = registry.createType('()');
|
||||
|
||||
assert(tt1[2].bitLength() && tt2.bitLength() && tt3[4].bitLength() && tt4[3].bitLength() && tt5.isEmpty, 'All ok');
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { CodecHash, Hash } from '../interfaces/runtime';
|
||||
import type { AnyJson, Codec, Registry } from '../types';
|
||||
import type { AnyJson, Codec, IVec, Registry } from '../types';
|
||||
|
||||
import { compactToU8a, u8aConcat, u8aToHex } from '@polkadot/util';
|
||||
|
||||
@@ -15,7 +15,7 @@ import { compareArray } from './utils/compareArray';
|
||||
* specific encoding/decoding on top of the base type.
|
||||
* @noInheritDoc
|
||||
*/
|
||||
export abstract class AbstractArray<T extends Codec> extends Array<T> implements Codec {
|
||||
export abstract class AbstractArray<T extends Codec> extends Array<T> implements IVec<Codec> {
|
||||
public readonly registry: Registry;
|
||||
|
||||
public createdAtHash?: Hash;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { CodecHash, Hash } from '../interfaces';
|
||||
import type { AnyJson, Codec, Constructor, Registry } from '../types';
|
||||
import type { AnyJson, Codec, Constructor, IOption, Registry } from '../types';
|
||||
|
||||
import { assert, isNull, isU8a, isUndefined, u8aToHex } from '@polkadot/util';
|
||||
|
||||
@@ -47,7 +47,7 @@ function decodeOption (registry: Registry, typeName: Constructor | string, value
|
||||
* implements that - decodes, checks for optionality and wraps the required structure
|
||||
* with a value if/as required/found.
|
||||
*/
|
||||
export class Option<T extends Codec> implements Codec {
|
||||
export class Option<T extends Codec> implements IOption<T> {
|
||||
public readonly registry: Registry;
|
||||
|
||||
public createdAtHash?: Hash;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { AnyNumber, AnyString, AnyU8a, Codec, Constructor, Registry } from '../types';
|
||||
import type { AnyNumber, AnyString, AnyU8a, Codec, Constructor, ITuple, Registry } from '../types';
|
||||
|
||||
import { isHex, isU8a, stringify, u8aConcat, u8aToU8a } from '@polkadot/util';
|
||||
|
||||
@@ -49,7 +49,7 @@ function decodeTuple (registry: Registry, _Types: TupleConstructors, value?: Any
|
||||
* A Tuple defines an anonymous fixed-length array, where each element has its
|
||||
* own type. It extends the base JS `Array` object.
|
||||
*/
|
||||
export class Tuple extends AbstractArray<Codec> {
|
||||
export class Tuple extends AbstractArray<Codec> implements ITuple<Codec[]> {
|
||||
private _Types: TupleConstructors;
|
||||
|
||||
constructor (registry: Registry, Types: TupleTypes, value?: AnyTuple) {
|
||||
|
||||
@@ -53,32 +53,32 @@ function getTypeClassArray (value: TypeDef): string[] {
|
||||
return getSubDefArray(value).map(({ type }) => type);
|
||||
}
|
||||
|
||||
function createInt ({ displayName, length }: TypeDef, Clazz: typeof Int | typeof UInt): Constructor {
|
||||
function createInt ({ displayName, length }: TypeDef, Clazz: typeof Int | typeof UInt): Constructor<Codec> {
|
||||
assert(isNumber(length), () => `Expected bitLength information for ${displayName || Clazz.constructor.name}<bitLength>`);
|
||||
|
||||
return Clazz.with(length as UIntBitLength, displayName);
|
||||
}
|
||||
|
||||
function createHashMap (value: TypeDef, Clazz: typeof BTreeMap | typeof HashMap): Constructor {
|
||||
function createHashMap (value: TypeDef, Clazz: typeof BTreeMap | typeof HashMap): Constructor<Codec> {
|
||||
const [keyType, valueType] = getTypeClassArray(value);
|
||||
|
||||
return Clazz.with(keyType, valueType);
|
||||
}
|
||||
|
||||
const infoMapping: Record<TypeDefInfo, (registry: Registry, value: TypeDef) => Constructor> = {
|
||||
[TypeDefInfo.BTreeMap]: (registry: Registry, value: TypeDef): Constructor =>
|
||||
const infoMapping: Record<TypeDefInfo, (registry: Registry, value: TypeDef) => Constructor<Codec>> = {
|
||||
[TypeDefInfo.BTreeMap]: (registry: Registry, value: TypeDef): Constructor<Codec> =>
|
||||
createHashMap(value, BTreeMap),
|
||||
|
||||
[TypeDefInfo.BTreeSet]: (registry: Registry, value: TypeDef): Constructor =>
|
||||
[TypeDefInfo.BTreeSet]: (registry: Registry, value: TypeDef): Constructor<Codec> =>
|
||||
BTreeSet.with(getSubType(value)),
|
||||
|
||||
[TypeDefInfo.Compact]: (registry: Registry, value: TypeDef): Constructor =>
|
||||
[TypeDefInfo.Compact]: (registry: Registry, value: TypeDef): Constructor<Codec> =>
|
||||
Compact.with(getSubType(value)),
|
||||
|
||||
[TypeDefInfo.DoNotConstruct]: (registry: Registry, value: TypeDef): Constructor =>
|
||||
[TypeDefInfo.DoNotConstruct]: (registry: Registry, value: TypeDef): Constructor<Codec> =>
|
||||
DoNotConstruct.with(value.displayName || value.type),
|
||||
|
||||
[TypeDefInfo.Enum]: (registry: Registry, value: TypeDef): Constructor => {
|
||||
[TypeDefInfo.Enum]: (registry: Registry, value: TypeDef): Constructor<Codec> => {
|
||||
const subs = getSubDefArray(value);
|
||||
|
||||
return Enum.with(
|
||||
@@ -92,14 +92,14 @@ const infoMapping: Record<TypeDefInfo, (registry: Registry, value: TypeDef) => C
|
||||
);
|
||||
},
|
||||
|
||||
[TypeDefInfo.HashMap]: (registry: Registry, value: TypeDef): Constructor =>
|
||||
[TypeDefInfo.HashMap]: (registry: Registry, value: TypeDef): Constructor<Codec> =>
|
||||
createHashMap(value, HashMap),
|
||||
|
||||
[TypeDefInfo.Int]: (registry: Registry, value: TypeDef): Constructor =>
|
||||
[TypeDefInfo.Int]: (registry: Registry, value: TypeDef): Constructor<Codec> =>
|
||||
createInt(value, Int),
|
||||
|
||||
// We have circular deps between Linkage & Struct
|
||||
[TypeDefInfo.Linkage]: (registry: Registry, value: TypeDef): Constructor => {
|
||||
[TypeDefInfo.Linkage]: (registry: Registry, value: TypeDef): Constructor<Codec> => {
|
||||
const type = `Option<${getSubType(value)}>`;
|
||||
// eslint-disable-next-line sort-keys
|
||||
const Clazz = Struct.with({ previous: type, next: type } as any);
|
||||
@@ -114,23 +114,23 @@ const infoMapping: Record<TypeDefInfo, (registry: Registry, value: TypeDef) => C
|
||||
},
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
[TypeDefInfo.Null]: (registry: Registry, _: TypeDef): Constructor =>
|
||||
[TypeDefInfo.Null]: (registry: Registry, _: TypeDef): Constructor<Codec> =>
|
||||
Null,
|
||||
|
||||
[TypeDefInfo.Option]: (registry: Registry, value: TypeDef): Constructor =>
|
||||
[TypeDefInfo.Option]: (registry: Registry, value: TypeDef): Constructor<Codec> =>
|
||||
Option.with(getSubType(value)),
|
||||
|
||||
[TypeDefInfo.Plain]: (registry: Registry, value: TypeDef): Constructor =>
|
||||
[TypeDefInfo.Plain]: (registry: Registry, value: TypeDef): Constructor<Codec> =>
|
||||
registry.getOrUnknown(value.type),
|
||||
|
||||
[TypeDefInfo.Result]: (registry: Registry, value: TypeDef): Constructor => {
|
||||
[TypeDefInfo.Result]: (registry: Registry, value: TypeDef): Constructor<Codec> => {
|
||||
const [Ok, Err] = getTypeClassArray(value);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
return Result.with({ Err, Ok });
|
||||
},
|
||||
|
||||
[TypeDefInfo.Set]: (registry: Registry, value: TypeDef): Constructor => {
|
||||
[TypeDefInfo.Set]: (registry: Registry, value: TypeDef): Constructor<Codec> => {
|
||||
const result: Record<string, number> = {};
|
||||
|
||||
return CodecSet.with(
|
||||
@@ -143,19 +143,19 @@ const infoMapping: Record<TypeDefInfo, (registry: Registry, value: TypeDef) => C
|
||||
);
|
||||
},
|
||||
|
||||
[TypeDefInfo.Si]: (registry: Registry, value: TypeDef): Constructor =>
|
||||
[TypeDefInfo.Si]: (registry: Registry, value: TypeDef): Constructor<Codec> =>
|
||||
getTypeClass(registry, registry.lookup.getTypeDef(value.type)),
|
||||
|
||||
[TypeDefInfo.Struct]: (registry: Registry, value: TypeDef): Constructor =>
|
||||
[TypeDefInfo.Struct]: (registry: Registry, value: TypeDef): Constructor<Codec> =>
|
||||
Struct.with(getTypeClassMap(value), value.alias),
|
||||
|
||||
[TypeDefInfo.Tuple]: (registry: Registry, value: TypeDef): Constructor =>
|
||||
[TypeDefInfo.Tuple]: (registry: Registry, value: TypeDef): Constructor<Codec> =>
|
||||
Tuple.with(getTypeClassArray(value)),
|
||||
|
||||
[TypeDefInfo.UInt]: (registry: Registry, value: TypeDef): Constructor =>
|
||||
[TypeDefInfo.UInt]: (registry: Registry, value: TypeDef): Constructor<Codec> =>
|
||||
createInt(value, UInt),
|
||||
|
||||
[TypeDefInfo.Vec]: (registry: Registry, value: TypeDef): Constructor => {
|
||||
[TypeDefInfo.Vec]: (registry: Registry, value: TypeDef): Constructor<Codec> => {
|
||||
const subType = getSubType(value);
|
||||
|
||||
return (
|
||||
@@ -165,7 +165,7 @@ const infoMapping: Record<TypeDefInfo, (registry: Registry, value: TypeDef) => C
|
||||
);
|
||||
},
|
||||
|
||||
[TypeDefInfo.VecFixed]: (registry: Registry, { displayName, length, sub }: TypeDef): Constructor => {
|
||||
[TypeDefInfo.VecFixed]: (registry: Registry, { displayName, length, sub }: TypeDef): Constructor<Codec> => {
|
||||
assert(isNumber(length) && !isUndefined(sub), 'Expected length & type information for fixed vector');
|
||||
|
||||
const subType = (sub as TypeDef).type;
|
||||
@@ -180,7 +180,7 @@ const infoMapping: Record<TypeDefInfo, (registry: Registry, value: TypeDef) => C
|
||||
|
||||
// Returns the type Class for construction
|
||||
export function getTypeClass<T extends Codec = Codec> (registry: Registry, typeDef: TypeDef): Constructor<T> {
|
||||
let Type = registry.get<T>(typeDef.type);
|
||||
let Type = registry.get<T>(typeDef.type) as Constructor<T> | undefined;
|
||||
|
||||
if (Type) {
|
||||
return Type;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import type { ExtDef } from '../extrinsic/signedExtensions/types';
|
||||
import type { ChainProperties, CodecHash, DispatchErrorModule, Hash, MetadataLatest, PortableRegistry, SiLookupTypeId } from '../interfaces/types';
|
||||
import type { CallFunction, Codec, CodecHasher, Constructor, DetectCodec, DetectConstructor, InterfaceTypes, RegisteredTypes, Registry, RegistryError, RegistryTypes } from '../types';
|
||||
import type { CallFunction, Codec, CodecHasher, Constructor, DetectCodec, DetectConstructor, RegisteredTypes, Registry, RegistryError, RegistryTypes } from '../types';
|
||||
import type { CreateOptions } from './types';
|
||||
|
||||
import { assert, assertReturn, BN_ZERO, formatBalance, isFunction, isString, isU8a, logger, stringCamelCase, stringify, u8aToHex } from '@polkadot/util';
|
||||
@@ -342,11 +342,11 @@ export class TypeRegistry implements Registry {
|
||||
return this.get<T, K>(name, true) as DetectConstructor<T, K>;
|
||||
}
|
||||
|
||||
public getSignedExtensionExtra (): Record<string, keyof InterfaceTypes> {
|
||||
public getSignedExtensionExtra (): Record<string, string> {
|
||||
return expandExtensionTypes(this.#signedExtensions, 'payload', this.#userExtensions);
|
||||
}
|
||||
|
||||
public getSignedExtensionTypes (): Record<string, keyof InterfaceTypes> {
|
||||
public getSignedExtensionTypes (): Record<string, string> {
|
||||
return expandExtensionTypes(this.#signedExtensions, 'extrinsic', this.#userExtensions);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Address, Balance, BlockNumber, Call, ExtrinsicEra, Hash, Index, RuntimeVersion } from '../interfaces';
|
||||
import type { Codec, InterfaceTypes, ISignerPayload, Registry, SignerPayloadJSON, SignerPayloadRaw } from '../types';
|
||||
import type { Codec, ISignerPayload, Registry, SignerPayloadJSON, SignerPayloadRaw } from '../types';
|
||||
|
||||
import { u8aToHex } from '@polkadot/util';
|
||||
|
||||
@@ -26,7 +26,7 @@ export interface SignerPayloadType extends Codec {
|
||||
version: u8;
|
||||
}
|
||||
|
||||
const knownTypes: Record<string, keyof InterfaceTypes> = {
|
||||
const knownTypes: Record<string, string> = {
|
||||
address: 'Address',
|
||||
blockHash: 'Hash',
|
||||
blockNumber: 'BlockNumber',
|
||||
@@ -46,7 +46,7 @@ const knownTypes: Record<string, keyof InterfaceTypes> = {
|
||||
* A generic signer payload that can be used for serialization between API and signer
|
||||
*/
|
||||
export class GenericSignerPayload extends Struct implements ISignerPayload, SignerPayloadType {
|
||||
private readonly _extraTypes: Record<string, keyof InterfaceTypes>;
|
||||
private readonly _extraTypes: Record<string, string>;
|
||||
|
||||
constructor (registry: Registry, value?: string | { [x: string]: any; } | Map<unknown, unknown> | unknown[]) {
|
||||
const extensionTypes = {
|
||||
@@ -60,7 +60,7 @@ export class GenericSignerPayload extends Struct implements ISignerPayload, Sign
|
||||
}, value);
|
||||
|
||||
// add all extras that are not in the base types
|
||||
this._extraTypes = Object.entries(extensionTypes).reduce<Record<string, keyof InterfaceTypes>>((map, [key, type]) => {
|
||||
this._extraTypes = Object.entries(extensionTypes).reduce<Record<string, string>>((map, [key, type]) => {
|
||||
if (!knownTypes[key]) {
|
||||
map[key] = type;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { InterfaceTypes } from '../../types';
|
||||
|
||||
export type ExtTypes = Record<string, keyof InterfaceTypes>;
|
||||
export type ExtTypes = Record<string, string>;
|
||||
|
||||
export type ExtInfo = {
|
||||
extrinsic: ExtTypes;
|
||||
|
||||
@@ -22,7 +22,7 @@ describe('EventRecord', (): void => {
|
||||
});
|
||||
|
||||
it('decodes older EventRecord correctly', (): void => {
|
||||
const records = registry.createType('Vec<EventRecord>', json1.params.result.changes[0][1], true) as any;
|
||||
const records = registry.createType('Vec<EventRecord>', json1.params.result.changes[0][1], true);
|
||||
const er = records[0];
|
||||
|
||||
expect(er.phase.type).toEqual('ApplyExtrinsic');
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Compact, Option, Raw, Struct, Vec, VecFixed } from '../codec';
|
||||
import type { AbstractArray } from '../codec/AbstractArray';
|
||||
import type { CompactEncodable } from '../codec/types';
|
||||
import type { Bytes } from '../primitive';
|
||||
import type { Codec, Constructor } from './codec';
|
||||
import type { ITuple } from './interfaces';
|
||||
import type { InterfaceTypes } from './registry';
|
||||
|
||||
// Vec & Tuple extends AbstractArray
|
||||
export type KnownDetects = Compact<CompactEncodable> | Option<Codec> | AbstractArray<Codec> | Raw | Struct;
|
||||
|
||||
export type DetectCodec<T extends Codec, K extends string> = Expand<K, T>;
|
||||
|
||||
export type DetectConstructor<T extends Codec, K extends string> = Constructor<Expand<K, T>>;
|
||||
|
||||
export type Expand<K extends string, T extends Codec = Codec> = K extends keyof InterfaceTypes
|
||||
? InterfaceTypes[K]
|
||||
// these are the ones we short-circuit in the wrap itself
|
||||
: T extends KnownDetects
|
||||
? T
|
||||
: // strip any leading spaces from the types...
|
||||
K extends ` ${infer I}`
|
||||
? Expand<I, T>
|
||||
// ... and any trailing spaces
|
||||
: K extends `${infer I} `
|
||||
? Expand<I, T>
|
||||
: ExpandWrap<K, T>;
|
||||
|
||||
// ensure whatever we wrap is always Compact-capable
|
||||
export type ExpandCompact<T extends Codec> = T extends CompactEncodable
|
||||
? Compact<T>
|
||||
: never;
|
||||
|
||||
// currently we only support 5 levels for auto-extract
|
||||
export type ExpandTuple<X extends string, T extends Codec> = X extends `${infer A},${infer B},${infer C},${infer D},${infer E}`
|
||||
? ITuple<[Expand<A>, Expand<B>, Expand<C>, Expand<D>, Expand<E>]>
|
||||
: X extends `${infer A},${infer B},${infer C},${infer D}`
|
||||
? ITuple<[Expand<A>, Expand<B>, Expand<C>, Expand<D>]>
|
||||
: X extends `${infer A},${infer B},${infer C}`
|
||||
? ITuple<[Expand<A>, Expand<B>, Expand<C>]>
|
||||
: X extends `${infer A},${infer B}`
|
||||
? ITuple<[Expand<A>, Expand<B>]>
|
||||
: X extends `${infer A}`
|
||||
? Expand<A>
|
||||
: T;
|
||||
|
||||
// vec support with short-circuit for u8
|
||||
export type ExpandVec<X extends string, T extends Codec> = X extends 'u8'
|
||||
? Bytes
|
||||
: Vec<Expand<X, T>>;
|
||||
|
||||
// fixed vec support
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export type ExpandVecFixed<X extends string> = X extends `${infer Y};${infer _}`
|
||||
? Y extends 'u8'
|
||||
? Raw
|
||||
: VecFixed<Expand<Y>>
|
||||
: never;
|
||||
|
||||
export type ExpandWrap<K extends string, T extends Codec> = K extends `Compact<${infer X}>`
|
||||
? ExpandCompact<Expand<X>>
|
||||
: K extends `Option<${infer X}>`
|
||||
? Option<Expand<X>>
|
||||
: K extends `Vec<${infer X}>`
|
||||
? ExpandVec<X, T>
|
||||
: K extends `[${infer X}]`
|
||||
? ExpandVecFixed<X>
|
||||
: K extends `(${infer X})`
|
||||
? ExpandTuple<X, T>
|
||||
: T;
|
||||
@@ -8,6 +8,7 @@ export * from '../create/types';
|
||||
export * from './calls';
|
||||
export * from './codec';
|
||||
export * from './definitions';
|
||||
export * from './detect';
|
||||
export * from './events';
|
||||
export * from './extrinsic';
|
||||
export * from './interfaces';
|
||||
|
||||
@@ -7,13 +7,35 @@ import type { FunctionMetadataLatest, StorageEntryMetadataLatest } from '../inte
|
||||
import type { Hash } from '../interfaces/runtime';
|
||||
import type { AnyTuple, ArgsDef, Codec } from './codec';
|
||||
|
||||
export interface ICompact<T> extends Codec {
|
||||
export interface ICompact<T extends Codec> extends Codec {
|
||||
toBigInt (): bigint;
|
||||
toBn (): BN;
|
||||
toNumber (): number;
|
||||
unwrap (): T;
|
||||
}
|
||||
|
||||
export interface IOption<T extends Codec> extends Codec {
|
||||
isNone: boolean;
|
||||
isSome: boolean;
|
||||
value: Codec;
|
||||
|
||||
unwrap (): T;
|
||||
unwrapOr <O>(other: O): T | O;
|
||||
unwrapOrDefault (): T;
|
||||
}
|
||||
|
||||
// A type alias for [Type1, Type2] & Codec, representing a tuple (Type1, Type2)
|
||||
// FIXME Implement this generic <Sub> on Tuple.ts itself.
|
||||
export type ITuple<S extends AnyTuple> = S & Codec;
|
||||
|
||||
export interface IU8a extends Uint8Array, Codec {
|
||||
bitLength (): number;
|
||||
toHuman (isExtended?: boolean): any;
|
||||
toJSON (): any;
|
||||
}
|
||||
|
||||
export type IVec<S extends Codec> = Array<S> & Codec;
|
||||
|
||||
export interface IKeyringPair {
|
||||
address: string;
|
||||
addressRaw: Uint8Array;
|
||||
@@ -55,13 +77,3 @@ export interface IStorageKey<A extends AnyTuple> {
|
||||
|
||||
is: (key: IStorageKey<AnyTuple>) => key is IStorageKey<A>;
|
||||
}
|
||||
|
||||
// A type alias for [Type1, Type2] & Codec, representing a tuple (Type1, Type2)
|
||||
// FIXME Implement this generic <Sub> on Tuple.ts itself.
|
||||
export type ITuple<Sub extends AnyTuple> = Sub & Codec
|
||||
|
||||
export interface IU8a extends Uint8Array, Codec {
|
||||
bitLength (): number;
|
||||
toHuman (isExtended?: boolean): any;
|
||||
toJSON (): any;
|
||||
}
|
||||
|
||||
@@ -13,16 +13,11 @@ import type { Metadata } from '../metadata';
|
||||
import type { CallFunction } from './calls';
|
||||
import type { Codec, Constructor } from './codec';
|
||||
import type { DefinitionRpc, DefinitionRpcSub } from './definitions';
|
||||
import type { DetectCodec, DetectConstructor } from './detect';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface InterfaceTypes { }
|
||||
|
||||
export type DetectCodec<T extends Codec, K extends string> = K extends keyof InterfaceTypes
|
||||
? InterfaceTypes[K]
|
||||
: T;
|
||||
|
||||
export type DetectConstructor<T extends Codec, K extends string> = Constructor<DetectCodec<T, K>>;
|
||||
|
||||
export type CodecHasher = (data: Uint8Array) => Uint8Array;
|
||||
|
||||
export interface ChainUpgradeVersion {
|
||||
@@ -136,8 +131,8 @@ export interface Registry {
|
||||
getOrThrow <T extends Codec = Codec, K extends string = string> (name: K, msg?: string): DetectConstructor<T, K>;
|
||||
getOrUnknown <T extends Codec = Codec, K extends string = string> (name: K): DetectConstructor<T, K>;
|
||||
setKnownTypes (types: RegisteredTypes): void;
|
||||
getSignedExtensionExtra (): Record<string, keyof InterfaceTypes>;
|
||||
getSignedExtensionTypes (): Record<string, keyof InterfaceTypes>;
|
||||
getSignedExtensionExtra (): Record<string, string>;
|
||||
getSignedExtensionTypes (): Record<string, string>;
|
||||
hasClass (name: string): boolean;
|
||||
hasDef (name: string): boolean;
|
||||
hasType (name: string): boolean;
|
||||
|
||||
Reference in New Issue
Block a user