Pass registry to formatters (#3799)
This commit is contained in:
@@ -119,7 +119,7 @@ export class MetaRegistry extends TypeRegistry {
|
||||
|
||||
const displayName = path.pop()?.toString();
|
||||
|
||||
return withTypeString({
|
||||
return withTypeString(this, {
|
||||
...(displayName
|
||||
? { displayName }
|
||||
: {}
|
||||
@@ -243,7 +243,7 @@ export class MetaRegistry extends TypeRegistry {
|
||||
name: name.toString(),
|
||||
type: 'Null'
|
||||
}))
|
||||
: variants.map(({ fields, name }) => withTypeString({
|
||||
: variants.map(({ fields, name }) => withTypeString(this, {
|
||||
...this.#extractFields(fields),
|
||||
name: name.toString()
|
||||
}));
|
||||
|
||||
@@ -405,7 +405,7 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
|
||||
|
||||
private _decorateStorageEntry<ApiType extends ApiTypes> (creator: StorageEntry, decorateMethod: DecorateMethod<ApiType>): QueryableStorageEntry<ApiType> {
|
||||
// get the storage arguments, with DoubleMap as an array entry, otherwise spread
|
||||
const getArgs = (args: unknown[]): unknown[] => extractStorageArgs(creator, args);
|
||||
const getArgs = (args: unknown[]): unknown[] => extractStorageArgs(this.#registry, creator, args);
|
||||
|
||||
// Disable this where it occurs for each field we are decorating
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment */
|
||||
@@ -488,7 +488,7 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
|
||||
|
||||
private _decorateStorageEntryAt<ApiType extends ApiTypes> (creator: StorageEntry, decorateMethod: DecorateMethod<ApiType>, blockHash: Uint8Array): QueryableStorageEntryAt<ApiType> {
|
||||
// get the storage arguments, with DoubleMap as an array entry, otherwise spread
|
||||
const getArgs = (args: unknown[]): unknown[] => extractStorageArgs(creator, args);
|
||||
const getArgs = (args: unknown[]): unknown[] => extractStorageArgs(this.#registry, creator, args);
|
||||
|
||||
// Disable this where it occurs for each field we are decorating
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment */
|
||||
@@ -545,18 +545,18 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
return decorateMethod((...args: unknown[]): Observable<Codec> => {
|
||||
return this.hasSubscriptions
|
||||
? this._rpcCore.state.subscribeStorage<[Codec]>([extractStorageArgs(creator, args)]).pipe(
|
||||
? this._rpcCore.state.subscribeStorage<[Codec]>([extractStorageArgs(this.#registry, creator, args)]).pipe(
|
||||
map(([data]) => data) // extract first/only result from list
|
||||
)
|
||||
: this._rpcCore.state.getStorage(extractStorageArgs(creator, args));
|
||||
: this._rpcCore.state.getStorage(extractStorageArgs(this.#registry, creator, args));
|
||||
}, {
|
||||
methodName: creator.method,
|
||||
overrideNoSub: (...args: unknown[]) => this._rpcCore.state.getStorage(extractStorageArgs(creator, args))
|
||||
overrideNoSub: (...args: unknown[]) => this._rpcCore.state.getStorage(extractStorageArgs(this.#registry, creator, args))
|
||||
});
|
||||
}
|
||||
|
||||
private _decorateStorageRange<ApiType extends ApiTypes> (decorated: QueryableStorageEntry<ApiType>, args: Arg[], range: [Hash, Hash?]): Observable<[Hash, Codec][]> {
|
||||
const outputType = unwrapStorageType(decorated.creator.meta.type, decorated.creator.meta.modifier.isOptional);
|
||||
const outputType = unwrapStorageType(this.#registry, decorated.creator.meta.type, decorated.creator.meta.modifier.isOptional);
|
||||
|
||||
return this._rpcCore.state
|
||||
.queryStorage<[Option<Raw>]>([decorated.key(...args)], ...range)
|
||||
|
||||
@@ -20,79 +20,79 @@ describe('extractStorageArgs', (): void => {
|
||||
|
||||
it('validates no-arg plain', (): void => {
|
||||
expect(
|
||||
extractStorageArgs(storage.timestamp.now, [])
|
||||
extractStorageArgs(registry, storage.timestamp.now, [])
|
||||
).toEqual([storage.timestamp.now]);
|
||||
});
|
||||
|
||||
it('validates no-arg plain (with undefined, undefined)', (): void => {
|
||||
expect(
|
||||
extractStorageArgs(storage.timestamp.now, [undefined, undefined])
|
||||
extractStorageArgs(registry, storage.timestamp.now, [undefined, undefined])
|
||||
).toEqual([storage.timestamp.now]);
|
||||
});
|
||||
|
||||
it('validates no-arg plain (failing when there are args)', (): void => {
|
||||
expect(
|
||||
(): unknown => extractStorageArgs(storage.timestamp.now, [123, 456])
|
||||
(): unknown => extractStorageArgs(registry, storage.timestamp.now, [123, 456])
|
||||
).toThrow('timestamp.now() does not take any arguments, 2 found');
|
||||
});
|
||||
|
||||
it('validates map, 1 arg', (): void => {
|
||||
expect(
|
||||
extractStorageArgs(storage.staking.payee, ['abc'])
|
||||
extractStorageArgs(registry, storage.staking.payee, ['abc'])
|
||||
).toEqual([storage.staking.payee, 'abc']);
|
||||
});
|
||||
|
||||
it('validates map, 1 arg (failing with no args)', (): void => {
|
||||
expect(
|
||||
(): any =>
|
||||
extractStorageArgs(storage.staking.payee, [])
|
||||
extractStorageArgs(registry, storage.staking.payee, [])
|
||||
).toThrow('staking.payee(AccountId) is a map, requiring 1 argument, 0 found');
|
||||
});
|
||||
|
||||
it('validates map, 1 arg (failing with no args)', (): void => {
|
||||
expect(
|
||||
(): any =>
|
||||
extractStorageArgs(storage.staking.payee, ['abc', 'def'])
|
||||
extractStorageArgs(registry, storage.staking.payee, ['abc', 'def'])
|
||||
).toThrow('staking.payee(AccountId) is a map, requiring 1 argument, 2 found');
|
||||
});
|
||||
|
||||
it('validates doublemap, 2 args', (): void => {
|
||||
expect(
|
||||
extractStorageArgs(storage.staking.erasStakers, [1, '0x1234'])
|
||||
extractStorageArgs(registry, storage.staking.erasStakers, [1, '0x1234'])
|
||||
).toEqual([storage.staking.erasStakers, [1, '0x1234']]);
|
||||
});
|
||||
|
||||
it('validates doublemap, 2 args (failing with no args)', (): void => {
|
||||
expect(
|
||||
(): any =>
|
||||
extractStorageArgs(storage.staking.erasStakers, [])
|
||||
extractStorageArgs(registry, storage.staking.erasStakers, [])
|
||||
).toThrow('staking.erasStakers(EraIndex, AccountId) is a double map, requiring 2 arguments, 0 found');
|
||||
});
|
||||
|
||||
it('validates doublemap, 2 args (failing with 1 arg)', (): void => {
|
||||
expect(
|
||||
(): any =>
|
||||
extractStorageArgs(storage.staking.erasStakers, [123])
|
||||
extractStorageArgs(registry, storage.staking.erasStakers, [123])
|
||||
).toThrow('staking.erasStakers(EraIndex, AccountId) is a double map, requiring 2 arguments, 1 found');
|
||||
});
|
||||
|
||||
// Linked maps have been removed
|
||||
it.skip('validates linked map, no args', (): void => {
|
||||
expect(
|
||||
extractStorageArgs(storage.staking.validators, [])
|
||||
extractStorageArgs(registry, storage.staking.validators, [])
|
||||
).toEqual([storage.staking.validators]);
|
||||
});
|
||||
|
||||
it.skip('validates linked map, single arg', (): void => {
|
||||
expect(
|
||||
extractStorageArgs(storage.staking.validators, [123])
|
||||
extractStorageArgs(registry, storage.staking.validators, [123])
|
||||
).toEqual([storage.staking.validators, 123]);
|
||||
});
|
||||
|
||||
it.skip('validates linked map (failing with extra args)', (): void => {
|
||||
expect(
|
||||
(): any[] =>
|
||||
extractStorageArgs(storage.staking.validators, [123, 456])
|
||||
extractStorageArgs(registry, storage.staking.validators, [123, 456])
|
||||
).toThrow('staking.validators(AccountId) is a linked map, requiring either 0 arguments (retrieving all) or 1 argument, 2 found');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,26 +3,27 @@
|
||||
|
||||
import type { Type } from '@polkadot/types';
|
||||
import type { StorageEntry } from '@polkadot/types/primitive/types';
|
||||
import type { Registry } from '@polkadot/types/types';
|
||||
|
||||
import { assert, isUndefined } from '@polkadot/util';
|
||||
|
||||
function sig ({ method, section }: StorageEntry, args: Type[]): string {
|
||||
function sig (_: Registry, { method, section }: StorageEntry, args: Type[]): string {
|
||||
return `${section}.${method}(${args.join(', ')})`;
|
||||
}
|
||||
|
||||
function doDoubleMap (creator: StorageEntry, args: unknown[]): [StorageEntry, [any, any]] {
|
||||
function doDoubleMap (registry: Registry, creator: StorageEntry, args: unknown[]): [StorageEntry, [any, any]] {
|
||||
const { key1, key2 } = creator.meta.type.asDoubleMap;
|
||||
|
||||
assert(args.length === 2, () => `${sig(creator, [key1, key2])} is a double map, requiring 2 arguments, ${args.length} found`);
|
||||
assert(args.length === 2, () => `${sig(registry, creator, [key1, key2])} is a double map, requiring 2 arguments, ${args.length} found`);
|
||||
|
||||
// pass as tuple
|
||||
return [creator, args as [any, any]];
|
||||
}
|
||||
|
||||
function doMap (creator: StorageEntry, args: unknown[]): [StorageEntry] | [StorageEntry, any] {
|
||||
function doMap (registry: Registry, creator: StorageEntry, args: unknown[]): [StorageEntry] | [StorageEntry, any] {
|
||||
const { key } = creator.meta.type.asMap;
|
||||
|
||||
assert(args.length === 1, () => `${sig(creator, [key])} is a map, requiring 1 argument, ${args.length} found`);
|
||||
assert(args.length === 1, () => `${sig(registry, creator, [key])} is a map, requiring 1 argument, ${args.length} found`);
|
||||
|
||||
// expand
|
||||
return args.length
|
||||
@@ -30,10 +31,10 @@ function doMap (creator: StorageEntry, args: unknown[]): [StorageEntry] | [Stora
|
||||
: [creator];
|
||||
}
|
||||
|
||||
function doNMap (creator: StorageEntry, args: unknown[]): [StorageEntry, any[]] {
|
||||
function doNMap (registry: Registry, creator: StorageEntry, args: unknown[]): [StorageEntry, any[]] {
|
||||
const { keyVec } = creator.meta.type.asNMap;
|
||||
|
||||
assert(args.length === keyVec.length, () => `${sig(creator, keyVec)} is a multi map, requiring ${keyVec.length} arguments, ${args.length} found`);
|
||||
assert(args.length === keyVec.length, () => `${sig(registry, creator, keyVec)} is a multi map, requiring ${keyVec.length} arguments, ${args.length} found`);
|
||||
|
||||
// pass as tuple
|
||||
return [creator, args];
|
||||
@@ -41,18 +42,18 @@ function doNMap (creator: StorageEntry, args: unknown[]): [StorageEntry, any[]]
|
||||
|
||||
// sets up the arguments in the form of [creator, args] ready to be used in a storage
|
||||
// call. Additionally, it verifies that the correct number of arguments have been passed
|
||||
export function extractStorageArgs (creator: StorageEntry, _args: unknown[]): [StorageEntry, any[]] | [StorageEntry] | [StorageEntry, any] {
|
||||
export function extractStorageArgs (registry: Registry, creator: StorageEntry, _args: unknown[]): [StorageEntry, any[]] | [StorageEntry] | [StorageEntry, any] {
|
||||
const args = _args.filter((arg) => !isUndefined(arg));
|
||||
|
||||
if (creator.meta.type.isDoubleMap) {
|
||||
return doDoubleMap(creator, args);
|
||||
return doDoubleMap(registry, creator, args);
|
||||
} else if (creator.meta.type.isMap) {
|
||||
return doMap(creator, args);
|
||||
return doMap(registry, creator, args);
|
||||
} else if (creator.meta.type.isNMap) {
|
||||
return doNMap(creator, args);
|
||||
return doNMap(registry, creator, args);
|
||||
}
|
||||
|
||||
assert(args.length === 0, () => `${sig(creator, [])} does not take any arguments, ${args.length} found`);
|
||||
assert(args.length === 0, () => `${sig(registry, creator, [])} does not take any arguments, ${args.length} found`);
|
||||
|
||||
// no args
|
||||
return [creator];
|
||||
|
||||
@@ -32,7 +32,7 @@ function generateForMeta (meta: Metadata, dest: string, extraTypes: ExtraTypes,
|
||||
|
||||
const items = constants
|
||||
.map(({ docs, name, type }) => {
|
||||
const returnType = formatType(allDefs, type.toString(), imports);
|
||||
const returnType = formatType(meta.registry, allDefs, type.toString(), imports);
|
||||
|
||||
setImports(allDefs, imports, [returnType]);
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ function generateForMeta (meta: Metadata, dest: string, extraTypes: ExtraTypes,
|
||||
.unwrap()
|
||||
.sort(compareName)
|
||||
.map(({ args, docs, name }) => {
|
||||
const types = args.map((type) => formatType(allDefs, type.toString(), imports));
|
||||
const types = args.map((type) => formatType(meta.registry, allDefs, type.toString(), imports));
|
||||
|
||||
setImports(allDefs, imports, types);
|
||||
|
||||
|
||||
@@ -18,12 +18,12 @@ import { ModuleTypes } from '../util/imports';
|
||||
// From a storage entry metadata, we return [args, returnType]
|
||||
/** @internal */
|
||||
function entrySignature (allDefs: Record<string, ModuleTypes>, registry: Registry, storageEntry: StorageEntryMetadataLatest, imports: TypeImports): [string, string, string] {
|
||||
const outputType = unwrapStorageType(storageEntry.type, storageEntry.modifier.isOptional);
|
||||
const outputType = unwrapStorageType(registry, storageEntry.type, storageEntry.modifier.isOptional);
|
||||
|
||||
if (storageEntry.type.isPlain) {
|
||||
setImports(allDefs, imports, [storageEntry.type.asPlain.toString()]);
|
||||
|
||||
return ['', '', formatType(allDefs, outputType, imports)];
|
||||
return ['', '', formatType(registry, allDefs, outputType, imports)];
|
||||
} else if (storageEntry.type.isMap) {
|
||||
const map = storageEntry.type.asMap;
|
||||
|
||||
@@ -36,9 +36,9 @@ function entrySignature (allDefs: Record<string, ModuleTypes>, registry: Registr
|
||||
]);
|
||||
|
||||
return [
|
||||
formatType(allDefs, map.key.toString(), imports),
|
||||
formatType(registry, allDefs, map.key.toString(), imports),
|
||||
`arg: ${similarTypes.join(' | ')}`,
|
||||
formatType(allDefs, outputType, imports)
|
||||
formatType(registry, allDefs, outputType, imports)
|
||||
];
|
||||
} else if (storageEntry.type.isDoubleMap) {
|
||||
const dm = storageEntry.type.asDoubleMap;
|
||||
@@ -57,9 +57,12 @@ function entrySignature (allDefs: Record<string, ModuleTypes>, registry: Registr
|
||||
const key2Types = similarTypes2.join(' | ');
|
||||
|
||||
return [
|
||||
[formatType(allDefs, dm.key1.toString(), imports), formatType(allDefs, dm.key2.toString(), imports)].join(', '),
|
||||
[
|
||||
formatType(registry, allDefs, dm.key1.toString(), imports),
|
||||
formatType(registry, allDefs, dm.key2.toString(), imports)
|
||||
].join(', '),
|
||||
`arg1: ${key1Types}, arg2: ${key2Types}`,
|
||||
formatType(allDefs, outputType, imports)
|
||||
formatType(registry, allDefs, outputType, imports)
|
||||
];
|
||||
} else if (storageEntry.type.isNMap) {
|
||||
const nmap = storageEntry.type.asNMap;
|
||||
@@ -75,9 +78,9 @@ function entrySignature (allDefs: Record<string, ModuleTypes>, registry: Registr
|
||||
const keyTypes = similarTypes.map((t) => t.join(' | '));
|
||||
|
||||
return [
|
||||
nmap.keyVec.map((k) => formatType(allDefs, k.toString(), imports)).join(', '),
|
||||
nmap.keyVec.map((k) => formatType(registry, allDefs, k.toString(), imports)).join(', '),
|
||||
keyTypes.map((t, i) => `arg${i + 1}: ${t}`).join(', '),
|
||||
formatType(allDefs, outputType, imports)
|
||||
formatType(registry, allDefs, outputType, imports)
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ export function generateRpcTypes (registry: TypeRegistry, importDefinitions: Rec
|
||||
return `${param.name}${param.isOptional ? '?' : ''}: ${similarTypes.join(' | ')}`;
|
||||
});
|
||||
|
||||
type = formatType(allDefs, def.type, imports);
|
||||
type = formatType(registry, allDefs, def.type, imports);
|
||||
generic = '';
|
||||
}
|
||||
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { TypeDef } from '@polkadot/types/create/types';
|
||||
import type { Registry } from '@polkadot/types/types';
|
||||
import type { ModuleTypes } from '../util/imports';
|
||||
|
||||
import Handlebars from 'handlebars';
|
||||
import path from 'path';
|
||||
|
||||
import { getTypeDef } from '@polkadot/types/create';
|
||||
import { getTypeDef, TypeRegistry } from '@polkadot/types/create';
|
||||
import { TypeDefInfo } from '@polkadot/types/create/types';
|
||||
import * as defaultDefinitions from '@polkadot/types/interfaces/definitions';
|
||||
import { assert, isString, stringCamelCase, stringify, stringUpperFirst } from '@polkadot/util';
|
||||
@@ -28,13 +29,13 @@ export function createGetter (definitions: Record<string, ModuleTypes>, name = '
|
||||
|
||||
/** @internal */
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
function errorUnhandled (definitions: Record<string, ModuleTypes>, def: TypeDef, imports: TypeImports): string {
|
||||
function errorUnhandled (_: Registry, definitions: Record<string, ModuleTypes>, def: TypeDef, imports: TypeImports): string {
|
||||
throw new Error(`Generate: ${def.name || ''}: Unhandled type ${TypeDefInfo[def.info]}`);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
function tsExport (definitions: Record<string, ModuleTypes>, def: TypeDef, imports: TypeImports): string {
|
||||
return exportInterface(def.name, formatType(definitions, def, imports));
|
||||
function tsExport (registry: Registry, definitions: Record<string, ModuleTypes>, def: TypeDef, imports: TypeImports): string {
|
||||
return exportInterface(def.name, formatType(registry, definitions, def, imports));
|
||||
}
|
||||
|
||||
const tsBTreeMap = tsExport;
|
||||
@@ -47,7 +48,7 @@ const tsPlain = tsExport;
|
||||
const tsTuple = tsExport;
|
||||
|
||||
/** @internal */
|
||||
function tsEnum (definitions: Record<string, ModuleTypes>, { name: enumName, sub }: TypeDef, imports: TypeImports): string {
|
||||
function tsEnum (registry: Registry, definitions: Record<string, ModuleTypes>, { name: enumName, sub }: TypeDef, imports: TypeImports): string {
|
||||
setImports(definitions, imports, ['Enum']);
|
||||
|
||||
const keys = (sub as TypeDef[]).map((def, index): string => {
|
||||
@@ -56,7 +57,7 @@ function tsEnum (definitions: Record<string, ModuleTypes>, { name: enumName, sub
|
||||
const isComplex = [TypeDefInfo.Struct, TypeDefInfo.Tuple, TypeDefInfo.Vec, TypeDefInfo.VecFixed].includes(info);
|
||||
const asGetter = type === 'Null' || info === TypeDefInfo.DoNotConstruct
|
||||
? ''
|
||||
: createGetter(definitions, `as${getter}`, isComplex ? formatType(definitions, info === TypeDefInfo.Struct ? def : type, imports) : type, imports);
|
||||
: createGetter(definitions, `as${getter}`, isComplex ? formatType(registry, definitions, info === TypeDefInfo.Struct ? def : type, imports) : type, imports);
|
||||
const isGetter = info === TypeDefInfo.DoNotConstruct
|
||||
? ''
|
||||
: createGetter(definitions, `is${getter}`, 'boolean', imports);
|
||||
@@ -82,18 +83,18 @@ function tsEnum (definitions: Record<string, ModuleTypes>, { name: enumName, sub
|
||||
return exportInterface(enumName, 'Enum', keys.join(''));
|
||||
}
|
||||
|
||||
function tsInt (definitions: Record<string, ModuleTypes>, def: TypeDef, imports: TypeImports, type: 'Int' | 'UInt' = 'Int'): string {
|
||||
function tsInt (_: Registry, definitions: Record<string, ModuleTypes>, def: TypeDef, imports: TypeImports, type: 'Int' | 'UInt' = 'Int'): string {
|
||||
setImports(definitions, imports, [type]);
|
||||
|
||||
return exportInterface(def.name, type);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
function tsResultGetter (definitions: Record<string, ModuleTypes>, resultName = '', getter: 'Ok' | 'Err' | 'Error', def: TypeDef, imports: TypeImports): string {
|
||||
function tsResultGetter (registry: Registry, definitions: Record<string, ModuleTypes>, resultName = '', getter: 'Ok' | 'Err' | 'Error', def: TypeDef, imports: TypeImports): string {
|
||||
const { info, type } = def;
|
||||
const asGetter = type === 'Null'
|
||||
? ''
|
||||
: (getter === 'Error' ? ' /** @deprecated Use asErr */\n' : '') + createGetter(definitions, `as${getter}`, info === TypeDefInfo.Tuple ? formatType(definitions, def, imports) : type, imports);
|
||||
: (getter === 'Error' ? ' /** @deprecated Use asErr */\n' : '') + createGetter(definitions, `as${getter}`, info === TypeDefInfo.Tuple ? formatType(registry, definitions, def, imports) : type, imports);
|
||||
const isGetter = (getter === 'Error' ? ' /** @deprecated Use isErr */\n' : '') + createGetter(definitions, `is${getter}`, 'boolean', imports);
|
||||
|
||||
switch (info) {
|
||||
@@ -109,28 +110,28 @@ function tsResultGetter (definitions: Record<string, ModuleTypes>, resultName =
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
function tsResult (definitions: Record<string, ModuleTypes>, def: TypeDef, imports: TypeImports): string {
|
||||
function tsResult (registry: Registry, definitions: Record<string, ModuleTypes>, def: TypeDef, imports: TypeImports): string {
|
||||
const [okDef, errorDef] = (def.sub as TypeDef[]);
|
||||
const inner = [
|
||||
tsResultGetter(definitions, def.name, 'Err', errorDef, imports),
|
||||
tsResultGetter(registry, definitions, def.name, 'Err', errorDef, imports),
|
||||
// @deprecated, use Err
|
||||
tsResultGetter(definitions, def.name, 'Error', errorDef, imports),
|
||||
tsResultGetter(definitions, def.name, 'Ok', okDef, imports)
|
||||
tsResultGetter(registry, definitions, def.name, 'Error', errorDef, imports),
|
||||
tsResultGetter(registry, definitions, def.name, 'Ok', okDef, imports)
|
||||
].join('');
|
||||
|
||||
setImports(definitions, imports, [def.type]);
|
||||
|
||||
return exportInterface(def.name, formatType(definitions, def, imports), inner);
|
||||
return exportInterface(def.name, formatType(registry, definitions, def, imports), inner);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
function tsSi (definitions: Record<string, ModuleTypes>, { type }: TypeDef, imports: TypeImports): string {
|
||||
function tsSi (registry: Registry, definitions: Record<string, ModuleTypes>, { type }: TypeDef, imports: TypeImports): string {
|
||||
throw new Error('Unable to generate string definition from TypeDefInfo.Si');
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
function tsSet (definitions: Record<string, ModuleTypes>, { name: setName, sub }: TypeDef, imports: TypeImports): string {
|
||||
function tsSet (_: Registry, definitions: Record<string, ModuleTypes>, { name: setName, sub }: TypeDef, imports: TypeImports): string {
|
||||
setImports(definitions, imports, ['Set']);
|
||||
|
||||
const types = (sub as TypeDef[]).map(({ name }): string => {
|
||||
@@ -143,11 +144,11 @@ function tsSet (definitions: Record<string, ModuleTypes>, { name: setName, sub }
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
function tsStruct (definitions: Record<string, ModuleTypes>, { name: structName, sub }: TypeDef, imports: TypeImports): string {
|
||||
function tsStruct (registry: Registry, definitions: Record<string, ModuleTypes>, { name: structName, sub }: TypeDef, imports: TypeImports): string {
|
||||
setImports(definitions, imports, ['Struct']);
|
||||
|
||||
const keys = (sub as TypeDef[]).map((typedef): string => {
|
||||
const returnType = formatType(definitions, typedef, imports);
|
||||
const returnType = formatType(registry, definitions, typedef, imports);
|
||||
|
||||
return createGetter(definitions, typedef.name, returnType, imports);
|
||||
});
|
||||
@@ -156,12 +157,12 @@ function tsStruct (definitions: Record<string, ModuleTypes>, { name: structName,
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
function tsUInt (definitions: Record<string, ModuleTypes>, def: TypeDef, imports: TypeImports): string {
|
||||
return tsInt(definitions, def, imports, 'UInt');
|
||||
function tsUInt (registry: Registry, definitions: Record<string, ModuleTypes>, def: TypeDef, imports: TypeImports): string {
|
||||
return tsInt(registry, definitions, def, imports, 'UInt');
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
function tsVec (definitions: Record<string, ModuleTypes>, def: TypeDef, imports: TypeImports): string {
|
||||
function tsVec (registry: Registry, definitions: Record<string, ModuleTypes>, def: TypeDef, imports: TypeImports): string {
|
||||
const type = (def.sub as TypeDef).type;
|
||||
|
||||
if (def.info === TypeDefInfo.VecFixed && type === 'u8') {
|
||||
@@ -170,13 +171,13 @@ function tsVec (definitions: Record<string, ModuleTypes>, def: TypeDef, imports:
|
||||
return exportType(def.name, 'U8aFixed');
|
||||
}
|
||||
|
||||
return exportInterface(def.name, formatType(definitions, def, imports));
|
||||
return exportInterface(def.name, formatType(registry, definitions, def, imports));
|
||||
}
|
||||
|
||||
// handlers are defined externally to use - this means that when we do a
|
||||
// `generators[typedef.info](...)` TS will show any unhandled types. Rather
|
||||
// we are being explicit in having no handlers where we do not support (yet)
|
||||
const encoders: Record<TypeDefInfo, (definitions: Record<string, ModuleTypes>, def: TypeDef, imports: TypeImports) => string> = {
|
||||
const encoders: Record<TypeDefInfo, (registry: Registry, definitions: Record<string, ModuleTypes>, def: TypeDef, imports: TypeImports) => string> = {
|
||||
[TypeDefInfo.BTreeMap]: tsBTreeMap,
|
||||
[TypeDefInfo.BTreeSet]: tsBTreeSet,
|
||||
[TypeDefInfo.Compact]: tsCompact,
|
||||
@@ -199,11 +200,11 @@ const encoders: Record<TypeDefInfo, (definitions: Record<string, ModuleTypes>, d
|
||||
};
|
||||
|
||||
/** @internal */
|
||||
function generateInterfaces (definitions: Record<string, ModuleTypes>, { types }: { types: Record<string, any> }, imports: Imports): [string, string][] {
|
||||
function generateInterfaces (registry: Registry, definitions: Record<string, ModuleTypes>, { types }: { types: Record<string, any> }, imports: Imports): [string, string][] {
|
||||
return Object.entries(types).map(([name, type]): [string, string] => {
|
||||
const def = getTypeDef(isString(type) ? type : stringify(type), { name });
|
||||
|
||||
return [name, encoders[def.info](definitions, def, imports)];
|
||||
return [name, encoders[def.info](registry, definitions, def, imports)];
|
||||
});
|
||||
}
|
||||
|
||||
@@ -217,10 +218,10 @@ const templateTypes = readTemplate('tsDef/types');
|
||||
const generateTsDefTypesTemplate = Handlebars.compile(templateTypes);
|
||||
|
||||
/** @internal */
|
||||
function generateTsDefFor (importDefinitions: { [importPath: string]: Record<string, ModuleTypes> }, defName: string, { types }: { types: Record<string, any> }, outputDir: string): void {
|
||||
function generateTsDefFor (registry: Registry, importDefinitions: { [importPath: string]: Record<string, ModuleTypes> }, defName: string, { types }: { types: Record<string, any> }, outputDir: string): void {
|
||||
const imports = { ...createImports(importDefinitions, { types }), interfaces: [] } as Imports;
|
||||
const definitions = imports.definitions;
|
||||
const interfaces = generateInterfaces(definitions, { types }, imports);
|
||||
const interfaces = generateInterfaces(registry, definitions, { types }, imports);
|
||||
const items = interfaces.sort((a, b): number => a[0].localeCompare(b[0])).map(([, definition]): string => definition);
|
||||
|
||||
const importTypes = [
|
||||
@@ -242,13 +243,15 @@ function generateTsDefFor (importDefinitions: { [importPath: string]: Record<str
|
||||
|
||||
/** @internal */
|
||||
export function generateTsDef (importDefinitions: { [importPath: string]: Record<string, ModuleTypes> }, outputDir: string, generatingPackage: string): void {
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
writeFile(path.join(outputDir, 'types.ts'), (): string => {
|
||||
const definitions = importDefinitions[generatingPackage];
|
||||
|
||||
Object.entries(definitions).forEach(([defName, obj]): void => {
|
||||
console.log(`\tExtracting interfaces for ${defName}`);
|
||||
|
||||
generateTsDefFor(importDefinitions, defName, obj, outputDir);
|
||||
generateTsDefFor(registry, importDefinitions, defName, obj, outputDir);
|
||||
});
|
||||
|
||||
return generateTsDefTypesTemplate({
|
||||
|
||||
@@ -55,7 +55,7 @@ function generateForMeta (registry: Registry, meta: Metadata, dest: string, extr
|
||||
.join(', ');
|
||||
|
||||
return {
|
||||
args: args.map(({ type }) => formatType(allDefs, type.toString(), imports)).join(', '),
|
||||
args: args.map(({ type }) => formatType(registry, allDefs, type.toString(), imports)).join(', '),
|
||||
docs,
|
||||
name: stringCamelCase(name),
|
||||
params
|
||||
|
||||
@@ -211,7 +211,7 @@ function addStorage (metadata: MetadataLatest): string {
|
||||
? ('`' + func.type.asNMap.keyVec.map((k) => k.toString()).join(', ') + '`')
|
||||
: '';
|
||||
const methodName = stringLowerFirst(func.name);
|
||||
const outputType = unwrapStorageType(func.type, func.modifier.isOptional);
|
||||
const outputType = unwrapStorageType(metadata.registry, func.type, func.modifier.isOptional);
|
||||
|
||||
return {
|
||||
interface: '`' + `api.query.${sectionName}.${methodName}` + '`',
|
||||
@@ -234,7 +234,7 @@ function addStorage (metadata: MetadataLatest): string {
|
||||
? ('`' + meta.type.asDoubleMap.key1.toString() + ', ' + meta.type.asDoubleMap.key2.toString() + '`')
|
||||
: '';
|
||||
const methodName = stringLowerFirst(name);
|
||||
const outputType = unwrapStorageType(meta.type, meta.modifier.isOptional);
|
||||
const outputType = unwrapStorageType(metadata.registry, meta.type, meta.modifier.isOptional);
|
||||
|
||||
return {
|
||||
interface: '`' + `api.query.substrate.${methodName}` + '`',
|
||||
|
||||
@@ -54,7 +54,7 @@ export function getDerivedTypes (registry: Registry, definitions: Record<string,
|
||||
});
|
||||
}
|
||||
|
||||
const result = types.map((t) => formatType(definitions, t, imports)).map((t) => `'${t}': ${t};`);
|
||||
const result = types.map((t) => formatType(registry, definitions, t, imports)).map((t) => `'${t}': ${t};`);
|
||||
|
||||
result.unshift(`${type}: ${type};`);
|
||||
|
||||
@@ -68,7 +68,7 @@ export function getDerivedTypes (registry: Registry, definitions: Record<string,
|
||||
export function getSimilarTypes (registry: Registry, definitions: Record<string, ModuleTypes>, _type: string, imports: TypeImports): string[] {
|
||||
const typeParts = _type.split('::');
|
||||
const type = typeParts[typeParts.length - 1];
|
||||
const possibleTypes = [formatType(definitions, type, imports)];
|
||||
const possibleTypes = [formatType(registry, definitions, type, imports)];
|
||||
|
||||
if (type === 'Extrinsic') {
|
||||
setImports(definitions, imports, ['IExtrinsic']);
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
// Copyright 2017-2021 @polkadot/typegen authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { TypeRegistry } from '@polkadot/types';
|
||||
|
||||
import { formatType } from './formatting';
|
||||
|
||||
describe('formatType', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
it('handles nested Tuples', (): void => {
|
||||
expect(
|
||||
formatType({}, '(AccountId, (Balance, u32), u64)', {
|
||||
formatType(registry, {}, '(AccountId, (Balance, u32), u64)', {
|
||||
codecTypes: {},
|
||||
definitions: {},
|
||||
extrinsicTypes: {},
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { TypeDef } from '@polkadot/types/create/types';
|
||||
import type { Registry } from '@polkadot/types/types';
|
||||
|
||||
import Handlebars from 'handlebars';
|
||||
|
||||
@@ -176,7 +177,7 @@ function formatVec (inner: string): string {
|
||||
*/
|
||||
/** @internal */
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export function formatType (definitions: Record<string, ModuleTypes>, type: string | String | TypeDef, imports: TypeImports): string {
|
||||
export function formatType (registry: Registry, definitions: Record<string, ModuleTypes>, type: string | String | TypeDef, imports: TypeImports): string {
|
||||
let typeDef: TypeDef;
|
||||
|
||||
if (isString(type)) {
|
||||
@@ -200,7 +201,9 @@ export function formatType (definitions: Record<string, ModuleTypes>, type: stri
|
||||
case TypeDefInfo.Compact: {
|
||||
setImports(definitions, imports, ['Compact']);
|
||||
|
||||
return formatCompact(formatType(definitions, (typeDef.sub as TypeDef).type, imports));
|
||||
return formatCompact(
|
||||
formatType(registry, definitions, (typeDef.sub as TypeDef).type, imports)
|
||||
);
|
||||
}
|
||||
|
||||
case TypeDefInfo.DoNotConstruct: {
|
||||
@@ -212,7 +215,9 @@ export function formatType (definitions: Record<string, ModuleTypes>, type: stri
|
||||
case TypeDefInfo.Option: {
|
||||
setImports(definitions, imports, ['Option']);
|
||||
|
||||
return formatOption(formatType(definitions, (typeDef.sub as TypeDef).type, imports));
|
||||
return formatOption(
|
||||
formatType(registry, definitions, (typeDef.sub as TypeDef).type, imports)
|
||||
);
|
||||
}
|
||||
|
||||
case TypeDefInfo.Plain: {
|
||||
@@ -225,7 +230,7 @@ export function formatType (definitions: Record<string, ModuleTypes>, type: stri
|
||||
return formatStruct(
|
||||
((typeDef.sub as TypeDef[]).map(({ name, type }, index) => [
|
||||
name || `unknown${index}`,
|
||||
formatType(definitions, type, imports)
|
||||
formatType(registry, definitions, type, imports)
|
||||
]))
|
||||
);
|
||||
}
|
||||
@@ -235,14 +240,18 @@ export function formatType (definitions: Record<string, ModuleTypes>, type: stri
|
||||
|
||||
// `(a,b)` gets transformed into `ITuple<[a, b]>`
|
||||
return formatTuple(
|
||||
((typeDef.sub as TypeDef[]).map(({ type }) => formatType(definitions, type, imports)))
|
||||
((typeDef.sub as TypeDef[]).map(({ type }) =>
|
||||
formatType(registry, definitions, type, imports))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
case TypeDefInfo.Vec: {
|
||||
setImports(definitions, imports, ['Vec']);
|
||||
|
||||
return formatVec(formatType(definitions, (typeDef.sub as TypeDef).type, imports));
|
||||
return formatVec(
|
||||
formatType(registry, definitions, (typeDef.sub as TypeDef).type, imports)
|
||||
);
|
||||
}
|
||||
|
||||
case TypeDefInfo.VecFixed: {
|
||||
@@ -256,7 +265,9 @@ export function formatType (definitions: Record<string, ModuleTypes>, type: stri
|
||||
|
||||
setImports(definitions, imports, ['Vec']);
|
||||
|
||||
return formatVec(formatType(definitions, type, imports));
|
||||
return formatVec(
|
||||
formatType(registry, definitions, type, imports)
|
||||
);
|
||||
}
|
||||
|
||||
case TypeDefInfo.BTreeMap: {
|
||||
@@ -264,7 +275,10 @@ export function formatType (definitions: Record<string, ModuleTypes>, type: stri
|
||||
|
||||
const [keyDef, valDef] = (typeDef.sub as TypeDef[]);
|
||||
|
||||
return formatBTreeMap(formatType(definitions, keyDef.type, imports), formatType(definitions, valDef.type, imports));
|
||||
return formatBTreeMap(
|
||||
formatType(registry, definitions, keyDef.type, imports),
|
||||
formatType(registry, definitions, valDef.type, imports)
|
||||
);
|
||||
}
|
||||
|
||||
case TypeDefInfo.BTreeSet: {
|
||||
@@ -272,7 +286,9 @@ export function formatType (definitions: Record<string, ModuleTypes>, type: stri
|
||||
|
||||
const valDef = typeDef.sub as TypeDef;
|
||||
|
||||
return formatBTreeSet(formatType(definitions, valDef.type, imports));
|
||||
return formatBTreeSet(
|
||||
formatType(registry, definitions, valDef.type, imports)
|
||||
);
|
||||
}
|
||||
|
||||
case TypeDefInfo.HashMap: {
|
||||
@@ -280,7 +296,10 @@ export function formatType (definitions: Record<string, ModuleTypes>, type: stri
|
||||
|
||||
const [keyDef, valDef] = (typeDef.sub as TypeDef[]);
|
||||
|
||||
return formatHashMap(formatType(definitions, keyDef.type, imports), formatType(definitions, valDef.type, imports));
|
||||
return formatHashMap(
|
||||
formatType(registry, definitions, keyDef.type, imports),
|
||||
formatType(registry, definitions, valDef.type, imports)
|
||||
);
|
||||
}
|
||||
|
||||
case TypeDefInfo.Linkage: {
|
||||
@@ -288,7 +307,9 @@ export function formatType (definitions: Record<string, ModuleTypes>, type: stri
|
||||
|
||||
setImports(definitions, imports, ['Linkage']);
|
||||
|
||||
return formatLinkage(formatType(definitions, type, imports));
|
||||
return formatLinkage(
|
||||
formatType(registry, definitions, type, imports)
|
||||
);
|
||||
}
|
||||
|
||||
case TypeDefInfo.Result: {
|
||||
@@ -296,7 +317,10 @@ export function formatType (definitions: Record<string, ModuleTypes>, type: stri
|
||||
|
||||
const [okDef, errorDef] = (typeDef.sub as TypeDef[]);
|
||||
|
||||
return formatResult(formatType(definitions, okDef.type, imports), formatType(definitions, errorDef.type, imports));
|
||||
return formatResult(
|
||||
formatType(registry, definitions, okDef.type, imports),
|
||||
formatType(registry, definitions, errorDef.type, imports)
|
||||
);
|
||||
}
|
||||
|
||||
default: {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Registry } from '../types/registry';
|
||||
import type { TypeDef } from './types';
|
||||
|
||||
import { assert, isNumber, isUndefined, stringify } from '@polkadot/util';
|
||||
@@ -140,7 +141,7 @@ export function encodeTypeDef (typeDef: TypeDef): string {
|
||||
return encodeType(typeDef);
|
||||
}
|
||||
|
||||
export function withTypeString (typeDef: Omit<TypeDef, 'type'>): TypeDef {
|
||||
export function withTypeString (_: Registry, typeDef: Omit<TypeDef, 'type'>): TypeDef {
|
||||
return {
|
||||
...typeDef,
|
||||
type: encodeType(typeDef as TypeDef)
|
||||
|
||||
@@ -54,7 +54,7 @@ export function defaultValues (registry: Registry, rpcData: string, withThrow =
|
||||
|
||||
metadata.asLatest.modules.filter(({ storage }): boolean => storage.isSome).forEach((mod): void => {
|
||||
mod.storage.unwrap().items.forEach(({ fallback, modifier, name, type }): void => {
|
||||
const inner = unwrapStorageType(type, modifier.isOptional);
|
||||
const inner = unwrapStorageType(registry, type, modifier.isOptional);
|
||||
const location = `${mod.name.toString()}.${name.toString()}: ${inner}`;
|
||||
|
||||
it(`creates default types for ${location}`, (): void => {
|
||||
|
||||
@@ -33,7 +33,7 @@ const HASHER_MAP: Record<keyof typeof AllHashers, [number, boolean]> = {
|
||||
};
|
||||
|
||||
/** @internal */
|
||||
export function unwrapStorageType (type: StorageEntryTypeLatest, isOptional?: boolean): keyof InterfaceTypes {
|
||||
export function unwrapStorageType (_: Registry, type: StorageEntryTypeLatest, isOptional?: boolean): keyof InterfaceTypes {
|
||||
const outputType = type.isPlain
|
||||
? type.asPlain.toString()
|
||||
: type.isMap
|
||||
@@ -142,16 +142,16 @@ function getMeta (value: StorageKey | StorageEntry | [StorageEntry, unknown]): S
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
function getType (value: StorageKey | StorageEntry | [StorageEntry, unknown]): string {
|
||||
function getType (registry: Registry, value: StorageKey | StorageEntry | [StorageEntry, unknown]): string {
|
||||
if (value instanceof StorageKey) {
|
||||
return value.outputType;
|
||||
} else if (isFunction(value)) {
|
||||
return unwrapStorageType(value.meta.type);
|
||||
return unwrapStorageType(registry, value.meta.type);
|
||||
} else if (Array.isArray(value)) {
|
||||
const [fn] = value;
|
||||
|
||||
if (fn.meta) {
|
||||
return unwrapStorageType(fn.meta.type);
|
||||
return unwrapStorageType(registry, fn.meta.type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ export class StorageKey<A extends AnyTuple = AnyTuple> extends Bytes implements
|
||||
|
||||
super(registry, key);
|
||||
|
||||
this._outputType = getType(value as StorageKey);
|
||||
this._outputType = getType(registry, value as StorageKey);
|
||||
|
||||
// decode the args (as applicable based on the key and the hashers, after all init)
|
||||
this.setMeta(getMeta(value as StorageKey), override.section || section, override.method || method);
|
||||
@@ -237,7 +237,7 @@ export class StorageKey<A extends AnyTuple = AnyTuple> extends Bytes implements
|
||||
this._section = section || this._section;
|
||||
|
||||
if (meta) {
|
||||
this._outputType = unwrapStorageType(meta.type);
|
||||
this._outputType = unwrapStorageType(this.registry, meta.type);
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user