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 };