UNPKG

@graphql-mesh/transport-thrift

Version:
220 lines (219 loc) • 10.1 kB
"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, }, }); }