Files
skills/docs/api-stack/api/api-graphql-ui-altair/src/factory/create-altair-ui.md
2026-05-29 08:20:56 +01:00

3.1 KiB

factory/create-altair-ui — Altair UI plugin factory

(no submodules)

Purpose

factory/create-altair-ui is the package's public entry point. createAltairUi(opts) validates the caller's options against the Zod schema, builds the asset registry and OTel instruments, and returns a RouterPlugin whose mount(router) method registers GET <uiEndpoint> plus the hashed-asset routes against any Router instance. Endpoint collisions are detected up-front via router.collidesWith and reject the mount with a typed GRAPHQL_UI_ALTAIR.ENDPOINT_COLLISION error before any route is written — partial mounts are impossible.

Features

  • Zero-config call: createAltairUi() works out of the box.
  • Returns a frozen RouterPlugin with name, options, mount, renderHtml, and renderAsset members.
  • HTML response always carries the strict CSP + ancillary security headers.
  • Asset response carries Cache-Control: public, max-age=31536000, immutable.
  • Asset misses (wrong hash, wrong name) throw GraphqlUiAltairError with code ASSET_MISSING.
  • Endpoint collisions throw GraphqlUiAltairError with code ENDPOINT_COLLISION before any route is registered.
  • Injectable internals (assetRegistry, instruments) for integration tests and operators wanting custom asset bundles.

Usage: Basic

import { createAltairUi } from "@suaveplan/api-graphql-ui-altair/factory";
import { Router } from "@suaveplan/api-router";

const router = new Router();
const altair = createAltairUi();
altair.mount(router);

// router.match("GET", "/graphql/ui") now resolves to the HTML handler.

Usage: Advanced

import { createAltairUi } from "@suaveplan/api-graphql-ui-altair/factory";
import { createAltairInstruments } from "@suaveplan/api-graphql-ui-altair/instruments";
import { MeterProvider } from "@opentelemetry/sdk-metrics";
import { Router } from "@suaveplan/api-router";

const meterProvider = new MeterProvider();
const instruments = createAltairInstruments({ meterProvider });

const router = new Router();
const altair = createAltairUi(
    {
        uiEndpoint: "/dev/altair",
        graphqlEndpoint: "/api/graphql",
        theme: "dark",
        initialEnvironments: {
            production: {
                url: "https://api.example.com/graphql",
                headers: { "x-tenant": "acme" },
            },
        },
    },
    { instruments }
);
altair.mount(router);

API Reference

  • createAltairUi(input?: AltairUiOptionsInput, internals?: CreateAltairUiInternals): RouterPlugin.
  • RouterPlugin — { name, options, mount(router), renderHtml(), renderAsset(hash, name) }.
  • CreateAltairUiInternals — { assetRegistry?, instruments? }.

Implementation Notes

The factory composes five lower-level modules — options, assets, html, headers, instruments — and exposes their behaviour behind one ergonomic entry point. The RouterPlugin.options field is the parsed, defaulted bundle (not the caller's raw input) so downstream code reads the same value the renderer wrote. Frozen-everything posture means operators cannot accidentally mutate the plugin between mount calls.