UNPKG

@noggin/elastic-noggin-sdk

Version:
226 lines (225 loc) 10.4 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.updateRequestOptions = exports.send = void 0; const Eno_1 = require("./models/Eno"); const rxjs_1 = require("rxjs"); const got_1 = __importDefault(require("got")); const sessionTokenCache_1 = require("./sessionTokenCache"); const lodash_1 = require("lodash"); const jwt_decode_1 = __importDefault(require("jwt-decode")); const operators_1 = require("rxjs/operators"); const https_1 = require("https"); const http_1 = require("http"); const SessionTokenHeader = "session-token"; const THIN_OPERATIONS = ["op/pull", "op/formula", "op/query"]; const SessionIdHeader = "Session-Id"; const httpAgent = new http_1.Agent({ keepAlive: true }); const httpsAgent = new https_1.Agent({ keepAlive: true }); const retryIfFasterThanMs = 5000; function send(batch, options, queryOptions) { var _a; const requestOptions = { json: batch, responseType: "text", resolveBodyOnly: false, throwHttpErrors: false, headers: { "Content-type": ["application/json"], "Conn-Isolation": ["true"], "User-Agent": "ElasticNogginSDK", }, agent: { http: httpAgent, https: httpsAgent, }, retry: { methods: ['GET', 'POST'], limit: 2, }, hooks: { beforeRetry: [ (error, retryCount) => { var _a, _b; const elapsedMs = ((_a = retryCount.timings) === null || _a === void 0 ? void 0 : _a.end) - ((_b = retryCount.timings) === null || _b === void 0 ? void 0 : _b.start); if (isNaN(elapsedMs) || elapsedMs < retryIfFasterThanMs) { console.warn('[ElasticNogginSDK/Send] Retrying failed request', Object.assign(Object.assign({ elapsedMs }, retryCount), { namespace: options.namespace })); } else { console.warn('[ElasticNogginSDK/Send] Not retrying failed request', Object.assign(Object.assign({ elapsedMs }, retryCount), { namespace: options.namespace })); throw new Error('Send failed'); } } ] } }; if (options.clientIp) { (0, lodash_1.set)(requestOptions, ["headers", "encloud-clientip"], [options.clientIp]); } if (options.clientVia) { (0, lodash_1.set)(requestOptions, ["headers", "encloud-via"], [options.clientVia]); } if (options.bulk) { (0, lodash_1.set)(requestOptions, ["headers", "encloud-bulk"], ["true"]); } if (options.sessionToken) { requestOptions.headers[SessionTokenHeader] = options.sessionToken; } else if (options.useSharedAnonymousSession && (0, sessionTokenCache_1.hasToken)(options.namespace)) { requestOptions.headers[SessionTokenHeader] = (0, sessionTokenCache_1.getToken)(options.namespace); } if (options.useCurrentSession !== false) { try { requestOptions.headers[SessionIdHeader] = getSessionId(options.sessionToken); } catch (err) { } } if (requestOptions.headers[SessionTokenHeader] && options.maintainInitialSessionToken && !options.initialSessionToken) { let sessionToken = requestOptions.headers[SessionTokenHeader]; if ((0, lodash_1.isArray)(sessionToken)) { sessionToken = sessionToken[0]; } options.initialSessionToken = sessionToken; } if (options.additionalHeaders) { (0, lodash_1.each)(options.additionalHeaders, (value, key) => (0, lodash_1.set)(requestOptions, ["headers", key], value)); } updateRequestOptions(batch, options, requestOptions); if (options.additionalQueryString) { (0, lodash_1.each)(options.additionalQueryString, (value, key) => (requestOptions.url += "&" + encodeURIComponent(key) + "=" + encodeURIComponent(value))); } if ((_a = options.abortController) === null || _a === void 0 ? void 0 : _a.signal.aborted) { if (options.debug) { console.debug("[ElasticNogginSDK/Send] Already aborted", { url: requestOptions.url, requestHeaders: (0, lodash_1.omit)((0, lodash_1.get)(requestOptions, "headers"), [SessionTokenHeader, 'Authorization']), namespace: options.namespace }); } return (0, rxjs_1.throwError)(() => new Error('Request aborted')); } const postPromise = got_1.default.post(requestOptions); let subscriberCount = 0; const post$ = new rxjs_1.Observable(observer => { subscriberCount++; if (options.abortController) { options.abortController.signal.addEventListener('abort', (err) => { postPromise.cancel(); if (options.debug) { console.debug("[ElasticNogginSDK/Send] Abort signal", { url: requestOptions.url, requestHeaders: (0, lodash_1.omit)((0, lodash_1.get)(requestOptions, "headers"), [SessionTokenHeader, 'Authorization']), namespace: options.namespace, }); } observer.error(new Error('Request aborted')); }); } let isDone = false; postPromise.then(response => { isDone = true; observer.next(response); observer.complete(); }).catch(err => { observer.error(err); }); return () => { subscriberCount--; if (subscriberCount === 0 && !isDone && !postPromise.isCanceled) { if (options.debug) { console.debug("[ElasticNogginSDK/Send] All unsubscribed before response", { url: requestOptions.url, requestHeaders: (0, lodash_1.omit)((0, lodash_1.get)(requestOptions, "headers"), [SessionTokenHeader, 'Authorization']), namespace: options.namespace, }); } postPromise.cancel(); } }; }); return post$.pipe((0, operators_1.tap)((response) => { if (options.debug) { console.debug("[ElasticNogginSDK/Send] Response", { url: requestOptions.url, requestHeaders: (0, lodash_1.omit)((0, lodash_1.get)(requestOptions, "headers"), [SessionTokenHeader, 'Authorization']), responseHeaders: (0, lodash_1.omit)((0, lodash_1.get)(response, "headers"), [SessionTokenHeader, 'Authorization']), time: (0, lodash_1.pick)(response, [ "elapsedTime", "timingStart", "timings", "timingPhases", ]), namespace: options.namespace, statusCode: (0, lodash_1.get)(response, "statusCode"), requestBodySize: (0, lodash_1.size)(requestOptions.body), responseBodySize: (0, lodash_1.size)(requestOptions.body), }); } }), (0, operators_1.map)((response) => { if (response.statusCode == 200) { if (queryOptions) { const responseHeadersValues = (0, lodash_1.reduce)(queryOptions.responseHeadersToInclude, (headerValues, currentHeader) => { if (!headerValues) { headerValues = []; } const currentHeaderValue = { [currentHeader]: (0, lodash_1.get)(response, ["headers", currentHeader], null), }; headerValues.push(currentHeaderValue); return headerValues; }, null); queryOptions.responseHeadersToInclude = responseHeadersValues; } let newSessionToken = response.headers[SessionTokenHeader]; if ((0, lodash_1.isArray)(newSessionToken)) { newSessionToken = newSessionToken[0]; } if (newSessionToken) { if (options.maintainInitialSessionToken && !options.initialSessionToken) { options.initialSessionToken = newSessionToken; } if (options.useSharedAnonymousSession) { (0, sessionTokenCache_1.setToken)(options.namespace, newSessionToken); } else { options.sessionToken = newSessionToken; } } const parsedBody = JSON.parse(response.body); return parsedBody.map((obj) => new Eno_1.Eno(obj)); } else { throw { message: response.body, code: response.statusCode }; } })); } exports.send = send; function updateRequestOptions(batch, options, requestOptions) { if (batch.length === 1) { const type = batch[0].getType(); if (options.useQueryService && type === 'op/query') { requestOptions.url = options.enSrvUrl.replace(/\/ensrv\/+$/, "/query/ensrv"); const sessionToken = (0, lodash_1.get)(requestOptions, ['headers', SessionTokenHeader]); if (sessionToken) { (0, lodash_1.set)(requestOptions, ['headers', 'Authorization'], 'Bearer ' + sessionToken); (0, lodash_1.unset)(requestOptions, ['headers', SessionTokenHeader]); (0, lodash_1.unset)(requestOptions, ['headers', SessionIdHeader]); } (0, lodash_1.set)(requestOptions, ['headers', 'en-namespace'], options.namespace); return; } if (THIN_OPERATIONS.indexOf(type) > -1) { requestOptions.url = options.enSrvUrl.replace(/\/+$/, "") + "/" + type + "?ns=" + encodeURIComponent(options.namespace); return; } } requestOptions.url = options.enSrvUrl + "?ns=" + encodeURIComponent(options.namespace); } exports.updateRequestOptions = updateRequestOptions; function getSessionId(sessionToken) { const tokenPayload = (0, jwt_decode_1.default)(Buffer.from(sessionToken, "base64").toString()); return (0, lodash_1.get)(tokenPayload, "sessionId"); }