import * as globWithCallbacks from 'glob' ; import * as fs from 'fs' ; import * as path from 'path' ; import { promisify } from 'util' ; import mapTypes from './typeMap' ; import { ConfigManager } from '../configManager' ; import { pascalCase , camelCase } from './utils' ; const glob = promisify ( globWithCallbacks ) ; type IndentedGeneratorLevel = { [ key ] : Array < string > | IndentedGeneratorLevel ; } ; type GeneratorLevel = Array < string | IndentedGeneratorLevel > ; author Kevin Brown <github.com/thekevinbrown>
 *  author Mitch Pierias <github.com/MitchPierias>
 *  param eosType param contractName param contractStructs export const mapParameterType = ( { eosType , contractName , contractStructs , } ) => { const wrapper = eosType . endsWith ( '[]' ) ? 'Array' : undefined ; const parameterType = eosType . replace ( '[]' , '' ) ; const type = contractStructs && contractName && contractStructs [ parameterType ] ? pascalCase ( contractName ) + pascalCase ( parameterType ) : mapTypes [ parameterType ] || 'string' ; if ( wrapper ) { return `${ wrapper }<${ type }>` ; } else { return type ; } } ; export const generateTypesFromString = async ( rawABI , contractName ) : Promise < string > => { const abi = JSON . parse ( rawABI ) ; let contractActions = abi . actions ; let contractTables = abi . tables ; let contractStructs = Object . assign ( { } , ... abi . structs . map ( ( struct ) => ( { [ struct [ 'name' ] ] : struct } ) ) ) ; const result = [ '// =====================================================' , '// WARNING: GENERATED FILE' , '//' , '// Any changes you make will be overwritten by Lamington' , '// =====================================================' , '' , ] ; const imports = [ 'Account' , 'Contract' , 'GetTableRowsOptions' , 'ExtendedAsset' , 'ExtendedSymbol' , 'ActorPermission' , ] ; if ( contractTables . length > 0 ) imports . push ( 'TableRowsResult' ) ; result . push ( `import { ${ imports . join ( ', ' ) } } from 'lamington';` ) ; result . push ( '' ) ; result . push ( '// Table row types' ) ; for ( const key in contractStructs ) { const structInterface = { [ `export interface ${ pascalCase ( contractName ) }${ pascalCase ( key ) }` ] : contractStructs [ key ] . fields . map ( ( field ) => `${ field . name }: ${ mapParameterType ( { contractName , eosType : field . type } ) };` ) , } ; result . push ( structInterface ) ; result . push ( '' ) ; } const generatedContractActions = contractActions . map ( ( action ) => { const parameters = contractStructs [ action . name ] . fields . map ( ( parameter ) => `${ parameter . name }: ${ mapParameterType ( { contractName , contractStructs , eosType : parameter . type , } ) }` ) ; parameters . push ( 'options?: { from?: Account, auths?: ActorPermission[] }' ) ; return `${ action . name }(${ parameters . join ( ', ' ) }): Promise<any>;` ; } ) ; const generatedTables = contractTables . map ( ( table ) => `${ camelCase ( table . name ) + 'Table' }(options?: GetTableRowsOptions): Promise<TableRowsResult<${ pascalCase ( contractName ) }${ pascalCase ( table . type ) }>>;` ) ; const contractInterface = { [ `export interface ${ pascalCase ( contractName ) } extends Contract` ] : [ '// Actions' , ... generatedContractActions , '' , '// Tables' , ... generatedTables , ] , } ; result . push ( contractInterface ) ; result . push ( '' ) ; return flattenGeneratorLevels ( result ) ; } ; author Kevin Brown <github.com/thekevinbrown>
  export const generateAllTypes = async ( ) => { const files = await glob ( '**/*.abi' ) ; if ( files . length === 0 ) throw new Error ( 'No ABI files to generate from. Exiting.' ) ; for ( const file of files ) await generateTypes ( file ) ; } ; author Kevin Brown <github.com/thekevinbrown>
 *  author Mitch Pierias <github.com/MitchPierias>
 *  author Dallas Johnson <github.com/dallasjohnson>

 *  param contractIdentifier export const generateTypes = async ( contractIdentifier ) => { const contractName = path . basename ( contractIdentifier ) ; const abiPath = path . join ( ConfigManager . outDir , 'compiled_contracts' , `${ contractIdentifier }.abi` ) ; if ( ! fs . existsSync ( path . resolve ( abiPath ) ) ) throw new Error ( `Missing ABI file at path '${ path . resolve ( abiPath ) }'` ) ; const rawABI = fs . readFileSync ( path . resolve ( abiPath ) , 'utf8' ) ; const generaterLevels = await generateTypesFromString ( rawABI , contractName ) ; await saveInterface ( contractIdentifier , generaterLevels ) ; } ; const flattenGeneratorLevels = ( interfaceContent ) : string => { let result = '' ; let indentLevel = 0 ; const write = ( value ) => ( result += '\t' . repeat ( indentLevel ) + value + '\n' ) ; const writeIndented = ( level ) => { for ( const outerWrapper of Object . keys ( level ) ) { write ( `${ outerWrapper } {` ) ; indentLevel ++ ; writeLevel ( level [ outerWrapper ] ) ; indentLevel -- ; write ( '}' ) ; } } ; const writeLevel = ( level ) => { if ( Array . isArray ( level ) ) { for ( const entry of level ) { if ( typeof entry === 'string' ) { write ( entry ) ; } else { writeIndented ( entry ) ; } } } else { writeIndented ( level ) ; } } ; writeLevel ( interfaceContent ) ; return result ; } ; author Kevin Brown <github.com/thekevinbrown>
 *  author Dallas Johnson <github.com/dallasjohnson>
 *  param contractIdentifier param interfaceContent const saveInterface = async ( contractIdentifier , interfaceContent ) => { const file = fs . createWriteStream ( `${ contractIdentifier }.ts` ) ; file . write ( interfaceContent , ( error ) => { if ( error ) { throw error ; } } ) ; file . close ( ) ; } ;