@cosmology/ast
Version:
Cosmos TypeScript AST generation
95 lines (94 loc) • 4.58 kB
JavaScript
import * as t from '@babel/types';
import { slugify } from '@cosmology/utils';
import { arrowFunctionExpression, identifier } from '../../../utils';
const firstUpper = (s) => s = s.charAt(0).toUpperCase() + s.slice(1);
export const getInterfaceToAminoName = (str) => {
return firstUpper(slugify(str) + '_ToAmino');
};
export const createInterfaceToAmino = (context, ref, interfaceName) => {
if (interfaceName === 'cosmos.crypto.PubKey') {
// return a helper!
context.addUtil('decodePubkey');
context.addUtil('Pubkey');
const functionName = getInterfaceToAminoName(interfaceName);
return makeFunctionWrapper(context, functionName, t.returnStatement(t.callExpression(t.identifier('decodePubkey'), [
t.identifier('content')
])), t.tsTypeAnnotation(t.tsUnionType([t.tsTypeReference(t.identifier("Pubkey")), t.tsNullKeyword()])));
}
const typeMap = context.store.getTypeUrlMap(ref);
const typeRefs = typeMap[interfaceName];
return createInterfaceToAminoHelper(context, getInterfaceToAminoName(interfaceName), typeRefs);
};
const makeFunctionWrapper = (context, functionName, stmt, returnType) => {
return t.exportNamedDeclaration(t.variableDeclaration('const', [
t.variableDeclarator(t.identifier(functionName), arrowFunctionExpression([
identifier('content', t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Any')))),
...(context.options.interfaces.enabled &&
context.options.interfaces.useUseInterfacesParams
? [
t.assignmentPattern(identifier("useInterfaces", t.tsTypeAnnotation(t.tsBooleanKeyword())), t.identifier((context.pluginValue("interfaces.useByDefault") ?? true).toString())),
]
: []),
], t.blockStatement([
stmt
]), returnType))
]));
};
export const createInterfaceToAminoHelper = (context, functionName, typeRefs) => {
// 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.typeUrl), [
// return
t.returnStatement(t.objectExpression([
t.objectProperty(t.identifier('type'), t.stringLiteral(type.aminoType)),
t.objectProperty(t.identifier('value'), t.callExpression(t.memberExpression(t.identifier(type.importAs), t.identifier('toAmino')), [
t.callExpression(t.memberExpression(t.identifier(type.importAs), t.identifier('decode')), [
t.memberExpression(t.identifier('content'), t.identifier('value')),
t.identifier('undefined'),
...(context.options.interfaces.enabled &&
context.options.interfaces.useUseInterfacesParams
? [
t.identifier('useInterfaces')
]
: []),
]),
...(context.options.interfaces.enabled &&
context.options.interfaces.useUseInterfacesParams
? [
t.identifier('useInterfaces')
]
: []),
]))
]))
]);
}).filter(Boolean);
let ast;
if (!switchCases.length) {
ast = t.returnStatement(t.callExpression(t.memberExpression(t.identifier('Any'), t.identifier('toAmino')), [
t.identifier('content'),
...(context.options.interfaces.enabled && context.options.interfaces.useUseInterfacesParams ? [
t.identifier('useInterfaces')
] : []),
]));
}
else {
ast = t.switchStatement(t.memberExpression(t.identifier('content'), t.identifier('typeUrl')), [
...switchCases,
// default
t.switchCase(null, [
t.returnStatement(t.callExpression(t.memberExpression(t.identifier('Any'), t.identifier('toAmino')), [
t.identifier('content'),
...(context.options.interfaces.enabled && context.options.interfaces.useUseInterfacesParams ? [
t.identifier('useInterfaces')
] : []),
]))
])
]);
}
return makeFunctionWrapper(context, functionName, ast);
};