UNPKG

@creditkarma/thrift-client

Version:

Thrift client library for NodeJS written in TypeScript.

145 lines 5.97 kB
"use strict"; 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.HttpConnection = exports.DEFAULT_PATH = void 0; const Core = __importStar(require("@creditkarma/thrift-server-core")); const got_1 = __importStar(require("got")); const utils_1 = require("./utils"); exports.DEFAULT_PATH = '/thrift'; function shouldRetry(response, retry, withEndpointPerMethod) { return (withEndpointPerMethod && response?.statusCode === 404 && retry === false); } function isErrorResponse(response) { return (response.statusCode !== null && response.statusCode !== undefined && (response.statusCode < 200 || response.statusCode > 299)); } function filterHeaders(options, blacklist) { options.headers = options.headers || {}; blacklist = blacklist.map((next) => next.toLocaleLowerCase()); options.headers = Object.keys(options.headers).reduce((acc, next) => { if (blacklist.indexOf(next.toLocaleLowerCase()) === -1) { acc[next] = options.headers[next]; } return acc; }, {}); return options; } function applyFilters(currentRequest, filters, callback) { const [head, ...tail] = filters; if (head === undefined) { return callback(currentRequest); } else { return head(currentRequest, (nextData, nextOptions) => { const data = nextData !== undefined ? nextData : currentRequest.data; return applyFilters({ data, methodName: currentRequest.methodName, uri: currentRequest.uri, context: Core.deepMerge(currentRequest.context, nextOptions || {}), }, tail, callback); }); } } class HttpConnection extends Core.ThriftConnection { constructor({ hostName, port, path = '/thrift', https = false, transport = 'buffered', protocol = 'binary', requestOptions = {}, serviceName, withEndpointPerMethod = false, headerBlacklist = [], gotImpl = got_1.default, }) { super(Core.getTransport(transport), Core.getProtocol(protocol)); this.requestOptions = Object.freeze(filterHeaders({ responseType: 'buffer', ...requestOptions }, headerBlacklist)); this.port = port; this.hostName = hostName; this.path = Core.normalizePath(path || exports.DEFAULT_PATH); this.protocol = https === true ? 'https' : 'http'; this.serviceName = serviceName; this.basePath = `${this.protocol}://${this.hostName}:${this.port}`; this.withEndpointPerMethod = withEndpointPerMethod; this.url = `${this.basePath}${this.path}`; this.filters = []; this.gotImpl = gotImpl; } register(...filters) { filters.forEach((next) => { this.filters.push({ methods: next.methods || [], handler: next.handler, }); }); } send(dataToSend, context = {}) { const requestMethod = Core.readThriftMethod(dataToSend, this.Transport, this.Protocol); const filters = this.filtersForMethod(requestMethod); const thriftRequest = { data: dataToSend, methodName: requestMethod, uri: this.url, context, }; return applyFilters(thriftRequest, filters, (finalRequest) => { return this.write(finalRequest.data, finalRequest.methodName, finalRequest.context); }).then((res) => { return res.body; }); } write(dataToWrite, methodName, options = {}, retry = false) { const requestUrl = this.withEndpointPerMethod && retry === false ? `${this.url}/${this.serviceName}/${methodName}` : this.url; const requestOptions = Core.overlayObjects(this.requestOptions, options, { method: 'POST', body: dataToWrite, url: requestUrl, headers: { 'Content-Length': dataToWrite.length.toString(), 'Content-Type': 'application/octet-stream', }, }); return this.gotImpl(requestOptions) .then((response) => { if (isErrorResponse(response)) { throw response; } return { statusCode: response.statusCode, headers: response.headers, body: response.rawBody, }; }) .catch((err) => { if (err instanceof got_1.HTTPError) { if (shouldRetry(err.response, retry, this.withEndpointPerMethod)) { return this.write(dataToWrite, methodName, options, true); } } throw err; }); } filtersForMethod(name) { return this.filters .filter((0, utils_1.filterByMethod)(name)) .map((filter) => filter.handler); } } exports.HttpConnection = HttpConnection; //# sourceMappingURL=HttpConnection.js.map