@cosmwasm/ts-codegen 0.30.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/main/builder/builder.js +41 -4
- package/main/generators/create-helpers.js +38 -0
- package/main/helpers/contractContextBase.js +8 -0
- package/main/helpers/contractsContextTSX.js +8 -0
- package/main/helpers/index.js +31 -0
- package/main/plugins/client.js +11 -6
- package/main/plugins/message-composer.js +10 -6
- package/main/plugins/msg-builder.js +1 -1
- package/main/plugins/plugin-base.js +9 -2
- package/main/plugins/provider-bundle.js +146 -0
- package/main/plugins/provider.js +170 -0
- package/main/plugins/react-query.js +1 -1
- package/main/plugins/recoil.js +1 -1
- package/main/plugins/types.js +1 -1
- package/main/utils/files.js +77 -0
- package/main/utils/schemas.js +1 -2
- package/main/utils/unused.js +68 -0
- package/module/builder/builder.js +28 -2
- package/module/generators/create-helpers.js +25 -0
- package/module/helpers/contractContextBase.js +92 -0
- package/module/helpers/contractsContextTSX.js +73 -0
- package/module/helpers/index.js +2 -0
- package/module/plugins/client.js +13 -10
- package/module/plugins/message-composer.js +12 -10
- package/module/plugins/msg-builder.js +1 -1
- package/module/plugins/plugin-base.js +15 -8
- package/module/plugins/provider-bundle.js +65 -0
- package/module/plugins/provider.js +81 -0
- package/module/plugins/react-query.js +1 -1
- package/module/plugins/recoil.js +1 -1
- package/module/plugins/types.js +1 -1
- package/module/utils/files.js +44 -0
- package/module/utils/schemas.js +1 -2
- package/module/utils/unused.js +45 -0
- package/package.json +3 -3
- package/src/builder/builder.ts +36 -1
- package/src/generators/create-helpers.ts +28 -0
- package/src/helpers/contractContextBase.ts +92 -0
- package/src/helpers/contractsContextTSX.ts +73 -0
- package/src/helpers/index.ts +2 -0
- package/src/plugins/client.ts +30 -14
- package/src/plugins/message-composer.ts +23 -14
- package/src/plugins/msg-builder.ts +1 -1
- package/src/plugins/plugin-base.ts +30 -20
- package/src/plugins/provider-bundle.ts +97 -0
- package/src/plugins/provider.ts +114 -0
- package/src/plugins/react-query.ts +1 -1
- package/src/plugins/recoil.ts +1 -1
- package/src/plugins/types.ts +1 -1
- package/src/utils/files.ts +73 -0
- package/src/utils/schemas.ts +1 -3
- package/src/utils/unused.ts +52 -0
- package/types/src/builder/builder.d.ts +7 -1
- package/types/src/generators/create-helpers.d.ts +3 -0
- package/types/src/helpers/contractContextBase.d.ts +1 -0
- package/types/src/helpers/contractsContextTSX.d.ts +1 -0
- package/types/src/helpers/index.d.ts +2 -0
- package/types/src/plugins/client.d.ts +4 -3
- package/types/src/plugins/message-composer.d.ts +4 -3
- package/types/src/plugins/plugin-base.d.ts +7 -3
- package/types/src/plugins/provider-bundle.d.ts +13 -0
- package/types/src/plugins/provider.d.ts +15 -0
- package/types/src/plugins/use-contracts.d.ts +12 -0
- package/types/src/utils/files.d.ts +3 -0
- package/types/src/utils/unused.d.ts +5 -0
package/module/plugins/client.js
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
-
import { pascal } from
|
2
|
-
import * as w from
|
3
|
-
import { findExecuteMsg, findAndParseTypes, findQueryMsg } from
|
4
|
-
import { RenderContext, getMessageProperties } from
|
5
|
-
import { BuilderPluginBase } from
|
1
|
+
import { pascal } from "case";
|
2
|
+
import * as w from "wasm-ast-types";
|
3
|
+
import { findExecuteMsg, findAndParseTypes, findQueryMsg } from "../utils";
|
4
|
+
import { RenderContext, getMessageProperties } from "wasm-ast-types";
|
5
|
+
import { BuilderPluginBase } from "./plugin-base";
|
6
|
+
export const TYPE = "client";
|
6
7
|
export class ClientPlugin extends BuilderPluginBase {
|
7
8
|
initContext(contract, options) {
|
8
|
-
return new RenderContext(contract, options);
|
9
|
+
return new RenderContext(contract, options, this.builder.builderContext);
|
9
10
|
}
|
10
11
|
|
11
12
|
async doRender(name, context) {
|
@@ -20,8 +21,8 @@ export class ClientPlugin extends BuilderPluginBase {
|
|
20
21
|
const {
|
21
22
|
schemas
|
22
23
|
} = context.contract;
|
23
|
-
const localname = pascal(name) +
|
24
|
-
const TypesFile = pascal(name) +
|
24
|
+
const localname = pascal(name) + ".client.ts";
|
25
|
+
const TypesFile = pascal(name) + ".types";
|
25
26
|
const QueryMsg = findQueryMsg(schemas);
|
26
27
|
const ExecuteMsg = findExecuteMsg(schemas);
|
27
28
|
const typeHash = await findAndParseTypes(schemas);
|
@@ -37,6 +38,7 @@ export class ClientPlugin extends BuilderPluginBase {
|
|
37
38
|
ReadOnlyInstance = pascal(`${name}ReadOnlyInterface`);
|
38
39
|
body.push(w.createQueryInterface(context, ReadOnlyInstance, QueryMsg));
|
39
40
|
body.push(w.createQueryClass(context, QueryClient, ReadOnlyInstance, QueryMsg));
|
41
|
+
context.addProviderInfo(name, w.PROVIDER_TYPES.QUERY_CLIENT_TYPE, QueryClient, localname);
|
40
42
|
} // execute messages
|
41
43
|
|
42
44
|
|
@@ -48,16 +50,17 @@ export class ClientPlugin extends BuilderPluginBase {
|
|
48
50
|
Instance = pascal(`${name}Interface`);
|
49
51
|
body.push(w.createExecuteInterface(context, Instance, this.option.client.execExtendsQuery ? ReadOnlyInstance : null, ExecuteMsg));
|
50
52
|
body.push(w.createExecuteClass(context, Client, Instance, this.option.client.execExtendsQuery ? QueryClient : null, ExecuteMsg));
|
53
|
+
context.addProviderInfo(name, w.PROVIDER_TYPES.SIGNING_CLIENT_TYPE, Client, localname);
|
51
54
|
}
|
52
55
|
}
|
53
56
|
|
54
|
-
if (typeHash.hasOwnProperty(
|
57
|
+
if (typeHash.hasOwnProperty("Coin")) {
|
55
58
|
// @ts-ignore
|
56
59
|
delete context.utils.Coin;
|
57
60
|
}
|
58
61
|
|
59
62
|
return [{
|
60
|
-
type:
|
63
|
+
type: TYPE,
|
61
64
|
localname,
|
62
65
|
body
|
63
66
|
}];
|
@@ -1,11 +1,12 @@
|
|
1
|
-
import { pascal } from
|
2
|
-
import * as w from
|
3
|
-
import { findAndParseTypes, findExecuteMsg } from
|
4
|
-
import { getMessageProperties, RenderContext } from
|
5
|
-
import { BuilderPluginBase } from
|
1
|
+
import { pascal } from "case";
|
2
|
+
import * as w from "wasm-ast-types";
|
3
|
+
import { findAndParseTypes, findExecuteMsg } from "../utils";
|
4
|
+
import { getMessageProperties, RenderContext } from "wasm-ast-types";
|
5
|
+
import { BuilderPluginBase } from "./plugin-base";
|
6
|
+
export const TYPE = "message-composer";
|
6
7
|
export class MessageComposerPlugin extends BuilderPluginBase {
|
7
8
|
initContext(contract, options) {
|
8
|
-
return new RenderContext(contract, options);
|
9
|
+
return new RenderContext(contract, options, this.builder.builderContext);
|
9
10
|
}
|
10
11
|
|
11
12
|
async doRender(name, context) {
|
@@ -20,8 +21,8 @@ export class MessageComposerPlugin extends BuilderPluginBase {
|
|
20
21
|
const {
|
21
22
|
schemas
|
22
23
|
} = context.contract;
|
23
|
-
const localname = pascal(name) +
|
24
|
-
const TypesFile = pascal(name) +
|
24
|
+
const localname = pascal(name) + ".message-composer.ts";
|
25
|
+
const TypesFile = pascal(name) + ".types";
|
25
26
|
const ExecuteMsg = findExecuteMsg(schemas);
|
26
27
|
const typeHash = await findAndParseTypes(schemas);
|
27
28
|
const body = [];
|
@@ -35,16 +36,17 @@ export class MessageComposerPlugin extends BuilderPluginBase {
|
|
35
36
|
const Interface = pascal(`${name}Message`);
|
36
37
|
body.push(w.createMessageComposerInterface(context, Interface, ExecuteMsg));
|
37
38
|
body.push(w.createMessageComposerClass(context, TheClass, Interface, ExecuteMsg));
|
39
|
+
context.addProviderInfo(name, w.PROVIDER_TYPES.MESSAGE_COMPOSER_TYPE, TheClass, localname);
|
38
40
|
}
|
39
41
|
}
|
40
42
|
|
41
|
-
if (typeHash.hasOwnProperty(
|
43
|
+
if (typeHash.hasOwnProperty("Coin")) {
|
42
44
|
// @ts-ignore
|
43
45
|
delete context.utils.Coin;
|
44
46
|
}
|
45
47
|
|
46
48
|
return [{
|
47
|
-
type:
|
49
|
+
type: TYPE,
|
48
50
|
localname,
|
49
51
|
body
|
50
52
|
}];
|
@@ -5,7 +5,7 @@ import { getMessageProperties, RenderContext } from 'wasm-ast-types';
|
|
5
5
|
import { BuilderPluginBase } from './plugin-base';
|
6
6
|
export class MsgBuilderPlugin extends BuilderPluginBase {
|
7
7
|
initContext(contract, options) {
|
8
|
-
return new RenderContext(contract, options);
|
8
|
+
return new RenderContext(contract, options, this.builder.builderContext);
|
9
9
|
}
|
10
10
|
|
11
11
|
async doRender(name, context) {
|
@@ -1,21 +1,28 @@
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
2
|
-
import { sync as mkdirp } from
|
3
|
-
import { join } from
|
4
|
-
import { writeFileSync } from
|
5
|
-
import { header } from
|
6
|
-
import generate from
|
7
|
-
import * as t from
|
2
|
+
import { sync as mkdirp } from "mkdirp";
|
3
|
+
import { join } from "path";
|
4
|
+
import { writeFileSync } from "fs";
|
5
|
+
import { header } from "../utils/header";
|
6
|
+
import generate from "@babel/generator";
|
7
|
+
import * as t from "@babel/types";
|
8
8
|
|
9
9
|
/**
|
10
10
|
* BuilderPluginBase enable ts-codegen users implement their own plugins by only implement a few functions.
|
11
11
|
*/
|
12
12
|
export class BuilderPluginBase {
|
13
|
-
constructor(opt) {
|
13
|
+
constructor(opt, builder) {
|
14
|
+
_defineProperty(this, "builder", void 0);
|
15
|
+
|
14
16
|
_defineProperty(this, "option", void 0);
|
15
17
|
|
16
18
|
_defineProperty(this, "utils", void 0);
|
17
19
|
|
18
20
|
this.option = opt;
|
21
|
+
this.builder = builder;
|
22
|
+
}
|
23
|
+
|
24
|
+
setBuilder(builder) {
|
25
|
+
this.builder = builder;
|
19
26
|
}
|
20
27
|
|
21
28
|
async render(name, contractInfo, outPath) {
|
@@ -35,7 +42,7 @@ export class BuilderPluginBase {
|
|
35
42
|
}
|
36
43
|
|
37
44
|
return results.map(result => {
|
38
|
-
const imports = context.getImports(this.utils);
|
45
|
+
const imports = context.getImports(this.utils, result.localname);
|
39
46
|
const code = header + generate(t.program([...imports, ...result.body])).code;
|
40
47
|
mkdirp(outPath);
|
41
48
|
const filename = join(outPath, result.localname);
|
@@ -0,0 +1,65 @@
|
|
1
|
+
import { pascal } from "case";
|
2
|
+
import * as w from "wasm-ast-types";
|
3
|
+
import { RenderContext } from "wasm-ast-types";
|
4
|
+
import { BuilderPluginBase } from "./plugin-base";
|
5
|
+
import { GetLocalBaseNameByContractName } from "./provider";
|
6
|
+
export class ContractsProviderBundlePlugin extends BuilderPluginBase {
|
7
|
+
constructor(opt) {
|
8
|
+
super(opt);
|
9
|
+
this.utils = {
|
10
|
+
CosmWasmClient: "@cosmjs/cosmwasm-stargate",
|
11
|
+
SigningCosmWasmClient: "@cosmjs/cosmwasm-stargate",
|
12
|
+
IQueryClientProvider: "__contractContextBase__",
|
13
|
+
ISigningClientProvider: "__contractContextBase__",
|
14
|
+
IMessageComposerProvider: "__contractContextBase__"
|
15
|
+
};
|
16
|
+
}
|
17
|
+
|
18
|
+
initContext(contract, options) {
|
19
|
+
return new RenderContext(contract, options, this.builder.builderContext);
|
20
|
+
}
|
21
|
+
|
22
|
+
async doRender(name, context) {
|
23
|
+
if (!this.option?.useContracts?.enabled) {
|
24
|
+
return;
|
25
|
+
}
|
26
|
+
|
27
|
+
const providerInfos = context.getProviderInfos();
|
28
|
+
|
29
|
+
if (!Object.keys(providerInfos)?.length) {
|
30
|
+
return;
|
31
|
+
}
|
32
|
+
|
33
|
+
const localname = "contractContextProviders.ts";
|
34
|
+
const body = [];
|
35
|
+
context.addUtil("CosmWasmClient");
|
36
|
+
context.addUtil("SigningCosmWasmClient");
|
37
|
+
context.addUtil("IQueryClientProvider");
|
38
|
+
context.addUtil("ISigningClientProvider");
|
39
|
+
context.addUtil("IMessageComposerProvider");
|
40
|
+
|
41
|
+
for (const name in providerInfos) {
|
42
|
+
if (Object.prototype.hasOwnProperty.call(providerInfos, name)) {
|
43
|
+
const providerInfo = providerInfos[name];
|
44
|
+
|
45
|
+
for (const key in providerInfo) {
|
46
|
+
if (Object.prototype.hasOwnProperty.call(providerInfo, key)) {
|
47
|
+
const info = providerInfo[key];
|
48
|
+
body.push(w.importStmt([info.classname], `./${info.basename}`));
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
body.push(w.importStmt([pascal(name)], `./${GetLocalBaseNameByContractName(name)}`));
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
body.push(w.createIContractsContext(providerInfos));
|
57
|
+
body.push(w.createGettingProviders(providerInfos));
|
58
|
+
return [{
|
59
|
+
type: "plugin",
|
60
|
+
localname,
|
61
|
+
body
|
62
|
+
}];
|
63
|
+
}
|
64
|
+
|
65
|
+
}
|
@@ -0,0 +1,81 @@
|
|
1
|
+
import { pascal } from "case";
|
2
|
+
import * as w from "wasm-ast-types";
|
3
|
+
import { RenderContext } from "wasm-ast-types";
|
4
|
+
import { BuilderPluginBase } from "./plugin-base";
|
5
|
+
export const GetLocalNameByContractName = name => `${pascal(name)}.provider.ts`;
|
6
|
+
export const GetLocalBaseNameByContractName = name => `${pascal(name)}.provider`;
|
7
|
+
export class ContractsContextProviderPlugin extends BuilderPluginBase {
|
8
|
+
constructor(opt) {
|
9
|
+
super(opt);
|
10
|
+
this.utils = {
|
11
|
+
ContractBase: "__contractContextBase__",
|
12
|
+
IContractConstructor: "__contractContextBase__",
|
13
|
+
IEmptyClient: "__contractContextBase__"
|
14
|
+
};
|
15
|
+
}
|
16
|
+
|
17
|
+
initContext(contract, options) {
|
18
|
+
return new RenderContext(contract, options, this.builder.builderContext);
|
19
|
+
}
|
20
|
+
|
21
|
+
async doRender(name, context) {
|
22
|
+
if (!this.option?.useContracts?.enabled) {
|
23
|
+
return;
|
24
|
+
}
|
25
|
+
|
26
|
+
const providerInfo = context.getProviderInfos()[name];
|
27
|
+
|
28
|
+
if (!Object.keys(providerInfo)?.length) {
|
29
|
+
return;
|
30
|
+
}
|
31
|
+
|
32
|
+
context.addUtil("ContractBase");
|
33
|
+
context.addUtil("IContractConstructor");
|
34
|
+
const localname = GetLocalNameByContractName(name);
|
35
|
+
let needEmptyClientType = false;
|
36
|
+
let clientFile = null;
|
37
|
+
let clientClasses = [];
|
38
|
+
const body = [];
|
39
|
+
const signClientProviderInfo = providerInfo[w.PROVIDER_TYPES.SIGNING_CLIENT_TYPE];
|
40
|
+
|
41
|
+
if (signClientProviderInfo) {
|
42
|
+
clientFile = `./${signClientProviderInfo.basename}`;
|
43
|
+
clientClasses.push(signClientProviderInfo.classname);
|
44
|
+
} else {
|
45
|
+
needEmptyClientType = true;
|
46
|
+
}
|
47
|
+
|
48
|
+
const queryClientProviderInfo = providerInfo[w.PROVIDER_TYPES.QUERY_CLIENT_TYPE];
|
49
|
+
|
50
|
+
if (queryClientProviderInfo) {
|
51
|
+
clientFile = `./${queryClientProviderInfo.basename}`;
|
52
|
+
clientClasses.push(queryClientProviderInfo.classname);
|
53
|
+
} else {
|
54
|
+
needEmptyClientType = true;
|
55
|
+
}
|
56
|
+
|
57
|
+
if (clientFile) {
|
58
|
+
body.push(w.importStmt(clientClasses, clientFile));
|
59
|
+
}
|
60
|
+
|
61
|
+
const messageComposerProviderInfo = providerInfo[w.PROVIDER_TYPES.MESSAGE_COMPOSER_TYPE];
|
62
|
+
|
63
|
+
if (messageComposerProviderInfo) {
|
64
|
+
body.push(w.importStmt([messageComposerProviderInfo.classname], `./${messageComposerProviderInfo.basename}`));
|
65
|
+
} else {
|
66
|
+
needEmptyClientType = true;
|
67
|
+
}
|
68
|
+
|
69
|
+
if (needEmptyClientType) {
|
70
|
+
context.addUtil("IEmptyClient");
|
71
|
+
}
|
72
|
+
|
73
|
+
body.push(w.createProvider(name, providerInfo));
|
74
|
+
return [{
|
75
|
+
type: "plugin",
|
76
|
+
localname,
|
77
|
+
body
|
78
|
+
}];
|
79
|
+
}
|
80
|
+
|
81
|
+
}
|
@@ -5,7 +5,7 @@ import { getMessageProperties, RenderContext } from 'wasm-ast-types';
|
|
5
5
|
import { BuilderPluginBase } from './plugin-base';
|
6
6
|
export class ReactQueryPlugin extends BuilderPluginBase {
|
7
7
|
initContext(contract, options) {
|
8
|
-
return new RenderContext(contract, options);
|
8
|
+
return new RenderContext(contract, options, this.builder.builderContext);
|
9
9
|
}
|
10
10
|
|
11
11
|
async doRender(name, context) {
|
package/module/plugins/recoil.js
CHANGED
@@ -14,7 +14,7 @@ export class RecoilPlugin extends BuilderPluginBase {
|
|
14
14
|
}
|
15
15
|
|
16
16
|
initContext(contract, options) {
|
17
|
-
return new RenderContext(contract, options);
|
17
|
+
return new RenderContext(contract, options, this.builder.builderContext);
|
18
18
|
}
|
19
19
|
|
20
20
|
async doRender(name, context) {
|
package/module/plugins/types.js
CHANGED
@@ -6,7 +6,7 @@ import { RenderContext } from 'wasm-ast-types';
|
|
6
6
|
import { BuilderPluginBase } from './plugin-base';
|
7
7
|
export class TypesPlugin extends BuilderPluginBase {
|
8
8
|
initContext(contract, options) {
|
9
|
-
return new RenderContext(contract, options);
|
9
|
+
return new RenderContext(contract, options, this.builder.builderContext);
|
10
10
|
}
|
11
11
|
|
12
12
|
async doRender(name, context) {
|
@@ -0,0 +1,44 @@
|
|
1
|
+
import * as t from "@babel/types";
|
2
|
+
import { parse } from "@babel/parser";
|
3
|
+
import { sync as mkdirp } from "mkdirp";
|
4
|
+
import { writeFileSync } from "fs";
|
5
|
+
import { dirname } from "path";
|
6
|
+
import generate from "@babel/generator";
|
7
|
+
import { unused } from "./unused";
|
8
|
+
import traverse from "@babel/traverse";
|
9
|
+
export const writeAstToFile = (outPath, program, filename, removeUnusedImports = false, isTsDisable = false, isEslintDisable = false) => {
|
10
|
+
const ast = t.program(program);
|
11
|
+
const content = generate(ast).code;
|
12
|
+
|
13
|
+
if (removeUnusedImports) {
|
14
|
+
const plugins = ["typescript"];
|
15
|
+
const newAst = parse(content, {
|
16
|
+
sourceType: "module",
|
17
|
+
plugins
|
18
|
+
});
|
19
|
+
traverse(newAst, unused);
|
20
|
+
const content2 = generate(newAst).code;
|
21
|
+
writeContentToFile(outPath, content2, filename, isTsDisable, isEslintDisable);
|
22
|
+
} else {
|
23
|
+
writeContentToFile(outPath, content, filename, isTsDisable, isEslintDisable);
|
24
|
+
}
|
25
|
+
};
|
26
|
+
export const writeContentToFile = (outPath, content, filename, isTsDisable = false, isEslintDisable = false) => {
|
27
|
+
let esLintPrefix = "";
|
28
|
+
let tsLintPrefix = "";
|
29
|
+
let nameWithoutPath = filename.replace(outPath, ""); // strip off leading slash
|
30
|
+
|
31
|
+
if (nameWithoutPath.startsWith("/")) nameWithoutPath = nameWithoutPath.replace(/^\//, "");
|
32
|
+
|
33
|
+
if (isTsDisable) {
|
34
|
+
tsLintPrefix = `//@ts-nocheck\n`;
|
35
|
+
}
|
36
|
+
|
37
|
+
if (isEslintDisable) {
|
38
|
+
esLintPrefix = `/* eslint-disable */\n`;
|
39
|
+
}
|
40
|
+
|
41
|
+
const text = tsLintPrefix + esLintPrefix + content;
|
42
|
+
mkdirp(dirname(filename));
|
43
|
+
writeFileSync(filename, text);
|
44
|
+
};
|
package/module/utils/schemas.js
CHANGED
@@ -72,8 +72,7 @@ export const findQueryMsg = schemas => {
|
|
72
72
|
return QueryMsg;
|
73
73
|
};
|
74
74
|
export const findExecuteMsg = schemas => {
|
75
|
-
const ExecuteMsg = schemas.find(schema => schema.title
|
76
|
-
schema.title === 'ExecuteMsgForEmpty');
|
75
|
+
const ExecuteMsg = schemas.find(schema => schema.title.startsWith('ExecuteMsg'));
|
77
76
|
return ExecuteMsg;
|
78
77
|
};
|
79
78
|
export const findAndParseTypes = async schemas => {
|
@@ -0,0 +1,45 @@
|
|
1
|
+
//@ts-nocheck
|
2
|
+
import * as t from '@babel/types'; // https://github.com/chuyik/babel-plugin-danger-remove-unused-import
|
3
|
+
// https://github.com/chuyik/babel-plugin-danger-remove-unused-import/blob/c5454c21e94698a2464a12baa5590761932a71a8/License#L1
|
4
|
+
|
5
|
+
export const unused = {
|
6
|
+
Program: {
|
7
|
+
exit: path => {
|
8
|
+
const UnRefBindings = new Map();
|
9
|
+
|
10
|
+
for (const [name, binding] of Object.entries(path.scope.bindings)) {
|
11
|
+
if (!binding.path.parentPath || binding.kind !== 'module') continue;
|
12
|
+
const source = binding.path.parentPath.get('source');
|
13
|
+
const importName = source.node.value;
|
14
|
+
if (!t.isStringLiteral(source)) continue;
|
15
|
+
const key = `${importName}(${source.node.loc && source.node.loc.start.line})`;
|
16
|
+
|
17
|
+
if (!UnRefBindings.has(key)) {
|
18
|
+
UnRefBindings.set(key, binding);
|
19
|
+
}
|
20
|
+
|
21
|
+
if (binding.referenced) {
|
22
|
+
UnRefBindings.set(key, null);
|
23
|
+
} else {
|
24
|
+
const nodeType = binding.path.node.type;
|
25
|
+
|
26
|
+
if (nodeType === 'ImportSpecifier') {
|
27
|
+
binding.path.remove();
|
28
|
+
} else if (nodeType === 'ImportDefaultSpecifier') {
|
29
|
+
binding.path.remove();
|
30
|
+
} else if (nodeType === 'ImportNamespaceSpecifier') {
|
31
|
+
binding.path.remove();
|
32
|
+
} else if (binding.path.parentPath) {
|
33
|
+
binding.path.parentPath.remove();
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
UnRefBindings.forEach((binding, key) => {
|
39
|
+
if (binding && binding.path.parentPath) {
|
40
|
+
binding.path.parentPath.remove();
|
41
|
+
}
|
42
|
+
});
|
43
|
+
}
|
44
|
+
}
|
45
|
+
};
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@cosmwasm/ts-codegen",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.31.0",
|
4
4
|
"description": "@cosmwasm/ts-codegen converts your CosmWasm smart contracts into dev-friendly TypeScript classes so you can focus on shipping code.",
|
5
5
|
"author": "Dan Lynch <pyramation@gmail.com>",
|
6
6
|
"homepage": "https://github.com/cosmwasm/ts-codegen",
|
@@ -96,7 +96,7 @@
|
|
96
96
|
"parse-package-name": "1.0.0",
|
97
97
|
"rimraf": "3.0.2",
|
98
98
|
"shelljs": "0.8.5",
|
99
|
-
"wasm-ast-types": "^0.
|
99
|
+
"wasm-ast-types": "^0.24.0"
|
100
100
|
},
|
101
|
-
"gitHead": "
|
101
|
+
"gitHead": "4553eb80cd89969583df6164d1c764ab5b289c63"
|
102
102
|
}
|
package/src/builder/builder.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { RenderOptions, defaultOptions, RenderContext, ContractInfo, MessageComposerOptions} from "wasm-ast-types";
|
1
|
+
import { RenderOptions, defaultOptions, RenderContext, ContractInfo, MessageComposerOptions, BuilderContext} from "wasm-ast-types";
|
2
2
|
|
3
3
|
import { header } from '../utils/header';
|
4
4
|
import { join } from "path";
|
@@ -21,6 +21,9 @@ import { MsgBuilderPlugin } from "../plugins/msg-builder";
|
|
21
21
|
import { MessageComposerPlugin } from "../plugins/message-composer";
|
22
22
|
import { ClientPlugin } from "../plugins/client";
|
23
23
|
import { TypesPlugin } from "../plugins/types";
|
24
|
+
import { ContractsContextProviderPlugin } from "../plugins/provider";
|
25
|
+
import { createHelpers } from "../generators/create-helpers";
|
26
|
+
import { ContractsProviderBundlePlugin } from "../plugins/provider-bundle";
|
24
27
|
|
25
28
|
const defaultOpts: TSBuilderOptions = {
|
26
29
|
bundle: {
|
@@ -44,8 +47,14 @@ export interface BundleOptions {
|
|
44
47
|
bundlePath?: string;
|
45
48
|
};
|
46
49
|
|
50
|
+
export interface UseContractsOptions {
|
51
|
+
enabled?: boolean;
|
52
|
+
filename?: string;
|
53
|
+
};
|
54
|
+
|
47
55
|
export type TSBuilderOptions = {
|
48
56
|
bundle?: BundleOptions;
|
57
|
+
useContracts?: UseContractsOptions;
|
49
58
|
} & RenderOptions;
|
50
59
|
|
51
60
|
export type BuilderFileType = 'type' | 'client' | 'recoil' | 'react-query' | 'message-composer' | 'msg-builder' | 'plugin';
|
@@ -83,6 +92,7 @@ export class TSBuilder {
|
|
83
92
|
outPath: string;
|
84
93
|
options?: TSBuilderOptions;
|
85
94
|
plugins: IBuilderPlugin[] = [];
|
95
|
+
builderContext: BuilderContext = new BuilderContext();
|
86
96
|
|
87
97
|
protected files: BuilderFile[] = [];
|
88
98
|
|
@@ -94,6 +104,7 @@ export class TSBuilder {
|
|
94
104
|
new ReactQueryPlugin(this.options),
|
95
105
|
new RecoilPlugin(this.options),
|
96
106
|
new MsgBuilderPlugin(this.options),
|
107
|
+
new ContractsContextProviderPlugin(this.options),
|
97
108
|
]);
|
98
109
|
}
|
99
110
|
|
@@ -113,6 +124,8 @@ export class TSBuilder {
|
|
113
124
|
if (plugins && plugins.length) {
|
114
125
|
[].push.apply(this.plugins, plugins);
|
115
126
|
}
|
127
|
+
|
128
|
+
this.plugins.forEach(plugin=> plugin.setBuilder(this))
|
116
129
|
}
|
117
130
|
|
118
131
|
async build() {
|
@@ -147,6 +160,28 @@ export class TSBuilder {
|
|
147
160
|
if (this.options.bundle.enabled) {
|
148
161
|
this.bundle();
|
149
162
|
}
|
163
|
+
|
164
|
+
//create useContracts bundle file
|
165
|
+
const contractsProviderBundlePlugin = new ContractsProviderBundlePlugin(this.options);
|
166
|
+
contractsProviderBundlePlugin.setBuilder(this);
|
167
|
+
|
168
|
+
let files = await contractsProviderBundlePlugin.render(
|
169
|
+
"",
|
170
|
+
{
|
171
|
+
schemas: [],
|
172
|
+
},
|
173
|
+
this.outPath
|
174
|
+
);
|
175
|
+
if(files && files.length){
|
176
|
+
[].push.apply(this.files, files);
|
177
|
+
}
|
178
|
+
|
179
|
+
createHelpers({
|
180
|
+
outPath: this.outPath,
|
181
|
+
contracts: this.contracts,
|
182
|
+
options: this.options,
|
183
|
+
plugins: this.plugins,
|
184
|
+
}, this.builderContext);
|
150
185
|
}
|
151
186
|
|
152
187
|
async bundle() {
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import { join, dirname } from "path";
|
2
|
+
import { sync as mkdirp } from "mkdirp";
|
3
|
+
import pkg from "../../package.json";
|
4
|
+
import { writeContentToFile } from "../utils/files";
|
5
|
+
import { TSBuilderInput } from "../builder";
|
6
|
+
import { contractContextBase, contractsContextTSX } from "../helpers";
|
7
|
+
import { BuilderContext } from "wasm-ast-types";
|
8
|
+
|
9
|
+
const version = process.env.NODE_ENV === "test" ? "latest" : pkg.version;
|
10
|
+
const header = `/**
|
11
|
+
* This file and any referenced files were automatically generated by ${pkg.name}@${version}
|
12
|
+
* DO NOT MODIFY BY HAND. Instead, download the latest proto files for your chain
|
13
|
+
* and run the transpile command or yarn proto command to regenerate this bundle.
|
14
|
+
*/
|
15
|
+
\n`;
|
16
|
+
|
17
|
+
const write = (outPath: string, file: string, content: string) => {
|
18
|
+
const outFile = join(outPath, file);
|
19
|
+
mkdirp(dirname(outFile));
|
20
|
+
writeContentToFile(outPath, header + content, outFile);
|
21
|
+
};
|
22
|
+
|
23
|
+
export const createHelpers = (input: TSBuilderInput, builderContext: BuilderContext) => {
|
24
|
+
if (input.options?.useContracts?.enabled && Object.keys(builderContext.providers)?.length) {
|
25
|
+
write(input.outPath, "contractContextBase.ts", contractContextBase);
|
26
|
+
write(input.outPath, "contracts-context.tsx", contractsContextTSX);
|
27
|
+
}
|
28
|
+
};
|
@@ -0,0 +1,92 @@
|
|
1
|
+
export const contractContextBase = `
|
2
|
+
import {
|
3
|
+
CosmWasmClient,
|
4
|
+
SigningCosmWasmClient,
|
5
|
+
} from '@cosmjs/cosmwasm-stargate';
|
6
|
+
|
7
|
+
export interface IContractConstructor {
|
8
|
+
address: string | undefined;
|
9
|
+
cosmWasmClient: CosmWasmClient | undefined;
|
10
|
+
signingCosmWasmClient: SigningCosmWasmClient | undefined;
|
11
|
+
}
|
12
|
+
|
13
|
+
export const NO_SINGING_ERROR_MESSAGE = 'signingCosmWasmClient not connected';
|
14
|
+
|
15
|
+
export const NO_COSMWASW_CLIENT_ERROR_MESSAGE = 'cosmWasmClient not connected';
|
16
|
+
|
17
|
+
export const NO_ADDRESS_ERROR_MESSAGE = "address doesn't exist";
|
18
|
+
|
19
|
+
export const NO_SIGNING_CLIENT_ERROR_MESSAGE =
|
20
|
+
'Signing client is not generated. Please check ts-codegen config';
|
21
|
+
|
22
|
+
export const NO_QUERY_CLIENT_ERROR_MESSAGE =
|
23
|
+
'Query client is not generated. Please check ts-codegen config';
|
24
|
+
|
25
|
+
export const NO_MESSAGE_COMPOSER_ERROR_MESSAGE =
|
26
|
+
'Message composer client is not generated. Please check ts-codegen config';
|
27
|
+
|
28
|
+
/**
|
29
|
+
* a placeholder for non-generated classes
|
30
|
+
*/
|
31
|
+
export interface IEmptyClient {}
|
32
|
+
|
33
|
+
export interface ISigningClientProvider<T> {
|
34
|
+
getSigningClient(contractAddr: string): T;
|
35
|
+
}
|
36
|
+
|
37
|
+
export interface IQueryClientProvider<T> {
|
38
|
+
getQueryClient(contractAddr: string): T;
|
39
|
+
}
|
40
|
+
|
41
|
+
export interface IMessageComposerProvider<T> {
|
42
|
+
getMessageComposer(contractAddr: string): T;
|
43
|
+
}
|
44
|
+
|
45
|
+
export class ContractBase<
|
46
|
+
TSign = IEmptyClient,
|
47
|
+
TQuery = IEmptyClient,
|
48
|
+
TMsgComposer = IEmptyClient
|
49
|
+
> {
|
50
|
+
constructor(
|
51
|
+
protected address: string | undefined,
|
52
|
+
protected cosmWasmClient: CosmWasmClient | undefined,
|
53
|
+
protected signingCosmWasmClient: SigningCosmWasmClient | undefined,
|
54
|
+
private TSign?: new (
|
55
|
+
client: SigningCosmWasmClient,
|
56
|
+
sender: string,
|
57
|
+
contractAddress: string
|
58
|
+
) => TSign,
|
59
|
+
private TQuery?: new (
|
60
|
+
client: CosmWasmClient,
|
61
|
+
contractAddress: string
|
62
|
+
) => TQuery,
|
63
|
+
private TMsgComposer?: new (
|
64
|
+
sender: string,
|
65
|
+
contractAddress: string
|
66
|
+
) => TMsgComposer
|
67
|
+
) {}
|
68
|
+
|
69
|
+
public getSigningClient(contractAddr: string): TSign {
|
70
|
+
if (!this.signingCosmWasmClient) throw new Error(NO_SINGING_ERROR_MESSAGE);
|
71
|
+
if (!this.address) throw new Error(NO_ADDRESS_ERROR_MESSAGE);
|
72
|
+
if (!this.TSign) throw new Error(NO_SIGNING_CLIENT_ERROR_MESSAGE);
|
73
|
+
return new this.TSign(
|
74
|
+
this.signingCosmWasmClient,
|
75
|
+
this.address,
|
76
|
+
contractAddr
|
77
|
+
);
|
78
|
+
}
|
79
|
+
|
80
|
+
public getQueryClient(contractAddr: string): TQuery {
|
81
|
+
if (!this.cosmWasmClient) throw new Error(NO_COSMWASW_CLIENT_ERROR_MESSAGE);
|
82
|
+
if (!this.TQuery) throw new Error(NO_QUERY_CLIENT_ERROR_MESSAGE);
|
83
|
+
return new this.TQuery(this.cosmWasmClient, contractAddr);
|
84
|
+
}
|
85
|
+
|
86
|
+
public getMessageComposer(contractAddr: string): TMsgComposer {
|
87
|
+
if (!this.address) throw new Error(NO_ADDRESS_ERROR_MESSAGE);
|
88
|
+
if (!this.TMsgComposer) throw new Error(NO_MESSAGE_COMPOSER_ERROR_MESSAGE);
|
89
|
+
return new this.TMsgComposer(this.address, contractAddr);
|
90
|
+
}
|
91
|
+
}
|
92
|
+
`;
|