@mft/moneyhub-api-client
Version:
Node.JS client for the Moneyhub API
174 lines • 7.31 kB
JavaScript
;
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;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.addVersionToUrl = void 0;
const got_1 = __importDefault(require("got"));
const query_string_1 = __importDefault(require("query-string"));
const R = __importStar(require("ramda"));
const discovery_1 = require("./discovery");
const DEFAULT_API_VERSION = "v3";
const DEFAULT_MAX_RETRY_AFTER = 5000;
const DEFAULT_RETRY_LIMIT = 2;
const DEFAULT_RETRY_METHODS = [
"GET",
"HEAD",
"PUT",
"DELETE",
"OPTIONS",
"TRACE",
];
const DEFAULT_RETRY_STATUS_CODES = [
408,
413,
429,
500,
502,
503,
504,
521,
522,
524, // A Timeout Occurred
];
const getResponseBody = (err) => {
let body = {};
try {
const { code, message, details } = JSON.parse(R.pathOr("{}", ["response", "body"], err));
body = { code, message, details: typeof details === "object" ? JSON.stringify(details) : details };
}
catch (e) {
body = {};
}
return body;
};
const attachErrorDetails = (err) => {
const { code, message, details } = getResponseBody(err);
err.error = code;
err.error_description = message;
err.error_details = details;
throw err;
};
/**
* Returns true if the URL should not have a version segment added (identity service has no API versioning).
* When identityServiceUrl is provided (e.g. gateway or identity base), any URL under that base is left unchanged.
* @param {string} url - Request URL to check
* @param {string} [identityServiceUrl] - Optional identity service base URL
* @returns {boolean} True if the URL is an identity service URL and should not be versioned
*/
const isIdentityServiceUrl = (url, identityServiceUrl) => {
if (identityServiceUrl) {
const base = identityServiceUrl.replace(/\/$/, "");
return url === base || url.startsWith(base + "/");
}
return url.includes("identity");
};
const addVersionToUrl = (url, apiVersioning, version = DEFAULT_API_VERSION, identityServiceUrl) => {
if (!apiVersioning || isIdentityServiceUrl(url, identityServiceUrl) || /\/v.+/g.test(url))
return url;
const urlWithVersion = R.pipe(R.split("/"), // split url [ "https:", "", "test.com", "path", "path2" ]
R.insert(3, String(version)), // insert and stringify version after domain
R.join("/"))(url);
return urlWithVersion;
};
exports.addVersionToUrl = addVersionToUrl;
const getRetryOptions = (retry, requestOptions = {}) => {
var _a, _b, _c, _d;
return {
limit: ((_a = requestOptions.retry) === null || _a === void 0 ? void 0 : _a.limit) || retry.limit || DEFAULT_RETRY_LIMIT,
methods: ((_b = requestOptions.retry) === null || _b === void 0 ? void 0 : _b.methods) || retry.methods || DEFAULT_RETRY_METHODS,
statusCodes: ((_c = requestOptions.retry) === null || _c === void 0 ? void 0 : _c.statusCodes) || retry.statusCodes || DEFAULT_RETRY_STATUS_CODES,
maxRetryAfter: ((_d = requestOptions.retry) === null || _d === void 0 ? void 0 : _d.maxRetryAfter) || retry.maxRetryAfter || DEFAULT_MAX_RETRY_AFTER,
};
};
const normaliseBase = (url) => url.replace(/\/$/, "");
exports.default = ({ client, options: { timeout, apiVersioning, agent, mTLS, retry = {} }, identityServiceUrl, gatewayResourceServerUrl, gatewayCaasResourceServerUrl, gatewayOsipResourceServerUrl, }) => async (url, opts = {}) => {
var _a, _b, _c, _d;
const retryOptions = getRetryOptions(retry, opts.options);
const gotOpts = {
method: opts.method || "GET",
headers: opts.headers || {},
searchParams: opts.searchParams ? query_string_1.default.stringify(R.reject(R.isNil)(opts.searchParams)) : undefined,
timeout,
retry: retryOptions,
};
if (agent) {
gotOpts.agent = agent;
}
const formattedUrl = (0, exports.addVersionToUrl)(url, apiVersioning, (_a = opts.options) === null || _a === void 0 ? void 0 : _a.version, identityServiceUrl);
if ((_b = opts.options) === null || _b === void 0 ? void 0 : _b.token) {
gotOpts.headers = R.assoc("Authorization", `Bearer ${opts.options.token}`, gotOpts.headers);
}
if ((_c = opts.options) === null || _c === void 0 ? void 0 : _c.headers) {
gotOpts.headers = R.mergeDeepRight(gotOpts.headers || {}, opts.options.headers);
}
if (!((_d = gotOpts.headers) === null || _d === void 0 ? void 0 : _d.Authorization) && opts.cc) {
const { access_token } = await client.grant({
grant_type: "client_credentials",
scope: opts.cc.scope,
sub: opts.cc.sub,
});
gotOpts.headers = R.assoc("Authorization", `Bearer ${access_token}`, gotOpts.headers);
}
if (opts.body) {
gotOpts.json = opts.body;
}
if (opts.form) {
gotOpts.form = opts.form;
}
if (opts.formData) {
gotOpts.body = opts.formData;
}
if (mTLS) {
gotOpts.https = {
certificate: mTLS.cert,
key: mTLS.key,
};
}
const req = (0, got_1.default)(formattedUrl, gotOpts);
if (opts.returnStatus) {
return req.then((res) => res.statusCode)
.catch(attachErrorDetails);
}
const body = await req.json().catch(attachErrorDetails);
const gatewayBases = [gatewayResourceServerUrl, gatewayCaasResourceServerUrl, gatewayOsipResourceServerUrl]
.filter((u) => Boolean(u))
.map(normaliseBase);
if (gatewayBases.length === 0)
return body;
const normalisedFormattedUrl = normaliseBase(formattedUrl);
const isGatewayRequest = gatewayBases.some((base) => normalisedFormattedUrl === base || normalisedFormattedUrl.startsWith(base + "/"));
if (!isGatewayRequest)
return body;
const requestBase = (0, discovery_1.inferCanonicalBaseFromLinkUrl)(formattedUrl);
if (!requestBase)
return body;
const links = body === null || body === void 0 ? void 0 : body.links;
if (!links || typeof links.self !== "string")
return body;
return (0, discovery_1.rewriteResourceServerResponseUrls)(body, requestBase);
};
//# sourceMappingURL=request.js.map