UNPKG

@graphql-mesh/serve-runtime

Version:
104 lines (103 loc) 4.1 kB
import { createYoga } from 'graphql-yoga'; import { convertSupergraphToFusiongraph } from '@graphql-mesh/fusion-federation'; import { useFusiongraph } from '@graphql-mesh/fusion-runtime'; // eslint-disable-next-line import/no-extraneous-dependencies import { DefaultLogger, getHeadersObj, wrapFetchWithHooks } from '@graphql-mesh/utils'; import { buildHTTPExecutor } from '@graphql-tools/executor-http'; import { useExecutor } from '@graphql-tools/executor-yoga'; import { isPromise } from '@graphql-tools/utils'; import { handleUnifiedGraphConfig } from './handleUnifiedGraphConfig.js'; export function createServeRuntime(config) { let fetchAPI = config.fetchAPI; // eslint-disable-next-line prefer-const let logger; let wrappedFetchFn; const configContext = { get fetch() { return wrappedFetchFn; }, get logger() { return logger; }, cwd: globalThis.process?.cwd(), cache: 'cache' in config ? config.cache : undefined, pubsub: 'pubsub' in config ? config.pubsub : undefined, }; let supergraphYogaPlugin; if ('fusiongraph' in config) { supergraphYogaPlugin = useFusiongraph({ getFusiongraph: () => handleUnifiedGraphConfig(config.fusiongraph, configContext), transports: config.transports, polling: config.polling, additionalResolvers: config.additionalResolvers, transportBaseContext: configContext, }); } else if ('supergraph' in config) { supergraphYogaPlugin = useFusiongraph({ getFusiongraph() { const supergraph$ = handleUnifiedGraphConfig(config.supergraph, configContext); configContext.logger?.info?.(`Converting Federation Supergraph to Fusiongraph`); if (isPromise(supergraph$)) { return supergraph$.then(supergraph => convertSupergraphToFusiongraph(supergraph)); } return convertSupergraphToFusiongraph(supergraph$); }, transports: config.transports, polling: config.polling, additionalResolvers: config.additionalResolvers, transportBaseContext: configContext, }); } else if ('proxy' in config) { const executor = buildHTTPExecutor({ fetch: fetchAPI?.fetch, ...config.proxy, }); supergraphYogaPlugin = useExecutor(executor); } const defaultFetchPlugin = { onFetch({ setFetchFn }) { setFetchFn(fetchAPI.fetch); }, onYogaInit({ yoga }) { const onFetchHooks = []; for (const plugin of yoga.getEnveloped._plugins) { if (plugin.onFetch) { onFetchHooks.push(plugin.onFetch); } } wrappedFetchFn = wrapFetchWithHooks(onFetchHooks); }, }; const yoga = createYoga({ fetchAPI: config.fetchAPI, logging: config.logging == null ? new DefaultLogger() : config.logging, plugins: [defaultFetchPlugin, supergraphYogaPlugin, ...(config.plugins?.(configContext) || [])], context: ({ request, req, connectionParams }) => ({ ...configContext, headers: // Maybe Node-like environment req?.headers ? getHeadersObj(req.headers) : // Fetch environment request?.headers ? getHeadersObj(request.headers) : // Unknown environment {}, connectionParams, }), cors: config.cors, graphiql: config.graphiql, batching: config.batching, graphqlEndpoint: config.graphqlEndpoint, maskedErrors: config.maskedErrors, }); fetchAPI ||= yoga.fetchAPI; logger = yoga.logger; Object.defineProperty(yoga, 'invalidateUnifiedGraph', { value: supergraphYogaPlugin.invalidateUnifiedGraph, configurable: true, }); return yoga; }