import type { Router } from "@suaveplan/api-router"; import type { ApolloGraphqlOptions } from "../options/options.js"; /** * UI plugin descriptor. The host wires a separate UI package (GraphiQL, * Altair, …) and hands a renderer in; the Apollo engine itself never * embeds Apollo's landing page (UI is opt-in — same stance as Yoga). */ export interface GraphqlUiPlugin { /** Returns the HTML body served at `/graphql/ui`. */ render(): string; /** MIME type — defaults to `text/html` when omitted. */ readonly contentType?: string; } /** Response envelope returned by the UI proxy handler. */ export interface UiProxyResponse { readonly status: 200 | 404; readonly body: string; readonly contentType: string; } /** * Mount the `/graphql/ui` proxy endpoint. When `ui` is `null` the * handler responds `404` with a short note explaining the UI is opt-in; * when supplied it returns the plugin's rendered HTML. */ export function mountGraphqlUiProxy(args: { readonly router: Router; readonly options: ApolloGraphqlOptions; readonly ui: GraphqlUiPlugin | null; }): () => void { const { router, options, ui } = args; router.get(options.uiEndpoint, (): UiProxyResponse => { if (ui === null) { return { status: 404, body: "GraphQL UI is opt-in — wire a UI plugin to enable", contentType: "text/plain", }; } return { status: 200, body: ui.render(), contentType: ui.contentType ?? "text/html", }; }); return () => { /* hot-reload teardown reserved */ }; }