diff --git a/CHANGELOG.md b/CHANGELOG.md index aa401ad528..5dfa4aa84d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # CHANGELOG +## master + +Contributed: + +- Add `Range` & `RangeInclusive` types (Thanks to https://github.com/c410-f3r) +- Always use TS `bigint` type (Thanks to https://github.com/ntduan) + +Changes: + +- Extend `createType` auto-TS decoration for `BreeMap`, `BTreeSet`, `HashMap` + + ## 5.4.1 Aug 9, 2021 Upgrade priority: Low. Recommended for potential users of NMap. diff --git a/packages/api-derive/src/session/types.ts b/packages/api-derive/src/session/types.ts index 93e0b5f5a9..145b54d7a7 100644 --- a/packages/api-derive/src/session/types.ts +++ b/packages/api-derive/src/session/types.ts @@ -1,7 +1,7 @@ // Copyright 2017-2021 @polkadot/api-derive authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { Option, u32 } from '@polkadot/types'; +import type { Option, u32, u64 } from '@polkadot/types'; import type { BlockNumber, EraIndex, Moment, SessionIndex } from '@polkadot/types/interfaces'; export interface DeriveSessionIndexes { @@ -15,7 +15,7 @@ export interface DeriveSessionIndexes { export interface DeriveSessionInfo extends DeriveSessionIndexes { eraLength: BlockNumber; isEpoch: boolean; - sessionLength: BlockNumber; + sessionLength: u64; sessionsPerEra: SessionIndex; } diff --git a/packages/types/src/checkTypes.manual.ts b/packages/types/src/checkTypes.manual.ts index e14ca8cf77..be2c6b5cd7 100644 --- a/packages/types/src/checkTypes.manual.ts +++ b/packages/types/src/checkTypes.manual.ts @@ -48,11 +48,13 @@ const vv = registry.createType('Vec< Vec< Vec< Vec> > >'); // vec with tuple const vt = registry.createType('Vec<(u8, u16)>'); // nested stuff from all-over -const vn = registry.createType('Vec<(u32, (u32, u64), Vec, Vec<(u32, u64)>, [u8;32], [u128;32])>'); +const vn = registry.createType('Vec<(u32, (u32, u64), Vec, Vec, Vec<(u32, u64)>, [u8;32], [u128;32])>'); // nested fixed const nf = registry.createType('[[[u8;32];5];3]'); +// with linkage +const tl = registry.createType('(ValidatorPrefsWithCommission, Linkage)'); -assert(ee[0].unwrap().unwrap().divn(123) && vb.unwrap().bitLength() && vv.toHuman() && vn.toHuman() && vt.toHuman() && nf.toHuman(), 'All ok'); +assert(ee[0].unwrap().unwrap().divn(123) && vb.unwrap().bitLength() && vv.toHuman() && vn[0][3][0].bitLength && vt.toHuman() && nf.toHuman() && tl[1].next, 'All ok'); // tuple & struct const vs = registry.createType('(u8, {"a":"u32","b":"(u32,u64)"},(u8,u16),{"foo":"Bar"},u16)'); @@ -70,8 +72,10 @@ assert(gg.subarray(1), 'All ok'); // Should end up as VecFixed const hh = registry.createType('[u128; 32]'); +// maps and sets +const ms = registry.createType('(BTreeSet, BTreeMap, HashMap)'); -assert(hh[0].bitLength(), 'All ok'); +assert(hh[0].bitLength() && ms[0].strings && ms[1].values && ms[2].keys, 'All ok'); // tuple! ITuple<[u32, Compact, u128, Codec]> const tt1 = registry.createType('(u32, Compact, u128 , Something)'); diff --git a/packages/types/src/codec/BTreeSet.ts b/packages/types/src/codec/BTreeSet.ts index 756645bf9e..4fa4aa8a48 100644 --- a/packages/types/src/codec/BTreeSet.ts +++ b/packages/types/src/codec/BTreeSet.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import type { CodecHash, Hash } from '../interfaces/runtime'; -import type { AnyJson, Codec, Constructor, Registry } from '../types'; +import type { AnyJson, Codec, Constructor, ISet, Registry } from '../types'; import { compactFromU8a, compactToU8a, isHex, isU8a, logger, stringify, u8aConcat, u8aToHex, u8aToU8a } from '@polkadot/util'; @@ -76,7 +76,7 @@ function decodeSet (registry: Registry, valType: Constructor throw new Error('BTreeSet: cannot decode type'); } -export class BTreeSet extends Set implements Codec { +export class BTreeSet extends Set implements ISet { public readonly registry: Registry; public createdAtHash?: Hash; @@ -125,6 +125,13 @@ export class BTreeSet extends Set implements Codec { return this.size === 0; } + /** + * @description The actual set values as a string[] + */ + public get strings (): string[] { + return [...super.values()].map((v) => v.toString()); + } + /** * @description Compares the value of the input to see if there is a match */ diff --git a/packages/types/src/codec/Linkage.spec.ts b/packages/types/src/codec/Linkage.spec.ts index 710d7bcb18..3bf66ca70e 100644 --- a/packages/types/src/codec/Linkage.spec.ts +++ b/packages/types/src/codec/Linkage.spec.ts @@ -1,8 +1,6 @@ // Copyright 2017-2021 @polkadot/types authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { Codec, ITuple } from '../types'; - import { TypeRegistry } from '../create/registry'; import { Linkage } from '.'; @@ -34,7 +32,7 @@ describe('Linkage', (): void => { // actual check expect( - registry.createType]>>( + registry.createType( '(ValidatorPrefsWithCommission, Linkage)', '0x0284d7170001da30b68f54f686f586ddb29de12b682dd8bd1404566fb8a8db5dec20aa5b6b36' ).toHuman() diff --git a/packages/types/src/codec/Set.ts b/packages/types/src/codec/Set.ts index 4b1f9ee7f7..59b70df173 100644 --- a/packages/types/src/codec/Set.ts +++ b/packages/types/src/codec/Set.ts @@ -74,7 +74,7 @@ function decodeSet (setValues: SetValues, value: string[] | Set | Uint8A * An Set is an array of string values, represented an an encoded type by * a bitwise representation of the values. */ -export class CodecSet extends Set implements ISet { +export class CodecSet extends Set implements ISet { public readonly registry: Registry; public createdAtHash?: Hash; diff --git a/packages/types/src/codec/index.ts b/packages/types/src/codec/index.ts index abf8264218..64aee4e410 100644 --- a/packages/types/src/codec/index.ts +++ b/packages/types/src/codec/index.ts @@ -21,6 +21,8 @@ export { CodecMap, CodecMap as Map } from './Map'; export { Option } from './Option'; export { Raw } from './Raw'; export { Result } from './Result'; +export { Range } from './Range'; +export { RangeInclusive } from './RangeInclusive'; export { CodecSet, CodecSet as Set } from './Set'; export { Struct } from './Struct'; export { Tuple } from './Tuple'; @@ -29,5 +31,3 @@ export { U8aFixed } from './U8aFixed'; export { Vec } from './Vec'; // export { VecAny } from './VecAny'; export { VecFixed } from './VecFixed'; -export { Range } from './Range'; -export { RangeInclusive } from './RangeInclusive'; diff --git a/packages/types/src/primitive/I128.ts b/packages/types/src/primitive/I128.ts index cbc97f3f52..f798baf4c3 100644 --- a/packages/types/src/primitive/I128.ts +++ b/packages/types/src/primitive/I128.ts @@ -8,4 +8,7 @@ import { Int } from '../codec/Int'; * @description * A 128-bit signed integer */ -export class i128 extends Int.with(128) {} +export class i128 extends Int.with(128) { + // NOTE without this, we cannot properly determine extensions + public readonly __IntType = 'i128'; +} diff --git a/packages/types/src/primitive/I16.ts b/packages/types/src/primitive/I16.ts index 7cdbc9f631..17aa761b1a 100644 --- a/packages/types/src/primitive/I16.ts +++ b/packages/types/src/primitive/I16.ts @@ -8,4 +8,7 @@ import { Int } from '../codec/Int'; * @description * A 16-bit signed integer */ -export class i16 extends Int.with(16) {} +export class i16 extends Int.with(16) { + // NOTE without this, we cannot properly determine extensions + public readonly __IntType = 'i16'; +} diff --git a/packages/types/src/primitive/I256.ts b/packages/types/src/primitive/I256.ts index bad91a8b7d..5a45cf6205 100644 --- a/packages/types/src/primitive/I256.ts +++ b/packages/types/src/primitive/I256.ts @@ -8,4 +8,7 @@ import { Int } from '../codec/Int'; * @description * A 256-bit signed integer */ -export class i256 extends Int.with(256) {} +export class i256 extends Int.with(256) { + // NOTE without this, we cannot properly determine extensions + public readonly __IntType = 'i256'; +} diff --git a/packages/types/src/primitive/I32.ts b/packages/types/src/primitive/I32.ts index 7a99872bf4..ab1c489046 100644 --- a/packages/types/src/primitive/I32.ts +++ b/packages/types/src/primitive/I32.ts @@ -8,4 +8,7 @@ import { Int } from '../codec/Int'; * @description * A 32-bit signed integer */ -export class i32 extends Int.with(32) {} +export class i32 extends Int.with(32) { + // NOTE without this, we cannot properly determine extensions + public readonly __IntType = 'i32'; +} diff --git a/packages/types/src/primitive/I64.ts b/packages/types/src/primitive/I64.ts index e709a64770..f7a8626d77 100644 --- a/packages/types/src/primitive/I64.ts +++ b/packages/types/src/primitive/I64.ts @@ -8,4 +8,7 @@ import { Int } from '../codec/Int'; * @description * A 64-bit signed integer */ -export class i64 extends Int.with(64) {} +export class i64 extends Int.with(64) { + // NOTE without this, we cannot properly determine extensions + public readonly __IntType = 'i64'; +} diff --git a/packages/types/src/primitive/I8.ts b/packages/types/src/primitive/I8.ts index 082cb6c4f1..999c05059f 100644 --- a/packages/types/src/primitive/I8.ts +++ b/packages/types/src/primitive/I8.ts @@ -8,4 +8,7 @@ import { Int } from '../codec/Int'; * @description * An 8-bit signed integer */ -export class i8 extends Int.with(8) {} +export class i8 extends Int.with(8) { + // NOTE without this, we cannot properly determine extensions + public readonly __IntType = 'i8'; +} diff --git a/packages/types/src/primitive/U128.ts b/packages/types/src/primitive/U128.ts index 7460617075..39e9fdd006 100644 --- a/packages/types/src/primitive/U128.ts +++ b/packages/types/src/primitive/U128.ts @@ -8,4 +8,7 @@ import { UInt } from '../codec/UInt'; * @description * A 128-bit unsigned integer */ -export class u128 extends UInt.with(128) {} +export class u128 extends UInt.with(128) { + // NOTE without this, we cannot properly determine extensions + public readonly __UIntType = 'u128'; +} diff --git a/packages/types/src/primitive/U16.ts b/packages/types/src/primitive/U16.ts index 8da470c751..989603b2e4 100644 --- a/packages/types/src/primitive/U16.ts +++ b/packages/types/src/primitive/U16.ts @@ -8,4 +8,7 @@ import { UInt } from '../codec/UInt'; * @description * A 16-bit unsigned integer */ -export class u16 extends UInt.with(16) {} +export class u16 extends UInt.with(16) { + // NOTE without this, we cannot properly determine extensions + public readonly __UIntType = 'u16'; +} diff --git a/packages/types/src/primitive/U256.ts b/packages/types/src/primitive/U256.ts index 61351e8d56..caf0953b74 100644 --- a/packages/types/src/primitive/U256.ts +++ b/packages/types/src/primitive/U256.ts @@ -8,4 +8,7 @@ import { UInt } from '../codec/UInt'; * @description * A 256-bit unsigned integer */ -export class u256 extends UInt.with(256) {} +export class u256 extends UInt.with(256) { + // NOTE without this, we cannot properly determine extensions + public readonly __UIntType = 'u256'; +} diff --git a/packages/types/src/primitive/U32.ts b/packages/types/src/primitive/U32.ts index c79bbeaa79..b745c4d205 100644 --- a/packages/types/src/primitive/U32.ts +++ b/packages/types/src/primitive/U32.ts @@ -8,4 +8,7 @@ import { UInt } from '../codec/UInt'; * @description * A 32-bit unsigned integer */ -export class u32 extends UInt.with(32) {} +export class u32 extends UInt.with(32) { + // NOTE without this, we cannot properly determine extensions + public readonly __UIntType = 'u32'; +} diff --git a/packages/types/src/primitive/U64.ts b/packages/types/src/primitive/U64.ts index f684989b12..8899be99f3 100644 --- a/packages/types/src/primitive/U64.ts +++ b/packages/types/src/primitive/U64.ts @@ -8,4 +8,7 @@ import { UInt } from '../codec/UInt'; * @description * A 64-bit unsigned integer */ -export class u64 extends UInt.with(64) {} +export class u64 extends UInt.with(64) { + // NOTE without this, we cannot properly determine extensions + public readonly __UIntType = 'u64'; +} diff --git a/packages/types/src/primitive/U8.ts b/packages/types/src/primitive/U8.ts index 3af2ec57e4..bb1f8aa833 100644 --- a/packages/types/src/primitive/U8.ts +++ b/packages/types/src/primitive/U8.ts @@ -8,4 +8,7 @@ import { UInt } from '../codec/UInt'; * @description * An 8-bit unsigned integer */ -export class u8 extends UInt.with(8) {} +export class u8 extends UInt.with(8) { + // NOTE without this, we cannot properly determine extensions + public readonly __UIntType = 'u8'; +} diff --git a/packages/types/src/types/detect.ts b/packages/types/src/types/detect.ts index 86ee448bbc..8c7ac6c211 100644 --- a/packages/types/src/types/detect.ts +++ b/packages/types/src/types/detect.ts @@ -1,8 +1,8 @@ // Copyright 2017-2021 @polkadot/types authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { Compact, Option, Raw, Vec, VecFixed } from '../codec'; -import type { Bytes, Null } from '../primitive'; +import type { BTreeMap, BTreeSet, CodecSet, Compact, Enum, HashMap, Linkage, Option, Raw, Struct, Vec, VecFixed } from '../codec'; +import type { Bytes, Null, u8 } from '../primitive'; import type { Codec, Constructor } from './codec'; import type { ICompact, IEnum, IMap, IMethod, INumber, IOption, IResult, ISet, IStruct, ITuple, IU8a, IVec } from './interfaces'; import type { InterfaceTypes } from './registry'; @@ -14,11 +14,11 @@ export type DetectCodec = ? InterfaceTypes[K] : T extends ICompact | IEnum | IMap | IMethod | INumber | IOption | IResult | ISet | IStruct | ITuple | IU8a | IVec ? T - : __ExtractCodec<__ToCodecs<__Tokenize<__Sanitize>[0]>>; + : __Codec<__Codecs<__Tokenize<__Sanitize>[0]>>; export type DetectConstructor = Constructor>; -export type __ExtractCodec = +export type __Codec = V[0] extends Codec ? V[0] : Codec; @@ -37,34 +37,34 @@ export type __Sanitize = export type __Value = string | Record | __Value[]; -export type __ToCodec = - K extends keyof InterfaceTypes - ? InterfaceTypes[K] - : K extends unknown[] - ? __ToTuple<__ToCodecs> - : K extends Record - ? K['_enum'] extends Record - ? IEnum - : K['_set'] extends Record - ? ISet - : IStruct - : K extends Set - ? ISet - : K extends '[' - ? N[0] extends 'u8' - ? Raw - : VecFixed - : K extends 'Vec<' - ? N[0] extends 'u8' - ? Bytes - : Vec - : K extends 'Option<' - ? Option - : K extends 'Compact<' - ? C[0] extends INumber - ? Compact - : Codec - : Codec; +export type __MapWrapOne = { + 'BTreeSet<': BTreeSet; + 'Compact<': C extends INumber ? Compact : Codec; + 'Linkage<': Linkage; + 'Option<': Option; + 'Vec<': C extends u8 ? Bytes : Vec; + '[': C extends u8 ? Raw : VecFixed; +}; + +// FIXME We don't cater for Int< & UInt< here. These could be problematic, since it has +// a variable number of inner arguments, better would be to just strip them inside the sanitize +export type __MapWrapTwo = { + 'BTreeMap<': BTreeMap; + 'HashMap<': HashMap; +}; + +export type __WrapOne = keyof __MapWrapOne; + +export type __WrapTwo = keyof __MapWrapTwo; + +export type __Wrap = __WrapOne | __WrapTwo; + +export type __ToStruct> = + K['_enum'] extends true + ? Enum + : K['_set'] extends true + ? CodecSet + : Struct; export type __ToTuple = O[0] extends Codec @@ -73,48 +73,64 @@ export type __ToTuple = : O[0] : Null; -export type __ToCodecsInner = - K extends '[' | 'Vec<' | 'Option<' | 'Compact<' - ? C extends [Codec, ...infer X] - ? [__ToCodec, ...X] - : never - : [__ToCodec, ...C]; +export type __CodecFirst = [ + K extends keyof InterfaceTypes + ? InterfaceTypes[K] + : K extends unknown[] + ? __ToTuple<__Codecs> + : K extends Record + ? __ToStruct + : K extends __WrapOne + ? __MapWrapOne[K] + : K extends __WrapTwo + ? __MapWrapTwo[K] + : Codec, + ...X +]; -export type __ToCodecs = - T extends [infer K, ...infer O] - ? __ToCodecsInner> +export type __CodecsNext = + K extends __WrapOne + ? C extends [Codec, ...infer X] + ? __CodecFirst + : never + : K extends __WrapTwo + ? C extends [Codec, Codec, ...infer X] + ? __CodecFirst + : never + : __CodecFirst; + +export type __Codecs = + T extends [infer K, ...infer N] + ? __CodecsNext> : []; -export type __RemoveEmpty = - T extends '' - ? [] - : [T]; - -export type __Combine = - [...V, ...__RemoveEmpty, ...__RemoveEmpty]; +export type __Combine = + I extends '' + ? V + : [...V, I]; export type __CombineInner = - [...__RemoveEmpty, ...V, X]; + I extends '' + ? [...V, X] + : [I, ...V, X]; -// TODO At this point structs are fully empty, no field indicators +// FIXME At this point enum/set/struct are empty, no field indicators, just type indicators export type __TokenizeStruct = - __Tokenize>; export type __TokenizeTuple = __Tokenize>; -export type __TokenizeWrapper = +export type __TokenizeWrapped = K extends `${infer X}${R}` - ? __Tokenize> + ? X extends '[' + ? __Tokenize, '[']> + : __Tokenize> : never; export type __TokenizeKnown = @@ -127,20 +143,18 @@ export type __TokenizeKnown = K extends '' | ')' | '>' | '}' ? [__Combine, ''] - : K extends `${'Vec<' | 'Option<' | 'Compact<'}${infer R}` - ? __TokenizeWrapper + : K extends `${__Wrap}${infer R}` + ? __TokenizeWrapped : K extends `${',' | '>'}${infer R}` ? __Tokenize> - : K extends `[${infer R}` - ? __Tokenize> - : K extends `)${infer R}` | `}${infer R}` - ? [__Combine, R] - : K extends `(${infer R}` - ? __TokenizeTuple<__Tokenize, V, I> - : K extends `{${infer R}` - ? __TokenizeStruct<__Tokenize, V, I, R> - : K extends `${keyof InterfaceTypes}${',' | '>'}${infer R}` - ? __TokenizeKnown - : K extends `${infer C}${infer R}` - ? __Tokenize - : [__Combine, '']; + : K extends `)${infer R}` | `}${infer R}` + ? [__Combine, R] + : K extends `(${infer R}` + ? __TokenizeTuple<__Tokenize, V, I> + : K extends `{${infer R}` + ? __TokenizeStruct<__Tokenize, V, I, R> + : K extends `${keyof InterfaceTypes}${',' | '>'}${infer R}` + ? __TokenizeKnown + : K extends `${infer C}${infer R}` + ? __Tokenize + : [__Combine, '']; diff --git a/packages/types/src/types/interfaces.ts b/packages/types/src/types/interfaces.ts index b915535e53..7f663ccff1 100644 --- a/packages/types/src/types/interfaces.ts +++ b/packages/types/src/types/interfaces.ts @@ -53,7 +53,6 @@ export interface IResult exten export interface ISet extends Set, Codec { readonly strings: string[]; - readonly valueEncoded: BN; } export interface IStruct extends Map, Codec {