@cosmology/ast
Version:
Cosmos TypeScript AST generation
73 lines (72 loc) • 3.49 kB
JavaScript
import * as t from '@babel/types';
import { slugify } from '@cosmology/utils';
import { identifier } from '../../../utils';
const firstUpper = (s) => s = s.charAt(0).toUpperCase() + s.slice(1);
export const getInterfaceFromAminoName = (str) => {
return firstUpper(slugify(str) + '_FromAmino');
};
const makeFunctionWrapper = (functionName, stmt) => {
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, ref, interfaceName) => {
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, functionName, typeRefs) => {
context.addUtil('DeepPartial');
// MARKED AS NOT DRY
const allTypes = 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;
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);
};