@dedot/codegen 0.15.2 → 0.16.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.
@@ -248,5 +248,5 @@ export declare abstract class ApiGen {
248
248
  }>;
249
249
  };
250
250
  };
251
- get registry(): import("@dedot/codecs").PortableRegistry;
251
+ get registry(): import("@dedot/codecs").PortableRegistry<import("@dedot/types").GenericSubstrateApi<import("@dedot/types").RpcVersion>>;
252
252
  }
@@ -1,7 +1,9 @@
1
1
  import { SubstrateRuntimeVersion } from '@dedot/api';
2
+ import { TypesGen } from './TypesGen.js';
2
3
  export declare class IndexGen {
3
4
  readonly interfaceName: string;
4
5
  readonly runtimeVersion: SubstrateRuntimeVersion;
5
- constructor(interfaceName: string, runtimeVersion: SubstrateRuntimeVersion);
6
+ readonly typesGen: TypesGen;
7
+ constructor(interfaceName: string, runtimeVersion: SubstrateRuntimeVersion, typesGen: TypesGen);
6
8
  generate(useSubPaths?: boolean): Promise<string>;
7
9
  }
@@ -1,22 +1,47 @@
1
- import { TypeImports } from '../../shared/index.js';
2
1
  import { beautifySourceCode, commentBlock, compileTemplate } from '../../utils.js';
