UNPKG

@noggin/elastic-noggin-sdk

Version:
172 lines (171 loc) 7.71 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.calcQueryTimeouts = exports.execute = exports.execute1dWithResponseHeaders = exports.execute1d = void 0; const EnoFactory_1 = require("./EnoFactory"); const rxjs_1 = require("rxjs"); const operators_1 = require("rxjs/operators"); const send_1 = require("./send"); const error_1 = require("./error"); const locale_1 = require("./locale"); const lodash_1 = require("lodash"); function execute1d(queryTip, enSrvOptions, options = { branch: "branch/master", lang: "en-us", vars: {}, extraFilters: [], extraAttributes: [], dimensionOptions: [{ label: "Tip", formula: "TIP()" }], includeFallbackLang: true }, timeoutMs = 10000) { return execute(queryTip, enSrvOptions, options, timeoutMs).pipe((0, operators_1.map)((response) => { const keys = response.dimensions[0].values; return response.results.map((result, i) => { return result[keys[i]]; }); })); } exports.execute1d = execute1d; function execute1dWithResponseHeaders(queryTip, enSrvOptions, options = { branch: "branch/master", lang: "en-us", vars: {}, extraFilters: [], extraAttributes: [], dimensionOptions: [{ label: "Tip", formula: "TIP()" }], includeFallbackLang: true, responseHeadersToInclude: [] }, timeoutMs = 10000) { return execute(queryTip, enSrvOptions, options, timeoutMs).pipe((0, operators_1.map)((response) => { const keys = response.dimensions[0].values; const results = response.results.map((result, i) => { return result[keys[i]]; }); return response.responseHeaders ? { results, responseHeaders: response.responseHeaders } : results; })); } exports.execute1dWithResponseHeaders = execute1dWithResponseHeaders; function execute(queryTip, enSrvOptions, options = { branch: "branch/master", lang: "en-us", vars: {}, extraFilters: [], dimensionOptions: [{ label: "Tip", formula: "TIP()" }], includeFallbackLang: true, responseHeadersToInclude: [] }, timeoutMs = 10000) { const setNow = (now) => (0, lodash_1.set)(options, ["vars", "---NOW---"], [now]); const timezone$ = (0, lodash_1.has)(options, ["vars", "---NOW---"]) ? (0, rxjs_1.of)(null) : (0, locale_1.nowVar)(enSrvOptions).pipe((0, operators_1.tap)(setNow)); const langs$ = (0, locale_1.getLangs)(enSrvOptions, (0, lodash_1.get)(options, "lang"), (0, lodash_1.get)(options, "includeFallbackLang", true)); const send$ = (langs) => { const { queryTimeoutMs, observableTimeoutMs } = calcQueryTimeouts(timeoutMs); const enoFactory = new EnoFactory_1.EnoFactory("op/query", "security/policy/op"); enoFactory.setField("op/query/tip", [queryTip]); enoFactory.setField("op/query/branch", [(0, lodash_1.get)(options, 'branch', 'branch/master')]); enoFactory.setField("op/query/lang", langs); enoFactory.setField("op/query/timeout", [queryTimeoutMs.toString()]); enoFactory.setField("op/query/query", [ JSON.stringify({ attributes: options.extraAttributes, filters: options.extraFilters, vars: options.vars || {}, dimensions: options.dimensionOptions || [], lastPersist: options.lastPersist, }), ]); return (0, send_1.send)([enoFactory.makeEno()], enSrvOptions, options).pipe((0, operators_1.tap)(error_1.checkBatchForError), (0, operators_1.map)((batch) => parseResponse(batch, options === null || options === void 0 ? void 0 : options.responseHeadersToInclude)), (0, operators_1.timeout)(observableTimeoutMs)); }; return (0, rxjs_1.forkJoin)({ tz: timezone$, langs: langs$ }).pipe((0, operators_1.switchMap)(({ langs }) => send$(langs))); } exports.execute = execute; function calcQueryTimeouts(timeoutMs) { const timeoutBufferMs = 2000; const minimumQueryTimeoutMs = 1000; const maximumQueryTimeoutMs = 28000; const minimumObservableTimeoutMs = 1500; const queryTimeoutMs = Math.min(maximumQueryTimeoutMs, Math.max(minimumQueryTimeoutMs, timeoutMs - timeoutBufferMs)); const observableTimeoutMs = Math.max(minimumObservableTimeoutMs, timeoutMs); return { queryTimeoutMs, observableTimeoutMs }; } exports.calcQueryTimeouts = calcQueryTimeouts; function parseResponse(sendBatch, responseHeaders) { let packedResults = undefined; const queryResponse = { attributes: [], dimensions: [], execTime: undefined, results: [], }; let runtimeDims = []; let runtimeAttrs = []; sendBatch.forEach((eno) => { switch (eno.getType()) { case "response/query": queryResponse.execTime = eno.getFieldNumberValue("response/query/exec-time"); runtimeAttrs = eno .getFieldValues("response/query/runtime-attributes") .map((attrJson) => JSON.parse(attrJson)); runtimeDims = eno .getFieldValues("response/query/runtime-dimensions") .map((dim) => JSON.parse(dim)) .map((dim) => ({ label: dim.label, values: dim.value })); packedResults = eno.getFieldValues("response/query/result"); break; case "response/query/dimension": queryResponse.dimensions.push({ tip: eno.tip, label: eno.getFieldStringValue("response/query/dimension/label"), values: eno.getFieldValues("response/query/dimension/value"), }); break; case "query/attribute": queryResponse.attributes.push({ tip: eno.tip, label: eno.getFieldStringValue("query/attribute/label"), formula: eno.getFieldStringValue("query/attribute/formula"), }); break; } }); if (packedResults === undefined) { throw new Error("No query response"); } runtimeAttrs.forEach((runtimeAttr) => queryResponse.attributes.push(runtimeAttr)); runtimeDims.forEach((runtimeDim) => queryResponse.dimensions.push(runtimeDim)); if (queryResponse.dimensions.length === 0) { throw new Error("No dimension in response"); } queryResponse.results = unpackQueryResults(packedResults, queryResponse.dimensions, queryResponse.attributes); return Object.assign(Object.assign({}, queryResponse), (responseHeaders ? { responseHeaders } : {})); } function unpackQueryResults(flatResult, dims, attrs, result = [], depth = 0) { if (depth === dims.length - 1) { let i = 0; dims[dims.length - 1].values.forEach((lastDimValue) => { const leafResult = {}; leafResult[lastDimValue] = {}; if (flatResult[i] === "{#}") { i += attrs.length; return; } for (const attr of attrs) { leafResult[lastDimValue][attr.label] = flatResult[i++]; } result.push(leafResult); }); return result; } dims[depth].values.forEach((dimValue, i) => { const subResult = []; const subResultSize = flatResult.length / dims[depth].values.length; const subResultStart = i * subResultSize; const subResultEnd = subResultStart + subResultSize; result[i] = {}; result[i][dimValue] = subResult; unpackQueryResults(flatResult.slice(subResultStart, subResultEnd), dims, attrs, subResult, depth + 1); }); return result; }