UNPKG

@openfga/sdk

Version:

JavaScript and Node.js SDK for OpenFGA

199 lines (198 loc) 8.12 kB
"use strict"; /** * JavaScript and Node.js SDK for OpenFGA * * API version: 1.x * Website: https://openfga.dev * Documentation: https://openfga.dev/docs * Support: https://openfga.dev/community * License: [Apache-2.0](https://github.com/openfga/js-sdk/blob/main/LICENSE) * * NOTE: This file was auto generated by OpenAPI Generator (https://openapi-generator.tech). DO NOT EDIT. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.createRequestFunction = exports.toPathString = exports.serializeDataIfNeeded = exports.setSearchParams = exports.setBearerAuthToObject = exports.DUMMY_BASE_URL = void 0; exports.attemptHttpRequest = attemptHttpRequest; const errors_1 = require("./errors"); const utils_1 = require("./utils"); const attributes_1 = require("./telemetry/attributes"); const histograms_1 = require("./telemetry/histograms"); /** * * @export */ exports.DUMMY_BASE_URL = "https://example.com"; /** * * @export */ const setBearerAuthToObject = async function (object, credentials) { const accessTokenHeader = await credentials.getAccessTokenHeader(); if (accessTokenHeader && !object[accessTokenHeader.name]) { object[accessTokenHeader.name] = accessTokenHeader.value; } }; exports.setBearerAuthToObject = setBearerAuthToObject; /** * * @export */ const setSearchParams = function (url, ...objects) { const searchParams = new URLSearchParams(url.search); for (const object of objects) { for (const key in object) { if (Array.isArray(object[key])) { searchParams.delete(key); for (const item of object[key]) { searchParams.append(key, item); } } else { searchParams.set(key, object[key]); } } } url.search = searchParams.toString(); }; exports.setSearchParams = setSearchParams; /** * Check if the given MIME is a JSON MIME. * JSON MIME examples: * application/json * application/json; charset=UTF8 * APPLICATION/JSON * application/vnd.company+json * @param mime - MIME (Multipurpose Internet Mail Extensions) * @return True if the given MIME is JSON, false otherwise. */ const isJsonMime = (mime) => { // eslint-disable-next-line no-control-regex const jsonMime = new RegExp("^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$", "i"); return mime !== null && (jsonMime.test(mime) || mime.toLowerCase() === "application/json-patch+json"); }; /** * * @export */ const serializeDataIfNeeded = function (value, requestOptions) { const nonString = typeof value !== "string"; const needsSerialization = nonString ? isJsonMime(requestOptions.headers["Content-Type"]) : nonString; return needsSerialization ? JSON.stringify(value !== undefined ? value : {}) : (value || ""); }; exports.serializeDataIfNeeded = serializeDataIfNeeded; /** * * @export */ const toPathString = function (url) { return url.pathname + url.search + url.hash; }; exports.toPathString = toPathString; /** * Returns true if this error is returned from axios * source: https://github.com/axios/axios/blob/21a5ad34c4a5956d81d338059ac0dd34a19ed094/lib/helpers/isAxiosError.js#L12 * @param err */ function isAxiosError(err) { return err && typeof err === "object" && err.isAxiosError === true; } function randomTime(loopCount, minWaitInMs) { const min = Math.ceil(2 ** loopCount * minWaitInMs); const max = Math.ceil(2 ** (loopCount + 1) * minWaitInMs); return Math.floor(Math.random() * (max - min) + min); //The maximum is exclusive and the minimum is inclusive } async function attemptHttpRequest(request, config, axiosInstance) { let iterationCount = 0; do { iterationCount++; try { const response = await axiosInstance(request); return { response: response, retries: iterationCount - 1, }; } catch (err) { if (!isAxiosError(err)) { throw new errors_1.FgaError(err); } const status = err?.response?.status; if (status === 400 || status === 422) { throw new errors_1.FgaApiValidationError(err); } else if (status === 401 || status === 403) { throw new errors_1.FgaApiAuthenticationError(err); } else if (status === 404) { throw new errors_1.FgaApiNotFoundError(err); } else if (status === 429 || status >= 500) { if (iterationCount >= config.maxRetry) { // We have reached the max retry limit // Thus, we have no choice but to throw if (status === 429) { throw new errors_1.FgaApiRateLimitExceededError(err); } else { throw new errors_1.FgaApiInternalError(err); } } await new Promise(r => setTimeout(r, randomTime(iterationCount, config.minWaitInMs))); } else { throw new errors_1.FgaApiError(err); } } } while (iterationCount < config.maxRetry + 1); } /** * creates an axios request function */ const createRequestFunction = function (axiosArgs, axiosInstance, configuration, credentials, methodAttributes = {}) { configuration.isValid(); const retryParams = axiosArgs.options?.retryParams ? axiosArgs.options?.retryParams : configuration.retryParams; const maxRetry = retryParams ? retryParams.maxRetry : 0; const minWaitInMs = retryParams ? retryParams.minWaitInMs : 0; const start = performance.now(); return async (axios = axiosInstance) => { await (0, exports.setBearerAuthToObject)(axiosArgs.options.headers, credentials); const url = configuration.getBasePath() + axiosArgs.url; const axiosRequestArgs = { ...axiosArgs.options, url: url }; const wrappedResponse = await attemptHttpRequest(axiosRequestArgs, { maxRetry, minWaitInMs, }, axios); const response = wrappedResponse?.response; const data = typeof response?.data === "undefined" ? {} : response?.data; const result = { ...data }; (0, utils_1.setNotEnumerableProperty)(result, "$response", response); let attributes = {}; attributes = attributes_1.TelemetryAttributes.fromRequest({ userAgent: configuration.baseOptions?.headers["User-Agent"], httpMethod: axiosArgs.options?.method, url, resendCount: wrappedResponse?.retries, start: start, credentials: credentials, attributes: methodAttributes, }); attributes = attributes_1.TelemetryAttributes.fromResponse({ response, attributes, }); // only if hisogramQueryDuration set AND if response header contains fga-query-duration-ms const serverRequestDuration = attributes[attributes_1.TelemetryAttribute.HttpServerRequestDuration]; if (configuration.telemetry?.metrics?.histogramQueryDuration && typeof serverRequestDuration !== "undefined") { configuration.telemetry.recorder.histogram(histograms_1.TelemetryHistograms.queryDuration, parseInt(attributes[attributes_1.TelemetryAttribute.HttpServerRequestDuration], 10), attributes_1.TelemetryAttributes.prepare(attributes, configuration.telemetry.metrics.histogramQueryDuration.attributes)); } if (configuration.telemetry?.metrics?.histogramRequestDuration) { configuration.telemetry.recorder.histogram(histograms_1.TelemetryHistograms.requestDuration, attributes[attributes_1.TelemetryAttribute.HttpClientRequestDuration], attributes_1.TelemetryAttributes.prepare(attributes, configuration.telemetry.metrics.histogramRequestDuration.attributes)); } return result; }; }; exports.createRequestFunction = createRequestFunction;