@graphql-mesh/serve-runtime
Version:
143 lines (142 loc) • 6.33 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.createServeRuntime = void 0;
const graphql_1 = require("graphql");
const graphql_yoga_1 = require("graphql-yoga");
const fusion_federation_1 = require("@graphql-mesh/fusion-federation");
const fusion_runtime_1 = require("@graphql-mesh/fusion-runtime");
// eslint-disable-next-line import/no-extraneous-dependencies
const utils_1 = require("@graphql-mesh/utils");
const executor_yoga_1 = require("@graphql-tools/executor-yoga");
const utils_2 = require("@graphql-tools/utils");
const getProxyExecutor_js_1 = require("./getProxyExecutor.js");
const handleUnifiedGraphConfig_js_1 = require("./handleUnifiedGraphConfig.js");
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 = (0, fusion_runtime_1.useFusiongraph)({
getFusiongraph: () => (0, handleUnifiedGraphConfig_js_1.handleUnifiedGraphConfig)(config.fusiongraph, configContext),
transports: config.transports,
polling: config.polling,
additionalResolvers: config.additionalResolvers,
transportBaseContext: configContext,
readinessCheckEndpoint: config.readinessCheckEndpoint || '/readiness',
});
}
else if ('supergraph' in config) {
supergraphYogaPlugin = (0, fusion_runtime_1.useFusiongraph)({
getFusiongraph() {
const supergraph$ = (0, handleUnifiedGraphConfig_js_1.handleUnifiedGraphConfig)(config.supergraph, configContext);
configContext.logger?.info?.(`Converting Federation Supergraph to Fusiongraph`);
if ((0, utils_2.isPromise)(supergraph$)) {
return supergraph$.then(supergraph => (0, fusion_federation_1.convertSupergraphToFusiongraph)(supergraph));
}
return (0, fusion_federation_1.convertSupergraphToFusiongraph)(supergraph$);
},
transports: config.transports,
polling: config.polling,
additionalResolvers: config.additionalResolvers,
transportBaseContext: configContext,
readinessCheckEndpoint: config.readinessCheckEndpoint || '/readiness',
});
}
else if ('proxy' in config) {
let schema;
const proxyExecutor = (0, getProxyExecutor_js_1.getProxyExecutor)(config, configContext, () => schema);
// TODO: fix useExecutor typings to inherit the context
const executorPlugin = (0, executor_yoga_1.useExecutor)(proxyExecutor);
supergraphYogaPlugin = {
onPluginInit({ addPlugin }) {
addPlugin(executorPlugin);
addPlugin(
// TODO: fix useReadinessCheck typings to inherit the context
(0, graphql_yoga_1.useReadinessCheck)({
endpoint: config.readinessCheckEndpoint || '/readiness',
check() {
const res$ = proxyExecutor({
document: (0, graphql_1.parse)(`query { __typename }`),
});
if ((0, utils_2.isPromise)(res$)) {
return res$.then(res => !(0, graphql_yoga_1.isAsyncIterable)(res) && !!res.data?.__typename);
}
if (!(0, graphql_yoga_1.isAsyncIterable)(res$)) {
return !!res$.data?.__typename;
}
return false;
},
}));
},
onSchemaChange: payload => {
schema = payload.schema;
},
invalidateUnifiedGraph: () => (executorPlugin.invalidateSupergraph || executorPlugin.invalidateUnifiedGraph)(),
};
}
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 = (0, utils_1.wrapFetchWithHooks)(onFetchHooks);
},
};
const yoga = (0, graphql_yoga_1.createYoga)({
fetchAPI: config.fetchAPI,
logging: config.logging == null ? new utils_1.DefaultLogger() : config.logging,
plugins: [defaultFetchPlugin, supergraphYogaPlugin, ...(config.plugins?.(configContext) || [])],
context: ({ request, params, ...rest }) => {
// TODO: I dont like this cast, but it's necessary
const { req, connectionParams } = rest;
return {
...configContext,
request,
params,
headers:
// Maybe Node-like environment
req?.headers
? (0, utils_1.getHeadersObj)(req.headers)
: // Fetch environment
request?.headers
? (0, utils_1.getHeadersObj)(request.headers)
: // Unknown environment
{},
connectionParams,
};
},
cors: config.cors,
graphiql: config.graphiql,
batching: config.batching,
graphqlEndpoint: config.graphqlEndpoint,
maskedErrors: config.maskedErrors,
healthCheckEndpoint: config.healthCheckEndpoint || '/healthcheck',
});
fetchAPI ||= yoga.fetchAPI;
logger = yoga.logger;
Object.defineProperty(yoga, 'invalidateUnifiedGraph', {
value: supergraphYogaPlugin.invalidateUnifiedGraph,
configurable: true,
});
return yoga;
}
exports.createServeRuntime = createServeRuntime;
;