Convert jsonrpc & typings to definitions (#2064)

* Convert jsonrpc & typings to definitions

* Handle empty interface generation (no types)

* Move jsonrpc/create to rpc-core/create

* Create imports

* Remove jsonrpc package, generate rpc-core from defs

* Debug :)

* Generate RPC definitions via interfaces

* Generate md docs

* Remove @polkadot/jsonrpc refs (at least packages)

* No empty types

* Add PAHNTOM "cleanup" gen

* *sigh* regex loop

* Update mock for no jsonrpc

* Add definition export types

* Cleanup linting

* Mocking 1 fix

* Mocking 2 fix

* rpc-core tests updates

* CHANGELOG & docs

* Add jsonrpc (already mapped) to interfaces

* Add aliasses for RPCs

* Fix rpc-core tests
This commit is contained in:
Jaco Greeff
2020-03-19 14:40:54 +01:00
committed by GitHub
parent 27e3fbfd0f
commit 044efbc6de
170 changed files with 1281 additions and 1346 deletions
+16 -13
View File
@@ -2,7 +2,6 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import interfaces from '@polkadot/jsonrpc';
import * as definitions from '@polkadot/types/interfaces/definitions';
import { TypeRegistry } from '@polkadot/types/create';
@@ -19,26 +18,30 @@ export default function generateRpcTypes (dest = 'packages/api/src/augment/rpc.t
const allDefs = Object.entries(allTypes).reduce((defs, [path, obj]) => {
return Object.entries(obj).reduce((defs, [key, value]) => ({ ...defs, [`${path}/${key}`]: value }), defs);
}, {});
const body = Object.keys(interfaces).sort().reduce<string[]>((allSections, section): string[] => {
const allMethods = Object.keys(interfaces[section].methods).sort().map((key): string => {
const method = interfaces[section].methods[key];
const rpcKeys = Object
.keys(definitions)
.filter((key) => Object.keys(definitions[key as 'babe'].rpc || {}).length !== 0)
.sort();
const body = rpcKeys.reduce<string[]>((allSections, section): string[] => {
const allMethods = Object.keys(definitions[section as 'babe'].rpc).sort().map((methodName): string => {
const def = definitions[section as 'babe'].rpc[methodName];
// These are too hard to type with generics, do manual overrides
if (section === 'state') {
setImports(allDefs, imports, ['Codec', 'Hash', 'StorageKey', 'Vec']);
if (method.method === 'getStorage') {
return createDocComments(6, [method.description]) + indent(6)(`getStorage: AugmentedRpc<<T = Codec>(key: ${StorageKeyTye}, block?: Hash | Uint8Array | string) => Observable<T>>;`);
} else if (method.method === 'queryStorage') {
return createDocComments(6, [method.description]) + indent(6)(`queryStorage: AugmentedRpc<<T = Codec[]>(keys: Vec<StorageKey> | (${StorageKeyTye})[], fromBlock?: Hash | Uint8Array | string, toBlock?: Hash | Uint8Array | string) => Observable<[Hash, T][]>>;`);
} else if (method.method === 'subscribeStorage') {
return createDocComments(6, [method.description]) + indent(6)(`subscribeStorage: AugmentedRpc<<T = Codec[]>(keys: Vec<StorageKey> | (${StorageKeyTye})[]) => Observable<T>>;`);
if (methodName === 'getStorage') {
return createDocComments(6, [def.description]) + indent(6)(`getStorage: AugmentedRpc<<T = Codec>(key: ${StorageKeyTye}, block?: Hash | Uint8Array | string) => Observable<T>>;`);
} else if (methodName === 'queryStorage') {
return createDocComments(6, [def.description]) + indent(6)(`queryStorage: AugmentedRpc<<T = Codec[]>(keys: Vec<StorageKey> | (${StorageKeyTye})[], fromBlock?: Hash | Uint8Array | string, toBlock?: Hash | Uint8Array | string) => Observable<[Hash, T][]>>;`);
} else if (methodName === 'subscribeStorage') {
return createDocComments(6, [def.description]) + indent(6)(`subscribeStorage: AugmentedRpc<<T = Codec[]>(keys: Vec<StorageKey> | (${StorageKeyTye})[]) => Observable<T>>;`);
}
}
setImports(allDefs, imports, [method.type]);
setImports(allDefs, imports, [def.type]);
const args = method.params.map((param): string => {
const args = def.params.map((param: any): string => {
const similarTypes = getSimilarTypes(definitions, registry, param.type, imports);
setImports(allDefs, imports, [param.type, ...similarTypes]);
@@ -46,7 +49,7 @@ export default function generateRpcTypes (dest = 'packages/api/src/augment/rpc.t
return `${param.name}${param.isOptional ? '?' : ''}: ${similarTypes.join(' | ')}`;
});
return createDocComments(6, [method.description]) + indent(6)(`${method.method}: AugmentedRpc<(${args.join(', ')}) => Observable<${method.type}>>;`);
return createDocComments(6, [def.description]) + indent(6)(`${methodName}: AugmentedRpc<(${args.join(', ')}) => Observable<${def.type}>>;`);
});
return allSections.concat(
+3 -4
View File
@@ -4,7 +4,6 @@
import { TypeDef, TypeDefInfo } from '@polkadot/types/create/types';
import fs from 'fs';
import path from 'path';
import { getTypeDef } from '@polkadot/types/create';
import * as defaultDefinitions from '@polkadot/types/interfaces/definitions';
@@ -194,8 +193,8 @@ function generateTsDefFor (importDefinitions: { [importPath: string]: object },
}))
]);
fs.writeFileSync(path.join(outputDir, defName, 'types.ts'), header.concat(sortedDefs).concat(FOOTER), { flag: 'w' });
fs.writeFileSync(path.join(outputDir, defName, 'index.ts'), HEADER('defs').concat('export * from \'./types\';').concat(FOOTER), { flag: 'w' });
writeFile(path.join(outputDir, defName, 'types.ts'), () => header.concat(sortedDefs).concat(`\n\nexport type PHANTOM_${defName.toUpperCase()} = '${defName}';`).concat(FOOTER), true);
writeFile(path.join(outputDir, defName, 'index.ts'), () => HEADER('defs').concat('export * from \'./types\';').concat(FOOTER), true);
}
/** @internal */
@@ -219,7 +218,7 @@ export function generateTsDef (importDefinitions: { [importPath: string]: object
.concat(FOOTER);
});
fs.writeFileSync(path.join(outputDir, 'index.ts'), HEADER('defs').concat('export * from \'./types\';').concat(FOOTER), { flag: 'w' });
writeFile(path.join(outputDir, 'index.ts'), () => HEADER('defs').concat('export * from \'./types\';').concat(FOOTER), true);
}
/** @internal */
+11 -7
View File
@@ -5,13 +5,13 @@
import { MetadataLatest } from '@polkadot/types/interfaces/metadata';
import fs from 'fs';
import interfaces from '@polkadot/jsonrpc';
import Decorated from '@polkadot/metadata/Decorated';
import rpcdata from '@polkadot/metadata/Metadata/static';
import Call from '@polkadot/types/generic/Call';
import { unwrapStorageType } from '@polkadot/types/primitive/StorageKey';
import { TypeRegistry } from '@polkadot/types/create';
import { Vec } from '@polkadot/types/codec';
import * as definitions from '@polkadot/types/interfaces/definitions';
import { Text } from '@polkadot/types/primitive';
import { stringCamelCase, stringLowerFirst } from '@polkadot/util';
@@ -100,22 +100,26 @@ function sortByName<T extends { name: any }> (a: T, b: T): number {
/** @internal */
function addRpc (): string {
const sections = Object
.keys(definitions)
.filter((key) => Object.keys(definitions[key as 'babe'].rpc || {}).length !== 0);
return renderPage({
title: 'JSON-RPC',
description: DESC_RPC,
sections: Object.keys(interfaces)
sections: sections
.sort()
.map((sectionName) => {
const section = interfaces[sectionName];
const section = definitions[sectionName as 'babe'];
return {
name: sectionName,
description: section.description,
items: Object.keys(section.methods)
// description: section.description,
items: Object.keys(section.rpc)
.sort()
.map((methodName) => {
const method = section.methods[methodName];
const args = method.params.map(({ name, isOptional, type }): string => {
const method = section.rpc[methodName];
const args = method.params.map(({ name, isOptional, type }: any): string => {
return name + (isOptional ? '?' : '') + ': `' + type + '`';
}).join(', ');
const type = '`' + method.type + '`';
+3 -2
View File
@@ -14,9 +14,10 @@ import Struct from '@polkadot/types/codec/Struct';
import UInt from '@polkadot/types/codec/UInt';
import Vec from '@polkadot/types/codec/Vec';
import Tuple from '@polkadot/types/codec/Tuple';
import { AllConvictions } from '@polkadot/types/interfaces/democracy/definitions';
import GenericAccountId from '@polkadot/types/generic/AccountId';
import GenericAddress from '@polkadot/types/generic/Address';
import Vote, { convictionNames as _voteConvictions } from '@polkadot/types/generic/Vote';
import Vote from '@polkadot/types/generic/Vote';
import Null from '@polkadot/types/primitive/Null';
import * as primitiveClasses from '@polkadot/types/primitive';
import { isChildClass, stringLowerFirst } from '@polkadot/util';
@@ -29,7 +30,7 @@ function arrayToStrType (arr: string[]): string {
return `(${arr.map((c): string => `'${c}'`).join(' | ')})`;
}
const voteConvictions = arrayToStrType(_voteConvictions);
const voteConvictions = arrayToStrType(AllConvictions);
// From `T`, generate `Compact<T>, Option<T>, Vec<T>`
/** @internal */
+9 -5
View File
@@ -4,14 +4,18 @@
import fs from 'fs';
export function writeFile (dest: string, generator: () => string): void {
console.log(`${dest}\n\tGenerating`);
export function writeFile (dest: string, generator: () => string, noLog?: boolean): void {
!noLog && console.log(`${dest}\n\tGenerating`);
const generated = generator();
let generated = generator();
console.log('\tWriting');
while (generated.includes('\n\n\n')) {
generated = generated.replace(/\n\n\n/g, '\n\n');
}
!noLog && console.log('\tWriting');
fs.writeFileSync(dest, generated, { flag: 'w' });
console.log('');
!noLog && console.log('');
}
+1 -1
View File
@@ -9,7 +9,7 @@ import { paramsNotation } from '@polkadot/types/codec/utils';
import { setImports, TypeImports } from './imports';
export const HEADER = (type: 'chain' | 'defs'): string => `// Auto-generated via \`yarn polkadot-types-from-${type}\`, do not edit\n/* eslint-disable @typescript-eslint/no-empty-interface */\n\n`;
export const HEADER = (type: 'chain' | 'defs'): string => `// Auto-generated via \`yarn polkadot-types-from-${type}\`, do not edit\n/* eslint-disable */\n\n`;
export const FOOTER = '\n';
const TYPES_NON_PRIMITIVE = ['Metadata'];