@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.
Files changed (135) hide show
  1. package/{generator → chaintypes/generator}/ApiGen.d.ts +16 -16
  2. package/{generator → chaintypes/generator}/ConstsGen.d.ts +1 -1
  3. package/{generator → chaintypes/generator}/ConstsGen.js +5 -5
  4. package/{generator → chaintypes/generator}/ErrorsGen.d.ts +1 -1
  5. package/{generator → chaintypes/generator}/ErrorsGen.js +9 -9
  6. package/{generator → chaintypes/generator}/EventsGen.d.ts +1 -1
  7. package/{generator → chaintypes/generator}/EventsGen.js +9 -9
  8. package/{generator → chaintypes/generator}/IndexGen.d.ts +1 -1
  9. package/chaintypes/generator/IndexGen.js +17 -0
  10. package/{generator → chaintypes/generator}/JsonRpcGen.d.ts +3 -2
  11. package/{generator → chaintypes/generator}/JsonRpcGen.js +8 -8
  12. package/{generator → chaintypes/generator}/QueryGen.d.ts +1 -1
  13. package/{generator → chaintypes/generator}/QueryGen.js +15 -15
  14. package/{generator → chaintypes/generator}/RuntimeApisGen.d.ts +1 -1
  15. package/{generator → chaintypes/generator}/RuntimeApisGen.js +11 -11
  16. package/{generator → chaintypes/generator}/TxGen.d.ts +1 -1
  17. package/{generator → chaintypes/generator}/TxGen.js +16 -14
  18. package/chaintypes/generator/TypesGen.d.ts +11 -0
  19. package/chaintypes/generator/TypesGen.js +55 -0
  20. package/chaintypes/index.d.ts +3 -0
  21. package/chaintypes/index.js +49 -0
  22. package/chaintypes/templates/consts.hbs +7 -0
  23. package/chaintypes/templates/errors.hbs +7 -0
  24. package/chaintypes/templates/events.hbs +7 -0
  25. package/chaintypes/templates/index.hbs +27 -0
  26. package/chaintypes/templates/json-rpc.hbs +5 -0
  27. package/chaintypes/templates/query.hbs +7 -0
  28. package/chaintypes/templates/runtime.hbs +8 -0
  29. package/chaintypes/templates/tx.hbs +9 -0
  30. package/{templates → chaintypes/templates}/types.hbs +1 -1
  31. package/cjs/{generator → chaintypes/generator}/ConstsGen.js +5 -5
  32. package/cjs/{generator → chaintypes/generator}/ErrorsGen.js +9 -9
  33. package/cjs/{generator → chaintypes/generator}/EventsGen.js +9 -9
  34. package/cjs/chaintypes/generator/IndexGen.js +21 -0
  35. package/cjs/{generator → chaintypes/generator}/JsonRpcGen.js +10 -10
  36. package/cjs/{generator → chaintypes/generator}/QueryGen.js +15 -15
  37. package/cjs/{generator → chaintypes/generator}/RuntimeApisGen.js +14 -14
  38. package/cjs/{generator → chaintypes/generator}/TxGen.js +16 -14
  39. package/cjs/chaintypes/generator/TypesGen.js +59 -0
  40. package/cjs/chaintypes/index.js +77 -0
  41. package/cjs/chaintypes/templates/consts.hbs +7 -0
  42. package/cjs/chaintypes/templates/errors.hbs +7 -0
  43. package/cjs/chaintypes/templates/events.hbs +7 -0
  44. package/cjs/chaintypes/templates/index.hbs +27 -0
  45. package/cjs/chaintypes/templates/json-rpc.hbs +5 -0
  46. package/cjs/chaintypes/templates/query.hbs +7 -0
  47. package/cjs/chaintypes/templates/runtime.hbs +8 -0
  48. package/cjs/chaintypes/templates/tx.hbs +9 -0
  49. package/cjs/{templates → chaintypes/templates}/types.hbs +1 -1
  50. package/cjs/index.js +4 -62
  51. package/cjs/{generator/TypesGen.js → shared/BaseTypesGen.js} +111 -159
  52. package/cjs/{generator → shared}/TypeImports.js +27 -9
  53. package/cjs/shared/index.js +19 -0
  54. package/cjs/{generator → shared}/known-codecs.js +23 -4
  55. package/cjs/typink/generator/ConstructorQueryGen.js +24 -0
  56. package/cjs/typink/generator/ConstructorTxGen.js +24 -0
  57. package/cjs/typink/generator/EventsGen.js +35 -0
  58. package/cjs/typink/generator/IndexGen.js +24 -0
  59. package/cjs/typink/generator/QueryGen.js +72 -0
  60. package/cjs/typink/generator/TxGen.js +25 -0
  61. package/cjs/typink/generator/TypesGen.js +28 -0
  62. package/cjs/typink/generator/index.js +23 -0
  63. package/cjs/typink/index.js +40 -0
  64. package/cjs/typink/templates/constructor-query.hbs +7 -0
  65. package/cjs/typink/templates/constructor-tx.hbs +7 -0
  66. package/cjs/typink/templates/events.hbs +8 -0
  67. package/cjs/typink/templates/index.hbs +16 -0
  68. package/cjs/typink/templates/query.hbs +7 -0
  69. package/cjs/typink/templates/tx.hbs +7 -0
  70. package/cjs/typink/templates/types.hbs +5 -0
  71. package/cjs/{generator/utils.js → utils.js} +4 -4
  72. package/index.d.ts +2 -3
  73. package/index.js +2 -48
  74. package/package.json +15 -17
  75. package/{generator/TypesGen.d.ts → shared/BaseTypesGen.d.ts} +12 -11
  76. package/{generator/TypesGen.js → shared/BaseTypesGen.js} +108 -156
  77. package/{generator → shared}/TypeImports.d.ts +12 -3
  78. package/{generator → shared}/TypeImports.js +27 -9
  79. package/shared/index.d.ts +3 -0
  80. package/shared/index.js +3 -0
  81. package/{generator → shared}/known-codecs.d.ts +1 -1
  82. package/{generator → shared}/known-codecs.js +21 -2
  83. package/typink/generator/ConstructorQueryGen.d.ts +6 -0
  84. package/typink/generator/ConstructorQueryGen.js +20 -0
  85. package/typink/generator/ConstructorTxGen.d.ts +6 -0
  86. package/typink/generator/ConstructorTxGen.js +20 -0
  87. package/typink/generator/EventsGen.d.ts +7 -0
  88. package/typink/generator/EventsGen.js +31 -0
  89. package/typink/generator/IndexGen.d.ts +6 -0
  90. package/typink/generator/IndexGen.js +20 -0
  91. package/typink/generator/QueryGen.d.ts +12 -0
  92. package/typink/generator/QueryGen.js +68 -0
  93. package/typink/generator/TxGen.d.ts +6 -0
  94. package/typink/generator/TxGen.js +21 -0
  95. package/typink/generator/TypesGen.d.ts +7 -0
  96. package/typink/generator/TypesGen.js +24 -0
  97. package/typink/generator/index.d.ts +7 -0
  98. package/typink/generator/index.js +7 -0
  99. package/typink/index.d.ts +2 -0
  100. package/typink/index.js +33 -0
  101. package/typink/templates/constructor-query.hbs +7 -0
  102. package/typink/templates/constructor-tx.hbs +7 -0
  103. package/typink/templates/events.hbs +8 -0
  104. package/typink/templates/index.hbs +16 -0
  105. package/typink/templates/query.hbs +7 -0
  106. package/typink/templates/tx.hbs +7 -0
  107. package/typink/templates/types.hbs +5 -0
  108. package/{generator/utils.d.ts → utils.d.ts} +1 -1
  109. package/{generator/utils.js → utils.js} +4 -4
  110. package/cjs/generator/IndexGen.js +0 -17
  111. package/cjs/templates/consts.hbs +0 -7
  112. package/cjs/templates/errors.hbs +0 -7
  113. package/cjs/templates/events.hbs +0 -7
  114. package/cjs/templates/index.hbs +0 -22
  115. package/cjs/templates/json-rpc.hbs +0 -5
  116. package/cjs/templates/query.hbs +0 -7
  117. package/cjs/templates/runtime.hbs +0 -8
  118. package/cjs/templates/tx.hbs +0 -9
  119. package/generator/IndexGen.js +0 -13
  120. package/templates/consts.hbs +0 -7
  121. package/templates/errors.hbs +0 -7
  122. package/templates/events.hbs +0 -7
  123. package/templates/index.hbs +0 -22
  124. package/templates/json-rpc.hbs +0 -5
  125. package/templates/query.hbs +0 -7
  126. package/templates/runtime.hbs +0 -8
  127. package/templates/tx.hbs +0 -9
  128. /package/{generator → chaintypes/generator}/ApiGen.js +0 -0
  129. /package/{generator → chaintypes/generator}/index.d.ts +0 -0
  130. /package/{generator → chaintypes/generator}/index.js +0 -0
  131. /package/cjs/{generator → chaintypes/generator}/ApiGen.js +0 -0
  132. /package/cjs/{generator → chaintypes/generator}/index.js +0 -0
  133. /package/cjs/{generator/dirname.js → dirname.js} +0 -0
  134. /package/{generator/dirname.d.ts → dirname.d.ts} +0 -0
  135. /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, isKnownCodecType } from './known-codecs.js';
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
- const WRAPPER_TYPE_REGEX = /^(\w+)(<.*>)$/g;
29
- export class TypesGen {
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
- constructor(metadata) {
38
- this.metadata = metadata;
39
- this.registry = new PortableRegistry(this.metadata);
40
- this.includedTypes = 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
- generate() {
44
- this.clearCache();
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.metadata.types[typeId];
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 { type, path, docs } = def;
98
- const { tag, value } = type;
99
- switch (tag) {
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.registry.getEnumOptions(typeId);
198
+ const { tagKey, valueKey } = this.getEnumOptions(typeId);
171
199
  return membersType
172
200
  .map(([keyName, valueType, docs]) => ({
173
- tag: `${tagKey}: '${keyName}'`,
201
+ type: `${tagKey}: '${keyName}'`,
174
202
  value: valueType ? `, ${valueKey}${this.#isOptionalType(valueType) ? '?' : ''}: ${valueType} ` : '',
175
203
  docs,
176
204
  }))
177
- .map(({ tag, value, docs }) => `${commentBlock(docs)}{ ${tag}${value} }`)
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 = tag === 'SizedVec' ? `${value.len}` : null;
200
- const $innerType = this.metadata.types[value.typeParam].type;
201
- 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') {
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! ${tag}`);
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 { types } = this.metadata;
335
- const typeA = types[idA];
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 { type: defA, params: paramsA } = typeA;
340
- const { type: defB, params: paramsB } = typeB;
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.tag !== defB.tag)
293
+ if (defA.type !== defB.type)
345
294
  return false;
346
- if (defA.tag === 'BitSequence')
295
+ if (defA.type === 'BitSequence')
347
296
  return true;
348
- if (defA.tag === 'Primitive' && defB.tag === 'Primitive') {
297
+ if (defA.type === 'Primitive' && defB.type === 'Primitive') {
349
298
  return defA.value.kind === defB.value.kind;
350
299
  }
351
- 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')) {
352
302
  return this.typeEql(defA.value.typeParam, defB.value.typeParam, lvl + 1);
353
303
  }
354
- if (defA.tag === 'SizedVec' && defB.tag === 'SizedVec') {
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.tag === 'Tuple' && defB.tag === 'Tuple') {
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.tag === 'Struct' && defB.tag === 'Struct') {
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.tag === 'Enum' && defB.tag === 'Enum') {
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
- #extractDupTypeSuffix(dupTypeId, originalTypeId, dupCount) {
380
- const { types } = this.metadata;
381
- const originalTypeParams = types[originalTypeId].params;
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.tag === 'Primitive') {
391
- return stringPascalCase(diffType.type.value.kind);
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
- specTypes: Set<string>;
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(...excludeModules: string[]): string;
16
+ toImports(config?: ImportConfig): string;
11
17
  addPortableType(...types: string[]): void;
12
18
  addCodecType(...types: string[]): void;
13
19
  addKnownType(...types: string[]): void;
14
- addSpecType(...types: string[]): void;
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
- specTypes;
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.specTypes = new Set();
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.specTypes.clear();
28
+ this.knownJsonRpcTypes.clear();
23
29
  this.outTypes.clear();
30
+ this.contractTypes.clear();
31
+ this.chainTypes.clear();
24
32
  }
25
- toImports(...excludeModules) {
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, '@dedot/types'],
29
- [this.specTypes, '@dedot/specs'],
30
- [this.codecTypes, '@dedot/codecs'],
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
- addSpecType(...types) {
55
- types.forEach((one) => this.specTypes.add(one));
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
  }
@@ -0,0 +1,3 @@
1
+ export * from './BaseTypesGen.js';
2
+ export * from './known-codecs.js';
3
+ export * from './TypeImports.js';
@@ -0,0 +1,3 @@
1
+ export * from './BaseTypesGen.js';
2
+ export * from './known-codecs.js';
3
+ export * from './TypeImports.js';
@@ -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 isKnownCodecType(path: string | string[]): boolean;
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 isKnownCodecType(path) {
119
+ export function checkKnownCodecType(path) {
118
120
  const joinedPath = Array.isArray(path) ? path.join('::') : path;
119
- return KNOWN_PATHS.some((one) => joinedPath.match(one));
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,6 @@
1
+ import { ContractMetadata } from '@dedot/contracts';
2
+ export declare class IndexGen {
3
+ contractMetadata: ContractMetadata;
4
+ constructor(contractMetadata: ContractMetadata);
5
+ generate(useSubPaths?: boolean): Promise<string>;
6
+ }
@@ -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
+ }