@dedot/codegen 0.0.1-next.cfee875e.21 → 0.0.1-next.d731b849.13

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.
Files changed (41) hide show
  1. package/chaintypes/generator/ApiGen.d.ts +12 -12
  2. package/chaintypes/generator/ErrorsGen.js +2 -2
  3. package/chaintypes/generator/EventsGen.js +2 -2
  4. package/chaintypes/generator/QueryGen.js +7 -7
  5. package/chaintypes/generator/TxGen.js +7 -7
  6. package/chaintypes/generator/TypesGen.js +1 -1
  7. package/cjs/chaintypes/generator/ErrorsGen.js +2 -2
  8. package/cjs/chaintypes/generator/EventsGen.js +2 -2
  9. package/cjs/chaintypes/generator/QueryGen.js +7 -7
  10. package/cjs/chaintypes/generator/TxGen.js +7 -7
  11. package/cjs/chaintypes/generator/TypesGen.js +1 -1
  12. package/cjs/shared/BaseTypesGen.js +26 -22
  13. package/cjs/typink/generator/ConstructorQueryGen.js +6 -3
  14. package/cjs/typink/generator/EventsGen.js +35 -0
  15. package/cjs/typink/generator/IndexGen.js +8 -3
  16. package/cjs/typink/generator/QueryGen.js +9 -7
  17. package/cjs/typink/generator/TypesGen.js +1 -8
  18. package/cjs/typink/generator/index.js +1 -0
  19. package/cjs/typink/index.js +4 -1
  20. package/cjs/typink/templates/events.hbs +8 -0
  21. package/cjs/typink/templates/index.hbs +12 -5
  22. package/cjs/utils.js +1 -1
  23. package/package.json +11 -11
  24. package/shared/BaseTypesGen.d.ts +1 -1
  25. package/shared/BaseTypesGen.js +26 -22
  26. package/typink/generator/ConstructorQueryGen.js +6 -3
  27. package/typink/generator/EventsGen.d.ts +7 -0
  28. package/typink/generator/EventsGen.js +31 -0
  29. package/typink/generator/IndexGen.d.ts +3 -1
  30. package/typink/generator/IndexGen.js +8 -3
  31. package/typink/generator/QueryGen.d.ts +3 -3
  32. package/typink/generator/QueryGen.js +9 -7
  33. package/typink/generator/TxGen.d.ts +2 -2
  34. package/typink/generator/TypesGen.d.ts +0 -1
  35. package/typink/generator/TypesGen.js +1 -8
  36. package/typink/generator/index.d.ts +1 -0
  37. package/typink/generator/index.js +1 -0
  38. package/typink/index.js +5 -2
  39. package/typink/templates/events.hbs +8 -0
  40. package/typink/templates/index.hbs +12 -5
  41. package/utils.js +1 -1
@@ -10,13 +10,13 @@ export declare abstract class ApiGen {
10
10
  name: string;
11
11
  typeId: number | undefined;
12
12
  }[];
