first commit
This commit is contained in:
107
docs/api-stack/api/api-graphql-ui-graphiql/README.md
Normal file
107
docs/api-stack/api/api-graphql-ui-graphiql/README.md
Normal file
@@ -0,0 +1,107 @@
|
||||
# @suaveplan/api-graphql-ui-graphiql — GraphiQL UI mount for the Suaveplan API plugin system. Exposes createGraphiqlUi() — a factory returning a RouterPlugin that registers GET /graphql/ui (or any configured endpoint) and serves a self-contained HTML shell + bundled assets with a strict CSP. Default GraphQL explorer when operators want GraphiQL; sibling api-graphql-ui-altair covers the Altair alternative.
|
||||
|
||||
GraphiQL UI mount for the Suaveplan API plugin system. Stage 7 of
|
||||
the umbrella plan.
|
||||
|
||||
`createGraphiqlUi(opts)` returns a `RouterPlugin` that registers
|
||||
`GET /graphql/ui` (or any configured endpoint) on a host
|
||||
`@suaveplan/api-router` `Router`. The endpoint serves a self-contained
|
||||
HTML shell plus bundled JS/CSS assets — no CDN fetches.
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
## Documentation tree
|
||||
|
||||
- [assets](./src/assets/assets.md) — Bundled static-asset registry for the GraphiQL UI plugin. The HTML shell references two assets (`graphiql.js`, `graphiq…
|
||||
- [assets](./src/assets/assets.md) — Bundled static-asset registry for the GraphiQL UI plugin. The HTML shell references two assets (`graphiql.js`, `graphiq…
|
||||
- [error-codes](./src/error-codes/error-codes.md) — Owns the stable `GRAPHQL_UI_GRAPHIQL.*` error-code registry consumed by the GraphiQL UI plugin. Every code in the regis…
|
||||
- [error-codes](./src/error-codes/error-codes.md) — Owns the stable `GRAPHQL_UI_GRAPHIQL.*` error-code registry consumed by the GraphiQL UI plugin. Every code in the regis…
|
||||
- [factory](./src/factory/create-graphiql-ui.md) — Public entry point of the package. `createGraphiqlUi(opts)` returns a `RouterPlugin` — a plain value with `name`, `vers…
|
||||
- [create-graphiql-ui](./src/factory/create-graphiql-ui.md) — Public entry point of the package. `createGraphiqlUi(opts)` returns a `RouterPlugin` — a plain value with `name`, `vers…
|
||||
- [headers](./src/headers/csp.md) — Owns the `Content-Security-Policy` header values emitted on the GraphiQL HTML response. The policy is hard-coded to a p…
|
||||
- [csp](./src/headers/csp.md) — Owns the `Content-Security-Policy` header values emitted on the GraphiQL HTML response. The policy is hard-coded to a p…
|
||||
- [html](./src/html/render-shell.md) — Renders the GraphiQL HTML shell. The output embeds the configured GraphQL endpoint, subscription endpoint, theme, and e…
|
||||
- [render-shell](./src/html/render-shell.md) — Renders the GraphiQL HTML shell. The output embeds the configured GraphQL endpoint, subscription endpoint, theme, and e…
|
||||
- [instruments](./src/instruments/instruments.md) — Owns the OpenTelemetry instrument bundle emitted by the GraphiQL UI plugin. A single `Counter` (`graphql.ui.requests_to…
|
||||
- [instruments](./src/instruments/instruments.md) — Owns the OpenTelemetry instrument bundle emitted by the GraphiQL UI plugin. A single `Counter` (`graphql.ui.requests_to…
|
||||
- [options](./src/options/options.md) — Zod-validated configuration surface for `createGraphiqlUi`. Owns `GraphiqlUiOptions` (resolved shape with every default…
|
||||
- [options](./src/options/options.md) — Zod-validated configuration surface for `createGraphiqlUi`. Owns `GraphiqlUiOptions` (resolved shape with every default…
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Why opt-in
|
||||
|
||||
Per the design doc (`docs/superpowers/specs/2026-05-13-api-plugin-foundation-design.md`
|
||||
§10.6) the API foundation reserves `GET /graphql/ui` for an interactive
|
||||
explorer but does not bundle one by default — UI choice is operator-
|
||||
chosen so the runtime image stays minimal for production deployments
|
||||
that don't need it.
|
||||
|
||||
Operators wire ONE of:
|
||||
|
||||
- `@suaveplan/api-graphql-ui-graphiql` — canonical GraphiQL (this
|
||||
package).
|
||||
- `@suaveplan/api-graphql-ui-altair` — Altair alternative.
|
||||
|
||||
The GraphQL engine adapters (`api-graphql-yoga`, `api-graphql-apollo`)
|
||||
return 404 at `/graphql/ui` when no UI plugin is wired.
|
||||
|
||||
## Quick start
|
||||
|
||||
```ts
|
||||
import { Router } from "@suaveplan/api-router";
|
||||
import { createGraphiqlUi } from "@suaveplan/api-graphql-ui-graphiql";
|
||||
|
||||
const router = new Router({ plugin: "host" });
|
||||
createGraphiqlUi({}).register(router);
|
||||
// GET /graphql/ui -> the explorer
|
||||
// GET /graphql/ui/assets/graphiql.<hash>.js -> bundled JS
|
||||
// GET /graphql/ui/assets/graphiql.<hash>.css -> bundled CSS
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
| Option | Default | Notes |
|
||||
|---|---|---|
|
||||
| `uiEndpoint` | `/graphql/ui` | Must start with `/`. |
|
||||
| `graphqlEndpoint` | `/graphql` | Embedded into the explorer config. |
|
||||
| `subscriptionEndpoint` | `/graphql/ws` | Embedded into the explorer config. |
|
||||
| `theme` | `"system"` | `"light"` / `"dark"` / `"system"`. |
|
||||
| `defaultQuery` | `""` | HTML-escaped before embedding. |
|
||||
| `defaultVariableEditorOpen` | `false` | Opens the variables pane on load. |
|
||||
| `editorOptions` | `{}` | CodeMirror passthroughs. |
|
||||
| `meterProvider` | OTel global | OTel `MeterProvider` for the counter. |
|
||||
|
||||
## Security posture
|
||||
|
||||
- **Bundled assets only.** Every `src` / `href` in the rendered HTML
|
||||
points inside the package's own `/<uiEndpoint>/assets/` namespace.
|
||||
Cross-checked by `src/html/render-shell.test.ts`.
|
||||
- **Strict CSP.** `default-src 'self'; style-src 'self' 'unsafe-inline';
|
||||
script-src 'self'; img-src 'self' data:; connect-src 'self'`.
|
||||
Inline scripts are NOT permitted. Cross-checked by
|
||||
`src/headers/csp.test.ts`.
|
||||
- **Cache-immutable assets.** Bundled JS/CSS carries
|
||||
`Cache-Control: public, max-age=31536000, immutable`.
|
||||
- **Stale-hash tolerance.** Hashed filenames resolve any matching
|
||||
stem+ext to the current asset bytes — rolling deploys don't
|
||||
404 in-flight sessions.
|
||||
|
||||
## OTel
|
||||
|
||||
- `graphql.ui.requests_total { ui: "graphiql" }` — counter incremented
|
||||
on each successful HTML response. Asset hits are NOT counted.
|
||||
|
||||
## Error codes
|
||||
|
||||
- `GRAPHQL_UI_GRAPHIQL.ASSET_MISSING` — asset lookup failure.
|
||||
- `GRAPHQL_UI_GRAPHIQL.ENDPOINT_COLLISION` — `<uiEndpoint>` already
|
||||
registered by another plugin.
|
||||
|
||||
## Tests
|
||||
|
||||
```bash
|
||||
bunx --bun turbo lint typecheck test:coverage --filter=@suaveplan/api-graphql-ui-graphiql
|
||||
```
|
||||
|
||||
100% statements / branches / functions / lines required on touched
|
||||
modules (`provider: istanbul`).
|
||||
|
||||
Reference in New Issue
Block a user