@cosmology/ast
Version:
Cosmos TypeScript AST generation
183 lines (182 loc) • 8.52 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.createGrpcWebQueryClass = exports.createGrpcWebQueryInterface = void 0;
const utils_1 = require("../../../../utils");
const utils_2 = require("@cosmology/utils");
const rpc_1 = require("../utils/rpc");
const utils_3 = require("./utils");
const t = __importStar(require("@babel/types"));
function capitalizeFirstLetter(s) {
return s.charAt(0).toUpperCase() + s.slice(1);
}
const gRPCWebMethodDefinition = (context, name, msg, svc, packageImport, trailingComments, leadingComments) => {
const requestType = svc.requestType;
const responseType = svc.responseType;
//interface body is empty so nothing here
const body = t.blockStatement([]);
let optional = false;
const fieldNames = Object.keys(svc.fields ?? {});
const hasParams = fieldNames.length > 0;
if (!hasParams) {
optional = true;
}
else if (hasParams && fieldNames.length === 1 && fieldNames.includes('pagination')) {
// if only argument "required" is pagination
// also default to empty
optional = true;
}
const methodArgs = (0, utils_1.identifier)('request', t.tsTypeAnnotation(t.tsTypeReference(t.identifier('DeepPartial'), t.tsTypeParameterInstantiation([
t.tsTypeReference(t.identifier(requestType))
]))), optional);
const metadataArgs = utils_3.metadata;
return (0, utils_1.tsMethodSignature)(t.identifier(name), null, [
methodArgs,
metadataArgs
], (0, rpc_1.returnReponseType)(responseType), trailingComments, leadingComments);
};
const createGrpcWebQueryInterface = (context, service) => {
const camelRpcMethods = context.pluginValue('rpcClients.camelCase');
const keys = Object.keys(service.methods ?? {});
const methods = keys
.map((key) => {
const method = service.methods[key];
const name = camelRpcMethods ? (0, utils_2.camel)(key) : key;
const leadingComments = method.comment ? [(0, utils_1.commentBlock)((0, rpc_1.processRpcComment)(method))] : [];
let trailingComments = [];
return gRPCWebMethodDefinition(context, name, key, method, context.ref.proto.package + '.' + service.name, trailingComments, leadingComments);
});
const obj = t.exportNamedDeclaration(t.tsInterfaceDeclaration(t.identifier(service.name), null, [], t.tsInterfaceBody([
...methods,
])));
if (service.comment) {
obj.leadingComments = [(0, utils_1.commentBlock)(`* ${service.comment} `)];
}
return obj;
};
exports.createGrpcWebQueryInterface = createGrpcWebQueryInterface;
const rpcClassConstructor = (context, methods) => {
let bound = [];
if (!context.pluginValue('classesUseArrowFunctions')) {
bound = methods.map(method => (0, utils_3.bindThis)(method));
}
return (0, utils_1.classMethod)('constructor', t.identifier('constructor'), [
(0, utils_1.identifier)('rpc', t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Rpc'))))
], t.blockStatement([
t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.thisExpression(), t.identifier('rpc')), t.identifier('rpc'))),
/// methods
...bound
]));
};
const GrpcWebClassMethod = (context, name, svc, implementsName) => {
let partialName = 'DeepPartial';
let optional = false;
const requestType = svc.requestType;
const responseType = svc.responseType;
const comment = svc.comment ?? svc.name;
let methodArgs = (0, utils_1.identifier)('request', t.tsTypeAnnotation(t.tsTypeReference(t.identifier(partialName), t.tsTypeParameterInstantiation([
t.tsTypeReference(t.identifier(requestType))
]))), optional);
const metadataArgs = utils_3.metadata;
const fieldNames = Object.keys(svc.fields ?? {});
const hasParams = fieldNames.length > 0;
// if no params, then let's default to empty object for cleaner API
if (!hasParams) {
methodArgs = t.assignmentPattern(methodArgs, t.objectExpression([]));
}
else if (hasParams && fieldNames.length === 1 && fieldNames.includes('pagination')) {
const paginationDefaultFromPartial = context.pluginValue('prototypes.paginationDefaultFromPartial');
// if only argument "required" is pagination
// also default to empty
methodArgs = t.assignmentPattern(methodArgs, t.objectExpression([
t.objectProperty(t.identifier('pagination'), paginationDefaultFromPartial ? t.callExpression(t.memberExpression(t.identifier("PageRequest"), t.identifier("fromPartial")), [t.objectExpression([])]) :
t.identifier('undefined'), false, false)
]));
}
// method from service do not have prefix
let serviceName;
if (implementsName === 'Service') {
serviceName = '';
}
else {
serviceName = implementsName;
}
/*
return this.rpc.unary(
QueryParamsDesc,
QueryParamsRequest.fromPartial(request),
metadata,
);
*/
const body = t.blockStatement([
t.returnStatement(t.callExpression(t.memberExpression(t.memberExpression(t.thisExpression(), t.identifier('rpc')), t.identifier('unary')), [
//No Desc field so we need to modify it
t.identifier(serviceName + capitalizeFirstLetter(name) + 'Desc'),
t.callExpression(t.memberExpression(t.identifier(requestType), t.identifier('fromPartial')), [
t.identifier('request')
]),
t.identifier('metadata')
]))
]);
if (context.pluginValue('classesUseArrowFunctions')) {
return (0, utils_1.classProperty)(t.identifier(name), (0, utils_1.arrowFunctionExpression)([methodArgs], body, (0, rpc_1.returnReponseType)(responseType), true), undefined, undefined, undefined, undefined, undefined, undefined, (0, utils_3.makeComment)(comment));
}
return (0, utils_1.classMethod)('method', t.identifier(name), [
methodArgs,
metadataArgs
], body, (0, rpc_1.returnReponseType)(responseType));
};
const createGrpcWebQueryClass = (context, service) => {
//adding import
context.addUtil('_m0');
context.addUtil('grpc');
context.addUtil('UnaryMethodDefinitionish'); // for other descriptor
//use type DeepPartial
context.addUtil('DeepPartial');
let partialName = 'DeepPartial';
const camelRpcMethods = context.pluginValue('rpcClients.camelCase');
const name = (0, utils_3.getRpcClassName)(service);
const implementsName = service.name;
const methodNames = Object.keys(service.methods ?? {})
.map(key => {
return camelRpcMethods ? (0, utils_2.camel)(key) : key;
});
const methods = Object.keys(service.methods ?? {})
.map(key => {
const method = service.methods[key];
const name = camelRpcMethods ? (0, utils_2.camel)(key) : key;
return GrpcWebClassMethod(context, name, method, implementsName);
});
return t.exportNamedDeclaration((0, utils_1.classDeclaration)(t.identifier(name), null, t.classBody([
(0, utils_1.classProperty)(t.identifier('rpc'), null, t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Rpc'))), null, false, false, true, 'private'),
// CONSTRUCTOR
rpcClassConstructor(context, methodNames),
// METHODS
...methods
]), null, [
t.tsExpressionWithTypeArguments(t.identifier(implementsName))
]));
};
exports.createGrpcWebQueryClass = createGrpcWebQueryClass;
;