UNPKG

@kiwicom/smart-faq

Version:

Smart FAQ

124 lines (104 loc) 2.83 kB
// @noflow import { Environment, Network, RecordSource, Store, QueryResponseCache, } from 'relay-runtime'; import idx from 'idx'; import * as fallbacks from "../../fallbacks/"; // eslint-disable-line import { DEFAULT_LOCALE } from '../helpers/translationUtils'; require('isomorphic-fetch'); // used when smart FAQ installed as dependency const uri = 'https://graphql.kiwi.com'; const cache = new QueryResponseCache({ size: 200, ttl: 30 * 60 * 1000 }); export const ERROR_FORBIDDEN = 'Forbidden 403'; const getFallbackData = (error, operation) => { if (operation.name in fallbacks) { return fallbacks[operation.name]; } else { throw error; } }; const handleForbiddenError = json => { if ( json.errors && json.errors.length > 0 && json.errors.some( error => idx(error, _ => _.extensions.proxy.statusCode) === '403', ) ) { throw new Error(ERROR_FORBIDDEN); } }; const composeRequestBody = (operation, variables) => JSON.stringify({ query: operation.text, // GraphQL text from input variables, operationName: operation.name, }); const composeRequest = (headers, operation, variables) => { const body = composeRequestBody(operation, variables); return [ process.env.GRAPHQL_URI || uri, { method: 'POST', headers, body, }, ]; }; export async function fetchQuery(headers, operation, variables) { let fallbackData = null; let response = null; try { response = await fetch(...composeRequest(headers, operation, variables)); } catch (error) { fallbackData = getFallbackData(error, operation); } let json = fallbackData; if (!json) { json = await response.json(); } handleForbiddenError(json); return json; } const buildQueryFetcher = ( token: string = '', kwAuthToken: string = '', locale: string = DEFAULT_LOCALE, ) => { return async (operation, variables, cacheConfig) => { const forceFetch = cacheConfig.force; const isQuery = operation.operationKind === 'query'; if (!forceFetch && isQuery) { const cachedData = cache.get(operation.text, variables); if (cachedData) { return cachedData; } } const headers = { 'Content-Type': 'application/json', 'Accept-Language': locale, 'KW-Auth-Token': kwAuthToken, Authorization: token, }; const json = await fetchQuery(headers, operation, variables); if (!forceFetch && isQuery) { cache.set(operation.text, variables, json); } return json; }; }; const createEnvironment = ( token: ?string, kwAuthToken: ?string, locale: ?string, ) => { return new Environment({ network: Network.create(buildQueryFetcher(token, kwAuthToken, locale)), store: new Store(new RecordSource()), }); }; export default createEnvironment;