3
2
  export class IndexGen {
4
3
  interfaceName;
5
4
  runtimeVersion;
6
- constructor(interfaceName, runtimeVersion) {
5
+ typesGen;
6
+ constructor(interfaceName, runtimeVersion, typesGen) {
7
7
  this.interfaceName = interfaceName;
8
8
  this.runtimeVersion = runtimeVersion;
9
+ this.typesGen = typesGen;
9
10
  }
10
11
  async generate(useSubPaths = false) {
11
12
  const interfaceName = this.interfaceName;
12
- const typeImports = new TypeImports();
13
- typeImports.addKnownType('GenericSubstrateApi', 'RpcLegacy', 'RpcV2', 'RpcVersion');
14
- const importTypes = typeImports.toImports({ useSubPaths });
13
+ // Clear cache and setup type imports
14
+ this.typesGen.clearCache();
15
+ this.typesGen.typeImports.addKnownType('GenericSubstrateApi', 'GenericChainKnownTypes', 'RpcLegacy', 'RpcV2', 'RpcVersion');
16
+ // Extract type IDs from metadata.extrinsic
17
+ const { callTypeId, addressTypeId, signatureTypeId, signedExtensions } = this.typesGen.metadata.extrinsic;
18
+ // Generate proper TypeScript types using typeOut format (0, true)
19
+ const runtimeCallType = this.typesGen.generateType(callTypeId, 1, true);
20
+ const addressType = this.typesGen.generateType(addressTypeId, 1, true);
21
+ const signatureType = this.typesGen.generateType(signatureTypeId, 1, true);
22
+ // Generate Extra type from signed extensions
23
+ let extraType = 'any[]'; // Default fallback
24
+ if (signedExtensions && signedExtensions.length > 0) {
25
+ const signedExtensionTypes = signedExtensions.map(({ typeId }) => this.typesGen.generateType(typeId, 1, true));
26
+ extraType = `[${signedExtensionTypes.join(', ')}]`;
27
+ }
28
+ // Add generated types to imports
29
+ const generatedTypes = [runtimeCallType, addressType, signatureType, extraType];
30
+ this.typesGen.addTypeImport(generatedTypes);
31
+ const importTypes = this.typesGen.typeImports.toImports({ useSubPaths });
15
32
  const interfaceDocs = commentBlock([
16
33
  `@name: ${interfaceName}`, // prettier-end-here
17
34
  `@specVersion: ${this.runtimeVersion.specVersion}`,
18
35
  ]);
19
36
  const template = compileTemplate('chaintypes/templates/index.hbs');
20
- return beautifySourceCode(template({ interfaceName, interfaceDocs, importTypes }));
37
+ return beautifySourceCode(template({
38
+ interfaceName,
39
+ interfaceDocs,
40
+ importTypes,
41
+ addressType,
42
+ signatureType,
43
+ runtimeCallType,
44
+ extraType,
45
+ }));
21
46
  }
22
47
  }
@@ -33,12 +33,12 @@ export async function generateTypes(chain, metadata, rpcMethods, runtimeVersion,
33
33
  const constsGen = new ConstsGen(typesGen);
34
34
  const queryGen = new QueryGen(typesGen);
35
35
  const jsonRpcGen = new JsonRpcGen(typesGen, rpcMethods);
36
- const indexGen = new IndexGen(interfaceName, runtimeVersion);
37
36
  const errorsGen = new ErrorsGen(typesGen);
38
37
  const eventsGen = new EventsGen(typesGen);
39
38
  const runtimeApisGen = new RuntimeApisGen(typesGen, runtimeVersion.apis);
40
39
  const txGen = new TxGen(typesGen);
41
40
  const viewFunctionGen = new ViewFunctionsGen(typesGen);
41
+ const indexGen = new IndexGen(interfaceName, runtimeVersion, typesGen);
42
42
  fs.writeFileSync(defTypesFileName, await typesGen.generate(useSubPaths));
43
43
  fs.writeFileSync(errorsFileName, await errorsGen.generate(useSubPaths));
44
44
  fs.writeFileSync(eventsFileName, await eventsGen.generate(useSubPaths));
@@ -46,8 +46,8 @@ export async function generateTypes(chain, metadata, rpcMethods, runtimeVersion,
46
46
  fs.writeFileSync(queryTypesFileName, await queryGen.generate(useSubPaths));
47
47
  fs.writeFileSync(constsTypesFileName, await constsGen.generate(useSubPaths));
48
48
  fs.writeFileSync(txFileName, await txGen.generate(useSubPaths));
49
- fs.writeFileSync(indexFileName, await indexGen.generate(useSubPaths));
50
49
  fs.writeFileSync(runtimeApisFileName, await runtimeApisGen.generate(useSubPaths));
51
50
  fs.writeFileSync(viewFunctionsFileName, await viewFunctionGen.generate(useSubPaths));
51
+ fs.writeFileSync(indexFileName, await indexGen.generate(useSubPaths));
52
52
  return { interfaceName, outputFolder: dirPath };
53
53
  }
@@ -12,6 +12,13 @@ import { ChainTx } from './tx.js';
12
12
 
13
13
  export * from './types.js';
14
14
 
15
+ interface ChainKnownTypes extends GenericChainKnownTypes {
16
+ Address: {{{addressType}}};
17
+ Signature: {{{signatureType}}};
18
+ RuntimeCall: {{{runtimeCallType}}};
19
+ Extra: {{{extraType}}};
20
+ }
21
+
15
22
  export interface Versioned{{{interfaceName}}}<Rv extends RpcVersion> extends GenericSubstrateApi<Rv> {
16
23
  rpc: ChainJsonRpcApis<Rv>;
17
24
  consts: ChainConsts<Rv>;
@@ -21,6 +28,8 @@ export interface Versioned{{{interfaceName}}}<Rv extends RpcVersion> extends Gen
21
28
  call: RuntimeApis<Rv>;
22
29
  view: ChainViewFunctions<Rv>;
23
30
  tx: ChainTx<Rv>;
31
+
32
+ types: ChainKnownTypes;
24
33
  }
25
34
 
26
35
  {{interfaceDocs}}export interface {{{interfaceName}}} {
@@ -1,26 +1,51 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.IndexGen = void 0;
4
- const index_js_1 = require("../../shared/index.js");
5
4
  const utils_js_1 = require("../../utils.js");
6
5
  class IndexGen {
7
6
  interfaceName;
8
7
  runtimeVersion;
9
- constructor(interfaceName, runtimeVersion) {
8
+ typesGen;
9
+ constructor(interfaceName, runtimeVersion, typesGen) {
10
10
  this.interfaceName = interfaceName;
11
11
  this.runtimeVersion = runtimeVersion;
12
+ this.typesGen = typesGen;
12
13
  }
13
14
  async generate(useSubPaths = false) {
14
15
  const interfaceName = this.interfaceName;
15
- const typeImports = new index_js_1.TypeImports();
16
- typeImports.addKnownType('GenericSubstrateApi', 'RpcLegacy', 'RpcV2', 'RpcVersion');
17
- const importTypes = typeImports.toImports({ useSubPaths });
16
+ // Clear cache and setup type imports
17
+ this.typesGen.clearCache();
18
+ this.typesGen.typeImports.addKnownType('GenericSubstrateApi', 'GenericChainKnownTypes', 'RpcLegacy', 'RpcV2', 'RpcVersion');
19
+ // Extract type IDs from metadata.extrinsic
20
+ const { callTypeId, addressTypeId, signatureTypeId, signedExtensions } = this.typesGen.metadata.extrinsic;
21
+ // Generate proper TypeScript types using typeOut format (0, true)
22
+ const runtimeCallType = this.typesGen.generateType(callTypeId, 1, true);
23
+ const addressType = this.typesGen.generateType(addressTypeId, 1, true);
24
+ const signatureType = this.typesGen.generateType(signatureTypeId, 1, true);
25
+ // Generate Extra type from signed extensions
26
+ let extraType = 'any[]'; // Default fallback
27
+ if (signedExtensions && signedExtensions.length > 0) {
28
+ const signedExtensionTypes = signedExtensions.map(({ typeId }) => this.typesGen.generateType(typeId, 1, true));
29
+ extraType = `[${signedExtensionTypes.join(', ')}]`;
30
+ }
31
+ // Add generated types to imports
32
+ const generatedTypes = [runtimeCallType, addressType, signatureType, extraType];
33
+ this.typesGen.addTypeImport(generatedTypes);
34
+ const importTypes = this.typesGen.typeImports.toImports({ useSubPaths });
18
35
  const interfaceDocs = (0, utils_js_1.commentBlock)([
19
36
  `@name: ${interfaceName}`, // prettier-end-here
20
37
  `@specVersion: ${this.runtimeVersion.specVersion}`,
21
38
  ]);
22
39
  const template = (0, utils_js_1.compileTemplate)('chaintypes/templates/index.hbs');
23
- return (0, utils_js_1.beautifySourceCode)(template({ interfaceName, interfaceDocs, importTypes }));
40
+ return (0, utils_js_1.beautifySourceCode)(template({
41
+ interfaceName,
42
+ interfaceDocs,
43
+ importTypes,
44
+ addressType,
45
+ signatureType,
46
+ runtimeCallType,
47
+ extraType,
48
+ }));
24
49
  }
25
50
  }
26
51
  exports.IndexGen = IndexGen;
@@ -60,12 +60,12 @@ async function generateTypes(chain, metadata, rpcMethods, runtimeVersion, outDir
60
60
  const constsGen = new index_js_1.ConstsGen(typesGen);
61
61
  const queryGen = new index_js_1.QueryGen(typesGen);
62
62
  const jsonRpcGen = new index_js_1.JsonRpcGen(typesGen, rpcMethods);
63
- const indexGen = new index_js_1.IndexGen(interfaceName, runtimeVersion);
64
63
  const errorsGen = new index_js_1.ErrorsGen(typesGen);
65
64
  const eventsGen = new index_js_1.EventsGen(typesGen);
66
65
  const runtimeApisGen = new index_js_1.RuntimeApisGen(typesGen, runtimeVersion.apis);
67
66
  const txGen = new index_js_1.TxGen(typesGen);
68
67
  const viewFunctionGen = new index_js_1.ViewFunctionsGen(typesGen);
68
+ const indexGen = new index_js_1.IndexGen(interfaceName, runtimeVersion, typesGen);
69
69
  fs.writeFileSync(defTypesFileName, await typesGen.generate(useSubPaths));
70
70
  fs.writeFileSync(errorsFileName, await errorsGen.generate(useSubPaths));
71
71
  fs.writeFileSync(eventsFileName, await eventsGen.generate(useSubPaths));
@@ -73,9 +73,9 @@ async function generateTypes(chain, metadata, rpcMethods, runtimeVersion, outDir
73
73
  fs.writeFileSync(queryTypesFileName, await queryGen.generate(useSubPaths));
74
74
  fs.writeFileSync(constsTypesFileName, await constsGen.generate(useSubPaths));
75
75
  fs.writeFileSync(txFileName, await txGen.generate(useSubPaths));
76
- fs.writeFileSync(indexFileName, await indexGen.generate(useSubPaths));
77
76
  fs.writeFileSync(runtimeApisFileName, await runtimeApisGen.generate(useSubPaths));
78
77
  fs.writeFileSync(viewFunctionsFileName, await viewFunctionGen.generate(useSubPaths));
78
+ fs.writeFileSync(indexFileName, await indexGen.generate(useSubPaths));
79
79
  return { interfaceName, outputFolder: dirPath };
80
80
  }
81
81
  exports.generateTypes = generateTypes;
@@ -12,6 +12,13 @@ import { ChainTx } from './tx.js';
12
12
 
13
13
  export * from './types.js';
14
14
 
15
+ interface ChainKnownTypes extends GenericChainKnownTypes {
16
+ Address: {{{addressType}}};
17
+ Signature: {{{signatureType}}};
18
+ RuntimeCall: {{{runtimeCallType}}};
19
+ Extra: {{{extraType}}};
20
+ }
21
+
15
22
  export interface Versioned{{{interfaceName}}}<Rv extends RpcVersion> extends GenericSubstrateApi<Rv> {
16
23
  rpc: ChainJsonRpcApis<Rv>;
17
24
  consts: ChainConsts<Rv>;
@@ -21,6 +28,8 @@ export interface Versioned{{{interfaceName}}}<Rv extends RpcVersion> extends Gen
21
28
  call: RuntimeApis<Rv>;
22
29
  view: ChainViewFunctions<Rv>;
23
30
  tx: ChainTx<Rv>;
31
+
32
+ types: ChainKnownTypes;
24
33
  }
25
34
 
26
35
  {{interfaceDocs}}export interface {{{interfaceName}}} {
@@ -58,7 +58,12 @@ class BaseTypesGen {
58
58
  }
59
59
  else {
60
60
  pathsCount.get(joinedPath).push(id);
61
- typeSuffixes.set(id, this.extractDupTypeSuffix(id, firstOccurrenceTypeId, pathsCount.get(joinedPath).length));
61
+ const existingSuffixes = pathsCount
62
+ .get(joinedPath)
63
+ .map((id) => typeSuffixes.get(id))
64
+ .filter((x) => x);
65
+ typeSuffixes.set(id, this.extractDupTypeSuffix(id, // --
66
+ firstOccurrenceTypeId, pathsCount.get(joinedPath).length, existingSuffixes));
62
67
  }
63
68
  }
64
69
  else {
@@ -340,13 +345,9 @@ class BaseTypesGen {
340
345
  (param1.typeId === undefined) === (param2.typeId === undefined) &&
341
346
  (param1.typeId === undefined || this.#typeEql(param1.typeId, param2.typeId)));
342
347
  }
343
- extractDupTypeSuffix(dupTypeId, originalTypeId, dupCount) {
344
- const originalTypeParams = this.types[originalTypeId].params;
345
- const dupTypeParams = this.types[dupTypeId].params;
346
- const diffParam = dupTypeParams.find((one, idx) => !this.#eqlTypeParam(one, originalTypeParams[idx]));
347
- // TODO make sure these suffix is unique if a type is duplicated more than 2 times
348
- if (diffParam?.typeId) {
349
- const diffType = this.types[diffParam.typeId];
348
+ #getTypeSuffix(typeId) {
349
+ if (typeId) {
350
+ const diffType = this.types[typeId];
350
351
  if (diffType.path.length > 0) {
351
352
  return (0, utils_1.stringPascalCase)(diffType.path.at(-1));
352
353
  }
@@ -354,6 +355,17 @@ class BaseTypesGen {
354
355
  return (0, utils_1.stringPascalCase)(diffType.typeDef.value.kind);
355
356
  }
356
357
  }
358
+ }
359
+ extractDupTypeSuffix(dupTypeId, originalTypeId, dupCount, existingSuffixes = []) {
360
+ const originalTypeParams = this.types[originalTypeId].params;
361
+ const dupTypeParams = this.types[dupTypeId].params;
362
+ const diffParam = dupTypeParams.find((one, idx) => !this.#eqlTypeParam(one, originalTypeParams[idx]));
363
+ if (diffParam?.typeId) {
364
+ const suffix = this.#getTypeSuffix(diffParam.typeId);
365
+ if (suffix && !existingSuffixes.includes(suffix)) {
366
+ return suffix;
367
+ }
368
+ }
357
369
  // Last resort!
358
370
  return dupCount.toString().padStart(3, '0');
359
371
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dedot/codegen",
3
- "version": "0.15.2",
3
+ "version": "0.16.0",
4
4
  "description": "Generate types",
5
5
  "author": "Thang X. Vu <thang@dedot.dev>",
6
6
  "homepage": "https://dedot.dev",
@@ -18,16 +18,16 @@
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.15.2",
22
- "@dedot/codecs": "0.15.2",
23
- "@dedot/contracts": "0.15.2",
24
- "@dedot/providers": "0.15.2",
25
- "@dedot/runtime-specs": "0.15.2",
26
- "@dedot/shape": "0.15.2",
27
- "@dedot/types": "0.15.2",
28
- "@dedot/utils": "0.15.2",
21
+ "@dedot/api": "0.16.0",
22
+ "@dedot/codecs": "0.16.0",
23
+ "@dedot/contracts": "0.16.0",
24
+ "@dedot/providers": "0.16.0",
25
+ "@dedot/runtime-specs": "0.16.0",
26
+ "@dedot/shape": "0.16.0",
27
+ "@dedot/types": "0.16.0",
28
+ "@dedot/utils": "0.16.0",
29
29
  "handlebars": "^4.7.8",
30
- "prettier": "^3.5.3"
30
+ "prettier": "^3.6.2"
31
31
  },
32
32
  "publishConfig": {
33
33
  "access": "public",
@@ -37,7 +37,7 @@
37
37
  "node": ">=18"
38
38
  },
39
39
  "license": "Apache-2.0",
40
- "gitHead": "75231d6888303dcf598cfd31592df13230707cb4",
40
+ "gitHead": "3e78a8eebb8977de0c5fb956154e5b09c4448f31",
41
41
  "module": "./index.js",
42
42
  "types": "./index.d.ts",
43
43
  "exports": {
@@ -27,7 +27,7 @@ export declare abstract class BaseTypesGen {
27
27
  cleanPath(path: string[]): string;
28
28
  eqlCache: Map<string, boolean>;
29
29
  typeEql(idA: number, idB: number, level?: number): boolean;
30
- extractDupTypeSuffix(dupTypeId: TypeId, originalTypeId: TypeId, dupCount: number): string;
30
+ extractDupTypeSuffix(dupTypeId: TypeId, originalTypeId: TypeId, dupCount: number, existingSuffixes?: string[]): string;
31
31
  addTypeImport(typeName: string | string[]): void;
32
32
  getEnumOptions(_typeId: TypeId): EnumOptions;
33
33
  }
@@ -55,7 +55,12 @@ export class BaseTypesGen {
55
55
  }
56
56
  else {
57
57
  pathsCount.get(joinedPath).push(id);
58
- typeSuffixes.set(id, this.extractDupTypeSuffix(id, firstOccurrenceTypeId, pathsCount.get(joinedPath).length));
58
+ const existingSuffixes = pathsCount
59
+ .get(joinedPath)
60
+ .map((id) => typeSuffixes.get(id))
61
+ .filter((x) => x);
62
+ typeSuffixes.set(id, this.extractDupTypeSuffix(id, // --
63
+ firstOccurrenceTypeId, pathsCount.get(joinedPath).length, existingSuffixes));
59
64
  }
60
65
  }
61
66
  else {
@@ -337,13 +342,9 @@ export class BaseTypesGen {
337
342
  (param1.typeId === undefined) === (param2.typeId === undefined) &&
338
343
  (param1.typeId === undefined || this.#typeEql(param1.typeId, param2.typeId)));
339
344
  }
340
- extractDupTypeSuffix(dupTypeId, originalTypeId, dupCount) {
341
- const originalTypeParams = this.types[originalTypeId].params;
342
- const dupTypeParams = this.types[dupTypeId].params;
343
- const diffParam = dupTypeParams.find((one, idx) => !this.#eqlTypeParam(one, originalTypeParams[idx]));
344
- // TODO make sure these suffix is unique if a type is duplicated more than 2 times
345
- if (diffParam?.typeId) {
346
- const diffType = this.types[diffParam.typeId];
345
+ #getTypeSuffix(typeId) {
346
+ if (typeId) {
347
+ const diffType = this.types[typeId];
347
348
  if (diffType.path.length > 0) {
348
349
  return stringPascalCase(diffType.path.at(-1));
349
350
  }
@@ -351,6 +352,17 @@ export class BaseTypesGen {
351
352
  return stringPascalCase(diffType.typeDef.value.kind);
352
353
  }
353
354
  }
355
+ }
356
+ extractDupTypeSuffix(dupTypeId, originalTypeId, dupCount, existingSuffixes = []) {
357
+ const originalTypeParams = this.types[originalTypeId].params;
358
+ const dupTypeParams = this.types[dupTypeId].params;
359
+ const diffParam = dupTypeParams.find((one, idx) => !this.#eqlTypeParam(one, originalTypeParams[idx]));
360
+ if (diffParam?.typeId) {
361
+ const suffix = this.#getTypeSuffix(diffParam.typeId);
362
+ if (suffix && !existingSuffixes.includes(suffix)) {
363
+ return suffix;
364
+ }
365
+ }
354
366
  // Last resort!
355
367
  return dupCount.toString().padStart(3, '0');
356
368
  }