Files
raven-client/ayanova/src/api/gzapi.js

279 lines
7.8 KiB
JavaScript

/* Xeslint-disable */
import store from "../store";
import router from "../router";
import auth from "./auth";
import errorHandler from "./errorhandler";
function stringifyPrimitive(v) {
switch (typeof v) {
case "string":
return v;
case "boolean":
return v ? "true" : "false";
case "number":
return isFinite(v) ? v : "";
default:
return "";
}
}
/////////////////////////////////////////////////
// Show unexpected errors during development
//
function devShowUnknownError(error) {
if (errorHandler.devMode) {
// eslint-disable-next-line
console.log("gzapi::devShowUnknownError, error is:");
// eslint-disable-next-line
console.log(error);
// eslint-disable-next-line
alert(
"DEV ERROR gzapi::devShowUnknownError - unexpected error during api operation see console "
);
}
}
////////////////////////////////////////////
// Try to handle an api error
// return true if handled or false if not
//
function handleError(action, error, route, reject) {
var errorMessage =
"API error: " + action + " route =" + route + ", message =" + error.message;
store.commit("logItem", errorMessage);
//BUGBUG?? What if the 401 is just a rights issue and not because they have no authentication at all??
//perhaps that would never happen
if (error.message && error.message.includes("NotAuthenticated")) {
store.commit("logItem", "User is not authorized, redirecting to login");
auth.logout();
router.push("/login");
return reject("[ErrorUserNotAuthenticated]");
}
//is it a network error?
//https://medium.com/@vinhlh/how-to-handle-networkerror-when-using-fetch-ff2663220435
if (error instanceof TypeError) {
if (
error.message.includes("Failed to fetch") ||
error.message.includes("NetworkError") ||
error.message.includes("Network request failed")
) {
store.commit("logItem", "Network error");
//note: using locale key in square brackets
return reject("[ErrorServerUnresponsive]");
//throw "Error: unable to contact server";
}
}
//Ideally this should never get called because any issue should be addressed above
devShowUnknownError(error);
}
export default {
status(response) {
//Handle expected api errors
if (response.status == 401) {
//must reject if not authorized
return Promise.reject(new Error("[ErrorUserNotAuthenticated]"));
}
if (response.status >= 200 && response.status < 300) {
return Promise.resolve(response);
} else {
//log unhandled api error
store.commit(
"logItem",
"API error: status=" +
response.status +
", statusText=" +
response.statusText +
", url=" +
response.url
);
//let it float up for dealing with by caller(s)
return Promise.resolve(response);
}
},
json(response) {
return response.json();
},
apiErrorToHumanString(apiError) {
//empty error object?
if (!apiError) {
return "apiErrorToHumanString():: Empty API eror, unknown";
}
//convert to readable string
return JSON.stringify(apiError);
},
patchAuthorizedHeaders() {
return {
//Accept: "application/json, text/plain, */*",
Accept: "application/json",
"Content-Type": "application/json-patch+json",
Authorization: "Bearer " + store.state.apiToken
};
},
postAuthorizedHeaders() {
return {
Accept: "application/json",
"Content-Type": "application/json",
Authorization: "Bearer " + store.state.apiToken
};
},
postUnAuthorizedHeaders() {
return {
Accept: "application/json",
"Content-Type": "application/json"
};
},
fetchPostNoAuthOptions(data) {
return {
method: "post",
mode: "cors",
headers: this.postUnAuthorizedHeaders(),
body: JSON.stringify(data)
};
},
fetchPostOptions(data) {
return {
method: "post",
mode: "cors",
headers: this.postAuthorizedHeaders(),
body: JSON.stringify(data)
};
},
fetchPutOptions(data) {
return {
method: "put",
mode: "cors",
headers: this.postAuthorizedHeaders(),
body: JSON.stringify(data)
};
},
fetchGetOptions() {
/* GET WITH AUTH */
return {
method: "get",
mode: "cors",
headers: this.postAuthorizedHeaders()
};
},
APIUrl(apiPath) {
if ("" == store.state.apiUrl) {
//construct the api url and store it
//development location?
if (
(window.location.hostname == "localhost" ||
window.location.hostname == "192.168.1.56") &&
window.location.port == "8080"
) {
store.commit("setAPIURL", "http://localhost:7575/api/v8.0/");
store.commit("setHelpURL", "http://localhost:7575/docs/");
store.commit(
"logItem",
"gzapi::APIUrl -> setting to dev. mode: " + store.state.apiUrl
);
} else {
//production location <protocol>//<hostname>:<port>/
store.commit(
"setHelpURL",
window.location.protocol + "//" + window.location.host + "/docs/"
);
store.commit(
"setAPIURL",
window.location.protocol + "//" + window.location.host + "/api/v8.0/"
);
store.commit(
"logItem",
"gzapi::APIUrl -> setting to: " + store.state.apiUrl
);
}
}
return store.state.apiUrl + apiPath;
},
/////////////////////////////
// ENCODE QUERY STRING
//
buildQuery(obj, sep, eq, name) {
sep = sep || "&";
eq = eq || "=";
if (obj === null) {
obj = undefined;
}
if (typeof obj === "object") {
return Object.keys(obj)
.map(function(k) {
var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
if (Array.isArray(obj[k])) {
return obj[k]
.map(function(v) {
return ks + encodeURIComponent(stringifyPrimitive(v));
})
.join(sep);
} else {
return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
}
})
.filter(Boolean)
.join(sep);
}
if (!name) return "";
return (
encodeURIComponent(stringifyPrimitive(name)) +
eq +
encodeURIComponent(stringifyPrimitive(obj))
);
},
///////////////////////////////////
// GET DATA FROM API SERVER
//
get(route) {
var that = this;
return new Promise(function getDataFromServer(resolve, reject) {
fetch(that.APIUrl(route), that.fetchGetOptions())
.then(that.status)
.then(that.json)
.then(response => {
resolve(response);
})
.catch(function handleGetError(error) {
//fundamental error, can't proceed with this call
handleError("GET", error, route, reject);
});
});
},
///////////////////////////////////
// POST / PUT DATA TO API SERVER
//
upsert(route, data) {
var that = this;
return new Promise(function upsertDataToServer(resolve, reject) {
//determine if this is a new or existing record
var fetchOptions = undefined;
if (data.concurrencyToken) {
fetchOptions = that.fetchPutOptions(data);
} else {
fetchOptions = that.fetchPostOptions(data);
}
fetch(that.APIUrl(route), fetchOptions)
.then(that.status)
.then(that.json)
.then(response => {
//Note: response.error indicates there is an error, however this is not an unusual condition
//it could be validation errors or other general error so we need to treat it here like it's normal
//and let the caller deal with it appropriately
resolve(response);
})
.catch(function handleUpsertError(error) {
handleError("UPSERT", error, route, reject);
});
});
}
//new functions above here
};