13
- type: {
14
- tag: "Struct";
13
+ typeDef: {
14
+ type: "Struct";
15
15
  value: {
16
16
  fields: import("@dedot/codecs").Field[];
17
17
  };
18
18
  } | {
19
- tag: "Enum";
19
+ type: "Enum";
20
20
  value: {
21
21
  members: {
22
22
  name: string;
@@ -26,33 +26,33 @@ export declare abstract class ApiGen {
26
26
  }[];
27
27
  };
28
28
  } | {
29
- tag: "Sequence";
29
+ type: "Sequence";
30
30
  value: {
31
31
  typeParam: number;
32
32
  };
33
33
  } | {
34
- tag: "SizedVec";
34
+ type: "SizedVec";
35
35
  value: {
36
36
  len: number;
37
37
  typeParam: number;
38
38
  };
39
39
  } | {
40
- tag: "Tuple";
40
+ type: "Tuple";
41
41
  value: {
42
42
  fields: number[];
43
43
  };
44
44
  } | {
45
- tag: "Primitive";
45
+ type: "Primitive";
46
46
  value: {
47
47
  kind: "bool" | "u8" | "i8" | "u16" | "i16" | "u32" | "i32" | "u64" | "i64" | "u128" | "i128" | "u256" | "i256" | "str" | "char";
48
48
  };
49
49
  } | {
50
- tag: "Compact";
50
+ type: "Compact";
51
51
  value: {
52
52
  typeParam: number;
53
53
  };
54
54
  } | {
55
- tag: "BitSequence";
55
+ type: "BitSequence";
56
56
  value: {
57
57
  bitOrderType: number;
58
58
  bitStoreType: number;
@@ -67,13 +67,13 @@ export declare abstract class ApiGen {
67
67
  entries: {
68
68
  name: string;
69
69
  modifier: string;
70
- type: {
71
- tag: "Plain";
70
+ storageType: {
71
+ type: "Plain";
72
72
  value: {
73
73
  valueTypeId: number;
74
74
  };
75
75
  } | {
76
- tag: "Map";
76
+ type: "Map";
77
77
  value: {
78
78
  hashers: ("identity" | "blake2_128" | "blake2_256" | "blake2_128Concat" | "twox128" | "twox256" | "twox64Concat")[];
79
79
  keyTypeId: number;
@@ -29,8 +29,8 @@ export class ErrorsGen extends ApiGen {
29
29
  #getErrorDefs(errorTypeId) {
30
30
  const def = this.metadata.types[errorTypeId];
31
31
  assert(def, `Error def not found for id ${errorTypeId}`);
32
- const { tag, value } = def.type;
33
- assert(tag === 'Enum', `Invalid pallet error type!`);
32
+ const { type, value } = def.typeDef;
33
+ assert(type === 'Enum', 'Invalid pallet error type!');
34
34
  return value.members;
35
35
  }
36
36
  }
@@ -41,8 +41,8 @@ export class EventsGen extends ApiGen {
41
41
  #getEventDefs(typeId) {
42
42
  const def = this.metadata.types[typeId];
43
43
  assert(def, `Event def not found for id ${typeId}`);
44
- const { tag, value } = def.type;
45
- assert(tag === 'Enum', 'Invalid pallet event type!');
44
+ const { type, value } = def.typeDef;
45
+ assert(type === 'Enum', 'Invalid pallet event type!');
46
46
  return value.members;
47
47
  }
48
48
  #generateMemberDefType(fields) {
@@ -32,15 +32,15 @@ export class QueryGen extends ApiGen {
32
32
  return beautifySourceCode(template({ importTypes, defTypeOut }));
33
33
  }
34
34
  #generateEntry(entry) {
35
- const { name, type, docs, modifier } = entry;
35
+ const { name, storageType, docs, modifier } = entry;
36
36
  let valueType, keyTypeOut, keyTypeIn;
37
- if (type.tag === 'Plain') {
38
- valueType = this.typesGen.generateType(type.value.valueTypeId, 1, true);
37
+ if (storageType.type === 'Plain') {
38
+ valueType = this.typesGen.generateType(storageType.value.valueTypeId, 1, true);
39
39
  }
40
- else if (type.tag === 'Map') {
41
- valueType = this.typesGen.generateType(type.value.valueTypeId, 1, true);
42
- keyTypeOut = this.typesGen.generateType(type.value.keyTypeId, 1, true);
43
- keyTypeIn = this.typesGen.generateType(type.value.keyTypeId, 1);
40
+ else if (storageType.type === 'Map') {
41
+ valueType = this.typesGen.generateType(storageType.value.valueTypeId, 1, true);
42
+ keyTypeOut = this.typesGen.generateType(storageType.value.keyTypeId, 1, true);
43
+ keyTypeIn = this.typesGen.generateType(storageType.value.keyTypeId, 1);
44
44
  }
45
45
  else {
46
46
  throw Error('Invalid entry type!');
@@ -5,7 +5,7 @@ export class TxGen extends ApiGen {
5
5
  generate(useSubPaths = false) {
6
6
  const { pallets, types } = this.metadata;
7
7
  this.typesGen.clearCache();
8
- this.typesGen.typeImports.addKnownType('GenericChainTx', 'GenericTxCall', 'ISubmittableExtrinsic', 'ISubmittableResult', 'IRuntimeTxCall', 'RpcVersion', 'RpcV2', 'ISubmittableExtrinsicLegacy', 'TransactionStatusLegacy', 'TransactionStatusV2');
8
+ this.typesGen.typeImports.addKnownType('GenericChainTx', 'GenericTxCall', 'ISubmittableExtrinsic', 'ISubmittableResult', 'IRuntimeTxCall', 'RpcVersion', 'RpcV2', 'ISubmittableExtrinsicLegacy');
9
9
  const { callTypeId, addressTypeId, signatureTypeId } = this.metadata.extrinsic;
10
10
  const callTypeIn = this.typesGen.generateType(callTypeId, 1);
11
11
  const addressTypeIn = this.typesGen.generateType(addressTypeId, 1);
@@ -17,11 +17,11 @@ export class TxGen extends ApiGen {
17
17
  for (let pallet of pallets) {
18
18
  if (pallet.calls === undefined)
19
19
  continue;
20
- const { type } = types[pallet.calls];
21
- if (type.tag !== 'Enum')
20
+ const { typeDef } = types[pallet.calls];
21
+ if (typeDef.type !== 'Enum')
22
22
  continue;
23
- const isFlatEnum = type.value.members.every((m) => m.fields.length === 0);
24
- const typedTxs = type.value.members
23
+ const isFlatEnum = typeDef.value.members.every((m) => m.fields.length === 0);
24
+ const typedTxs = typeDef.value.members
25
25
  .map((one) => ({
26
26
  functionName: stringCamelCase(one.name),
27
27
  params: one.fields.map((f) => ({
@@ -53,8 +53,8 @@ export class TxGen extends ApiGen {
53
53
  export type ChainSubmittableExtrinsic<Rv extends RpcVersion, T extends IRuntimeTxCall = ${callTypeIn}> =
54
54
  Extrinsic<${addressTypeIn}, T, ${signatureTypeIn}, any[]> &
55
55
  (Rv extends RpcV2
56
- ? ISubmittableExtrinsic<ISubmittableResult<FrameSystemEventRecord, TransactionStatusV2>>
57
- : ISubmittableExtrinsicLegacy<ISubmittableResult<FrameSystemEventRecord, TransactionStatusLegacy>>)
56
+ ? ISubmittableExtrinsic<ISubmittableResult<FrameSystemEventRecord>>
57
+ : ISubmittableExtrinsicLegacy<ISubmittableResult<FrameSystemEventRecord>>)
58
58
 
59
59
  export type TxCall<Rv extends RpcVersion> = (...args: any[]) => ChainSubmittableExtrinsic<Rv>;
60
60
  `;
@@ -46,7 +46,7 @@ export class TypesGen extends BaseTypesGen {
46
46
  }
47
47
  shouldGenerateTypeIn(id) {
48
48
  const { callTypeId } = this.metadata.extrinsic;
49
- const palletCallTypeIds = this.registry.getPalletCallTypeIds();
49
+ const palletCallTypeIds = this.registry.getFieldTypeIdsFromEnum(callTypeId);
50
50
  return callTypeId === id || palletCallTypeIds.includes(id);
51
51
  }
52
52
  getEnumOptions(typeId) {
@@ -32,8 +32,8 @@ class ErrorsGen extends ApiGen_js_1.ApiGen {
32
32
  #getErrorDefs(errorTypeId) {
33
33
  const def = this.metadata.types[errorTypeId];
34
34
  (0, utils_1.assert)(def, `Error def not found for id ${errorTypeId}`);
35
- const { tag, value } = def.type;
36
- (0, utils_1.assert)(tag === 'Enum', `Invalid pallet error type!`);
35
+ const { type, value } = def.typeDef;
36
+ (0, utils_1.assert)(type === 'Enum', 'Invalid pallet error type!');
37
37
  return value.members;
38
38
  }
39
39
  }
@@ -44,8 +44,8 @@ class EventsGen extends ApiGen_js_1.ApiGen {
44
44
  #getEventDefs(typeId) {
45
45
  const def = this.metadata.types[typeId];
46
46
  (0, utils_1.assert)(def, `Event def not found for id ${typeId}`);
47
- const { tag, value } = def.type;
48
- (0, utils_1.assert)(tag === 'Enum', 'Invalid pallet event type!');
47
+ const { type, value } = def.typeDef;
48
+ (0, utils_1.assert)(type === 'Enum', 'Invalid pallet event type!');
49
49
  return value.members;
50
50
  }
51
51
  #generateMemberDefType(fields) {
@@ -35,15 +35,15 @@ class QueryGen extends ApiGen_js_1.ApiGen {
35
35
  return (0, utils_js_1.beautifySourceCode)(template({ importTypes, defTypeOut }));
36
36
  }
37
37
  #generateEntry(entry) {
38
- const { name, type, docs, modifier } = entry;
38
+ const { name, storageType, docs, modifier } = entry;
39
39
  let valueType, keyTypeOut, keyTypeIn;
40
- if (type.tag === 'Plain') {
41
- valueType = this.typesGen.generateType(type.value.valueTypeId, 1, true);
40
+ if (storageType.type === 'Plain') {
41
+ valueType = this.typesGen.generateType(storageType.value.valueTypeId, 1, true);
42
42
  }
43
- else if (type.tag === 'Map') {
44
- valueType = this.typesGen.generateType(type.value.valueTypeId, 1, true);
45
- keyTypeOut = this.typesGen.generateType(type.value.keyTypeId, 1, true);
46
- keyTypeIn = this.typesGen.generateType(type.value.keyTypeId, 1);
43
+ else if (storageType.type === 'Map') {
44
+ valueType = this.typesGen.generateType(storageType.value.valueTypeId, 1, true);
45
+ keyTypeOut = this.typesGen.generateType(storageType.value.keyTypeId, 1, true);
46
+ keyTypeIn = this.typesGen.generateType(storageType.value.keyTypeId, 1);
47
47
  }
48
48
  else {
49
49
  throw Error('Invalid entry type!');
@@ -8,7 +8,7 @@ class TxGen extends index_js_1.ApiGen {
8
8
  generate(useSubPaths = false) {
9
9
  const { pallets, types } = this.metadata;
10
10
  this.typesGen.clearCache();
11
- this.typesGen.typeImports.addKnownType('GenericChainTx', 'GenericTxCall', 'ISubmittableExtrinsic', 'ISubmittableResult', 'IRuntimeTxCall', 'RpcVersion', 'RpcV2', 'ISubmittableExtrinsicLegacy', 'TransactionStatusLegacy', 'TransactionStatusV2');
11
+ this.typesGen.typeImports.addKnownType('GenericChainTx', 'GenericTxCall', 'ISubmittableExtrinsic', 'ISubmittableResult', 'IRuntimeTxCall', 'RpcVersion', 'RpcV2', 'ISubmittableExtrinsicLegacy');
12
12
  const { callTypeId, addressTypeId, signatureTypeId } = this.metadata.extrinsic;
13
13
  const callTypeIn = this.typesGen.generateType(callTypeId, 1);
14
14
  const addressTypeIn = this.typesGen.generateType(addressTypeId, 1);
@@ -20,11 +20,11 @@ class TxGen extends index_js_1.ApiGen {
20
20
  for (let pallet of pallets) {
21
21
  if (pallet.calls === undefined)
22
22
  continue;
23
- const { type } = types[pallet.calls];
24
- if (type.tag !== 'Enum')
23
+ const { typeDef } = types[pallet.calls];
24
+ if (typeDef.type !== 'Enum')
25
25
  continue;
26
- const isFlatEnum = type.value.members.every((m) => m.fields.length === 0);
27
- const typedTxs = type.value.members
26
+ const isFlatEnum = typeDef.value.members.every((m) => m.fields.length === 0);
27
+ const typedTxs = typeDef.value.members
28
28
  .map((one) => ({
29
29
  functionName: (0, utils_1.stringCamelCase)(one.name),
30
30
  params: one.fields.map((f) => ({
@@ -56,8 +56,8 @@ class TxGen extends index_js_1.ApiGen {
56
56
  export type ChainSubmittableExtrinsic<Rv extends RpcVersion, T extends IRuntimeTxCall = ${callTypeIn}> =
57
57
  Extrinsic<${addressTypeIn}, T, ${signatureTypeIn}, any[]> &
58
58
  (Rv extends RpcV2
59
- ? ISubmittableExtrinsic<ISubmittableResult<FrameSystemEventRecord, TransactionStatusV2>>
60
- : ISubmittableExtrinsicLegacy<ISubmittableResult<FrameSystemEventRecord, TransactionStatusLegacy>>)
59
+ ? ISubmittableExtrinsic<ISubmittableResult<FrameSystemEventRecord>>
60
+ : ISubmittableExtrinsicLegacy<ISubmittableResult<FrameSystemEventRecord>>)
61
61
 
62
62
  export type TxCall<Rv extends RpcVersion> = (...args: any[]) => ChainSubmittableExtrinsic<Rv>;
63
63
  `;
@@ -49,7 +49,7 @@ class TypesGen extends index_js_1.BaseTypesGen {
49
49
  }
50
50
  shouldGenerateTypeIn(id) {
51
51
  const { callTypeId } = this.metadata.extrinsic;
52
- const palletCallTypeIds = this.registry.getPalletCallTypeIds();
52
+ const palletCallTypeIds = this.registry.getFieldTypeIdsFromEnum(callTypeId);
53
53
  return callTypeId === id || palletCallTypeIds.includes(id);
54
54
  }
55
55
  getEnumOptions(typeId) {
@@ -20,6 +20,9 @@ class BaseTypesGen {
20
20
  this.typeImports = new TypeImports_js_1.TypeImports();
21
21
  this.skipTypes = [];
22
22
  }
23
+ shouldGenerateTypeIn(_id) {
24
+ return false;
25
+ }
23
26
  typeCache = {};
24
27
  clearCache() {
25
28
  this.typeCache = {};
@@ -122,9 +125,9 @@ class BaseTypesGen {
122
125
  if (!def) {
123
126
  throw new Error(`Type def not found ${JSON.stringify(def)}`);
124
127
  }
125
- const { type, path, docs } = def;
126
- const { tag, value } = type;
127
- switch (tag) {
128
+ const { typeDef, path, docs } = def;
129
+ const { type, value } = typeDef;
130
+ switch (type) {
128
131
  case 'Primitive':
129
132
  const $codec = (0, known_codecs_js_1.findKnownCodec)(value.kind);
130
133
  if ($codec.nativeType) {
@@ -198,11 +201,11 @@ class BaseTypesGen {
198
201
  const { tagKey, valueKey } = this.getEnumOptions(typeId);
199
202
  return membersType
200
203
  .map(([keyName, valueType, docs]) => ({
201
- tag: `${tagKey}: '${keyName}'`,
204
+ type: `${tagKey}: '${keyName}'`,
202
205
  value: valueType ? `, ${valueKey}${this.#isOptionalType(valueType) ? '?' : ''}: ${valueType} ` : '',
203
206
  docs,
204
207
  }))
205
- .map(({ tag, value, docs }) => `${(0, utils_js_1.commentBlock)(docs)}{ ${tag}${value} }`)
208
+ .map(({ type, value, docs }) => `${(0, utils_js_1.commentBlock)(docs)}{ ${type}${value} }`)
206
209
  .join(' | ');
207
210
  }
208
211
  }
@@ -224,9 +227,9 @@ class BaseTypesGen {
224
227
  return this.generateType(value.typeParam, nestedLevel + 1, typeOut);
225
228
  case 'Sequence':
226
229
  case 'SizedVec': {
227
- const fixedSize = tag === 'SizedVec' ? `${value.len}` : null;
228
- const $innerType = this.types[value.typeParam].type;
229
- if ($innerType.tag === 'Primitive' && $innerType.value.kind === 'u8') {
230
+ const fixedSize = type === 'SizedVec' ? `${value.len}` : null;
231
+ const $innerType = this.types[value.typeParam].typeDef;
232
+ if ($innerType.type === 'Primitive' && $innerType.value.kind === 'u8') {
230
233
  return fixedSize ? `FixedBytes<${fixedSize}>` : typeOut ? 'Bytes' : 'BytesLike';
231
234
  }
232
235
  else {
@@ -235,7 +238,7 @@ class BaseTypesGen {
235
238
  }
236
239
  }
237
240
  default:
238
- throw new Error(`Invalid type! ${tag}`);
241
+ throw new Error(`Invalid type! ${type}`);
239
242
  }
240
243
  }
241
244
  generateObjectType(fields, nestedLevel = 0, typeOut = false) {
@@ -285,31 +288,32 @@ class BaseTypesGen {
285
288
  const typeB = this.types[idB];
286
289
  if (typeA.path.join('::') !== typeB.path.join('::'))
287
290
  return false;
288
- const { type: defA, params: paramsA } = typeA;
289
- const { type: defB, params: paramsB } = typeB;
291
+ const { typeDef: defA, params: paramsA } = typeA;
292
+ const { typeDef: defB, params: paramsB } = typeB;
290
293
  if (!this.#eqlArray(paramsA, paramsB, (valA, valB) => this.#eqlTypeParam(valA, valB))) {
291
294
  return false;
292
295
  }
293
- if (defA.tag !== defB.tag)
296
+ if (defA.type !== defB.type)
294
297
  return false;
295
- if (defA.tag === 'BitSequence')
298
+ if (defA.type === 'BitSequence')
296
299
  return true;
297
- if (defA.tag === 'Primitive' && defB.tag === 'Primitive') {
300
+ if (defA.type === 'Primitive' && defB.type === 'Primitive') {
298
301
  return defA.value.kind === defB.value.kind;
299
302
  }
300
- if ((defA.tag === 'Compact' && defB.tag === 'Compact') || (defA.tag === 'Sequence' && defB.tag === 'Sequence')) {
303
+ if ((defA.type === 'Compact' && defB.type === 'Compact') ||
304
+ (defA.type === 'Sequence' && defB.type === 'Sequence')) {
301
305
  return this.typeEql(defA.value.typeParam, defB.value.typeParam, lvl + 1);
302
306
  }
303
- if (defA.tag === 'SizedVec' && defB.tag === 'SizedVec') {
307
+ if (defA.type === 'SizedVec' && defB.type === 'SizedVec') {
304
308
  return defA.value.len === defB.value.len && this.typeEql(defA.value.typeParam, defB.value.typeParam, lvl + 1);
305
309
  }
306
- if (defA.tag === 'Tuple' && defB.tag === 'Tuple') {
310
+ if (defA.type === 'Tuple' && defB.type === 'Tuple') {
307
311
  return this.#eqlArray(defA.value.fields, defB.value.fields, (val1, val2) => this.typeEql(val1, val2, lvl + 1));
308
312
  }
309
- if (defA.tag === 'Struct' && defB.tag === 'Struct') {
313
+ if (defA.type === 'Struct' && defB.type === 'Struct') {
310
314
  return this.#eqlFields(defA.value.fields, defB.value.fields, lvl);
311
315
  }
312
- if (defA.tag === 'Enum' && defB.tag === 'Enum') {
316
+ if (defA.type === 'Enum' && defB.type === 'Enum') {
313
317
  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));
314
318
  }
315
319
  return false;
@@ -335,8 +339,8 @@ class BaseTypesGen {
335
339
  if (diffType.path.length > 0) {
336
340
  return (0, utils_1.stringPascalCase)(diffType.path.at(-1));
337
341
  }
338
- else if (diffType.type.tag === 'Primitive') {
339
- return (0, utils_1.stringPascalCase)(diffType.type.value.kind);
342
+ else if (diffType.typeDef.type === 'Primitive') {
343
+ return (0, utils_1.stringPascalCase)(diffType.typeDef.value.kind);
340
344
  }
341
345
  }
342
346
  // Last resort!
@@ -372,7 +376,7 @@ class BaseTypesGen {
372
376
  this.typeImports.addOutType(typeName);
373
377
  }
374
378
  getEnumOptions(_typeId) {
375
- return { tagKey: 'tag', valueKey: 'value' };
379
+ return { tagKey: 'type', valueKey: 'value' };
376
380
  }
377
381
  }
378
382
  exports.BaseTypesGen = BaseTypesGen;
@@ -7,7 +7,7 @@ class ConstructorQueryGen extends QueryGen_js_1.QueryGen {
7
7
  generate(useSubPaths = false) {
8
8
  this.typesGen.clearCache();
9
9
  this.typesGen.typeImports.addKnownType('GenericSubstrateApi');
10
- this.typesGen.typeImports.addContractType('GenericConstructorQuery', 'GenericConstructorQueryCall', 'ConstructorCallOptions', 'ContractInstantiateResult');
10
+ this.typesGen.typeImports.addContractType('GenericConstructorQuery', 'GenericConstructorQueryCall', 'GenericConstructorCallResult', 'ConstructorCallOptions', 'ContractInstantiateResult');
11
11
  const { constructors } = this.contractMetadata.spec;
12
12
  const constructorsOut = this.doGenerate(constructors, 'ConstructorCallOptions');
13
13
  const importTypes = this.typesGen.typeImports.toImports({ useSubPaths });
@@ -15,10 +15,13 @@ class ConstructorQueryGen extends QueryGen_js_1.QueryGen {
15
15
  return (0, utils_js_1.beautifySourceCode)(template({ importTypes, constructorsOut }));
16
16
  }
17
17
  generateMethodDef(def) {
18
- const { args } = def;
18
+ const { args, returnType } = def;
19
19
  args.forEach(({ type: { type } }) => this.importType(type));
20
20
  const paramsOut = this.generateParamsOut(args);
21
- return `GenericConstructorQueryCall<ChainApi, (${paramsOut && `${paramsOut},`} options: ConstructorCallOptions) => Promise<ContractInstantiateResult<ChainApi>>>`;
21
+ const typeOutRaw = this.typesGen.generateType(returnType.type, 0, true);
22
+ // Unwrap langError result
23
+ const typeOut = typeOutRaw.match(/^(\w+)<(.*), (.*)>$/).at(2);
24
+ return `GenericConstructorQueryCall<ChainApi, (${paramsOut && `${paramsOut},`} options: ConstructorCallOptions) => Promise<GenericConstructorCallResult<${typeOut}, ContractInstantiateResult<ChainApi>>>>`;
22
25
  }
23
26
  }
24
27
  exports.ConstructorQueryGen = ConstructorQueryGen;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EventsGen = void 0;
4
+ const utils_1 = require("@dedot/utils");
5
+ const utils_js_1 = require("../../utils.js");
6
+ const QueryGen_js_1 = require("./QueryGen.js");
7
+ class EventsGen extends QueryGen_js_1.QueryGen {
8
+ generate(useSubPaths = false) {
9
+ this.typesGen.clearCache();
10
+ this.typesGen.typeImports.addContractType('GenericContractEvents', 'GenericContractEvent');
11
+ const { events } = this.contractMetadata.spec;
12
+ let eventsOut = '';
13
+ events.forEach((event) => {
14
+ const { docs, label } = event;
15
+ const isV5 = 'signature_topic' in event;
16
+ eventsOut += `${(0, utils_js_1.commentBlock)(docs, '\n', isV5 ? event.signature_topic ? `@signature_topic: ${event.signature_topic}` : '- Anonymous event' : '')}`;
17
+ eventsOut += `${(0, utils_1.stringPascalCase)(label)}: ${this.#generateEventDef(event)};\n\n`;
18
+ });
19
+ const importTypes = this.typesGen.typeImports.toImports({ useSubPaths });
20
+ const template = (0, utils_js_1.compileTemplate)('typink/templates/events.hbs');
21
+ return (0, utils_js_1.beautifySourceCode)(template({ importTypes, eventsOut }));
22
+ }
23
+ #generateEventDef(event) {
24
+ const { args, label } = event;
25
+ args.forEach(({ type: { type } }) => this.importType(type));
26
+ const paramsOut = this.generateParamsOut(args);
27
+ return `GenericContractEvent<'${(0, utils_1.stringPascalCase)(label)}', {${paramsOut}}>`;
28
+ }
29
+ generateParamsOut(args) {
30
+ return args
31
+ .map(({ type: { type }, label, docs, indexed }) => `${(0, utils_js_1.commentBlock)(docs, '\n', `@indexed: ${indexed}`)}${(0, utils_1.stringCamelCase)(label)}: ${this.typesGen.generateType(type, 1)}`)
32
+ .join(', ');
33
+ }
34
+ }
35
+ exports.EventsGen = EventsGen;
@@ -7,18 +7,23 @@ const utils_js_1 = require("../../utils.js");
7
7
  const SUFFIX = 'contract_api';
8
8
  class IndexGen {
9
9
  contractMetadata;
10
- constructor(contractMetadata) {
10
+ typesGen;
11
+ constructor(contractMetadata, typesGen) {
11
12
  this.contractMetadata = contractMetadata;
13
+ this.typesGen = typesGen;
12
14
  }
13
15
  generate(useSubPaths = false) {
14
16
  const contractName = (0, utils_1.stringPascalCase)(`${this.contractMetadata.contract.name}_${SUFFIX}`);
17
+ const langErrorId = this.contractMetadata.spec.lang_error.type;
18
+ const langErrorName = this.typesGen.cleanPath(this.contractMetadata.types[langErrorId].type.path);
15
19
  const typeImports = new index_js_1.TypeImports();
16
- typeImports.addKnownType('VersionedGenericSubstrateApi', 'RpcVersion');
20
+ typeImports.addKnownType('VersionedGenericSubstrateApi', 'RpcVersion', 'RpcV2');
17
21
  typeImports.addContractType('GenericContractApi');
18
22
  typeImports.addChainType('SubstrateApi');
23
+ typeImports.addPortableType(langErrorName);
19
24
  const importTypes = typeImports.toImports({ useSubPaths });
20
25
  const template = (0, utils_js_1.compileTemplate)('typink/templates/index.hbs');
21
- return (0, utils_js_1.beautifySourceCode)(template({ contractName, importTypes }));
26
+ return (0, utils_js_1.beautifySourceCode)(template({ contractName, langErrorName, importTypes }));
22
27
  }
23
28
  }
24
29
  exports.IndexGen = IndexGen;
@@ -35,7 +35,9 @@ class QueryGen {
35
35
  this.importType(returnType.type);
36
36
  args.forEach(({ type: { type } }) => this.importType(type));
37
37
  const paramsOut = this.generateParamsOut(args);
38
- const typeOut = this.typesGen.generateType(returnType.type, 0, true);
38
+ const typeOutRaw = this.typesGen.generateType(returnType.type, 0, true);
39
+ // Unwrap langError result
40
+ const typeOut = typeOutRaw.match(/^(\w+)<(.*), (.*)>$/).at(2);
39
41
  return `GenericContractQueryCall<ChainApi, (${paramsOut && `${paramsOut},`} options: ContractCallOptions) => Promise<GenericContractCallResult<${typeOut}, ContractCallResult<ChainApi>>>>`;
40
42
  }
41
43
  generateParamsOut(args) {
@@ -44,14 +46,14 @@ class QueryGen {
44
46
  .join(', ');
45
47
  }
46
48
  importType(typeId) {
47
- const type = this.contractMetadata.types[typeId];
48
- const def = (0, contracts_1.normalizeContractTypeDef)(this.contractMetadata.types[typeId].type.def);
49
- if (this.typesGen.includedTypes[type.id]) {
50
- this.typesGen.addTypeImport(this.typesGen.includedTypes[type.id].name);
49
+ const contractType = this.contractMetadata.types[typeId];
50
+ const typeDef = (0, contracts_1.normalizeContractTypeDef)(this.contractMetadata.types[typeId].type.def);
51
+ if (this.typesGen.includedTypes[contractType.id]) {
52
+ this.typesGen.addTypeImport(this.typesGen.includedTypes[contractType.id].name);
51
53
  return;
52
54
  }
53
- const { tag, value } = def;
54
- switch (tag) {
55
+ const { type, value } = typeDef;
56
+ switch (type) {
55
57
  case 'Compact':
56
58
  case 'Primitive':
57
59
  case 'BitSequence':
@@ -17,19 +17,12 @@ class TypesGen extends index_js_1.BaseTypesGen {
17
17
  let defTypeOut = '';
18
18
  Object.values(this.includedTypes)
19
19
  .filter(({ skip, knownType }) => !(skip || knownType))
20
- .forEach(({ name, nameOut, id }) => {
20
+ .forEach(({ nameOut, id }) => {
21
21
  defTypeOut += `export type ${nameOut} = ${this.generateType(id, 0, true)};\n\n`;
22
- if (this.shouldGenerateTypeIn(id)) {
23
- defTypeOut += `export type ${name} = ${this.generateType(id)};\n\n`;
24
- }
25
22
  });
26
23
  const importTypes = this.typeImports.toImports({ excludeModules: ['./types'], useSubPaths });
27
24
  const template = (0, utils_js_1.compileTemplate)('typink/templates/types.hbs');
28
25
  return (0, utils_js_1.beautifySourceCode)(template({ importTypes, defTypeOut }));
29
26
  }
30
- shouldGenerateTypeIn(id) {
31
- const { messages } = this.contractMetadata.spec;
32
- return messages.some((message) => message.returnType.type === id);
33
- }
34
27
  }
35
28
  exports.TypesGen = TypesGen;
@@ -20,3 +20,4 @@ __exportStar(require("./TypesGen.js"), exports);
20
20
  __exportStar(require("./TxGen.js"), exports);
21
21
  __exportStar(require("./ConstructorTxGen.js"), exports);
22
22
  __exportStar(require("./ConstructorQueryGen.js"), exports);
23
+ __exportStar(require("./EventsGen.js"), exports);
@@ -17,6 +17,7 @@ async function generateContractTypes(metadata, contract, outDir = '.', extension
17
17
  const txTypesFileName = path_1.default.join(dirPath, `tx.${extension}`);
18
18
  const constructorTxTypesFileName = path_1.default.join(dirPath, `constructor-tx.${extension}`);
19
19
  const constructorQueryTypesFileName = path_1.default.join(dirPath, `constructor-query.${extension}`);
20
+ const eventsTypesFile = path_1.default.join(dirPath, `events.${extension}`);
20
21
  const indexTypesFileName = path_1.default.join(dirPath, `index.${extension}`);
21
22
  if (!fs_1.default.existsSync(dirPath)) {
22
23
  fs_1.default.mkdirSync(dirPath, { recursive: true });
@@ -26,12 +27,14 @@ async function generateContractTypes(metadata, contract, outDir = '.', extension
26
27
  const txGen = new index_js_1.TxGen(contractMetadata, typesGen);
27
28
  const constructorTxGen = new index_js_1.ConstructorTxGen(contractMetadata, typesGen);
28
29
  const constructorQueryGen = new index_js_1.ConstructorQueryGen(contractMetadata, typesGen);
29
- const indexGen = new index_js_1.IndexGen(contractMetadata);
30
+ const eventsGen = new index_js_1.EventsGen(contractMetadata, typesGen);
31
+ const indexGen = new index_js_1.IndexGen(contractMetadata, typesGen);
30
32
  fs_1.default.writeFileSync(typesFileName, await typesGen.generate(useSubPaths));
31
33
  fs_1.default.writeFileSync(queryTypesFileName, await queryGen.generate(useSubPaths));
32
34
  fs_1.default.writeFileSync(txTypesFileName, await txGen.generate(useSubPaths));
33
35
  fs_1.default.writeFileSync(constructorQueryTypesFileName, await constructorQueryGen.generate(useSubPaths));
34
36
  fs_1.default.writeFileSync(constructorTxTypesFileName, await constructorTxGen.generate(useSubPaths));
37
+ fs_1.default.writeFileSync(eventsTypesFile, await eventsGen.generate(useSubPaths));
35
38
  fs_1.default.writeFileSync(indexTypesFileName, await indexGen.generate(useSubPaths));
36
39
  }
37
40
  exports.generateContractTypes = generateContractTypes;
@@ -0,0 +1,8 @@
1
+ // Generated by dedot cli
2
+
3
+ import { GenericSubstrateApi } from '@dedot/types';
4
+ {{{ importTypes }}}
5
+
6
+ export interface ContractEvents<ChainApi extends GenericSubstrateApi> extends GenericContractEvents<ChainApi> {
7
+ {{{ eventsOut }}}
8
+ }
@@ -5,10 +5,17 @@ import { ContractQuery } from './query';
5
5
  import { ContractTx } from './tx';
6
6
  import { ConstructorQuery } from './constructor-query';
7
7
  import { ConstructorTx } from './constructor-tx';
8
+ import { ContractEvents } from './events'
8
9
 
9
- export interface {{{contractName}}}<ChainApi extends VersionedGenericSubstrateApi = SubstrateApi> extends GenericContractApi<ChainApi> {
10
- query: ContractQuery<ChainApi[RpcVersion]>;
11
- tx: ContractTx<ChainApi[RpcVersion]>;
12
- constructorQuery: ConstructorQuery<ChainApi[RpcVersion]>;
13
- constructorTx: ConstructorTx<ChainApi[RpcVersion]>;
10
+ export interface {{{contractName}}}<Rv extends RpcVersion = RpcV2, ChainApi extends VersionedGenericSubstrateApi = SubstrateApi> extends GenericContractApi<Rv, ChainApi> {
11
+ query: ContractQuery<ChainApi[Rv]>;
12
+ tx: ContractTx<ChainApi[Rv]>;
13
+ constructorQuery: ConstructorQuery<ChainApi[Rv]>;
14
+ constructorTx: ConstructorTx<ChainApi[Rv]>;
15
+ events: ContractEvents<ChainApi[Rv]>;
16
+
17
+ types: {
18
+ LangError: {{{langErrorName}}};
19
+ ChainApi: ChainApi[Rv];
20
+ };
14
21
  }
package/cjs/utils.js CHANGED
@@ -36,7 +36,7 @@ exports.WRAPPER_TYPE_REGEX = /^(\w+)<(.*)>$/;
36
36
  exports.TUPLE_TYPE_REGEX = /^\[(.*)]$/;
37
37
  const commentBlock = (...docs) => {
38
38
  const flatLines = docs.flat();
39
- if (flatLines.length === 0 || !flatLines.find((o) => !!o)) {
39
+ if (flatLines.length === 0 || !flatLines.some((o) => !!o)) {
40
40
  return '';
41
41
  }
42
42
  else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dedot/codegen",
3
- "version": "0.0.1-next.cfee875e.21+cfee875",
3
+ "version": "0.0.1-next.d731b849.13+d731b84",
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,22 +18,22 @@
18
18
  "copy": "cp -R ./src/chaintypes/templates ./dist/chaintypes && cp -R ./src/chaintypes/templates ./dist/cjs/chaintypes && cp -R ./src/typink/templates ./dist/typink && cp -R ./src/typink/templates ./dist/cjs/typink"
19
19
  },
20
20
  "dependencies": {
21
- "@dedot/api": "0.0.1-next.cfee875e.21+cfee875",
22
- "@dedot/codecs": "0.0.1-next.cfee875e.21+cfee875",
23
- "@dedot/providers": "0.0.1-next.cfee875e.21+cfee875",
24
- "@dedot/runtime-specs": "0.0.1-next.cfee875e.21+cfee875",
25
- "@dedot/shape": "0.0.1-next.cfee875e.21+cfee875",
26
- "@dedot/types": "0.0.1-next.cfee875e.21+cfee875",
27
- "@dedot/utils": "0.0.1-next.cfee875e.21+cfee875",
28
- "handlebars": "^4.7.7",
29
- "prettier": "^3.2.5"
21
+ "@dedot/api": "0.0.1-next.d731b849.13+d731b84",
22
+ "@dedot/codecs": "0.0.1-next.d731b849.13+d731b84",
23
+ "@dedot/providers": "0.0.1-next.d731b849.13+d731b84",
24
+ "@dedot/runtime-specs": "0.0.1-next.d731b849.13+d731b84",
25
+ "@dedot/shape": "0.0.1-next.d731b849.13+d731b84",
26
+ "@dedot/types": "0.0.1-next.d731b849.13+d731b84",
27
+ "@dedot/utils": "0.0.1-next.d731b849.13+d731b84",
28
+ "handlebars": "^4.7.8",
29
+ "prettier": "^3.3.3"
30
30
  },
31
31
  "publishConfig": {
32
32
  "access": "public",
33
33
  "directory": "dist"
34
34
  },
35
35
  "license": "Apache-2.0",
36
- "gitHead": "cfee875eafba07e0fbb8a72556ca549a62ddceff",
36
+ "gitHead": "d731b849f66c92ca6fa69894e45792c49381d407",
37
37
  "module": "./index.js",
38
38
  "types": "./index.d.ts",
39
39
  "exports": {
@@ -16,7 +16,7 @@ export declare abstract class BaseTypesGen {
16
16
  typeImports: TypeImports;
17
17
  skipTypes: string[];
18
18
  protected constructor(types: PortableType[]);
19
- abstract shouldGenerateTypeIn(id: TypeId): boolean;
19
+ shouldGenerateTypeIn(_id: TypeId): boolean;
20
20
  typeCache: Record<string, string>;
21
21
  clearCache(): void;
22
22
  includeTypes(): Record<TypeId, NamedType>;
@@ -17,6 +17,9 @@ export class BaseTypesGen {
17
17
  this.typeImports = new TypeImports();
18
18
  this.skipTypes = [];
19
19
  }
20
+ shouldGenerateTypeIn(_id) {
21
+ return false;
22
+ }
20
23
  typeCache = {};
21
24
  clearCache() {
22
25
  this.typeCache = {};
@@ -119,9 +122,9 @@ export class BaseTypesGen {
119
122
  if (!def) {
120
123
  throw new Error(`Type def not found ${JSON.stringify(def)}`);
121
124
  }
122
- const { type, path, docs } = def;
123
- const { tag, value } = type;
124
- switch (tag) {
125
+ const { typeDef, path, docs } = def;
126
+ const { type, value } = typeDef;
127
+ switch (type) {
125
128
  case 'Primitive':
126
129
  const $codec = findKnownCodec(value.kind);
127
130
  if ($codec.nativeType) {
@@ -195,11 +198,11 @@ export class BaseTypesGen {
195
198
  const { tagKey, valueKey } = this.getEnumOptions(typeId);
196
199
  return membersType
197
200
  .map(([keyName, valueType, docs]) => ({
198
- tag: `${tagKey}: '${keyName}'`,
201
+ type: `${tagKey}: '${keyName}'`,
199
202
  value: valueType ? `, ${valueKey}${this.#isOptionalType(valueType) ? '?' : ''}: ${valueType} ` : '',
200
203
  docs,
201
204
  }))
202
- .map(({ tag, value, docs }) => `${commentBlock(docs)}{ ${tag}${value} }`)
205
+ .map(({ type, value, docs }) => `${commentBlock(docs)}{ ${type}${value} }`)
203
206
  .join(' | ');
204
207
  }
205
208
  }
@@ -221,9 +224,9 @@ export class BaseTypesGen {
221
224
  return this.generateType(value.typeParam, nestedLevel + 1, typeOut);
222
225
  case 'Sequence':
223
226
  case 'SizedVec': {
224
- const fixedSize = tag === 'SizedVec' ? `${value.len}` : null;
225
- const $innerType = this.types[value.typeParam].type;
226
- if ($innerType.tag === 'Primitive' && $innerType.value.kind === 'u8') {
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') {
227
230
  return fixedSize ? `FixedBytes<${fixedSize}>` : typeOut ? 'Bytes' : 'BytesLike';
228
231
  }
229
232
  else {
@@ -232,7 +235,7 @@ export class BaseTypesGen {
232
235
  }
233
236
  }
234
237
  default:
235
- throw new Error(`Invalid type! ${tag}`);
238
+ throw new Error(`Invalid type! ${type}`);
236
239
  }
237
240
  }
238
241
  generateObjectType(fields, nestedLevel = 0, typeOut = false) {
@@ -282,31 +285,32 @@ export class BaseTypesGen {
282
285
  const typeB = this.types[idB];
283
286
  if (typeA.path.join('::') !== typeB.path.join('::'))
284
287
  return false;
285
- const { type: defA, params: paramsA } = typeA;
286
- const { type: defB, params: paramsB } = typeB;
288
+ const { typeDef: defA, params: paramsA } = typeA;
289
+ const { typeDef: defB, params: paramsB } = typeB;
287
290
  if (!this.#eqlArray(paramsA, paramsB, (valA, valB) => this.#eqlTypeParam(valA, valB))) {
288
291
  return false;
289
292
  }
290
- if (defA.tag !== defB.tag)
293
+ if (defA.type !== defB.type)
291
294
  return false;
292
- if (defA.tag === 'BitSequence')
295
+ if (defA.type === 'BitSequence')
293
296
  return true;
294
- if (defA.tag === 'Primitive' && defB.tag === 'Primitive') {
297
+ if (defA.type === 'Primitive' && defB.type === 'Primitive') {
295
298
  return defA.value.kind === defB.value.kind;
296
299
  }
297
- if ((defA.tag === 'Compact' && defB.tag === 'Compact') || (defA.tag === 'Sequence' && defB.tag === 'Sequence')) {
300
+ if ((defA.type === 'Compact' && defB.type === 'Compact') ||
301
+ (defA.type === 'Sequence' && defB.type === 'Sequence')) {
298
302
  return this.typeEql(defA.value.typeParam, defB.value.typeParam, lvl + 1);
299
303
  }
300
- if (defA.tag === 'SizedVec' && defB.tag === 'SizedVec') {
304
+ if (defA.type === 'SizedVec' && defB.type === 'SizedVec') {
301
305
  return defA.value.len === defB.value.len && this.typeEql(defA.value.typeParam, defB.value.typeParam, lvl + 1);
302
306
  }
303
- if (defA.tag === 'Tuple' && defB.tag === 'Tuple') {
307
+ if (defA.type === 'Tuple' && defB.type === 'Tuple') {
304
308
  return this.#eqlArray(defA.value.fields, defB.value.fields, (val1, val2) => this.typeEql(val1, val2, lvl + 1));
305
309
  }
306
- if (defA.tag === 'Struct' && defB.tag === 'Struct') {
310
+ if (defA.type === 'Struct' && defB.type === 'Struct') {
307
311
  return this.#eqlFields(defA.value.fields, defB.value.fields, lvl);
308
312
  }
309
- if (defA.tag === 'Enum' && defB.tag === 'Enum') {
313
+ if (defA.type === 'Enum' && defB.type === 'Enum') {
310
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));
311
315
  }
312
316
  return false;
@@ -332,8 +336,8 @@ export class BaseTypesGen {
332
336
  if (diffType.path.length > 0) {
333
337
  return stringPascalCase(diffType.path.at(-1));
334
338
  }
335
- else if (diffType.type.tag === 'Primitive') {
336
- return stringPascalCase(diffType.type.value.kind);
339
+ else if (diffType.typeDef.type === 'Primitive') {
340
+ return stringPascalCase(diffType.typeDef.value.kind);
337
341
  }
338
342
  }
339
343
  // Last resort!
@@ -369,6 +373,6 @@ export class BaseTypesGen {
369
373
  this.typeImports.addOutType(typeName);
370
374
  }
371
375
  getEnumOptions(_typeId) {
372
- return { tagKey: 'tag', valueKey: 'value' };
376
+ return { tagKey: 'type', valueKey: 'value' };
373
377
  }
374
378
  }
@@ -4,7 +4,7 @@ export class ConstructorQueryGen extends QueryGen {
4
4
  generate(useSubPaths = false) {
5
5
  this.typesGen.clearCache();
6
6
  this.typesGen.typeImports.addKnownType('GenericSubstrateApi');
7
- this.typesGen.typeImports.addContractType('GenericConstructorQuery', 'GenericConstructorQueryCall', 'ConstructorCallOptions', 'ContractInstantiateResult');
7
+ this.typesGen.typeImports.addContractType('GenericConstructorQuery', 'GenericConstructorQueryCall', 'GenericConstructorCallResult', 'ConstructorCallOptions', 'ContractInstantiateResult');
8
8
  const { constructors } = this.contractMetadata.spec;
9
9
  const constructorsOut = this.doGenerate(constructors, 'ConstructorCallOptions');
10
10
  const importTypes = this.typesGen.typeImports.toImports({ useSubPaths });
@@ -12,9 +12,12 @@ export class ConstructorQueryGen extends QueryGen {
12
12
  return beautifySourceCode(template({ importTypes, constructorsOut }));
13
13
  }
14
14
  generateMethodDef(def) {
15
- const { args } = def;
15
+ const { args, returnType } = def;
16
16
  args.forEach(({ type: { type } }) => this.importType(type));
17
17
  const paramsOut = this.generateParamsOut(args);
18
- return `GenericConstructorQueryCall<ChainApi, (${paramsOut && `${paramsOut},`} options: ConstructorCallOptions) => Promise<ContractInstantiateResult<ChainApi>>>`;
18
+ const typeOutRaw = this.typesGen.generateType(returnType.type, 0, true);
19
+ // Unwrap langError result
20
+ const typeOut = typeOutRaw.match(/^(\w+)<(.*), (.*)>$/).at(2);
21
+ return `GenericConstructorQueryCall<ChainApi, (${paramsOut && `${paramsOut},`} options: ConstructorCallOptions) => Promise<GenericConstructorCallResult<${typeOut}, ContractInstantiateResult<ChainApi>>>>`;
19
22
  }
20
23
  }
@@ -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
+ }
@@ -1,6 +1,8 @@
1
1
  import { ContractMetadata } from '@dedot/contracts';
2
+ import { TypesGen } from './TypesGen.js';
2
3
  export declare class IndexGen {
3
4
  contractMetadata: ContractMetadata;
4
- constructor(contractMetadata: ContractMetadata);
5
+ typesGen: TypesGen;
6
+ constructor(contractMetadata: ContractMetadata, typesGen: TypesGen);
5
7
  generate(useSubPaths?: boolean): Promise<string>;
6
8
  }
@@ -4,17 +4,22 @@ import { beautifySourceCode, compileTemplate } from '../../utils.js';
4
4
  const SUFFIX = 'contract_api';
5
5
  export class IndexGen {
6
6
  contractMetadata;
7
- constructor(contractMetadata) {
7
+ typesGen;
8
+ constructor(contractMetadata, typesGen) {
8
9
  this.contractMetadata = contractMetadata;
10
+ this.typesGen = typesGen;
9
11
  }
10
12
  generate(useSubPaths = false) {
11
13
  const contractName = stringPascalCase(`${this.contractMetadata.contract.name}_${SUFFIX}`);
14
+ const langErrorId = this.contractMetadata.spec.lang_error.type;
15
+ const langErrorName = this.typesGen.cleanPath(this.contractMetadata.types[langErrorId].type.path);
12
16
  const typeImports = new TypeImports();
13
- typeImports.addKnownType('VersionedGenericSubstrateApi', 'RpcVersion');
17
+ typeImports.addKnownType('VersionedGenericSubstrateApi', 'RpcVersion', 'RpcV2');
14
18
  typeImports.addContractType('GenericContractApi');
15
19
  typeImports.addChainType('SubstrateApi');
20
+ typeImports.addPortableType(langErrorName);
16
21
  const importTypes = typeImports.toImports({ useSubPaths });
17
22
  const template = compileTemplate('typink/templates/index.hbs');
18
- return beautifySourceCode(template({ contractName, importTypes }));
23
+ return beautifySourceCode(template({ contractName, langErrorName, importTypes }));
19
24
  }
20
25
  }
@@ -1,12 +1,12 @@
1
- import { ContractMetadata, Message, ContractMessageArg } from '@dedot/contracts';
1
+ import { ContractMetadata, ContractMessage, ContractMessageArg } from '@dedot/contracts';
2
2
  import { TypesGen } from './TypesGen.js';
3
3
  export declare class QueryGen {
4
4
  contractMetadata: ContractMetadata;
5
5
  typesGen: TypesGen;
6
6
  constructor(contractMetadata: ContractMetadata, typeGen: TypesGen);
7
7
  generate(useSubPaths?: boolean): Promise<string>;
8
- doGenerate(messages: Message[], optionsTypeName?: string): string;
9
- generateMethodDef(def: Message): string;
8
+ doGenerate(messages: ContractMessage[], optionsTypeName?: string): string;
9
+ generateMethodDef(def: ContractMessage): string;
10
10
  generateParamsOut(args: ContractMessageArg[]): string;
11
11
  importType(typeId: number): any;
12
12
  }
@@ -32,7 +32,9 @@ export class QueryGen {
32
32
  this.importType(returnType.type);
33
33
  args.forEach(({ type: { type } }) => this.importType(type));
34
34
  const paramsOut = this.generateParamsOut(args);
35
- const typeOut = this.typesGen.generateType(returnType.type, 0, true);
35
+ const typeOutRaw = this.typesGen.generateType(returnType.type, 0, true);
36
+ // Unwrap langError result
37
+ const typeOut = typeOutRaw.match(/^(\w+)<(.*), (.*)>$/).at(2);
36
38
  return `GenericContractQueryCall<ChainApi, (${paramsOut && `${paramsOut},`} options: ContractCallOptions) => Promise<GenericContractCallResult<${typeOut}, ContractCallResult<ChainApi>>>>`;
37
39
  }
38
40
  generateParamsOut(args) {
@@ -41,14 +43,14 @@ export class QueryGen {
41
43
  .join(', ');
42
44
  }
43
45
  importType(typeId) {
44
- const type = this.contractMetadata.types[typeId];
45
- const def = normalizeContractTypeDef(this.contractMetadata.types[typeId].type.def);
46
- if (this.typesGen.includedTypes[type.id]) {
47
- this.typesGen.addTypeImport(this.typesGen.includedTypes[type.id].name);
46
+ const contractType = this.contractMetadata.types[typeId];
47
+ const typeDef = normalizeContractTypeDef(this.contractMetadata.types[typeId].type.def);
48
+ if (this.typesGen.includedTypes[contractType.id]) {
49
+ this.typesGen.addTypeImport(this.typesGen.includedTypes[contractType.id].name);
48
50
  return;
49
51
  }
50
- const { tag, value } = def;
51
- switch (tag) {
52
+ const { type, value } = typeDef;
53
+ switch (type) {
52
54
  case 'Compact':
53
55
  case 'Primitive':
54
56
  case 'BitSequence':
@@ -1,6 +1,6 @@
1
- import { Message } from '@dedot/contracts';
1
+ import { ContractMessage } from '@dedot/contracts';
2
2
  import { QueryGen } from './QueryGen.js';
3
3
  export declare class TxGen extends QueryGen {
4
4
  generate(useSubPaths?: boolean): Promise<string>;
5
- generateMethodDef(def: Message): string;
5
+ generateMethodDef(def: ContractMessage): string;
6
6
  }
@@ -4,5 +4,4 @@ export declare class TypesGen extends BaseTypesGen {
4
4
  contractMetadata: ContractMetadata;
5
5
  constructor(contractMetadata: ContractMetadata);
6
6
  generate(useSubPaths?: boolean): Promise<string>;
7
- shouldGenerateTypeIn(id: number): boolean;
8
7
  }
@@ -14,18 +14,11 @@ export class TypesGen extends BaseTypesGen {
14
14
  let defTypeOut = '';
15
15
  Object.values(this.includedTypes)
16
16
  .filter(({ skip, knownType }) => !(skip || knownType))
17
- .forEach(({ name, nameOut, id }) => {
17
+ .forEach(({ nameOut, id }) => {
18
18
  defTypeOut += `export type ${nameOut} = ${this.generateType(id, 0, true)};\n\n`;
19
- if (this.shouldGenerateTypeIn(id)) {
20
- defTypeOut += `export type ${name} = ${this.generateType(id)};\n\n`;
21
- }
22
19
  });
23
20
  const importTypes = this.typeImports.toImports({ excludeModules: ['./types'], useSubPaths });
24
21
  const template = compileTemplate('typink/templates/types.hbs');
25
22
  return beautifySourceCode(template({ importTypes, defTypeOut }));
26
23
  }
27
- shouldGenerateTypeIn(id) {
28
- const { messages } = this.contractMetadata.spec;
29
- return messages.some((message) => message.returnType.type === id);
30
- }
31
24
  }
@@ -4,3 +4,4 @@ export * from './TypesGen.js';
4
4
  export * from './TxGen.js';
5
5
  export * from './ConstructorTxGen.js';
6
6
  export * from './ConstructorQueryGen.js';
7
+ export * from './EventsGen.js';
@@ -4,3 +4,4 @@ export * from './TypesGen.js';
4
4
  export * from './TxGen.js';
5
5
  export * from './ConstructorTxGen.js';
6
6
  export * from './ConstructorQueryGen.js';
7
+ export * from './EventsGen.js';
package/typink/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { parseRawMetadata } from '@dedot/contracts';
2
2
  import fs from 'fs';
3
3
  import path from 'path';
4
- import { IndexGen, QueryGen, TxGen, TypesGen, ConstructorTxGen, ConstructorQueryGen } from './generator/index.js';
4
+ import { IndexGen, QueryGen, EventsGen, TxGen, TypesGen, ConstructorTxGen, ConstructorQueryGen, } from './generator/index.js';
5
5
  export async function generateContractTypes(metadata, contract, outDir = '.', extension = 'd.ts', useSubPaths = false) {
6
6
  let contractMetadata = typeof metadata === 'string' ? parseRawMetadata(metadata) : metadata;
7
7
  contract = contract || contractMetadata.contract.name;
@@ -11,6 +11,7 @@ export async function generateContractTypes(metadata, contract, outDir = '.', ex
11
11
  const txTypesFileName = path.join(dirPath, `tx.${extension}`);
12
12
  const constructorTxTypesFileName = path.join(dirPath, `constructor-tx.${extension}`);
13
13
  const constructorQueryTypesFileName = path.join(dirPath, `constructor-query.${extension}`);
14
+ const eventsTypesFile = path.join(dirPath, `events.${extension}`);
14
15
  const indexTypesFileName = path.join(dirPath, `index.${extension}`);
15
16
  if (!fs.existsSync(dirPath)) {
16
17
  fs.mkdirSync(dirPath, { recursive: true });
@@ -20,11 +21,13 @@ export async function generateContractTypes(metadata, contract, outDir = '.', ex
20
21
  const txGen = new TxGen(contractMetadata, typesGen);
21
22
  const constructorTxGen = new ConstructorTxGen(contractMetadata, typesGen);
22
23
  const constructorQueryGen = new ConstructorQueryGen(contractMetadata, typesGen);
23
- const indexGen = new IndexGen(contractMetadata);
24
+ const eventsGen = new EventsGen(contractMetadata, typesGen);
25
+ const indexGen = new IndexGen(contractMetadata, typesGen);
24
26
  fs.writeFileSync(typesFileName, await typesGen.generate(useSubPaths));
25
27
  fs.writeFileSync(queryTypesFileName, await queryGen.generate(useSubPaths));
26
28
  fs.writeFileSync(txTypesFileName, await txGen.generate(useSubPaths));
27
29
  fs.writeFileSync(constructorQueryTypesFileName, await constructorQueryGen.generate(useSubPaths));
28
30
  fs.writeFileSync(constructorTxTypesFileName, await constructorTxGen.generate(useSubPaths));
31
+ fs.writeFileSync(eventsTypesFile, await eventsGen.generate(useSubPaths));
29
32
  fs.writeFileSync(indexTypesFileName, await indexGen.generate(useSubPaths));
30
33
  }
@@ -0,0 +1,8 @@
1
+ // Generated by dedot cli
2
+
3
+ import { GenericSubstrateApi } from '@dedot/types';
4
+ {{{ importTypes }}}
5
+
6
+ export interface ContractEvents<ChainApi extends GenericSubstrateApi> extends GenericContractEvents<ChainApi> {
7
+ {{{ eventsOut }}}
8
+ }
@@ -5,10 +5,17 @@ import { ContractQuery } from './query';
5
5
  import { ContractTx } from './tx';
6
6
  import { ConstructorQuery } from './constructor-query';
7
7
  import { ConstructorTx } from './constructor-tx';
8
+ import { ContractEvents } from './events'
8
9
 
9
- export interface {{{contractName}}}<ChainApi extends VersionedGenericSubstrateApi = SubstrateApi> extends GenericContractApi<ChainApi> {
10
- query: ContractQuery<ChainApi[RpcVersion]>;
11
- tx: ContractTx<ChainApi[RpcVersion]>;
12
- constructorQuery: ConstructorQuery<ChainApi[RpcVersion]>;
13
- constructorTx: ConstructorTx<ChainApi[RpcVersion]>;
10
+ export interface {{{contractName}}}<Rv extends RpcVersion = RpcV2, ChainApi extends VersionedGenericSubstrateApi = SubstrateApi> extends GenericContractApi<Rv, ChainApi> {
11
+ query: ContractQuery<ChainApi[Rv]>;
12
+ tx: ContractTx<ChainApi[Rv]>;
13
+ constructorQuery: ConstructorQuery<ChainApi[Rv]>;
14
+ constructorTx: ConstructorTx<ChainApi[Rv]>;
15
+ events: ContractEvents<ChainApi[Rv]>;
16
+
17
+ types: {
18
+ LangError: {{{langErrorName}}};
19
+ ChainApi: ChainApi[Rv];
20
+ };
14
21
  }
package/utils.js CHANGED
@@ -7,7 +7,7 @@ export const WRAPPER_TYPE_REGEX = /^(\w+)<(.*)>$/;
7
7
  export const TUPLE_TYPE_REGEX = /^\[(.*)]$/;
8
8
  export const commentBlock = (...docs) => {
9
9
  const flatLines = docs.flat();
10
- if (flatLines.length === 0 || !flatLines.find((o) => !!o)) {
10
+ if (flatLines.length === 0 || !flatLines.some((o) => !!o)) {
11
11
  return '';
12
12
  }
13
13
  else {