@cosmology/ast
Version:
Cosmos TypeScript AST generation
475 lines (474 loc) • 23.6 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.toAminoMessages = exports.arrayTypes = exports.toAminoJSON = void 0;
const t = __importStar(require("@babel/types"));
const utils_1 = require("../../../utils");
const types_1 = require("../../types");
const implements_1 = require("../implements");
const utils_2 = require("@cosmology/utils");
const setValue = (args, valExpr) => {
const { propName, origName } = (0, types_1.getFieldNames)(args.field);
const omitEmpty = (0, utils_2.shouldOmitEmpty)(args.context, args.field);
valExpr = valExpr ?? t.memberExpression(t.identifier("message"), t.identifier(propName));
if (omitEmpty) {
valExpr = t.conditionalExpression(t.binaryExpression("===", valExpr, (0, types_1.getDefaultTSTypeFromProtoType)(args.context, args.field, args.isOneOf, true)), t.identifier('undefined'), valExpr);
}
else {
valExpr = t.logicalExpression("??", valExpr, (0, types_1.getDefaultTSTypeFromProtoType)(args.context, args.field, args.isOneOf, true));
}
return t.expressionStatement(t.assignmentExpression("=", t.memberExpression(t.identifier("obj"), t.identifier(origName)), valExpr));
};
exports.toAminoJSON = {
scalar(args, valExpr) {
return setValue(args, valExpr);
},
string(args) {
let valueExpr;
const useCosmosSDKDec = args.context.pluginValue('aminoEncoding.customTypes.useCosmosSDKDec');
if (useCosmosSDKDec) {
const isCosmosSDKDec = (args.field.options?.['(gogoproto.customtype)'] ==
'github.com/cosmos/cosmos-sdk/types.Dec') ||
(args.field.options?.['(gogoproto.customtype)'] ==
'cosmossdk.io/math.LegacyDec');
if (isCosmosSDKDec) {
args.context.addUtil('padDecimal');
const { propName } = (0, types_1.getFieldNames)(args.field);
valueExpr = t.callExpression(t.identifier('padDecimal'), [
t.memberExpression(t.identifier('message'), t.identifier(propName))
]);
}
}
return setValue(args, valueExpr);
},
double(args) {
return exports.toAminoJSON.scalar(args);
},
float(args) {
return exports.toAminoJSON.scalar(args);
},
bool(args) {
return exports.toAminoJSON.scalar(args);
},
number(args) {
return exports.toAminoJSON.scalar(args);
},
int32(args) {
return exports.toAminoJSON.scalar(args);
},
uint32(args) {
return exports.toAminoJSON.scalar(args);
},
sint32(args) {
return exports.toAminoJSON.scalar(args);
},
fixed32(args) {
return exports.toAminoJSON.scalar(args);
},
sfixed32(args) {
return exports.toAminoJSON.scalar(args);
},
// obj.big = message.big ? message.big.toString() : "0";
// obj.o_big = message.oBig !== BigInt(0) ? message.oBig.toString() : undefined;
long(args) {
const { propName, origName } = (0, types_1.getFieldNames)(args.field);
const omitEmpty = (0, utils_2.shouldOmitEmpty)(args.context, args.field);
const nullTest = omitEmpty
? utils_1.TypeLong.getLongNotZero(propName, args.context)
: t.memberExpression(t.identifier("message"), t.identifier(propName));
const template = require('@babel/template').default;
// Create a template that represents message.oBig.toString()
const expressionTemplate = template.expression(`
MESSAGE.OBJECT?.METHOD()
`);
// Generate AST node from the template by providing the identifiers
const messageNode = expressionTemplate({
MESSAGE: t.identifier('message'),
OBJECT: t.identifier(propName),
METHOD: t.identifier('toString'),
});
return t.expressionStatement(t.assignmentExpression("=", t.memberExpression(t.identifier("obj"), t.identifier(origName)), t.conditionalExpression(nullTest, messageNode, omitEmpty ? t.identifier("undefined") : t.stringLiteral("0"))));
},
int64(args) {
return exports.toAminoJSON.long(args);
},
uint64(args) {
return exports.toAminoJSON.long(args);
},
sint64(args) {
return exports.toAminoJSON.long(args);
},
fixed64(args) {
return exports.toAminoJSON.long(args);
},
sfixed64(args) {
return exports.toAminoJSON.long(args);
},
// obj.proto = message.proto ? AccessConfig.toAmino(message.proto) : AccessConfig.toAmino(AccessConfig.fromPartial({}));
// obj.o_proto = message.oProto ? AccessConfig.toAmino(message.oProto) : undefined;
protoType(args) {
const { propName, origName } = (0, types_1.getFieldNames)(args.field);
const name = args.context.getTypeName(args.field);
const omitEmpty = (0, utils_2.shouldOmitEmpty)(args.context, args.field);
let defaultValue = omitEmpty ? t.identifier('undefined') : (0, types_1.getDefaultTSTypeFromAminoTypeDefault)(args.context, args.field);
if (args.field.type === 'ibc.core.client.v1.Height') {
defaultValue = t.objectExpression([]);
}
return t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.identifier('obj'), t.identifier(origName)), t.conditionalExpression(t.memberExpression(t.identifier('message'), t.identifier(propName)), t.callExpression(t.memberExpression(t.identifier(name), t.identifier('toAmino')), [
t.memberExpression(t.identifier('message'), t.identifier(propName)),
...(args.context.options.interfaces.enabled && args.context.options.interfaces.useUseInterfacesParams ? [
t.identifier('useInterfaces')
] : []),
]), defaultValue)));
},
anyType(args) {
const { propName, origName } = (0, types_1.getFieldNames)(args.field);
const interfaceName = args.field.options['(cosmos_proto.accepts_interface)'];
const interfaceFnName = (0, implements_1.getInterfaceToAminoName)(interfaceName);
args.context.getTypeName(args.field);
const omitEmpty = (0, utils_2.shouldOmitEmpty)(args.context, args.field);
let defaultValue = !omitEmpty ? t.objectExpression([
t.objectProperty(t.identifier("type"), t.stringLiteral("")),
t.objectProperty(t.identifier("value"), t.objectExpression([])),
]) : t.identifier('undefined');
let aminoFuncExpr = t.callExpression(t.identifier(interfaceFnName), [
t.tsAsExpression(t.memberExpression(t.identifier('message'), t.identifier(propName)), t.tsTypeReference(t.identifier('Any'))),
...(args.context.options.interfaces.enabled && args.context.options.interfaces.useUseInterfacesParams ? [
t.identifier('useInterfaces')
] : []),
]);
const isGlobalRegistry = args.context.options.interfaces?.useGlobalDecoderRegistry;
if (isGlobalRegistry) {
aminoFuncExpr = t.callExpression(t.memberExpression(t.identifier('GlobalDecoderRegistry'), t.identifier('toAminoMsg')), [
t.memberExpression(t.identifier('message'), t.identifier(propName))
]);
}
return t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.identifier('obj'), t.identifier(origName)), t.conditionalExpression(t.memberExpression(t.identifier('message'), t.identifier(propName)), aminoFuncExpr, defaultValue)));
},
type(args) {
if (!args.context.options.aminoEncoding.useLegacyInlineEncoding &&
args.context.options.interfaces.enabled &&
args.field.type === 'google.protobuf.Any' &&
args.field.options['(cosmos_proto.accepts_interface)']) {
return exports.toAminoJSON.anyType(args);
}
return exports.toAminoJSON.protoType(args);
},
enum(args) {
return exports.toAminoJSON.scalar(args);
},
bytes(args) {
args.context.addUtil('base64FromBytes');
const { propName, origName } = (0, types_1.getFieldNames)(args.field);
const omitEmpty = (0, utils_2.shouldOmitEmpty)(args.context, args.field);
let defaultValue = !omitEmpty ? t.stringLiteral("") : t.identifier('undefined');
const expr = t.callExpression(t.identifier('base64FromBytes'), [
t.memberExpression(t.identifier('message'), t.identifier(propName))
]);
return t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.identifier('obj'), t.identifier(origName)), t.conditionalExpression(t.memberExpression(t.identifier('message'), t.identifier(propName)), expr, defaultValue)));
},
duration(args) {
return exports.toAminoJSON.type(args);
},
timestamp(args) {
const timestampFormat = args.context.pluginValue('prototypes.typingsFormat.timestamp');
switch (timestampFormat) {
case 'timestamp':
return exports.toAminoJSON.type(args);
case 'date':
default:
return exports.toAminoJSON.timestampDate(args);
}
},
timestampDate(args) {
const { propName, origName } = (0, types_1.getFieldNames)(args.field);
args.context.addUtil('toTimestamp');
const omitEmpty = (0, utils_2.shouldOmitEmpty)(args.context, args.field);
let defaultValue = !omitEmpty ? (0, types_1.getDefaultTSTypeFromProtoType)(args.context, args.field, args.isOneOf, true) : t.identifier('undefined');
return t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.identifier('obj'), t.identifier(origName)), t.conditionalExpression(t.memberExpression(t.identifier('message'), t.identifier(propName)), t.callExpression(t.memberExpression(t.identifier('Timestamp'), t.identifier('toAmino')), [
t.callExpression(t.identifier('toTimestamp'), [
t.memberExpression(t.identifier('message'), t.identifier(propName))
])
]), defaultValue)));
},
pubkey(args) {
args.context.addUtil('decodePubkey');
const { propName, origName } = (0, types_1.getFieldNames)(args.field);
const omitEmpty = (0, utils_2.shouldOmitEmpty)(args.context, args.field);
let defaultValue = !omitEmpty ? (0, types_1.getDefaultTSTypeFromProtoType)(args.context, args.field, args.isOneOf, true) : t.identifier('undefined');
return t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.identifier('obj'), t.identifier(origName)), t.conditionalExpression(t.memberExpression(t.identifier('message'), t.identifier(propName)),
//
t.callExpression(t.identifier('decodePubkey'), [
t.memberExpression(t.identifier('message'), t.identifier(propName)),
]),
//
defaultValue)));
},
rawBytes(args) {
args.context.addUtil('fromUtf8');
const { propName, origName } = (0, types_1.getFieldNames)(args.field);
const omitEmpty = (0, utils_2.shouldOmitEmpty)(args.context, args.field);
let defaultValue = !omitEmpty ? t.objectExpression([]) : t.identifier('undefined');
return t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.identifier('obj'), t.identifier(origName)), t.conditionalExpression(t.memberExpression(t.identifier('message'), t.identifier(propName)),
//
t.callExpression(t.memberExpression(t.identifier('JSON'), t.identifier('parse')), [
t.callExpression(t.identifier('fromUtf8'), [
t.memberExpression(t.identifier('message'), t.identifier(propName)),
])
]),
//
defaultValue)));
},
wasmByteCode(args) {
args.context.addUtil('toBase64');
const { propName, origName } = (0, types_1.getFieldNames)(args.field);
const omitEmpty = (0, utils_2.shouldOmitEmpty)(args.context, args.field);
let defaultValue = !omitEmpty ? t.stringLiteral("") : t.identifier('undefined');
return t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.identifier('obj'), t.identifier(origName)), t.conditionalExpression(t.memberExpression(t.identifier('message'), t.identifier(propName)),
//
t.callExpression(t.identifier('toBase64'), [
t.memberExpression(t.identifier('message'), t.identifier(propName)),
]),
//
defaultValue)));
},
keyHash(args) {
const { propName, origName } = (0, types_1.getFieldNames)(args.field);
const keyType = args.field.keyType;
const valueType = args.field.parsedType.name;
let toAminoJSON = null;
switch (valueType) {
case 'string':
toAminoJSON = t.identifier('v');
break;
case 'uint32':
case 'int32':
toAminoJSON = t.callExpression(t.memberExpression(t.identifier('Math'), t.identifier('round')), [
t.identifier('v')
]);
break;
case 'int64':
case 'uint64':
toAminoJSON = t.callExpression(t.memberExpression(t.identifier('v'), t.identifier('toString')), []);
break;
default:
toAminoJSON = t.callExpression(t.memberExpression(t.identifier(valueType), t.identifier('toAmino')), [
t.identifier('v')
]);
}
return [
t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.identifier('obj'), t.identifier(origName)), t.objectExpression([]))),
//
t.ifStatement(t.memberExpression(t.identifier('message'), t.identifier(propName)), t.blockStatement([
t.expressionStatement(t.callExpression(t.memberExpression(t.callExpression(t.memberExpression(t.identifier('Object'), t.identifier('entries')), [
t.memberExpression(t.identifier('message'), t.identifier(propName))
]), t.identifier('forEach')), [
t.arrowFunctionExpression([
t.arrayPattern([
t.identifier('k'),
t.identifier('v')
])
], t.blockStatement([
t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.memberExpression(t.identifier('obj'), t.identifier(origName)), t.identifier('k'), true), toAminoJSON))
]))
]))
]))
];
},
array(args, expr) {
const { propName, origName } = (0, types_1.getFieldNames)(args.field);
return t.ifStatement(t.memberExpression(t.identifier('message'), t.identifier(propName)), t.blockStatement([
t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.identifier('obj'), t.identifier(origName)), t.callExpression(t.memberExpression(t.memberExpression(t.identifier('message'), t.identifier(propName)), t.identifier('map')), [
t.arrowFunctionExpression([
t.identifier('e')
], expr)
])))
]), t.blockStatement([
t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.identifier('obj'), t.identifier(origName)), t.memberExpression(t.identifier('message'), t.identifier(propName))))
]));
}
};
exports.arrayTypes = {
scalar() {
return t.identifier('e');
},
string(args) {
const useCosmosSDKDec = args.context.pluginValue('aminoEncoding.customTypes.useCosmosSDKDec');
if (useCosmosSDKDec) {
const isCosmosSDKDec = (args.field.options?.['(gogoproto.customtype)'] ==
'github.com/cosmos/cosmos-sdk/types.Dec') ||
(args.field.options?.['(gogoproto.customtype)'] ==
'cosmossdk.io/math.LegacyDec');
if (isCosmosSDKDec) {
args.context.addUtil('padDecimal');
const { propName } = (0, types_1.getFieldNames)(args.field);
return t.callExpression(t.identifier('padDecimal'), [
t.identifier('e')
]);
}
}
return exports.arrayTypes.scalar();
},
double() {
return exports.arrayTypes.scalar();
},
float() {
return exports.arrayTypes.scalar();
},
bool() {
return exports.arrayTypes.scalar();
},
number() {
return exports.arrayTypes.scalar();
},
int32() {
return exports.arrayTypes.number();
},
uint32() {
return exports.arrayTypes.number();
},
sint32() {
return exports.arrayTypes.number();
},
fixed32() {
return exports.arrayTypes.number();
},
sfixed32() {
return exports.arrayTypes.number();
},
long(args) {
return utils_1.TypeLong.getToStringArray(args.context);
},
int64(args) {
return exports.arrayTypes.long(args);
},
uint64(args) {
return exports.arrayTypes.long(args);
},
sint64(args) {
return exports.arrayTypes.long(args);
},
fixed64(args) {
return exports.arrayTypes.long(args);
},
sfixed64(args) {
return exports.arrayTypes.long(args);
},
rawBytes(args) {
args.context.addUtil("fromUtf8");
return t.callExpression(t.memberExpression(t.identifier("JSON"), t.identifier("parse")), [
t.callExpression(t.identifier("fromUtf8"), [t.identifier("e")]),
]);
},
wasmByteCode(args) {
args.context.addUtil("toBase64");
return t.callExpression(t.identifier("toBase64"), [
t.identifier("e")
]);
},
bytes(args) {
// bytes [RawContractMessage]
if (args.field.options?.["(gogoproto.casttype)"] === "RawContractMessage") {
return exports.arrayTypes.rawBytes(args);
}
// bytes [WASMByteCode]
if (args.field.options?.["(gogoproto.customname)"] === "WASMByteCode") {
return exports.arrayTypes.wasmByteCode(args);
}
//default
args.context.addUtil("base64FromBytes");
return t.callExpression(t.identifier("base64FromBytes"), [
t.identifier("e"),
]);
},
enum() {
return exports.arrayTypes.scalar();
},
anyType(args) {
const { propName, origName } = (0, types_1.getFieldNames)(args.field);
const interfaceName = args.field.options['(cosmos_proto.accepts_interface)'];
const interfaceFnName = (0, implements_1.getInterfaceToAminoName)(interfaceName);
const isGlobalRegistry = args.context.options.interfaces?.useGlobalDecoderRegistry;
let aminoFuncExpr = t.callExpression(t.identifier(interfaceFnName), [
t.tsAsExpression(t.identifier('e'), t.tsTypeReference(t.identifier('Any'))),
...(args.context.options.interfaces.enabled && args.context.options.interfaces.useUseInterfacesParams ? [
t.identifier('useInterfaces')
] : []),
]);
if (isGlobalRegistry) {
aminoFuncExpr = t.callExpression(t.memberExpression(t.identifier('GlobalDecoderRegistry'), t.identifier('toAminoMsg')), [
t.identifier('e')
]);
}
return t.conditionalExpression(t.identifier('e'), aminoFuncExpr, t.identifier('undefined'));
},
protoType(args) {
const name = args.context.getTypeName(args.field);
return t.conditionalExpression(t.identifier('e'), t.callExpression(t.memberExpression(t.identifier(name), t.identifier('toAmino')), [
t.identifier('e'),
...(args.context.options.interfaces.enabled && args.context.options.interfaces.useUseInterfacesParams ? [
t.identifier('useInterfaces')
] : []),
]), t.identifier('undefined'));
},
type(args) {
if (!args.context.options.aminoEncoding.useLegacyInlineEncoding &&
args.context.options.interfaces.enabled &&
args.field.type === 'google.protobuf.Any' &&
args.field.options['(cosmos_proto.accepts_interface)']) {
return exports.arrayTypes.anyType(args);
}
return exports.arrayTypes.protoType(args);
}
};
exports.toAminoMessages = {
anyType() {
return [
t.variableDeclaration('const', [
t.variableDeclarator((0, utils_1.identifier)('obj', t.tsTypeAnnotation(t.tsAnyKeyword())), t.objectExpression([]))
]),
t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.identifier('obj'), t.identifier('type')), t.memberExpression(t.identifier('message'), t.identifier('typeUrl')))),
t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.identifier('obj'), t.identifier('value')), t.memberExpression(t.identifier('message'), t.identifier('value')))),
t.returnStatement(t.identifier('obj'))
];
},
timestamp(context, name, proto) {
context.addUtil('fromTimestamp');
return t.returnStatement(t.callExpression(t.memberExpression(t.callExpression(t.memberExpression(t.callExpression(t.identifier('fromTimestamp'), [t.identifier('message')]), t.identifier('toISOString')), []), t.identifier('replace')), [
t.regExpLiteral('\\.\\d+Z$'),
t.stringLiteral('Z')
]));
},
duration(context, name, proto) {
const longType = utils_1.TypeLong.getType(context);
switch (longType) {
case 'BigInt':
return t.returnStatement(t.callExpression(t.memberExpression(t.parenthesizedExpression(t.binaryExpression('+', t.binaryExpression('*', t.memberExpression(t.identifier('message'), t.identifier('seconds')), t.callExpression(t.identifier('BigInt'), [t.stringLiteral("1000000000")])), t.callExpression(t.identifier('BigInt'), [t.memberExpression(t.identifier('message'), t.identifier('nanos'))]))), t.identifier('toString')), []));
case 'Long':
default:
return t.returnStatement(t.callExpression(t.memberExpression(t.binaryExpression('+', t.binaryExpression('*', t.callExpression(t.memberExpression(t.memberExpression(t.identifier('message'), t.identifier('seconds')), t.identifier('toInt')), []), utils_1.BILLION), t.memberExpression(t.identifier('message'), t.identifier('nanos'))), t.identifier('toString')), []));
}
}
};