UNPKG

@graphql-yoga/plugin-sofa

Version:
106 lines (105 loc) 3.95 kB
import { OpenAPI, useSofa as createSofaHandler } from 'sofa-api'; import { getSwaggerUIHTMLForSofa } from './swagger-ui.js'; export { OpenAPI } from 'sofa-api'; export function useSofaWithSwaggerUI(config) { const swaggerUIEndpoint = config.swaggerUIEndpoint || '/swagger'; let openApi; const onRoute = (route) => { openApi.addRoute(route, { basePath: config.basePath }); if (config.onRoute) { config.onRoute(route); } }; let swaggerJsonPattern; let swaggerUIPattern; return { onPluginInit({ addPlugin }) { addPlugin(useSofa({ ...config, onRoute })); }, onSchemaChange({ schema }) { openApi = OpenAPI({ schema, info: config.info, servers: config.servers, components: config.components, security: config.security, tags: config.tags, customScalars: config.customScalars, }); }, onYogaInit({ yoga }) { swaggerJsonPattern = new yoga.fetchAPI.URLPattern({ pathname: '/swagger.json', }); swaggerUIPattern = new yoga.fetchAPI.URLPattern({ pathname: swaggerUIEndpoint, }); }, onRequest({ url, fetchAPI, endResponse }) { if (swaggerUIPattern.test(url)) { const swaggerUIHTML = getSwaggerUIHTMLForSofa(openApi); const response = new fetchAPI.Response(swaggerUIHTML, { status: 200, headers: { 'Content-Type': 'text/html', }, }); endResponse(response); } if (swaggerJsonPattern.test(url)) { const response = new fetchAPI.Response(JSON.stringify(openApi.get()), { status: 200, headers: { 'Content-Type': 'application/json', }, }); endResponse(response); } }, }; } export function useSofa(config) { let sofaHandler; let getEnveloped; const envelopedByContext = new WeakMap(); const requestByContext = new WeakMap(); return { onYogaInit({ yoga }) { getEnveloped = yoga.getEnveloped; }, onSchemaChange(onSchemaChangeEventPayload) { sofaHandler = createSofaHandler({ ...config, schema: onSchemaChangeEventPayload.schema, async context(serverContext) { const enveloped = getEnveloped(serverContext); const request = requestByContext.get(serverContext); const contextValue = await enveloped.contextFactory({ request }); envelopedByContext.set(contextValue, enveloped); return contextValue; }, execute(args) { const enveloped = envelopedByContext.get(args.contextValue); if (!enveloped) { throw new TypeError('Illegal invocation.'); } return enveloped.execute(args); }, subscribe(args) { const enveloped = envelopedByContext.get(args.contextValue); if (!enveloped) { throw new TypeError('Illegal invocation.'); } return enveloped.subscribe(args); }, }); }, async onRequest({ request, serverContext, endResponse }) { requestByContext.set(serverContext, request); const response = await sofaHandler.handle(request, serverContext); if (response) { endResponse(response); } }, }; }