import { graphql } from 'graphql'; import schema from './your_schema_path'; import type { VariablesOf, GraphQLTaggedNode } from 'react-relay'; import type { ConcreteRequest, PayloadData, OperationType, } from 'relay-runtime'; export type ServerQuery = { id: string; variables: VariablesOf; payload: PayloadData; }; const preloadServerQuery = async ( gqlQuery: GraphQLTaggedNode, variables: VariablesOf, ): Promise> => { if (typeof gqlQuery === 'function') { gqlQuery = gqlQuery(); } if (gqlQuery.kind !== 'Request') { throw new Error( 'preloadServerQuery: Expected a graphql`...` tagged query.', ); } const request = gqlQuery as ConcreteRequest; const { params } = request; const queryVariables = { ...variables }; const { providedVariables } = params as any; if (providedVariables) { Object.keys(providedVariables).forEach(key => { //@ts-expect-error no types queryVariables[key] = params.providedVariables[key].get(); }); } // fetch instead of graphql if necessary const response = await graphql({ schema, // handle persisted queries is necessary source: params.text as string, variableValues: queryVariables, }); return { id: params.id ?? params.cacheID!, variables, // see https://github.com/apollographql/apollo-server/issues/3149#issuecomment-1117566982 payload: normalizeObject(response.data), }; }; export default preloadServerQuery; const normalizeObject = (obj: any): any => { if (typeof obj !== 'object' || obj == null) { return obj; } if (Array.isArray(obj)) { return obj.map(normalizeObject); } if (!(obj instanceof Object)) { const res = {} as any; const keys = Object.keys(obj); for (const key of keys) { res[key] = normalizeObject(obj[key]); } obj = res; } return obj; };