@dedot/codegen 0.0.1-next.fecbe32d.13 → 0.1.0
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/{generator → chaintypes/generator}/ApiGen.d.ts +16 -16
- package/{generator → chaintypes/generator}/ConstsGen.d.ts +1 -1
- package/{generator → chaintypes/generator}/ConstsGen.js +5 -5
- package/{generator → chaintypes/generator}/ErrorsGen.d.ts +1 -1
- package/{generator → chaintypes/generator}/ErrorsGen.js +9 -9
- package/{generator → chaintypes/generator}/EventsGen.d.ts +1 -1
- package/{generator → chaintypes/generator}/EventsGen.js +9 -9
- package/{generator → chaintypes/generator}/IndexGen.d.ts +1 -1
- package/chaintypes/generator/IndexGen.js +17 -0
- package/{generator → chaintypes/generator}/JsonRpcGen.d.ts +3 -2
- package/{generator → chaintypes/generator}/JsonRpcGen.js +8 -8
- package/{generator → chaintypes/generator}/QueryGen.d.ts +1 -1
- package/{generator → chaintypes/generator}/QueryGen.js +15 -15
- package/{generator → chaintypes/generator}/RuntimeApisGen.d.ts +1 -1
- package/{generator → chaintypes/generator}/RuntimeApisGen.js +11 -11
- package/{generator → chaintypes/generator}/TxGen.d.ts +1 -1
- package/{generator → chaintypes/generator}/TxGen.js +16 -14
- package/chaintypes/generator/TypesGen.d.ts +11 -0
- package/chaintypes/generator/TypesGen.js +55 -0
- package/chaintypes/index.d.ts +3 -0
- package/chaintypes/index.js +49 -0
- package/chaintypes/templates/consts.hbs +7 -0
- package/chaintypes/templates/errors.hbs +7 -0
- package/chaintypes/templates/events.hbs +7 -0
- package/chaintypes/templates/index.hbs +27 -0
- package/chaintypes/templates/json-rpc.hbs +5 -0
- package/chaintypes/templates/query.hbs +7 -0
- package/chaintypes/templates/runtime.hbs +8 -0
- package/chaintypes/templates/tx.hbs +9 -0
- package/{templates → chaintypes/templates}/types.hbs +1 -1
- package/cjs/{generator → chaintypes/generator}/ConstsGen.js +5 -5
- package/cjs/{generator → chaintypes/generator}/ErrorsGen.js +9 -9
- package/cjs/{generator → chaintypes/generator}/EventsGen.js +9 -9
- package/cjs/chaintypes/generator/IndexGen.js +21 -0
- package/cjs/{generator → chaintypes/generator}/JsonRpcGen.js +10 -10
- package/cjs/{generator → chaintypes/generator}/QueryGen.js +15 -15
- package/cjs/{generator → chaintypes/generator}/RuntimeApisGen.js +14 -14
- package/cjs/{generator → chaintypes/generator}/TxGen.js +16 -14
- package/cjs/chaintypes/generator/TypesGen.js +59 -0
- package/cjs/chaintypes/index.js +77 -0
- package/cjs/chaintypes/templates/consts.hbs +7 -0
- package/cjs/chaintypes/templates/errors.hbs +7 -0
- package/cjs/chaintypes/templates/events.hbs +7 -0
- package/cjs/chaintypes/templates/index.hbs +27 -0
- package/cjs/chaintypes/templates/json-rpc.hbs +5 -0
- package/cjs/chaintypes/templates/query.hbs +7 -0
- package/cjs/chaintypes/templates/runtime.hbs +8 -0
- package/cjs/chaintypes/templates/tx.hbs +9 -0
- package/cjs/{templates → chaintypes/templates}/types.hbs +1 -1
- package/cjs/index.js +4 -62
- package/cjs/{generator/TypesGen.js → shared/BaseTypesGen.js} +111 -159
- package/cjs/{generator → shared}/TypeImports.js +27 -9
- package/cjs/shared/index.js +19 -0
- package/cjs/{generator → shared}/known-codecs.js +23 -4
- package/cjs/typink/generator/ConstructorQueryGen.js +24 -0
- package/cjs/typink/generator/ConstructorTxGen.js +24 -0
- package/cjs/typink/generator/EventsGen.js +35 -0
- package/cjs/typink/generator/IndexGen.js +24 -0
- package/cjs/typink/generator/QueryGen.js +72 -0
- package/cjs/typink/generator/TxGen.js +25 -0
- package/cjs/typink/generator/TypesGen.js +28 -0
- package/cjs/typink/generator/index.js +23 -0
- package/cjs/typink/index.js +40 -0
- package/cjs/typink/templates/constructor-query.hbs +7 -0
- package/cjs/typink/templates/constructor-tx.hbs +7 -0
- package/cjs/typink/templates/events.hbs +8 -0
- package/cjs/typink/templates/index.hbs +16 -0
- package/cjs/typink/templates/query.hbs +7 -0
- package/cjs/typink/templates/tx.hbs +7 -0
- package/cjs/typink/templates/types.hbs +5 -0
- package/cjs/{generator/utils.js → utils.js} +4 -4
- package/index.d.ts +2 -3
- package/index.js +2 -48
- package/package.json +15 -17
- package/{generator/TypesGen.d.ts → shared/BaseTypesGen.d.ts} +12 -11
- package/{generator/TypesGen.js → shared/BaseTypesGen.js} +108 -156
- package/{generator → shared}/TypeImports.d.ts +12 -3
- package/{generator → shared}/TypeImports.js +27 -9
- package/shared/index.d.ts +3 -0
- package/shared/index.js +3 -0
- package/{generator → shared}/known-codecs.d.ts +1 -1
- package/{generator → shared}/known-codecs.js +21 -2
- package/typink/generator/ConstructorQueryGen.d.ts +6 -0
- package/typink/generator/ConstructorQueryGen.js +20 -0
- package/typink/generator/ConstructorTxGen.d.ts +6 -0
- package/typink/generator/ConstructorTxGen.js +20 -0
- package/typink/generator/EventsGen.d.ts +7 -0
- package/typink/generator/EventsGen.js +31 -0
- package/typink/generator/IndexGen.d.ts +6 -0
- package/typink/generator/IndexGen.js +20 -0
- package/typink/generator/QueryGen.d.ts +12 -0
- package/typink/generator/QueryGen.js +68 -0
- package/typink/generator/TxGen.d.ts +6 -0
- package/typink/generator/TxGen.js +21 -0
- package/typink/generator/TypesGen.d.ts +7 -0
- package/typink/generator/TypesGen.js +24 -0
- package/typink/generator/index.d.ts +7 -0
- package/typink/generator/index.js +7 -0
- package/typink/index.d.ts +2 -0
- package/typink/index.js +33 -0
- package/typink/templates/constructor-query.hbs +7 -0
- package/typink/templates/constructor-tx.hbs +7 -0
- package/typink/templates/events.hbs +8 -0
- package/typink/templates/index.hbs +16 -0
- package/typink/templates/query.hbs +7 -0
- package/typink/templates/tx.hbs +7 -0
- package/typink/templates/types.hbs +5 -0
- package/{generator/utils.d.ts → utils.d.ts} +1 -1
- package/{generator/utils.js → utils.js} +4 -4
- package/cjs/generator/IndexGen.js +0 -17
- package/cjs/templates/consts.hbs +0 -7
- package/cjs/templates/errors.hbs +0 -7
- package/cjs/templates/events.hbs +0 -7
- package/cjs/templates/index.hbs +0 -22
- package/cjs/templates/json-rpc.hbs +0 -5
- package/cjs/templates/query.hbs +0 -7
- package/cjs/templates/runtime.hbs +0 -8
- package/cjs/templates/tx.hbs +0 -9
- package/generator/IndexGen.js +0 -13
- package/templates/consts.hbs +0 -7
- package/templates/errors.hbs +0 -7
- package/templates/events.hbs +0 -7
- package/templates/index.hbs +0 -22
- package/templates/json-rpc.hbs +0 -5
- package/templates/query.hbs +0 -7
- package/templates/runtime.hbs +0 -8
- package/templates/tx.hbs +0 -9
- /package/{generator → chaintypes/generator}/ApiGen.js +0 -0
- /package/{generator → chaintypes/generator}/index.d.ts +0 -0
- /package/{generator → chaintypes/generator}/index.js +0 -0
- /package/cjs/{generator → chaintypes/generator}/ApiGen.js +0 -0
- /package/cjs/{generator → chaintypes/generator}/index.js +0 -0
- /package/cjs/{generator/dirname.js → dirname.js} +0 -0
- /package/{generator/dirname.d.ts → dirname.d.ts} +0 -0
- /package/{generator/dirname.js → dirname.js} +0 -0
|
@@ -1,65 +1,93 @@
|
|
|
1
|
-
import { PortableRegistry } from '@dedot/codecs';
|
|
2
1
|
import { normalizeName, stringPascalCase } from '@dedot/utils';
|
|
2
|
+
import { commentBlock, isNativeType, WRAPPER_TYPE_REGEX } from '../utils.js';
|
|
3
3
|
import { TypeImports } from './TypeImports.js';
|
|
4
|
-
import { findKnownCodec, findKnownCodecType
|
|
5
|
-
import { beautifySourceCode, commentBlock, compileTemplate, isNativeType } from './utils.js';
|
|
6
|
-
// Skip generate types for these
|
|
7
|
-
// as we do have native types for them
|
|
8
|
-
const SKIP_TYPES = [
|
|
9
|
-
'BoundedBTreeMap',
|
|
10
|
-
'BoundedBTreeSet',
|
|
11
|
-
'BoundedVec',
|
|
12
|
-
'Box',
|
|
13
|
-
'BTreeMap',
|
|
14
|
-
'BTreeSet',
|
|
15
|
-
'Cow',
|
|
16
|
-
'Option',
|
|
17
|
-
'Range',
|
|
18
|
-
'RangeInclusive',
|
|
19
|
-
'Result',
|
|
20
|
-
'WeakBoundedVec',
|
|
21
|
-
'WrapperKeepOpaque',
|
|
22
|
-
'WrapperOpaque',
|
|
23
|
-
];
|
|
4
|
+
import { checkKnownCodecType, findKnownCodec, findKnownCodecType } from './known-codecs.js';
|
|
24
5
|
// These are common & generic types, so we'll remove these from all paths at index 1
|
|
25
6
|
// This helps make the type name shorter
|
|
26
7
|
const PATH_RM_INDEX_1 = ['generic', 'misc', 'pallet', 'traits', 'types'];
|
|
27
8
|
export const BASIC_KNOWN_TYPES = ['BitSequence', 'Bytes', 'BytesLike', 'FixedBytes', 'FixedArray', 'Result'];
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
metadata;
|
|
31
|
-
/**
|
|
32
|
-
* Types will be generated its definition out.
|
|
33
|
-
*/
|
|
9
|
+
export class BaseTypesGen {
|
|
10
|
+
types;
|
|
34
11
|
includedTypes;
|
|
35
|
-
registry;
|
|
36
12
|
typeImports;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
this.
|
|
40
|
-
this.includedTypes =
|
|
13
|
+
skipTypes;
|
|
14
|
+
constructor(types) {
|
|
15
|
+
this.types = types;
|
|
16
|
+
this.includedTypes = {};
|
|
41
17
|
this.typeImports = new TypeImports();
|
|
18
|
+
this.skipTypes = [];
|
|
42
19
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
let defTypeOut = '';
|
|
46
|
-
Object.values(this.includedTypes)
|
|
47
|
-
.filter(({ skip, knownType }) => !(skip || knownType))
|
|
48
|
-
.forEach(({ name, nameOut, id, docs }) => {
|
|
49
|
-
defTypeOut += `${commentBlock(docs)}export type ${nameOut} = ${this.generateType(id, 0, true)};\n\n`;
|
|
50
|
-
if (this.#shouldGenerateTypeIn(id)) {
|
|
51
|
-
defTypeOut += `export type ${name} = ${this.generateType(id)};\n\n`;
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
const importTypes = this.typeImports.toImports('./types');
|
|
55
|
-
const template = compileTemplate('types.hbs');
|
|
56
|
-
return beautifySourceCode(template({ importTypes, defTypeOut }));
|
|
20
|
+
shouldGenerateTypeIn(_id) {
|
|
21
|
+
return false;
|
|
57
22
|
}
|
|
58
23
|
typeCache = {};
|
|
59
24
|
clearCache() {
|
|
60
25
|
this.typeCache = {};
|
|
61
26
|
this.typeImports.clear();
|
|
62
27
|
}
|
|
28
|
+
includeTypes() {
|
|
29
|
+
const pathsCount = new Map();
|
|
30
|
+
const typesWithPath = this.types.filter((one) => one.path.length > 0);
|
|
31
|
+
const skipIds = [];
|
|
32
|
+
const typeSuffixes = new Map();
|
|
33
|
+
typesWithPath.forEach(({ path, id }) => {
|
|
34
|
+
const joinedPath = path.join('::');
|
|
35
|
+
if (pathsCount.has(joinedPath)) {
|
|
36
|
+
// We compare 2 types with the same path here,
|
|
37
|
+
// if they are the same type -> skip the current one, keep the first occurrence
|
|
38
|
+
// if they are not the same type but has the same path -> we'll try to calculate & add a suffix for the current type name
|
|
39
|
+
const firstOccurrenceTypeId = pathsCount.get(joinedPath)[0];
|
|
40
|
+
const sameType = this.typeEql(firstOccurrenceTypeId, id);
|
|
41
|
+
if (sameType) {
|
|
42
|
+
skipIds.push(id);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
pathsCount.get(joinedPath).push(id);
|
|
46
|
+
typeSuffixes.set(id, this.extractDupTypeSuffix(id, firstOccurrenceTypeId, pathsCount.get(joinedPath).length));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
pathsCount.set(joinedPath, [id]);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
return typesWithPath.reduce((o, type) => {
|
|
54
|
+
const { path, id } = type;
|
|
55
|
+
const joinedPath = path.join('::');
|
|
56
|
+
if (this.skipTypes.includes(joinedPath) || this.skipTypes.includes(path.at(-1))) {
|
|
57
|
+
return o;
|
|
58
|
+
}
|
|
59
|
+
const suffix = typeSuffixes.get(id) || '';
|
|
60
|
+
let knownType = false;
|
|
61
|
+
let name, nameOut;
|
|
62
|
+
const [isKnownCodecType, codecName] = checkKnownCodecType(joinedPath);
|
|
63
|
+
if (isKnownCodecType) {
|
|
64
|
+
const codecType = findKnownCodecType(codecName);
|
|
65
|
+
name = codecType.typeIn;
|
|
66
|
+
nameOut = codecType.typeOut;
|
|
67
|
+
knownType = true;
|
|
68
|
+
}
|
|
69
|
+
else if (PATH_RM_INDEX_1.includes(path[1])) {
|
|
70
|
+
const newPath = path.slice();
|
|
71
|
+
newPath.splice(1, 1);
|
|
72
|
+
name = this.cleanPath(newPath);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
name = this.cleanPath(path);
|
|
76
|
+
}
|
|
77
|
+
if (this.shouldGenerateTypeIn(id)) {
|
|
78
|
+
nameOut = name;
|
|
79
|
+
name = name.endsWith('Like') ? name : `${name}Like`;
|
|
80
|
+
}
|
|
81
|
+
o[id] = {
|
|
82
|
+
name: `${name}${suffix}`,
|
|
83
|
+
nameOut: nameOut ? `${nameOut}${suffix}` : `${name}${suffix}`,
|
|
84
|
+
knownType,
|
|
85
|
+
skip: skipIds.includes(id),
|
|
86
|
+
...type,
|
|
87
|
+
};
|
|
88
|
+
return o;
|
|
89
|
+
}, {});
|
|
90
|
+
}
|
|
63
91
|
generateType(typeId, nestedLevel = 0, typeOut = false) {
|
|
64
92
|
if (nestedLevel > 0) {
|
|
65
93
|
const includedDef = this.includedTypes[typeId];
|
|
@@ -90,13 +118,13 @@ export class TypesGen {
|
|
|
90
118
|
return type;
|
|
91
119
|
}
|
|
92
120
|
#generateType(typeId, nestedLevel = 0, typeOut = false) {
|
|
93
|
-
const def = this.
|
|
121
|
+
const def = this.types[typeId];
|
|
94
122
|
if (!def) {
|
|
95
123
|
throw new Error(`Type def not found ${JSON.stringify(def)}`);
|
|
96
124
|
}
|
|
97
|
-
const {
|
|
98
|
-
const {
|
|
99
|
-
switch (
|
|
125
|
+
const { typeDef, path, docs } = def;
|
|
126
|
+
const { type, value } = typeDef;
|
|
127
|
+
switch (type) {
|
|
100
128
|
case 'Primitive':
|
|
101
129
|
const $codec = findKnownCodec(value.kind);
|
|
102
130
|
if ($codec.nativeType) {
|
|
@@ -167,14 +195,14 @@ export class TypesGen {
|
|
|
167
195
|
membersType.push([keyName, this.generateObjectType(fields, nestedLevel + 1, typeOut), docs]);
|
|
168
196
|
}
|
|
169
197
|
}
|
|
170
|
-
const { tagKey, valueKey } = this.
|
|
198
|
+
const { tagKey, valueKey } = this.getEnumOptions(typeId);
|
|
171
199
|
return membersType
|
|
172
200
|
.map(([keyName, valueType, docs]) => ({
|
|
173
|
-
|
|
201
|
+
type: `${tagKey}: '${keyName}'`,
|
|
174
202
|
value: valueType ? `, ${valueKey}${this.#isOptionalType(valueType) ? '?' : ''}: ${valueType} ` : '',
|
|
175
203
|
docs,
|
|
176
204
|
}))
|
|
177
|
-
.map(({
|
|
205
|
+
.map(({ type, value, docs }) => `${commentBlock(docs)}{ ${type}${value} }`)
|
|
178
206
|
.join(' | ');
|
|
179
207
|
}
|
|
180
208
|
}
|
|
@@ -196,9 +224,9 @@ export class TypesGen {
|
|
|
196
224
|
return this.generateType(value.typeParam, nestedLevel + 1, typeOut);
|
|
197
225
|
case 'Sequence':
|
|
198
226
|
case 'SizedVec': {
|
|
199
|
-
const fixedSize =
|
|
200
|
-
const $innerType = this.
|
|
201
|
-
if ($innerType.
|
|
227
|
+
const fixedSize = type === 'SizedVec' ? `${value.len}` : null;
|
|
228
|
+
const $innerType = this.types[value.typeParam].typeDef;
|
|
229
|
+
if ($innerType.type === 'Primitive' && $innerType.value.kind === 'u8') {
|
|
202
230
|
return fixedSize ? `FixedBytes<${fixedSize}>` : typeOut ? 'Bytes' : 'BytesLike';
|
|
203
231
|
}
|
|
204
232
|
else {
|
|
@@ -207,7 +235,7 @@ export class TypesGen {
|
|
|
207
235
|
}
|
|
208
236
|
}
|
|
209
237
|
default:
|
|
210
|
-
throw new Error(`Invalid type! ${
|
|
238
|
+
throw new Error(`Invalid type! ${type}`);
|
|
211
239
|
}
|
|
212
240
|
}
|
|
213
241
|
generateObjectType(fields, nestedLevel = 0, typeOut = false) {
|
|
@@ -227,69 +255,6 @@ export class TypesGen {
|
|
|
227
255
|
#isOptionalType(type) {
|
|
228
256
|
return type.endsWith('| undefined');
|
|
229
257
|
}
|
|
230
|
-
#includedTypes() {
|
|
231
|
-
const { types } = this.metadata;
|
|
232
|
-
const pathsCount = new Map();
|
|
233
|
-
const typesWithPath = types.filter((one) => one.path.length > 0);
|
|
234
|
-
const skipIds = [];
|
|
235
|
-
const typeSuffixes = new Map();
|
|
236
|
-
typesWithPath.forEach(({ path, id }) => {
|
|
237
|
-
const joinedPath = path.join('::');
|
|
238
|
-
if (pathsCount.has(joinedPath)) {
|
|
239
|
-
// We compare 2 types with the same path here,
|
|
240
|
-
// if they are the same type -> skip the current one, keep the first occurrence
|
|
241
|
-
// if they are not the same type but has the same path -> we'll try to calculate & add a suffix for the current type name
|
|
242
|
-
const firstOccurrenceTypeId = pathsCount.get(joinedPath)[0];
|
|
243
|
-
const sameType = this.typeEql(firstOccurrenceTypeId, id);
|
|
244
|
-
if (sameType) {
|
|
245
|
-
skipIds.push(id);
|
|
246
|
-
}
|
|
247
|
-
else {
|
|
248
|
-
pathsCount.get(joinedPath).push(id);
|
|
249
|
-
typeSuffixes.set(id, this.#extractDupTypeSuffix(id, firstOccurrenceTypeId, pathsCount.get(joinedPath).length));
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
else {
|
|
253
|
-
pathsCount.set(joinedPath, [id]);
|
|
254
|
-
}
|
|
255
|
-
});
|
|
256
|
-
return typesWithPath.reduce((o, type) => {
|
|
257
|
-
const { path, id } = type;
|
|
258
|
-
const joinedPath = path.join('::');
|
|
259
|
-
if (SKIP_TYPES.includes(joinedPath) || SKIP_TYPES.includes(path.at(-1))) {
|
|
260
|
-
return o;
|
|
261
|
-
}
|
|
262
|
-
const suffix = typeSuffixes.get(id) || '';
|
|
263
|
-
let knownType = false;
|
|
264
|
-
let name, nameOut;
|
|
265
|
-
if (isKnownCodecType(joinedPath)) {
|
|
266
|
-
const codecType = findKnownCodecType(path.at(-1));
|
|
267
|
-
name = codecType.typeIn;
|
|
268
|
-
nameOut = codecType.typeOut;
|
|
269
|
-
knownType = true;
|
|
270
|
-
}
|
|
271
|
-
else if (PATH_RM_INDEX_1.includes(path[1])) {
|
|
272
|
-
const newPath = path.slice();
|
|
273
|
-
newPath.splice(1, 1);
|
|
274
|
-
name = this.#cleanPath(newPath);
|
|
275
|
-
}
|
|
276
|
-
else {
|
|
277
|
-
name = this.#cleanPath(path);
|
|
278
|
-
}
|
|
279
|
-
if (this.#shouldGenerateTypeIn(id)) {
|
|
280
|
-
nameOut = name;
|
|
281
|
-
name = name.endsWith('Like') ? name : `${name}Like`;
|
|
282
|
-
}
|
|
283
|
-
o[id] = {
|
|
284
|
-
name: `${name}${suffix}`,
|
|
285
|
-
nameOut: nameOut ? `${nameOut}${suffix}` : `${name}${suffix}`,
|
|
286
|
-
knownType,
|
|
287
|
-
skip: skipIds.includes(id),
|
|
288
|
-
...type,
|
|
289
|
-
};
|
|
290
|
-
return o;
|
|
291
|
-
}, {});
|
|
292
|
-
}
|
|
293
258
|
#removeGenericPart(typeName) {
|
|
294
259
|
if (typeName.match(WRAPPER_TYPE_REGEX)) {
|
|
295
260
|
return typeName.replace(WRAPPER_TYPE_REGEX, (_, $1) => $1);
|
|
@@ -298,27 +263,12 @@ export class TypesGen {
|
|
|
298
263
|
return typeName;
|
|
299
264
|
}
|
|
300
265
|
}
|
|
301
|
-
|
|
302
|
-
* @description Remove duplicated part of the path
|
|
303
|
-
*
|
|
304
|
-
* Example:
|
|
305
|
-
* ["pallet_staking", "pallet", "pallet", "Event"]
|
|
306
|
-
* => ["pallet_staking", "pallet", "Event"]
|
|
307
|
-
*
|
|
308
|
-
* @param path
|
|
309
|
-
* @private
|
|
310
|
-
*/
|
|
311
|
-
#cleanPath(path) {
|
|
266
|
+
cleanPath(path) {
|
|
312
267
|
return path
|
|
313
268
|
.map((one) => stringPascalCase(one))
|
|
314
269
|
.filter((one, idx, currentPath) => idx === 0 || one !== currentPath[idx - 1])
|
|
315
270
|
.join('');
|
|
316
271
|
}
|
|
317
|
-
#shouldGenerateTypeIn(id) {
|
|
318
|
-
const { callTypeId } = this.metadata.extrinsic;
|
|
319
|
-
const palletCallTypeIds = this.registry.getPalletCallTypeIds();
|
|
320
|
-
return callTypeId === id || palletCallTypeIds.includes(id);
|
|
321
|
-
}
|
|
322
272
|
eqlCache = new Map();
|
|
323
273
|
typeEql(idA, idB, level = 0) {
|
|
324
274
|
const cacheKey = `${idA}==${idB}`;
|
|
@@ -331,36 +281,36 @@ export class TypesGen {
|
|
|
331
281
|
#typeEql(idA, idB, lvl = 0) {
|
|
332
282
|
if (idA === idB)
|
|
333
283
|
return true;
|
|
334
|
-
const
|
|
335
|
-
const
|
|
336
|
-
const typeB = types[idB];
|
|
284
|
+
const typeA = this.types[idA];
|
|
285
|
+
const typeB = this.types[idB];
|
|
337
286
|
if (typeA.path.join('::') !== typeB.path.join('::'))
|
|
338
287
|
return false;
|
|
339
|
-
const {
|
|
340
|
-
const {
|
|
288
|
+
const { typeDef: defA, params: paramsA } = typeA;
|
|
289
|
+
const { typeDef: defB, params: paramsB } = typeB;
|
|
341
290
|
if (!this.#eqlArray(paramsA, paramsB, (valA, valB) => this.#eqlTypeParam(valA, valB))) {
|
|
342
291
|
return false;
|
|
343
292
|
}
|
|
344
|
-
if (defA.
|
|
293
|
+
if (defA.type !== defB.type)
|
|
345
294
|
return false;
|
|
346
|
-
if (defA.
|
|
295
|
+
if (defA.type === 'BitSequence')
|
|
347
296
|
return true;
|
|
348
|
-
if (defA.
|
|
297
|
+
if (defA.type === 'Primitive' && defB.type === 'Primitive') {
|
|
349
298
|
return defA.value.kind === defB.value.kind;
|
|
350
299
|
}
|
|
351
|
-
if ((defA.
|
|
300
|
+
if ((defA.type === 'Compact' && defB.type === 'Compact') ||
|
|
301
|
+
(defA.type === 'Sequence' && defB.type === 'Sequence')) {
|
|
352
302
|
return this.typeEql(defA.value.typeParam, defB.value.typeParam, lvl + 1);
|
|
353
303
|
}
|
|
354
|
-
if (defA.
|
|
304
|
+
if (defA.type === 'SizedVec' && defB.type === 'SizedVec') {
|
|
355
305
|
return defA.value.len === defB.value.len && this.typeEql(defA.value.typeParam, defB.value.typeParam, lvl + 1);
|
|
356
306
|
}
|
|
357
|
-
if (defA.
|
|
307
|
+
if (defA.type === 'Tuple' && defB.type === 'Tuple') {
|
|
358
308
|
return this.#eqlArray(defA.value.fields, defB.value.fields, (val1, val2) => this.typeEql(val1, val2, lvl + 1));
|
|
359
309
|
}
|
|
360
|
-
if (defA.
|
|
310
|
+
if (defA.type === 'Struct' && defB.type === 'Struct') {
|
|
361
311
|
return this.#eqlFields(defA.value.fields, defB.value.fields, lvl);
|
|
362
312
|
}
|
|
363
|
-
if (defA.
|
|
313
|
+
if (defA.type === 'Enum' && defB.type === 'Enum') {
|
|
364
314
|
return this.#eqlArray(defA.value.members, defB.value.members, (val1, val2) => val1.name === val2.name && val1.index === val2.index && this.#eqlFields(val1.fields, val2.fields, lvl));
|
|
365
315
|
}
|
|
366
316
|
return false;
|
|
@@ -376,19 +326,18 @@ export class TypesGen {
|
|
|
376
326
|
(param1.typeId === undefined) === (param2.typeId === undefined) &&
|
|
377
327
|
(param1.typeId === undefined || this.#typeEql(param1.typeId, param2.typeId)));
|
|
378
328
|
}
|
|
379
|
-
|
|
380
|
-
const
|
|
381
|
-
const
|
|
382
|
-
const dupTypeParams = types[dupTypeId].params;
|
|
329
|
+
extractDupTypeSuffix(dupTypeId, originalTypeId, dupCount) {
|
|
330
|
+
const originalTypeParams = this.types[originalTypeId].params;
|
|
331
|
+
const dupTypeParams = this.types[dupTypeId].params;
|
|
383
332
|
const diffParam = dupTypeParams.find((one, idx) => !this.#eqlTypeParam(one, originalTypeParams[idx]));
|
|
384
333
|
// TODO make sure these suffix is unique if a type is duplicated more than 2 times
|
|
385
334
|
if (diffParam?.typeId) {
|
|
386
|
-
const diffType = types[diffParam.typeId];
|
|
335
|
+
const diffType = this.types[diffParam.typeId];
|
|
387
336
|
if (diffType.path.length > 0) {
|
|
388
337
|
return stringPascalCase(diffType.path.at(-1));
|
|
389
338
|
}
|
|
390
|
-
else if (diffType.type
|
|
391
|
-
return stringPascalCase(diffType.
|
|
339
|
+
else if (diffType.typeDef.type === 'Primitive') {
|
|
340
|
+
return stringPascalCase(diffType.typeDef.value.kind);
|
|
392
341
|
}
|
|
393
342
|
}
|
|
394
343
|
// Last resort!
|
|
@@ -423,4 +372,7 @@ export class TypesGen {
|
|
|
423
372
|
}
|
|
424
373
|
this.typeImports.addOutType(typeName);
|
|
425
374
|
}
|
|
375
|
+
getEnumOptions(_typeId) {
|
|
376
|
+
return { tagKey: 'type', valueKey: 'value' };
|
|
377
|
+
}
|
|
426
378
|
}
|
|
@@ -1,16 +1,25 @@
|
|
|
1
|
+
type ImportConfig = {
|
|
2
|
+
excludeModules?: string[];
|
|
3
|
+
useSubPaths?: boolean;
|
|
4
|
+
};
|
|
1
5
|
export declare class TypeImports {
|
|
2
6
|
#private;
|
|
3
7
|
portableTypes: Set<string>;
|
|
4
8
|
codecTypes: Set<string>;
|
|
5
9
|
knownTypes: Set<string>;
|
|
6
|
-
|
|
10
|
+
knownJsonRpcTypes: Set<string>;
|
|
7
11
|
outTypes: Set<string>;
|
|
12
|
+
contractTypes: Set<string>;
|
|
13
|
+
chainTypes: Set<string>;
|
|
8
14
|
constructor();
|
|
9
15
|
clear(): void;
|
|
10
|
-
toImports(
|
|
16
|
+
toImports(config?: ImportConfig): string;
|
|
11
17
|
addPortableType(...types: string[]): void;
|
|
12
18
|
addCodecType(...types: string[]): void;
|
|
13
19
|
addKnownType(...types: string[]): void;
|
|
14
|
-
|
|
20
|
+
addKnownJsonRpcType(...types: string[]): void;
|
|
15
21
|
addOutType(...types: string[]): void;
|
|
22
|
+
addContractType(...types: string[]): void;
|
|
23
|
+
addChainType(...types: string[]): void;
|
|
16
24
|
}
|
|
25
|
+
export {};
|
|
@@ -5,29 +5,41 @@ export class TypeImports {
|
|
|
5
5
|
codecTypes;
|
|
6
6
|
// Known types that're not codecs or chain/portable types defined in @dedot/types
|
|
7
7
|
knownTypes;
|
|
8
|
-
|
|
8
|
+
knownJsonRpcTypes;
|
|
9
9
|
// External types to define explicitly
|
|
10
10
|
outTypes;
|
|
11
|
+
// Know types defined in @dedot/contracts
|
|
12
|
+
contractTypes;
|
|
13
|
+
// Know types defined in @dedot/api/chaintypes or dedot/chaintypes
|
|
14
|
+
chainTypes;
|
|
11
15
|
constructor() {
|
|
12
16
|
this.portableTypes = new Set();
|
|
13
17
|
this.codecTypes = new Set();
|
|
14
18
|
this.knownTypes = new Set();
|
|
15
|
-
this.
|
|
19
|
+
this.knownJsonRpcTypes = new Set();
|
|
16
20
|
this.outTypes = new Set();
|
|
21
|
+
this.contractTypes = new Set();
|
|
22
|
+
this.chainTypes = new Set();
|
|
17
23
|
}
|
|
18
24
|
clear() {
|
|
19
25
|
this.portableTypes.clear();
|
|
20
26
|
this.codecTypes.clear();
|
|
21
27
|
this.knownTypes.clear();
|
|
22
|
-
this.
|
|
28
|
+
this.knownJsonRpcTypes.clear();
|
|
23
29
|
this.outTypes.clear();
|
|
30
|
+
this.contractTypes.clear();
|
|
31
|
+
this.chainTypes.clear();
|
|
24
32
|
}
|
|
25
|
-
toImports(
|
|
33
|
+
toImports(config) {
|
|
34
|
+
const { excludeModules = [], useSubPaths = false } = config || {};
|
|
26
35
|
// TODO generate outTypes!
|
|
36
|
+
const prefix = useSubPaths ? '' : '@';
|
|
27
37
|
const toImports = [
|
|
28
|
-
[this.knownTypes,
|
|
29
|
-
[this.
|
|
30
|
-
[this.codecTypes,
|
|
38
|
+
[this.knownTypes, `${prefix}dedot/types`],
|
|
39
|
+
[this.knownJsonRpcTypes, `${prefix}dedot/types/json-rpc`],
|
|
40
|
+
[this.codecTypes, `${prefix}dedot/codecs`],
|
|
41
|
+
[this.contractTypes, `${prefix}dedot/contracts`],
|
|
42
|
+
[this.chainTypes, prefix ? '@dedot/api/chaintypes' : 'dedot/chaintypes'],
|
|
31
43
|
[this.portableTypes, './types'],
|
|
32
44
|
];
|
|
33
45
|
return toImports
|
|
@@ -51,10 +63,16 @@ export class TypeImports {
|
|
|
51
63
|
addKnownType(...types) {
|
|
52
64
|
types.forEach((one) => this.knownTypes.add(one));
|
|
53
65
|
}
|
|
54
|
-
|
|
55
|
-
types.forEach((one) => this.
|
|
66
|
+
addKnownJsonRpcType(...types) {
|
|
67
|
+
types.forEach((one) => this.knownJsonRpcTypes.add(one));
|
|
56
68
|
}
|
|
57
69
|
addOutType(...types) {
|
|
58
70
|
types.forEach((one) => this.outTypes.add(one));
|
|
59
71
|
}
|
|
72
|
+
addContractType(...types) {
|
|
73
|
+
types.forEach((one) => this.contractTypes.add(one));
|
|
74
|
+
}
|
|
75
|
+
addChainType(...types) {
|
|
76
|
+
types.forEach((one) => this.chainTypes.add(one));
|
|
77
|
+
}
|
|
60
78
|
}
|
package/shared/index.js
ADDED
|
@@ -20,4 +20,4 @@ export declare const looseTypeCodecs: Record<string, AnyShape>;
|
|
|
20
20
|
export declare function findKnownCodecType(name: string): CodecType;
|
|
21
21
|
export declare function findKnownCodec<I = unknown, O = I>(typeName: string): $.Shape<I, O>;
|
|
22
22
|
export declare function findKnownWrapperCodec(typeName: string): $.AnyShape | undefined;
|
|
23
|
-
export declare function
|
|
23
|
+
export declare function checkKnownCodecType(path: string | string[]): [boolean, string];
|
|
@@ -30,6 +30,8 @@ const KNOWN_PATHS = [
|
|
|
30
30
|
/^primitive_types::\w+$/,
|
|
31
31
|
/^sp_arithmetic::per_things::\w+$/,
|
|
32
32
|
/^sp_arithmetic::fixed_point::\w+$/,
|
|
33
|
+
'ink_primitives::types::Hash',
|
|
34
|
+
{ path: 'ink_primitives::types::AccountId', codec: 'AccountId32' },
|
|
33
35
|
];
|
|
34
36
|
const WRAPPER_TYPE_REGEX = /^(\w+)<(.*)>$/;
|
|
35
37
|
const TUPLE_TYPE_REGEX = /^\[(.*)]$/;
|
|
@@ -114,7 +116,24 @@ export function findKnownWrapperCodec(typeName) {
|
|
|
114
116
|
return $.Tuple(...$inner);
|
|
115
117
|
}
|
|
116
118
|
}
|
|
117
|
-
export function
|
|
119
|
+
export function checkKnownCodecType(path) {
|
|
118
120
|
const joinedPath = Array.isArray(path) ? path.join('::') : path;
|
|
119
|
-
|
|
121
|
+
const knownPath = KNOWN_PATHS.find((one) => {
|
|
122
|
+
if (typeof one === 'string') {
|
|
123
|
+
return one === joinedPath;
|
|
124
|
+
}
|
|
125
|
+
else if (one instanceof RegExp) {
|
|
126
|
+
return one.test(joinedPath);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
return one.path === joinedPath;
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
if (!knownPath) {
|
|
133
|
+
return [false, ''];
|
|
134
|
+
}
|
|
135
|
+
if (typeof knownPath === 'string' || knownPath instanceof RegExp) {
|
|
136
|
+
return [true, joinedPath.split('::').at(-1)];
|
|
137
|
+
}
|
|
138
|
+
return [true, knownPath.codec];
|
|
120
139
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ContractConstructorMessage } from '@dedot/contracts';
|
|
2
|
+
import { QueryGen } from './QueryGen.js';
|
|
3
|
+
export declare class ConstructorQueryGen extends QueryGen {
|
|
4
|
+
generate(useSubPaths?: boolean): Promise<string>;
|
|
5
|
+
generateMethodDef(def: ContractConstructorMessage): string;
|
|
6
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { beautifySourceCode, compileTemplate } from '../../utils.js';
|
|
2
|
+
import { QueryGen } from './QueryGen.js';
|
|
3
|
+
export class ConstructorQueryGen extends QueryGen {
|
|
4
|
+
generate(useSubPaths = false) {
|
|
5
|
+
this.typesGen.clearCache();
|
|
6
|
+
this.typesGen.typeImports.addKnownType('GenericSubstrateApi');
|
|
7
|
+
this.typesGen.typeImports.addContractType('GenericConstructorQuery', 'GenericConstructorQueryCall', 'ConstructorCallOptions', 'ContractInstantiateResult');
|
|
8
|
+
const { constructors } = this.contractMetadata.spec;
|
|
9
|
+
const constructorsOut = this.doGenerate(constructors, 'ConstructorCallOptions');
|
|
10
|
+
const importTypes = this.typesGen.typeImports.toImports({ useSubPaths });
|
|
11
|
+
const template = compileTemplate('typink/templates/constructor-query.hbs');
|
|
12
|
+
return beautifySourceCode(template({ importTypes, constructorsOut }));
|
|
13
|
+
}
|
|
14
|
+
generateMethodDef(def) {
|
|
15
|
+
const { args } = def;
|
|
16
|
+
args.forEach(({ type: { type } }) => this.importType(type));
|
|
17
|
+
const paramsOut = this.generateParamsOut(args);
|
|
18
|
+
return `GenericConstructorQueryCall<ChainApi, (${paramsOut && `${paramsOut},`} options: ConstructorCallOptions) => Promise<ContractInstantiateResult<ChainApi>>>`;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ContractConstructorMessage } from '@dedot/contracts';
|
|
2
|
+
import { QueryGen } from './QueryGen.js';
|
|
3
|
+
export declare class ConstructorTxGen extends QueryGen {
|
|
4
|
+
generate(useSubPaths?: boolean): Promise<string>;
|
|
5
|
+
generateMethodDef(def: ContractConstructorMessage): string;
|
|
6
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { beautifySourceCode, compileTemplate } from '../../utils.js';
|
|
2
|
+
import { QueryGen } from './QueryGen.js';
|
|
3
|
+
export class ConstructorTxGen extends QueryGen {
|
|
4
|
+
generate(useSubPaths = false) {
|
|
5
|
+
this.typesGen.clearCache();
|
|
6
|
+
this.typesGen.typeImports.addKnownType('GenericSubstrateApi');
|
|
7
|
+
this.typesGen.typeImports.addContractType('GenericConstructorTx', 'GenericConstructorTxCall', 'ConstructorTxOptions', 'GenericInstantiateSubmittableExtrinsic');
|
|
8
|
+
const { constructors } = this.contractMetadata.spec;
|
|
9
|
+
const constructorsOut = this.doGenerate(constructors, 'ConstructorTxOptions');
|
|
10
|
+
const importTypes = this.typesGen.typeImports.toImports({ useSubPaths });
|
|
11
|
+
const template = compileTemplate('typink/templates/constructor-tx.hbs');
|
|
12
|
+
return beautifySourceCode(template({ importTypes, constructorsOut }));
|
|
13
|
+
}
|
|
14
|
+
generateMethodDef(def) {
|
|
15
|
+
const { args } = def;
|
|
16
|
+
args.forEach(({ type: { type } }) => this.importType(type));
|
|
17
|
+
const paramsOut = this.generateParamsOut(args);
|
|
18
|
+
return `GenericConstructorTxCall<ChainApi, (${paramsOut && `${paramsOut},`} options: ConstructorTxOptions) => GenericInstantiateSubmittableExtrinsic<ChainApi>>`;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ContractEventArg } from '@dedot/contracts';
|
|
2
|
+
import { QueryGen } from './QueryGen.js';
|
|
3
|
+
export declare class EventsGen extends QueryGen {
|
|
4
|
+
#private;
|
|
5
|
+
generate(useSubPaths?: boolean): Promise<string>;
|
|
6
|
+
generateParamsOut(args: ContractEventArg[]): string;
|
|
7
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { stringCamelCase, stringPascalCase } from '@dedot/utils';
|
|
2
|
+
import { beautifySourceCode, commentBlock, compileTemplate } from '../../utils.js';
|
|
3
|
+
import { QueryGen } from './QueryGen.js';
|
|
4
|
+
export class EventsGen extends QueryGen {
|
|
5
|
+
generate(useSubPaths = false) {
|
|
6
|
+
this.typesGen.clearCache();
|
|
7
|
+
this.typesGen.typeImports.addContractType('GenericContractEvents', 'GenericContractEvent');
|
|
8
|
+
const { events } = this.contractMetadata.spec;
|
|
9
|
+
let eventsOut = '';
|
|
10
|
+
events.forEach((event) => {
|
|
11
|
+
const { docs, label } = event;
|
|
12
|
+
const isV5 = 'signature_topic' in event;
|
|
13
|
+
eventsOut += `${commentBlock(docs, '\n', isV5 ? event.signature_topic ? `@signature_topic: ${event.signature_topic}` : '- Anonymous event' : '')}`;
|
|
14
|
+
eventsOut += `${stringPascalCase(label)}: ${this.#generateEventDef(event)};\n\n`;
|
|
15
|
+
});
|
|
16
|
+
const importTypes = this.typesGen.typeImports.toImports({ useSubPaths });
|
|
17
|
+
const template = compileTemplate('typink/templates/events.hbs');
|
|
18
|
+
return beautifySourceCode(template({ importTypes, eventsOut }));
|
|
19
|
+
}
|
|
20
|
+
#generateEventDef(event) {
|
|
21
|
+
const { args, label } = event;
|
|
22
|
+
args.forEach(({ type: { type } }) => this.importType(type));
|
|
23
|
+
const paramsOut = this.generateParamsOut(args);
|
|
24
|
+
return `GenericContractEvent<'${stringPascalCase(label)}', {${paramsOut}}>`;
|
|
25
|
+
}
|
|
26
|
+
generateParamsOut(args) {
|
|
27
|
+
return args
|
|
28
|
+
.map(({ type: { type }, label, docs, indexed }) => `${commentBlock(docs, '\n', `@indexed: ${indexed}`)}${stringCamelCase(label)}: ${this.typesGen.generateType(type, 1)}`)
|
|
29
|
+
.join(', ');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { stringPascalCase } from '@dedot/utils';
|
|
2
|
+
import { TypeImports } from '../../shared/index.js';
|
|
3
|
+
import { beautifySourceCode, compileTemplate } from '../../utils.js';
|
|
4
|
+
const SUFFIX = 'contract_api';
|
|
5
|
+
export class IndexGen {
|
|
6
|
+
contractMetadata;
|
|
7
|
+
constructor(contractMetadata) {
|
|
8
|
+
this.contractMetadata = contractMetadata;
|
|
9
|
+
}
|
|
10
|
+
generate(useSubPaths = false) {
|
|
11
|
+
const contractName = stringPascalCase(`${this.contractMetadata.contract.name}_${SUFFIX}`);
|
|
12
|
+
const typeImports = new TypeImports();
|
|
13
|
+
typeImports.addKnownType('VersionedGenericSubstrateApi', 'RpcVersion', 'RpcV2');
|
|
14
|
+
typeImports.addContractType('GenericContractApi');
|
|
15
|
+
typeImports.addChainType('SubstrateApi');
|
|
16
|
+
const importTypes = typeImports.toImports({ useSubPaths });
|
|
17
|
+
const template = compileTemplate('typink/templates/index.hbs');
|
|
18
|
+
return beautifySourceCode(template({ contractName, importTypes }));
|
|
19
|
+
}
|
|
20
|
+
}
|