UNPKG

@cosmology/ast

Version:
199 lines (179 loc) 7.01 kB
import * as t from '@babel/types'; import { InterfaceTypeUrlMap, ProtoRef, TraverseTypeUrlRef, TypeUrlRef } from '@cosmology/types'; import { slugify } from '@cosmology/utils'; import { identifier } from '../../../utils'; import { ProtoParseContext } from "../../context"; const firstUpper = (s: string) => s = s.charAt(0).toUpperCase() + s.slice(1); export const getInterfaceFromAminoName = (str: string) => { return firstUpper(slugify(str) + '_FromAmino'); }; const makeFunctionWrapper = (functionName: string, stmt: t.Statement) => { let arrowFunction = t.arrowFunctionExpression( [ identifier( 'content', t.tsTypeAnnotation( t.tsTypeReference( t.identifier('AnyAmino') ) ) ) ], t.blockStatement([ stmt ]) ); arrowFunction.returnType = t.tsTypeAnnotation( t.tsTypeReference( t.identifier('Any') ) ); return t.exportNamedDeclaration( t.variableDeclaration( 'const', [ t.variableDeclarator( t.identifier(functionName), arrowFunction ) ] ) ); }; export const createInterfaceFromAmino = ( context: ProtoParseContext, ref: ProtoRef, interfaceName: string, ) => { if (interfaceName === 'cosmos.crypto.PubKey') { // return a helper! context.addUtil('encodePubkey'); const functionName = getInterfaceFromAminoName(interfaceName); return makeFunctionWrapper(functionName, t.returnStatement( t.callExpression( t.identifier('encodePubkey'), [t.identifier('content')] ) )); } const typeMap = context.store.getTypeUrlMap(ref); const typeRefs = typeMap[interfaceName]; return createInterfaceFromAminoHelper( context, getInterfaceFromAminoName(interfaceName), typeRefs ); }; export const createInterfaceFromAminoHelper = ( context: ProtoParseContext, functionName: string, typeRefs: TraverseTypeUrlRef[] ) => { context.addUtil('DeepPartial'); // MARKED AS NOT DRY const allTypes: TypeUrlRef[] = typeRefs?.reduce((m, typeRef) => { return [...m, ...typeRef.types]; }, []) ?? []; const switchCases = allTypes.map(type => { if (!type.aminoType) return; return t.switchCase( t.stringLiteral(type.aminoType), [ t.returnStatement( t.callExpression( t.memberExpression( t.identifier('Any'), t.identifier('fromPartial') ), [ t.objectExpression([ t.objectProperty( t.identifier('typeUrl'), t.stringLiteral(type.typeUrl) ), t.objectProperty( t.identifier('value'), t.callExpression( t.memberExpression( t.callExpression( t.memberExpression( t.identifier(type.importAs), t.identifier('encode') ), [ t.callExpression( t.memberExpression( t.identifier(type.importAs), t.identifier('fromPartial') ), [ t.callExpression( t.memberExpression( t.identifier(type.importAs), t.identifier('fromAmino') ), [ t.memberExpression( t.identifier('content'), t.identifier('value') ) ] ) ] ) ] ), t.identifier('finish') ), [] ) ), ]) ] ) )] ); }).filter(Boolean); let ast: t.Statement; if (!switchCases.length) { ast = t.returnStatement( t.callExpression( t.memberExpression( t.identifier('Any'), t.identifier('fromAmino') ), [ t.identifier('content') ] ) ); } else { ast = t.switchStatement( t.memberExpression( t.identifier('content'), t.identifier('type') ), [ ...switchCases, /// default t.switchCase( null, [ t.returnStatement( t.callExpression( t.memberExpression( t.identifier('Any'), t.identifier('fromAmino') ), [ t.identifier('content') ] ) ) ] ) ] ); } return makeFunctionWrapper(functionName, ast); };