UNPKG

@cosmology/ast

Version:
122 lines (121 loc) 5.12 kB
import * as t from '@babel/types'; import { identifier, tsPropertySignature, makeCommentBlock } from '../../../utils'; import { getFieldOptionalityForAmino, getOneOfs } from '../types'; import { SymbolNames, getFieldAminoTypeReference, getTSAminoType } from '../../types'; import { getAminoTypeName } from '../../amino'; const getAminoField = (context, field) => { let ast = null; ast = getFieldAminoTypeReference(context, field); if (field.rule === 'repeated') { ast = t.tsArrayType(ast); } if (field.keyType) { ast = t.tsUnionType([ t.tsTypeLiteral([ t.tsIndexSignature([ identifier('key', t.tsTypeAnnotation(getTSAminoType(context, field.keyType))) ], t.tsTypeAnnotation(ast)) ]) ]); } return ast; }; export const createAminoType = (context, name, proto) => { const oneOfs = getOneOfs(proto); const AminoName = SymbolNames.Amino(name); // scalar amino types! let declaration; if (proto.type === 'Type') { switch (proto.name) { case 'Duration': case 'google.protobuf.Duration': case 'Timestamp': case 'google.protobuf.Timestamp': declaration = t.exportNamedDeclaration(t.tsTypeAliasDeclaration(t.identifier(AminoName), null, t.tsStringKeyword())); break; default: } } // declaration if (!declaration) { declaration = t.exportNamedDeclaration(t.tsInterfaceDeclaration(t.identifier(AminoName), null, [], t.tsInterfaceBody(Object.keys(proto.fields).reduce((m, fieldName) => { const isOneOf = oneOfs.includes(fieldName); const field = proto.fields[fieldName]; let isOptional = getFieldOptionalityForAmino(context, field, isOneOf); const orig = field.options?.['(telescope:orig)'] ?? fieldName; // this (useOriginalCase) is always true, right? // let fieldNameWithCase = options.useOriginalCase ? orig : fieldName; let fieldNameWithCase = orig; // should we actually just edit/add comments // to make this more "native" for any google.protobuf.Any? // let's see... if (name === 'Any' && context.ref.proto.package === 'google.protobuf' && // options.type === 'Amino' && orig === 'type_url') { // type_url => type fieldNameWithCase = 'type'; isOptional = false; } let aminoField = getAminoField(context, field); if (name === 'Any' && context.ref.proto.package === 'google.protobuf' && // options.type === 'Amino' && orig === 'value') { aminoField = t.tsAnyKeyword(); isOptional = false; } const propSig = tsPropertySignature(t.identifier(fieldNameWithCase), t.tsTypeAnnotation(aminoField), isOptional); const comments = []; if (field.comment) { comments.push(makeCommentBlock(field.comment)); } if (field.options?.deprecated) { comments.push(makeCommentBlock('@deprecated')); } if (comments.length) { propSig.leadingComments = comments; } m.push(propSig); return m; }, [])))); } const comments = []; if (proto.comment) { comments.push(makeCommentBlock(proto.comment)); } if (proto.options?.deprecated) { comments.push(makeCommentBlock('@deprecated')); } if (comments.length) { declaration.leadingComments = comments; } return declaration; }; export const createAminoTypeType = (context, name, proto) => { const AminoName = SymbolNames.Amino(name); const AminoTypeName = SymbolNames.AminoMsg(name); const aminoName = getAminoTypeName(context, context.ref.proto, proto); const typ = aminoName ? t.tsLiteralType(t.stringLiteral(aminoName)) : t.tsTypeReference(t.identifier('string')); let typeAnnotation = t.tsTypeAnnotation(typ); if (name === 'Any' && context.ref.proto.package === 'google.protobuf') { // replace type with plain string for this one case typeAnnotation = t.tsTypeAnnotation(t.tsStringKeyword()); } // scalar amino types! return t.exportNamedDeclaration(t.tsInterfaceDeclaration(t.identifier(AminoTypeName), null, [], t.tsInterfaceBody([ tsPropertySignature(t.identifier('type'), typeAnnotation, false), tsPropertySignature(t.identifier('value'), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(AminoName))), false) ]))); }; export const createEnumAminoType = (context, name, proto) => { return t.exportNamedDeclaration(t.variableDeclaration('const', [ t.variableDeclarator(t.identifier(SymbolNames.Amino(name)), t.identifier(name)) ])); // return createProtoEnum( // context, // name + 'Amino', // proto // ); };