UNPKG

@cosmwasm/ts-codegen

Version:

@cosmwasm/ts-codegen converts your CosmWasm smart contracts into dev-friendly TypeScript classes so you can focus on shipping code.

167 lines (166 loc) 6.55 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TSBuilder = void 0; const generator_1 = __importDefault(require("@babel/generator")); const t = __importStar(require("@babel/types")); const ts_codegen_ast_1 = require("@cosmwasm/ts-codegen-ast"); const case_1 = require("case"); const deepmerge_1 = __importDefault(require("deepmerge")); const fs_1 = require("fs"); const mkdirp_1 = require("mkdirp"); const path_1 = require("path"); const path_2 = require("path"); const bundler_1 = require("../bundler"); const create_helpers_1 = require("../helpers/create-helpers"); const client_1 = require("../plugins/client"); const message_builder_1 = require("../plugins/message-builder"); const message_composer_1 = require("../plugins/message-composer"); const provider_1 = require("../plugins/provider"); const provider_bundle_1 = require("../plugins/provider-bundle"); const react_query_1 = require("../plugins/react-query"); const recoil_1 = require("../plugins/recoil"); const types_1 = require("../plugins/types"); const utils_1 = require("../utils"); const contracts_1 = require("../utils/contracts"); const header_1 = require("../utils/header"); const defaultOpts = { bundle: { enabled: true, scope: 'contracts', bundleFile: 'bundle.ts' }, useShorthandCtor: true }; ; ; ; function getContract(contractOpt) { if (typeof contractOpt === 'string') { const name = (0, path_2.basename)(contractOpt); const contractName = (0, case_1.pascal)(name); return { name: contractName, dir: contractOpt }; } return { name: (0, case_1.pascal)(contractOpt.name), dir: contractOpt.dir }; } class TSBuilder { contracts; outPath; options; plugins = []; builderContext = new ts_codegen_ast_1.BuilderContext(); files = []; loadDefaultPlugins() { this.plugins.push(new types_1.TypesPlugin(this.options), new client_1.ClientPlugin(this.options), new message_composer_1.MessageComposerPlugin(this.options), new react_query_1.ReactQueryPlugin(this.options), new recoil_1.RecoilPlugin(this.options), new message_builder_1.MessageBuilderPlugin(this.options), new provider_1.ContractsContextProviderPlugin(this.options), new provider_bundle_1.ContractsProviderBundlePlugin(this.options)); } constructor({ contracts, outPath, options, plugins }) { this.contracts = contracts; this.outPath = outPath; this.options = (0, deepmerge_1.default)((0, deepmerge_1.default)(ts_codegen_ast_1.defaultOptions, defaultOpts), options ?? {}); this.loadDefaultPlugins(); if (plugins && plugins.length) { this.plugins.push(...plugins); } this.plugins.forEach(plugin => plugin.setBuilder(this)); } async build() { await this.process(); await this.after(); } // lifecycle functions async process() { for (const contractOpt of this.contracts) { const contract = getContract(contractOpt); //resolve contract schema. const contractInfo = await (0, utils_1.readSchemas)({ schemaDir: contract.dir }); //lifecycle and plugins. await this.render('main', contract.name, contractInfo); } } async render(lifecycle, name, contractInfo) { const plugins = lifecycle ? this.plugins.filter((p) => p.lifecycle === lifecycle) : this.plugins; for (const plugin of plugins) { let files = await plugin.render(this.outPath, name, contractInfo ?? (0, contracts_1.createDefaultContractInfo)()); if (files && files.length) { this.files.push(...files); } } } async after() { await this.render('after'); const helpers = (0, create_helpers_1.createHelpers)({ outPath: this.outPath, contracts: this.contracts, options: this.options, plugins: this.plugins, }, this.builderContext); if (helpers && helpers.length) { this.files.push(...helpers); } if (this.options.bundle.enabled) { this.bundle(); } } async bundle() { const allFiles = this.files; const bundleFile = this.options.bundle.bundleFile; const bundlePath = (0, path_1.join)(this.options?.bundle?.bundlePath ?? this.outPath, bundleFile); const bundleVariables = {}; const importPaths = []; allFiles.forEach(file => { (0, bundler_1.createFileBundle)(`${this.options.bundle.scope}.${file.contract}`, file.filename, bundlePath, importPaths, bundleVariables); }); const ast = (0, bundler_1.recursiveModuleBundle)(bundleVariables); const nodes = [ ...importPaths, ...ast ]; // @ts-ignore let code = (0, generator_1.default)(t.program( // @ts-ignore nodes)).code; if (this.options?.bundle?.bundlePath) { (0, mkdirp_1.sync)(this.options?.bundle?.bundlePath); } (0, mkdirp_1.sync)(this.outPath); if (code.trim() === '') code = 'export {};'; (0, fs_1.writeFileSync)(bundlePath, header_1.header + code); } } exports.TSBuilder = TSBuilder;