@dedot/codegen 0.0.1-next.8beb88c3.11 → 0.0.1-next.8d06d348.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/generator/RpcGen.js +1 -1
- package/cjs/generator/RuntimeApisGen.js +5 -1
- package/cjs/generator/TypesGen.js +6 -3
- package/cjs/helpers/KnownCodecRegistry.js +163 -0
- package/cjs/helpers/index.js +17 -0
- package/generator/ApiGen.d.ts +1 -1
- package/generator/RpcGen.js +1 -1
- package/generator/RuntimeApisGen.js +6 -2
- package/generator/TypesGen.d.ts +2 -0
- package/generator/TypesGen.js +6 -3
- package/helpers/KnownCodecRegistry.d.ts +22 -0
- package/helpers/KnownCodecRegistry.js +135 -0
- package/helpers/index.d.ts +1 -0
- package/helpers/index.js +1 -0
- package/package.json +7 -7
- package/types.d.ts +8 -0
package/cjs/generator/RpcGen.js
CHANGED
|
@@ -168,7 +168,7 @@ class RpcGen extends generator_1.ApiGen {
|
|
|
168
168
|
return type;
|
|
169
169
|
}
|
|
170
170
|
#getCodecType(type, toTypeIn = true) {
|
|
171
|
-
const { typeIn, typeOut } = this.
|
|
171
|
+
const { typeIn, typeOut } = this.typesGen.knownCodecRegistry.findCodecType(type);
|
|
172
172
|
return toTypeIn ? typeIn : typeOut;
|
|
173
173
|
}
|
|
174
174
|
}
|
|
@@ -96,7 +96,7 @@ class RuntimeApisGen extends RpcGen_1.RpcGen {
|
|
|
96
96
|
}
|
|
97
97
|
#targetRuntimeApiSpecs() {
|
|
98
98
|
const specs = this.runtimeApis.map(([runtimeApiHash, version]) => {
|
|
99
|
-
const runtimeApiSpec =
|
|
99
|
+
const runtimeApiSpec = this.#findRuntimeApiSpec(runtimeApiHash, version);
|
|
100
100
|
if (!runtimeApiSpec)
|
|
101
101
|
return;
|
|
102
102
|
return {
|
|
@@ -111,5 +111,9 @@ class RuntimeApisGen extends RpcGen_1.RpcGen {
|
|
|
111
111
|
return [...o, spec];
|
|
112
112
|
}, []);
|
|
113
113
|
}
|
|
114
|
+
#findRuntimeApiSpec = (runtimeApiHash, version) => {
|
|
115
|
+
const runtimeApiName = (0, specs_1.getRuntimeApiNames)().find((one) => (0, utils_2.calculateRuntimeApiHash)(one) === runtimeApiHash);
|
|
116
|
+
return (0, specs_1.getRuntimeApiSpecs)().find((one) => one.runtimeApiName === runtimeApiName && one.version === version);
|
|
117
|
+
};
|
|
114
118
|
}
|
|
115
119
|
exports.RuntimeApisGen = RuntimeApisGen;
|
|
@@ -7,6 +7,7 @@ const utils_1 = require("@dedot/utils");
|
|
|
7
7
|
const utils_2 = require("./utils");
|
|
8
8
|
const types_1 = require("@dedot/types");
|
|
9
9
|
const TypeImports_1 = require("./TypeImports");
|
|
10
|
+
const helpers_1 = require("../helpers");
|
|
10
11
|
// Skip generate types for these
|
|
11
12
|
// as we do have native types for them
|
|
12
13
|
const SKIP_TYPES = [
|
|
@@ -37,10 +38,12 @@ class TypesGen {
|
|
|
37
38
|
*/
|
|
38
39
|
includedTypes;
|
|
39
40
|
registry;
|
|
41
|
+
knownCodecRegistry;
|
|
40
42
|
typeImports;
|
|
41
43
|
constructor(metadata) {
|
|
42
44
|
this.metadata = metadata;
|
|
43
45
|
this.registry = new codecs_1.CodecRegistry(this.metadata);
|
|
46
|
+
this.knownCodecRegistry = new helpers_1.KnownCodecRegistry();
|
|
44
47
|
this.includedTypes = this.#includedTypes();
|
|
45
48
|
this.typeImports = new TypeImports_1.TypeImports();
|
|
46
49
|
}
|
|
@@ -102,7 +105,7 @@ class TypesGen {
|
|
|
102
105
|
const { tag, value } = type;
|
|
103
106
|
switch (tag) {
|
|
104
107
|
case 'Primitive':
|
|
105
|
-
const $codec = this.
|
|
108
|
+
const $codec = this.knownCodecRegistry.findCodec(value.kind);
|
|
106
109
|
if ($codec.nativeType) {
|
|
107
110
|
return $codec.nativeType;
|
|
108
111
|
}
|
|
@@ -266,8 +269,8 @@ class TypesGen {
|
|
|
266
269
|
const suffix = typeSuffixes.get(id) || '';
|
|
267
270
|
let knownType = false;
|
|
268
271
|
let name, nameOut;
|
|
269
|
-
if (this.
|
|
270
|
-
const codecType = this.
|
|
272
|
+
if (this.knownCodecRegistry.isKnownType(joinedPath)) {
|
|
273
|
+
const codecType = this.knownCodecRegistry.findCodecType(path.at(-1));
|
|
271
274
|
name = codecType.typeIn;
|
|
272
275
|
nameOut = codecType.typeOut;
|
|
273
276
|
knownType = true;
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.KnownCodecRegistry = exports.looseTypeCodecs = exports.normalizeCodecName = void 0;
|
|
27
|
+
const $ = __importStar(require("@dedot/shape"));
|
|
28
|
+
const Codecs = __importStar(require("@dedot/codecs"));
|
|
29
|
+
const codecs_1 = require("@dedot/codecs");
|
|
30
|
+
const normalizeCodecName = (name) => {
|
|
31
|
+
return name.startsWith('$') ? name : `$${name}`;
|
|
32
|
+
};
|
|
33
|
+
exports.normalizeCodecName = normalizeCodecName;
|
|
34
|
+
// Known paths for codecs (primitives) that are shared between
|
|
35
|
+
// different substrate-based blockchains
|
|
36
|
+
const KNOWN_PATHS = [
|
|
37
|
+
'sp_core::crypto::AccountId32',
|
|
38
|
+
'sp_runtime::generic::era::Era',
|
|
39
|
+
'sp_runtime::multiaddress::MultiAddress',
|
|
40
|
+
/^sp_runtime::DispatchError$/,
|
|
41
|
+
'sp_runtime::ModuleError',
|
|
42
|
+
'sp_runtime::TokenError',
|
|
43
|
+
'sp_arithmetic::ArithmeticError',
|
|
44
|
+
'sp_runtime::TransactionalError',
|
|
45
|
+
'frame_support::dispatch::DispatchInfo',
|
|
46
|
+
'frame_system::Phase',
|
|
47
|
+
'sp_version::RuntimeVersion',
|
|
48
|
+
'fp_account::AccountId20',
|
|
49
|
+
'account::AccountId20',
|
|
50
|
+
'polkadot_runtime_common::claims::EthereumAddress',
|
|
51
|
+
'pallet_identity::types::Data',
|
|
52
|
+
'sp_runtime::generic::digest::Digest',
|
|
53
|
+
'sp_runtime::generic::digest::DigestItem',
|
|
54
|
+
'sp_runtime::generic::header::Header',
|
|
55
|
+
'sp_runtime::generic::unchecked_extrinsic::UncheckedExtrinsic',
|
|
56
|
+
/^primitive_types::\w+$/,
|
|
57
|
+
/^sp_arithmetic::per_things::\w+$/,
|
|
58
|
+
/^sp_arithmetic::fixed_point::\w+$/,
|
|
59
|
+
];
|
|
60
|
+
const WRAPPER_TYPE_REGEX = /^(\w+)<(.*)>$/;
|
|
61
|
+
const TUPLE_TYPE_REGEX = /^\[(.*)]$/;
|
|
62
|
+
const KNOWN_WRAPPER_TYPES = ['Option', 'Vec', 'Result', 'Array'];
|
|
63
|
+
/**
|
|
64
|
+
* Collection of codec types with loose input types
|
|
65
|
+
*
|
|
66
|
+
* Loose codecs are codecs with different typeIn & typeOut,
|
|
67
|
+
* E.g: Codec `$AccountId32`, we have its typeIn is `AccountId32Like` & typeOut is `AccountId32`
|
|
68
|
+
*
|
|
69
|
+
* This registry keep track the list of codecs which follow this convention
|
|
70
|
+
*/
|
|
71
|
+
exports.looseTypeCodecs = {
|
|
72
|
+
$AccountId20: codecs_1.$AccountId20,
|
|
73
|
+
$EthereumAddress: codecs_1.$EthereumAddress,
|
|
74
|
+
$AccountId32: codecs_1.$AccountId32,
|
|
75
|
+
$ConsensusEngineId: codecs_1.$ConsensusEngineId,
|
|
76
|
+
$StorageKey: codecs_1.$StorageKey,
|
|
77
|
+
$StorageData: codecs_1.$StorageData,
|
|
78
|
+
$PrefixedStorageKey: codecs_1.$PrefixedStorageKey,
|
|
79
|
+
$Bytes: codecs_1.$Bytes,
|
|
80
|
+
$RawBytes: codecs_1.$RawBytes,
|
|
81
|
+
$MultiAddress: codecs_1.$MultiAddress,
|
|
82
|
+
$OpaqueExtrinsic: codecs_1.$OpaqueExtrinsic,
|
|
83
|
+
$UncheckedExtrinsic: codecs_1.$UncheckedExtrinsic,
|
|
84
|
+
$Era: codecs_1.$Era,
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* A codec registry for both known and portable codecs,
|
|
88
|
+
*/
|
|
89
|
+
class KnownCodecRegistry {
|
|
90
|
+
findCodec(name) {
|
|
91
|
+
return this.#findKnownCodec(name);
|
|
92
|
+
}
|
|
93
|
+
findCodecType(name) {
|
|
94
|
+
const normalizedName = (0, exports.normalizeCodecName)(name);
|
|
95
|
+
const $knownCodec = exports.looseTypeCodecs[normalizedName];
|
|
96
|
+
if ($knownCodec) {
|
|
97
|
+
return {
|
|
98
|
+
name: normalizedName,
|
|
99
|
+
$codec: $knownCodec,
|
|
100
|
+
typeIn: `${name}Like`,
|
|
101
|
+
typeOut: name,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
const $codec = this.findCodec(name);
|
|
105
|
+
if ($codec.nativeType && $[name]) {
|
|
106
|
+
return {
|
|
107
|
+
name: normalizedName,
|
|
108
|
+
$codec,
|
|
109
|
+
typeIn: $codec.nativeType,
|
|
110
|
+
typeOut: $codec.nativeType,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
name: normalizedName,
|
|
115
|
+
$codec,
|
|
116
|
+
typeIn: name,
|
|
117
|
+
typeOut: name,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
#findKnownCodec(typeName) {
|
|
121
|
+
// @ts-ignore
|
|
122
|
+
const $codec = this.#findKnownWrapperCodec(typeName) || Codecs[(0, exports.normalizeCodecName)(typeName)] || $[typeName];
|
|
123
|
+
if (!$codec) {
|
|
124
|
+
throw new Error(`Unsupported codec - ${typeName}`);
|
|
125
|
+
}
|
|
126
|
+
// This only works with top-level $.deferred codecs
|
|
127
|
+
// We should make it work for nested $.deferred codecs as well
|
|
128
|
+
if ($codec.metadata && $codec.metadata[0].name === '$.deferred') {
|
|
129
|
+
const getShape = $codec.metadata[0].args[0];
|
|
130
|
+
return $.deferred(() => getShape(this));
|
|
131
|
+
}
|
|
132
|
+
return $codec;
|
|
133
|
+
}
|
|
134
|
+
#findKnownWrapperCodec(typeName) {
|
|
135
|
+
const matchNames = typeName.match(WRAPPER_TYPE_REGEX);
|
|
136
|
+
if (matchNames) {
|
|
137
|
+
const [_, wrapper, inner] = matchNames;
|
|
138
|
+
if (KNOWN_WRAPPER_TYPES.includes(wrapper)) {
|
|
139
|
+
// @ts-ignore
|
|
140
|
+
const $Wrapper = $[wrapper];
|
|
141
|
+
if (inner.match(TUPLE_TYPE_REGEX) || inner.match(WRAPPER_TYPE_REGEX)) {
|
|
142
|
+
return $Wrapper(this.#findKnownWrapperCodec(inner));
|
|
143
|
+
}
|
|
144
|
+
const $inners = inner.split(',').map((one) => this.#findKnownCodec(one.trim()));
|
|
145
|
+
return $Wrapper(...$inners);
|
|
146
|
+
}
|
|
147
|
+
throw new Error(`Unknown wrapper type ${wrapper} from ${typeName}`);
|
|
148
|
+
}
|
|
149
|
+
else if (typeName.match(TUPLE_TYPE_REGEX)) {
|
|
150
|
+
const $inner = typeName
|
|
151
|
+
.slice(1, -1)
|
|
152
|
+
.split(',')
|
|
153
|
+
.filter((x) => x)
|
|
154
|
+
.map((one) => this.#findKnownCodec(one.trim()));
|
|
155
|
+
return $.Tuple(...$inner);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
isKnownType(path) {
|
|
159
|
+
const joinedPath = Array.isArray(path) ? path.join('::') : path;
|
|
160
|
+
return KNOWN_PATHS.some((one) => joinedPath.match(one));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
exports.KnownCodecRegistry = KnownCodecRegistry;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./KnownCodecRegistry"), exports);
|
package/generator/ApiGen.d.ts
CHANGED
|
@@ -44,7 +44,7 @@ export declare abstract class ApiGen {
|
|
|
44
44
|
} | {
|
|
45
45
|
tag: "Primitive";
|
|
46
46
|
value: {
|
|
47
|
-
kind: "bool" | "
|
|
47
|
+
kind: "bool" | "u8" | "i8" | "u16" | "i16" | "u32" | "i32" | "u64" | "i64" | "u128" | "i128" | "u256" | "i256" | "str" | "char";
|
|
48
48
|
};
|
|
49
49
|
} | {
|
|
50
50
|
tag: "Compact";
|
package/generator/RpcGen.js
CHANGED
|
@@ -165,7 +165,7 @@ export class RpcGen extends ApiGen {
|
|
|
165
165
|
return type;
|
|
166
166
|
}
|
|
167
167
|
#getCodecType(type, toTypeIn = true) {
|
|
168
|
-
const { typeIn, typeOut } = this.
|
|
168
|
+
const { typeIn, typeOut } = this.typesGen.knownCodecRegistry.findCodecType(type);
|
|
169
169
|
return toTypeIn ? typeIn : typeOut;
|
|
170
170
|
}
|
|
171
171
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getRuntimeApiNames, getRuntimeApiSpecs } from '@dedot/specs';
|
|
2
2
|
import { beautifySourceCode, commentBlock, compileTemplate } from './utils';
|
|
3
3
|
import { calculateRuntimeApiHash, stringSnakeCase } from '@dedot/utils';
|
|
4
4
|
import { RpcGen } from './RpcGen';
|
|
@@ -93,7 +93,7 @@ export class RuntimeApisGen extends RpcGen {
|
|
|
93
93
|
}
|
|
94
94
|
#targetRuntimeApiSpecs() {
|
|
95
95
|
const specs = this.runtimeApis.map(([runtimeApiHash, version]) => {
|
|
96
|
-
const runtimeApiSpec = findRuntimeApiSpec(runtimeApiHash, version);
|
|
96
|
+
const runtimeApiSpec = this.#findRuntimeApiSpec(runtimeApiHash, version);
|
|
97
97
|
if (!runtimeApiSpec)
|
|
98
98
|
return;
|
|
99
99
|
return {
|
|
@@ -108,4 +108,8 @@ export class RuntimeApisGen extends RpcGen {
|
|
|
108
108
|
return [...o, spec];
|
|
109
109
|
}, []);
|
|
110
110
|
}
|
|
111
|
+
#findRuntimeApiSpec = (runtimeApiHash, version) => {
|
|
112
|
+
const runtimeApiName = getRuntimeApiNames().find((one) => calculateRuntimeApiHash(one) === runtimeApiHash);
|
|
113
|
+
return getRuntimeApiSpecs().find((one) => one.runtimeApiName === runtimeApiName && one.version === version);
|
|
114
|
+
};
|
|
111
115
|
}
|
package/generator/TypesGen.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CodecRegistry, Field, MetadataLatest, PortableType, TypeId } from '@dedot/codecs';
|
|
2
2
|
import { TypeImports } from './TypeImports';
|
|
3
|
+
import { KnownCodecRegistry } from '../helpers';
|
|
3
4
|
interface NamedType extends PortableType {
|
|
4
5
|
name: string;
|
|
5
6
|
nameOut: string;
|
|
@@ -16,6 +17,7 @@ export declare class TypesGen {
|
|
|
16
17
|
*/
|
|
17
18
|
includedTypes: Record<TypeId, NamedType>;
|
|
18
19
|
registry: CodecRegistry;
|
|
20
|
+
knownCodecRegistry: KnownCodecRegistry;
|
|
19
21
|
typeImports: TypeImports;
|
|
20
22
|
constructor(metadata: MetadataLatest);
|
|
21
23
|
generate(): Promise<string>;
|
package/generator/TypesGen.js
CHANGED
|
@@ -4,6 +4,7 @@ import { isNativeType, normalizeName } from '@dedot/utils';
|
|
|
4
4
|
import { beautifySourceCode, commentBlock, compileTemplate } from './utils';
|
|
5
5
|
import { registry } from '@dedot/types';
|
|
6
6
|
import { TypeImports } from './TypeImports';
|
|
7
|
+
import { KnownCodecRegistry } from '../helpers';
|
|
7
8
|
// Skip generate types for these
|
|
8
9
|
// as we do have native types for them
|
|
9
10
|
const SKIP_TYPES = [
|
|
@@ -34,10 +35,12 @@ export class TypesGen {
|
|
|
34
35
|
*/
|
|
35
36
|
includedTypes;
|
|
36
37
|
registry;
|
|
38
|
+
knownCodecRegistry;
|
|
37
39
|
typeImports;
|
|
38
40
|
constructor(metadata) {
|
|
39
41
|
this.metadata = metadata;
|
|
40
42
|
this.registry = new CodecRegistry(this.metadata);
|
|
43
|
+
this.knownCodecRegistry = new KnownCodecRegistry();
|
|
41
44
|
this.includedTypes = this.#includedTypes();
|
|
42
45
|
this.typeImports = new TypeImports();
|
|
43
46
|
}
|
|
@@ -99,7 +102,7 @@ export class TypesGen {
|
|
|
99
102
|
const { tag, value } = type;
|
|
100
103
|
switch (tag) {
|
|
101
104
|
case 'Primitive':
|
|
102
|
-
const $codec = this.
|
|
105
|
+
const $codec = this.knownCodecRegistry.findCodec(value.kind);
|
|
103
106
|
if ($codec.nativeType) {
|
|
104
107
|
return $codec.nativeType;
|
|
105
108
|
}
|
|
@@ -263,8 +266,8 @@ export class TypesGen {
|
|
|
263
266
|
const suffix = typeSuffixes.get(id) || '';
|
|
264
267
|
let knownType = false;
|
|
265
268
|
let name, nameOut;
|
|
266
|
-
if (this.
|
|
267
|
-
const codecType = this.
|
|
269
|
+
if (this.knownCodecRegistry.isKnownType(joinedPath)) {
|
|
270
|
+
const codecType = this.knownCodecRegistry.findCodecType(path.at(-1));
|
|
268
271
|
name = codecType.typeIn;
|
|
269
272
|
nameOut = codecType.typeOut;
|
|
270
273
|
knownType = true;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as $ from '@dedot/shape';
|
|
2
|
+
import { AnyShape } from '@dedot/shape';
|
|
3
|
+
import { CodecType, CodecName } from '../types';
|
|
4
|
+
export declare const normalizeCodecName: (name: string | CodecName) => CodecName;
|
|
5
|
+
/**
|
|
6
|
+
* Collection of codec types with loose input types
|
|
7
|
+
*
|
|
8
|
+
* Loose codecs are codecs with different typeIn & typeOut,
|
|
9
|
+
* E.g: Codec `$AccountId32`, we have its typeIn is `AccountId32Like` & typeOut is `AccountId32`
|
|
10
|
+
*
|
|
11
|
+
* This registry keep track the list of codecs which follow this convention
|
|
12
|
+
*/
|
|
13
|
+
export declare const looseTypeCodecs: Record<string, AnyShape>;
|
|
14
|
+
/**
|
|
15
|
+
* A codec registry for both known and portable codecs,
|
|
16
|
+
*/
|
|
17
|
+
export declare class KnownCodecRegistry {
|
|
18
|
+
#private;
|
|
19
|
+
findCodec<I = unknown, O = I>(name: string): $.Shape<I, O>;
|
|
20
|
+
findCodecType(name: string): CodecType;
|
|
21
|
+
isKnownType(path: string | string[]): boolean;
|
|
22
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import * as $ from '@dedot/shape';
|
|
2
|
+
import * as Codecs from '@dedot/codecs';
|
|
3
|
+
import { $AccountId20, $AccountId32, $Bytes, $ConsensusEngineId, $Era, $EthereumAddress, $MultiAddress, $OpaqueExtrinsic, $PrefixedStorageKey, $RawBytes, $StorageData, $StorageKey, $UncheckedExtrinsic, } from '@dedot/codecs';
|
|
4
|
+
export const normalizeCodecName = (name) => {
|
|
5
|
+
return name.startsWith('$') ? name : `$${name}`;
|
|
6
|
+
};
|
|
7
|
+
// Known paths for codecs (primitives) that are shared between
|
|
8
|
+
// different substrate-based blockchains
|
|
9
|
+
const KNOWN_PATHS = [
|
|
10
|
+
'sp_core::crypto::AccountId32',
|
|
11
|
+
'sp_runtime::generic::era::Era',
|
|
12
|
+
'sp_runtime::multiaddress::MultiAddress',
|
|
13
|
+
/^sp_runtime::DispatchError$/,
|
|
14
|
+
'sp_runtime::ModuleError',
|
|
15
|
+
'sp_runtime::TokenError',
|
|
16
|
+
'sp_arithmetic::ArithmeticError',
|
|
17
|
+
'sp_runtime::TransactionalError',
|
|
18
|
+
'frame_support::dispatch::DispatchInfo',
|
|
19
|
+
'frame_system::Phase',
|
|
20
|
+
'sp_version::RuntimeVersion',
|
|
21
|
+
'fp_account::AccountId20',
|
|
22
|
+
'account::AccountId20',
|
|
23
|
+
'polkadot_runtime_common::claims::EthereumAddress',
|
|
24
|
+
'pallet_identity::types::Data',
|
|
25
|
+
'sp_runtime::generic::digest::Digest',
|
|
26
|
+
'sp_runtime::generic::digest::DigestItem',
|
|
27
|
+
'sp_runtime::generic::header::Header',
|
|
28
|
+
'sp_runtime::generic::unchecked_extrinsic::UncheckedExtrinsic',
|
|
29
|
+
/^primitive_types::\w+$/,
|
|
30
|
+
/^sp_arithmetic::per_things::\w+$/,
|
|
31
|
+
/^sp_arithmetic::fixed_point::\w+$/,
|
|
32
|
+
];
|
|
33
|
+
const WRAPPER_TYPE_REGEX = /^(\w+)<(.*)>$/;
|
|
34
|
+
const TUPLE_TYPE_REGEX = /^\[(.*)]$/;
|
|
35
|
+
const KNOWN_WRAPPER_TYPES = ['Option', 'Vec', 'Result', 'Array'];
|
|
36
|
+
/**
|
|
37
|
+
* Collection of codec types with loose input types
|
|
38
|
+
*
|
|
39
|
+
* Loose codecs are codecs with different typeIn & typeOut,
|
|
40
|
+
* E.g: Codec `$AccountId32`, we have its typeIn is `AccountId32Like` & typeOut is `AccountId32`
|
|
41
|
+
*
|
|
42
|
+
* This registry keep track the list of codecs which follow this convention
|
|
43
|
+
*/
|
|
44
|
+
export const looseTypeCodecs = {
|
|
45
|
+
$AccountId20,
|
|
46
|
+
$EthereumAddress,
|
|
47
|
+
$AccountId32,
|
|
48
|
+
$ConsensusEngineId,
|
|
49
|
+
$StorageKey,
|
|
50
|
+
$StorageData,
|
|
51
|
+
$PrefixedStorageKey,
|
|
52
|
+
$Bytes,
|
|
53
|
+
$RawBytes,
|
|
54
|
+
$MultiAddress,
|
|
55
|
+
$OpaqueExtrinsic,
|
|
56
|
+
$UncheckedExtrinsic,
|
|
57
|
+
$Era,
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* A codec registry for both known and portable codecs,
|
|
61
|
+
*/
|
|
62
|
+
export class KnownCodecRegistry {
|
|
63
|
+
findCodec(name) {
|
|
64
|
+
return this.#findKnownCodec(name);
|
|
65
|
+
}
|
|
66
|
+
findCodecType(name) {
|
|
67
|
+
const normalizedName = normalizeCodecName(name);
|
|
68
|
+
const $knownCodec = looseTypeCodecs[normalizedName];
|
|
69
|
+
if ($knownCodec) {
|
|
70
|
+
return {
|
|
71
|
+
name: normalizedName,
|
|
72
|
+
$codec: $knownCodec,
|
|
73
|
+
typeIn: `${name}Like`,
|
|
74
|
+
typeOut: name,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
const $codec = this.findCodec(name);
|
|
78
|
+
if ($codec.nativeType && $[name]) {
|
|
79
|
+
return {
|
|
80
|
+
name: normalizedName,
|
|
81
|
+
$codec,
|
|
82
|
+
typeIn: $codec.nativeType,
|
|
83
|
+
typeOut: $codec.nativeType,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
name: normalizedName,
|
|
88
|
+
$codec,
|
|
89
|
+
typeIn: name,
|
|
90
|
+
typeOut: name,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
#findKnownCodec(typeName) {
|
|
94
|
+
// @ts-ignore
|
|
95
|
+
const $codec = this.#findKnownWrapperCodec(typeName) || Codecs[normalizeCodecName(typeName)] || $[typeName];
|
|
96
|
+
if (!$codec) {
|
|
97
|
+
throw new Error(`Unsupported codec - ${typeName}`);
|
|
98
|
+
}
|
|
99
|
+
// This only works with top-level $.deferred codecs
|
|
100
|
+
// We should make it work for nested $.deferred codecs as well
|
|
101
|
+
if ($codec.metadata && $codec.metadata[0].name === '$.deferred') {
|
|
102
|
+
const getShape = $codec.metadata[0].args[0];
|
|
103
|
+
return $.deferred(() => getShape(this));
|
|
104
|
+
}
|
|
105
|
+
return $codec;
|
|
106
|
+
}
|
|
107
|
+
#findKnownWrapperCodec(typeName) {
|
|
108
|
+
const matchNames = typeName.match(WRAPPER_TYPE_REGEX);
|
|
109
|
+
if (matchNames) {
|
|
110
|
+
const [_, wrapper, inner] = matchNames;
|
|
111
|
+
if (KNOWN_WRAPPER_TYPES.includes(wrapper)) {
|
|
112
|
+
// @ts-ignore
|
|
113
|
+
const $Wrapper = $[wrapper];
|
|
114
|
+
if (inner.match(TUPLE_TYPE_REGEX) || inner.match(WRAPPER_TYPE_REGEX)) {
|
|
115
|
+
return $Wrapper(this.#findKnownWrapperCodec(inner));
|
|
116
|
+
}
|
|
117
|
+
const $inners = inner.split(',').map((one) => this.#findKnownCodec(one.trim()));
|
|
118
|
+
return $Wrapper(...$inners);
|
|
119
|
+
}
|
|
120
|
+
throw new Error(`Unknown wrapper type ${wrapper} from ${typeName}`);
|
|
121
|
+
}
|
|
122
|
+
else if (typeName.match(TUPLE_TYPE_REGEX)) {
|
|
123
|
+
const $inner = typeName
|
|
124
|
+
.slice(1, -1)
|
|
125
|
+
.split(',')
|
|
126
|
+
.filter((x) => x)
|
|
127
|
+
.map((one) => this.#findKnownCodec(one.trim()));
|
|
128
|
+
return $.Tuple(...$inner);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
isKnownType(path) {
|
|
132
|
+
const joinedPath = Array.isArray(path) ? path.join('::') : path;
|
|
133
|
+
return KNOWN_PATHS.some((one) => joinedPath.match(one));
|
|
134
|
+
}
|
|
135
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './KnownCodecRegistry';
|
package/helpers/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './KnownCodecRegistry';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dedot/codegen",
|
|
3
|
-
"version": "0.0.1-next.
|
|
3
|
+
"version": "0.0.1-next.8d06d348.17+8d06d34",
|
|
4
4
|
"description": "Generate types",
|
|
5
5
|
"author": "Thang X. Vu <thang@coongcrafts.io>",
|
|
6
6
|
"homepage": "https://github.com/dedotdev/dedot/tree/main/packages/codegen",
|
|
@@ -18,12 +18,12 @@
|
|
|
18
18
|
"copy": "cp -R ./src/templates ./dist && cp -R ./src/templates ./dist/cjs"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@dedot/codecs": "0.0.1-next.
|
|
22
|
-
"@dedot/shape": "0.0.1-next.
|
|
23
|
-
"@dedot/specs": "0.0.1-next.
|
|
24
|
-
"@dedot/utils": "0.0.1-next.
|
|
21
|
+
"@dedot/codecs": "0.0.1-next.8d06d348.17+8d06d34",
|
|
22
|
+
"@dedot/shape": "0.0.1-next.8d06d348.17+8d06d34",
|
|
23
|
+
"@dedot/specs": "0.0.1-next.8d06d348.17+8d06d34",
|
|
24
|
+
"@dedot/utils": "0.0.1-next.8d06d348.17+8d06d34",
|
|
25
25
|
"@polkadot/util": "^12.6.2",
|
|
26
|
-
"dedot": "0.0.1-next.
|
|
26
|
+
"dedot": "0.0.1-next.8d06d348.17+8d06d34",
|
|
27
27
|
"handlebars": "^4.7.8",
|
|
28
28
|
"prettier": "^3.0.3"
|
|
29
29
|
},
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"directory": "dist"
|
|
33
33
|
},
|
|
34
34
|
"license": "Apache-2.0",
|
|
35
|
-
"gitHead": "
|
|
35
|
+
"gitHead": "8d06d348e231fd78008acd9122e6ac8ed2794b51",
|
|
36
36
|
"module": "./index.js",
|
|
37
37
|
"types": "./index.d.ts",
|
|
38
38
|
"exports": {
|
package/types.d.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
+
import { AnyShape } from '@dedot/shape';
|
|
1
2
|
export type NetworkInfo = {
|
|
2
3
|
chain: string;
|
|
3
4
|
endpoint?: string;
|
|
4
5
|
metadataHex?: string;
|
|
5
6
|
rpcMethods?: string[];
|
|
6
7
|
};
|
|
8
|
+
export type CodecName = `$${string}`;
|
|
9
|
+
export interface CodecType {
|
|
10
|
+
name: CodecName;
|
|
11
|
+
$codec: AnyShape;
|
|
12
|
+
typeIn: string;
|
|
13
|
+
typeOut: string;
|
|
14
|
+
}
|