diff options
author | Leonid <logvinov.leon@gmail.com> | 2017-12-06 03:39:36 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-06 03:39:36 +0800 |
commit | 1153fa093b5a20863a2a7c1237a39ffdf7aaec49 (patch) | |
tree | b6d9bdad0c339d02336698f326f00352992be6d4 /packages/abi-gen/src/index.ts | |
parent | c0015c2c118c0fd563fa8d2ee672c28dca7ef809 (diff) | |
parent | c64ec92fb23fd130d0c54a4d42147bb468e434d9 (diff) | |
download | dexon-sol-tools-1153fa093b5a20863a2a7c1237a39ffdf7aaec49.tar dexon-sol-tools-1153fa093b5a20863a2a7c1237a39ffdf7aaec49.tar.gz dexon-sol-tools-1153fa093b5a20863a2a7c1237a39ffdf7aaec49.tar.bz2 dexon-sol-tools-1153fa093b5a20863a2a7c1237a39ffdf7aaec49.tar.lz dexon-sol-tools-1153fa093b5a20863a2a7c1237a39ffdf7aaec49.tar.xz dexon-sol-tools-1153fa093b5a20863a2a7c1237a39ffdf7aaec49.tar.zst dexon-sol-tools-1153fa093b5a20863a2a7c1237a39ffdf7aaec49.zip |
Merge pull request #249 from 0xProject/feature/typed-contracts
ABI to TS generator
Diffstat (limited to 'packages/abi-gen/src/index.ts')
-rw-r--r-- | packages/abi-gen/src/index.ts | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/packages/abi-gen/src/index.ts b/packages/abi-gen/src/index.ts new file mode 100644 index 000000000..12b78f96f --- /dev/null +++ b/packages/abi-gen/src/index.ts @@ -0,0 +1,103 @@ +#!/usr/bin/env node + +import chalk from 'chalk'; +import * as fs from 'fs'; +import {sync as globSync} from 'glob'; +import * as Handlebars from 'handlebars'; +import * as _ from 'lodash'; +import * as mkdirp from 'mkdirp'; +import * as yargs from 'yargs'; + +import toSnakeCase = require('to-snake-case'); +import * as Web3 from 'web3'; + +import {ContextData, ParamKind} from './types'; +import {utils} from './utils'; + +const ABI_TYPE_METHOD = 'function'; +const MAIN_TEMPLATE_NAME = 'contract.mustache'; + +const args = yargs + .option('abiGlob', { + describe: 'Glob pattern to search for ABI JSON files', + type: 'string', + demand: true, + }) + .option('templates', { + describe: 'Folder where to search for templates', + type: 'string', + demand: true, + }) + .option('output', { + describe: 'Folder where to put the output files', + type: 'string', + demand: true, + }) + .option('fileExtension', { + describe: 'The extension of the output file', + type: 'string', + demand: true, + }) + .argv; + +function writeOutputFile(name: string, renderedTsCode: string): void { + const fileName = toSnakeCase(name); + const filePath = `${args.output}/${fileName}.${args.fileExtension}`; + fs.writeFileSync(filePath, renderedTsCode); + utils.log(`Created: ${chalk.bold(filePath)}`); +} + +Handlebars.registerHelper('parameterType', utils.solTypeToTsType.bind(utils, ParamKind.Input)); +Handlebars.registerHelper('returnType', utils.solTypeToTsType.bind(utils, ParamKind.Output)); +const partialTemplateFileNames = globSync(`${args.templates}/partials/**/*.mustache`); +for (const partialTemplateFileName of partialTemplateFileNames) { + const namedContent = utils.getNamedContent(partialTemplateFileName); + Handlebars.registerPartial(namedContent.name, namedContent.content); +} + +const mainTemplate = utils.getNamedContent(`${args.templates}/${MAIN_TEMPLATE_NAME}`); +const template = Handlebars.compile<ContextData>(mainTemplate.content); +const abiFileNames = globSync(args.abiGlob); +if (_.isEmpty(abiFileNames)) { + utils.log(`${chalk.red(`No ABI files found.`)}`); + utils.log(`Please make sure you've passed the correct folder name and that the files have + ${chalk.bold('*.json')} extensions`); + process.exit(1); +} else { + utils.log(`Found ${chalk.green(`${abiFileNames.length}`)} ${chalk.bold('ABI')} files`); + mkdirp.sync(args.output); +} +for (const abiFileName of abiFileNames) { + const namedContent = utils.getNamedContent(abiFileName); + utils.log(`Processing: ${chalk.bold(namedContent.name)}...`); + const parsedContent = JSON.parse(namedContent.content); + const ABI = _.isArray(parsedContent) ? + parsedContent : // ABI file + parsedContent.abi; // Truffle contracts file + if (_.isUndefined(ABI)) { + utils.log(`${chalk.red(`ABI not found in ${abiFileName}.`)}`); + utils.log(`Please make sure your ABI file is either an array with ABI entries or an object with the abi key`); + process.exit(1); + } + const methodAbis = ABI.filter((abi: Web3.AbiDefinition) => abi.type === ABI_TYPE_METHOD) as Web3.MethodAbi[]; + const methodsData = _.map(methodAbis, methodAbi => { + _.map(methodAbi.inputs, input => { + if (_.isEmpty(input.name)) { + // Auto-generated getters don't have parameter names + input.name = 'index'; + } + }); + // This will make templates simpler + const methodData = { + ...methodAbi, + singleReturnValue: methodAbi.outputs.length === 1, + }; + return methodData; + }); + const contextData = { + contractName: namedContent.name, + methods: methodsData, + }; + const renderedTsCode = template(contextData); + writeOutputFile(namedContent.name, renderedTsCode); +} |