flechette
Version:
A highly configurable wrapper for Fetch API that supports programmatic retries and completely obfuscates promise handling.
105 lines (104 loc) • 4.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.checkCodes = (incomingCode, referenceCode) => {
if (typeof referenceCode === "number") {
if (incomingCode === referenceCode) {
return true;
}
}
else if (typeof referenceCode === "string") {
const codeRange = referenceCode.split("-");
if (codeRange.length > 1 && codeRange.length < 3) {
if (codeRange[0].includes(",") || codeRange[1].includes(",")) {
// just in case they've included comma separated numbers, reject early
// these will be parse to ints largely without issue since we're using
// 3 digit codes that and might cause some confusing behavior if allowed
// for example: "200-299,302" would put the range between 200 and 299302
// rather than having 302 as a separate code
return false;
}
const a = parseInt(codeRange[0], 10);
const b = parseInt(codeRange[1], 10);
if (isNaN(a) || isNaN(b)) {
// invalid number, exit early
return false;
}
if (a <= incomingCode && incomingCode <= b) {
return true;
}
}
else {
if (incomingCode.toString() === referenceCode) {
// do a straight text comparison
return true;
}
}
}
return false;
};
exports.combineHeaders = (localHeaders, globalHeaders) => {
// headers on the send args override those of the same key on the instance
const newHeaders = new Headers();
if (globalHeaders) {
// force conversion to Headers
const gh = new Headers(globalHeaders);
for (const pair of gh.entries()) {
newHeaders.append(pair[0], pair[1]);
}
}
if (localHeaders) {
const lh = new Headers(localHeaders);
for (const pair of lh.entries()) {
newHeaders.append(pair[0], pair[1]);
}
}
return newHeaders;
};
exports.determineRetryAction = (statusCode, sentArgs, globalRetryActions) => {
// A retry action on the send args should override the flechetteInstance's version
var action;
var i = -1;
// first check if there's an existing action in the instance
if (Array.isArray(globalRetryActions) && globalRetryActions.length > 0) {
i = globalRetryActions.findIndex(ra => ra.code === statusCode);
if (i > -1) {
// okay, we have a retryAction matching this code.
// now make sure it's not a path we want to ignore
if (exports.ignoreRetryPath(sentArgs.path, globalRetryActions[i])) {
i = -1; // make it seem like there is no match
}
else {
action = globalRetryActions[i];
}
}
}
// next check if there's an override
if (Array.isArray(sentArgs.retryActions) &&
sentArgs.retryActions.length > 0) {
const newActionIndex = sentArgs.retryActions.findIndex(ra => ra.code === statusCode);
if (newActionIndex > -1) {
if (!exports.ignoreRetryPath(sentArgs.path, sentArgs.retryActions[newActionIndex])) {
// make sure it's not a path we want to ignore
// this would be a weird use-case but honor
// the same rules for local as global
action = sentArgs.retryActions[newActionIndex];
// in case of overridden retryAction, the intention is for this to be a one
// time use, so we do not want to interfere with the default retry code in
// case it happens again.
i = -1;
// now remove it from our local list
sentArgs.retryActions.splice(newActionIndex, 1);
}
}
}
return [action, i];
};
exports.ignoreRetryPath = (path, retryAction) => {
const retVal = false;
if (Array.isArray(retryAction.pathsToIgnore)) {
if (retryAction.pathsToIgnore.includes(path)) {
return true;
}
}
return retVal;
};