@graphql-mesh/transport-thrift
Version:
220 lines (219 loc) • 10.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createGraphQLThriftClient = createGraphQLThriftClient;
const pascal_case_1 = require("pascal-case");
const thrift_client_1 = require("@creditkarma/thrift-client");
const thrift_server_core_1 = require("@creditkarma/thrift-server-core");
function createGraphQLThriftClient({ location, headers, options: { clientAnnotations: { serviceName, annotations, methodNames, methodAnnotations, methodParameters, }, topTypeMap, }, }) {
function getActualType(typeVal) {
if (typeVal.type === 'ref') {
return getActualType(topTypeMap[typeVal.name]);
}
else {
return typeVal.type;
}
}
class GraphQLThriftClient extends thrift_server_core_1.ThriftClient {
constructor() {
super(...arguments);
this._serviceName = serviceName;
this._annotations = annotations;
this._methodAnnotations = methodAnnotations;
this._methodNames = methodNames;
this._methodParameters = methodParameters;
}
writeType(typeVal, value, output) {
switch (typeVal.type) {
case 'ref':
this.writeType(topTypeMap[typeVal.name], value, output);
break;
case thrift_server_core_1.TType.BOOL:
output.writeBool(value);
break;
case thrift_server_core_1.TType.BYTE:
output.writeByte(value);
break;
case thrift_server_core_1.TType.DOUBLE:
output.writeDouble(value);
break;
case thrift_server_core_1.TType.I16:
output.writeI16(value);
break;
case thrift_server_core_1.TType.I32:
output.writeI32(value);
break;
case thrift_server_core_1.TType.I64:
output.writeI64(value.toString());
break;
case thrift_server_core_1.TType.STRING:
output.writeString(value);
break;
case thrift_server_core_1.TType.STRUCT: {
output.writeStructBegin(typeVal.name);
const typeMap = typeVal.fields;
for (const argName in value) {
const argType = typeMap[argName];
const argVal = value[argName];
if (argType) {
output.writeFieldBegin(argName, getActualType(argType), argType.id);
this.writeType(argType, argVal, output);
output.writeFieldEnd();
}
}
output.writeFieldStop();
output.writeStructEnd();
break;
}
case thrift_server_core_1.TType.ENUM:
// TODO: A
break;
case thrift_server_core_1.TType.MAP: {
const keys = Object.keys(value);
output.writeMapBegin(getActualType(typeVal.keyType), getActualType(typeVal.valType), keys.length);
for (const key of keys) {
this.writeType(typeVal.keyType, key, output);
const val = value[key];
this.writeType(typeVal.valType, val, output);
}
output.writeMapEnd();
break;
}
case thrift_server_core_1.TType.LIST:
output.writeListBegin(getActualType(typeVal.elementType), value.length);
for (const element of value) {
this.writeType(typeVal.elementType, element, output);
}
output.writeListEnd();
break;
case thrift_server_core_1.TType.SET:
output.writeSetBegin(getActualType(typeVal.elementType), value.length);
for (const element of value) {
this.writeType(typeVal.elementType, element, output);
}
output.writeSetEnd();
break;
}
}
readType(type, input) {
switch (type) {
case thrift_server_core_1.TType.BOOL:
return input.readBool();
case thrift_server_core_1.TType.BYTE:
return input.readByte();
case thrift_server_core_1.TType.DOUBLE:
return input.readDouble();
case thrift_server_core_1.TType.I16:
return input.readI16();
case thrift_server_core_1.TType.I32:
return input.readI32();
case thrift_server_core_1.TType.I64:
return BigInt(input.readI64().toString());
case thrift_server_core_1.TType.STRING:
return input.readString();
case thrift_server_core_1.TType.STRUCT: {
const result = {};
input.readStructBegin();
while (true) {
const field = input.readFieldBegin();
const fieldType = field.fieldType;
const fieldName = field.fieldName || 'success';
if (fieldType === thrift_server_core_1.TType.STOP) {
break;
}
result[fieldName] = this.readType(fieldType, input);
input.readFieldEnd();
}
input.readStructEnd();
return result;
}
case thrift_server_core_1.TType.ENUM:
// TODO: A
break;
case thrift_server_core_1.TType.MAP: {
const result = {};
const map = input.readMapBegin();
for (let i = 0; i < map.size; i++) {
const key = this.readType(map.keyType, input);
const value = this.readType(map.valueType, input);
result[key] = value;
}
input.readMapEnd();
return result;
}
case thrift_server_core_1.TType.LIST: {
const result = [];
const list = input.readListBegin();
for (let i = 0; i < list.size; i++) {
const element = this.readType(list.elementType, input);
result.push(element);
}
input.readListEnd();
return result;
}
case thrift_server_core_1.TType.SET: {
const result = [];
const list = input.readSetBegin();
for (let i = 0; i < list.size; i++) {
const element = this.readType(list.elementType, input);
result.push(element);
}
input.readSetEnd();
return result;
}
}
}
async doRequest(methodName, args, fields, context) {
const Transport = this.transport;
const Protocol = this.protocol;
const writer = new Transport();
const output = new Protocol(writer);
const id = this.incrementRequestId();
output.writeMessageBegin(methodName, thrift_server_core_1.MessageType.CALL, id);
this.writeType({
name: (0, pascal_case_1.pascalCase)(methodName) + '__Args',
type: thrift_server_core_1.TType.STRUCT,
fields,
id,
}, args, output);
output.writeMessageEnd();
const data = await this.connection.send(writer.flush(), context);
const reader = this.transport.receiver(data);
const input = new Protocol(reader);
const { fieldName, messageType } = input.readMessageBegin();
if (fieldName === methodName) {
if (messageType === thrift_server_core_1.MessageType.EXCEPTION) {
const err = thrift_server_core_1.TApplicationExceptionCodec.decode(input);
input.readMessageEnd();
return Promise.reject(err);
}
else {
const result = this.readType(thrift_server_core_1.TType.STRUCT, input);
input.readMessageEnd();
if (result.success != null) {
return result.success;
}
else {
throw new thrift_server_core_1.TApplicationException(thrift_server_core_1.TApplicationExceptionType.UNKNOWN, methodName + ' failed: unknown result');
}
}
}
else {
throw new thrift_server_core_1.TApplicationException(thrift_server_core_1.TApplicationExceptionType.WRONG_METHOD_NAME, 'Received a response to an unknown RPC function: ' + fieldName);
}
}
}
GraphQLThriftClient.serviceName = serviceName;
GraphQLThriftClient.annotations = annotations;
GraphQLThriftClient.methodAnnotations = methodAnnotations;
GraphQLThriftClient.methodNames = methodNames;
const locationUrl = new URL(location);
return (0, thrift_client_1.createHttpClient)(GraphQLThriftClient, {
hostName: locationUrl.hostname,
https: locationUrl.protocol === 'https:',
port: parseInt(locationUrl.port || '80', 10),
path: locationUrl.pathname,
requestOptions: {
headers,
},
});
}