import {isEqual} from 'lodash'
import Client from "../lib/GraphClient/GraphClient.js"
import introspectionQuery from "../lib/GraphClient/queries/introspection.json"
let client = new Client();
export const mutations = {
setParameters(state, data) {
try {
if (Object.keys(data).includes("errors")) {
state.error = data.errors[0].message
}
else {
localStorage.introspectionQuery = JSON.stringify(data);
let queryParams = data.data["__schema"]["types"].filter(param => param.name === "Query")[0];
state.searchQueryParameters = queryParams.fields.filter(param => param.name === "searchFairsharingRecords")[0];
if (!localStorage.searchQueryParameters) {
localStorage.searchQueryParameters = JSON.stringify(state.searchQueryParameters);
}
else {
if (!isEqual(JSON.parse(localStorage.searchQueryParameters), JSON.parse(JSON.stringify(state.searchQueryParameters)))) {
localStorage.searchQueryParameters = JSON.stringify(state.searchQueryParameters);
}
else {
state.searchQueryParameters = JSON.parse(localStorage.searchQueryParameters);
}
}
}
}
catch (e) {
state.error = "Can't initialize application"
}
},
setLocalStorageExpiryTime: function () {
let now = new Date();
localStorage.expiryDate = now;
return now;
},
setMaintenanceMode(state){
state.maintenanceMode = true;
},
setReadOnlyMode(state){
state.readOnlyMode = true;
}
};
export const actions = {
async fetchParameters(state, timer) {
let expirationTimer = (timer) ? timer : 24;
let data = await client.getData(introspectionQuery);
if (localStorage.expiryDate) {
const expiration = paramsAreExpired(localStorage.expiryDate, expirationTimer);
if (expiration) {
this.commit("introspection/setLocalStorageExpiryTime");
this.commit("introspection/setParameters", data.data);
}
else {
this.commit("introspection/setParameters", JSON.parse(localStorage.introspectionQuery));
}
}
if (!localStorage.introspectionQuery) {
this.commit("introspection/setLocalStorageExpiryTime");
this.commit("introspection/setParameters", data.data);
}
if (data.headers['maintenance'] === "true") this.commit("introspection/setMaintenanceMode");
if (data.headers['read-only'] === "true") this.commit("introspection/setReadOnlyMode");
// temp!
// this.commit("introspection/setMaintenanceMode");
// this.commit("introspection/setReadOnlyMode");
}
};
export const getters = {
buildQueryParameters: (state) => (params) => {
let queryParameters = {};
Object.keys(params[1]).forEach(function (param) {
let expectedTypeObject = null;
if(state.searchQueryParameters.args === undefined) return;
let currentParam = state.searchQueryParameters.args.filter(arg => arg.name === param)[0];
if(currentParam === undefined) return;
expectedTypeObject = currentParam.type;
if (expectedTypeObject.kind !== "LIST") {
queryParameters[param] = parseParam(expectedTypeObject, params[1][param]);
}
else {
const currentVal = params[1][param];
const expectedType = expectedTypeObject["ofType"]["ofType"].name;
queryParameters[param] = [];
if (currentVal.indexOf(",") > 0) {
currentVal.split(",").forEach(function (val) {
queryParameters[param].push(decodeURIComponent(parseParam(expectedType, val)))
});
}
else {
queryParameters[param] = decodeURIComponent(parseParam(expectedType, currentVal))
}
}
});
return queryParameters;
}
};
/**
* The introspection store is related to the introspection query that let us know which fields/types are allowed by the searchFairsharingRecords query
* @type {Object}
* */
let introspectionStore = {
namespaced: true,
/**
* @name states
* @type {Object}
* @property {String} errors - collects errors while introspecting.
* @property {object} searchQueryParameters - filters query parameters object coming from API.
*/
state: {
errors: String,
searchQueryParameters: {},
maintenanceMode: false,
readOnlyMode: false
},
modules: {},
mutations: mutations,
actions: actions,
getters: getters
};
export default introspectionStore;
/**
* Given a type and a value, parse the value with the expected type.
* @param {Object} param - the parameter types allowed
* @param {String} paramVal - the value to be parsed
* @returns {String | Number | Boolean} paramVal - the parse value
* @example <caption> Example usage of parseParam </caption>
* parseParam({name: "Boolean"}, "true");
* // return True
*/
const parseParam = function (param, paramVal) {
if (param.name === "Int") {
return parseFloat(paramVal)
}
else if (param.name === "Boolean") {
return JSON.parse(paramVal)
}
return paramVal;
};
/**
* Compares the given date with now and returns true if it greater than the given timer
* @param {Date} expiryDate - the date to compare
* @param {Number} expirationTimer - the timer to determine if the date has been expired or not
* @returns {boolean} - is the data expired or not
*/
export const paramsAreExpired = function (expiryDate, expirationTimer) {
const limit = expirationTimer * 3600;
const expiration = new Date(expiryDate);
const now = new Date();
return ((now - expiration) - limit) >= 0
};