82 lines
2.8 KiB
Markdown
82 lines
2.8 KiB
Markdown
# `html/render-shell` — Altair HTML shell builder
|
|
|
|
<!-- begin:auto-docs -->
|
|
_(no submodules)_
|
|
<!-- end:auto-docs -->
|
|
|
|
## Purpose
|
|
|
|
`html/render-shell` produces the single HTML document the Altair UI
|
|
plugin serves at `<uiEndpoint>`. The shell mounts a `<div id="altair-root">`,
|
|
embeds the resolved JS/CSS asset URLs (hash-busted, so CDN cache
|
|
behaviour is correct), and serialises the parsed `AltairUiOptions` as a
|
|
`<script type="application/json">` data block — never as executable
|
|
inline JavaScript — so the strict CSP attached by `headers/csp` can
|
|
forbid `script-src 'unsafe-inline'` outright.
|
|
|
|
## Features
|
|
|
|
- One self-contained HTML document — no external host references.
|
|
- Configurable endpoints surfaced both as `<meta>` tags AND as `data-*`
|
|
attributes on the root container, so consumers integrating Altair
|
|
via custom JS can read either layer.
|
|
- JSON config block escaped against `</script>` injection per the HTML5
|
|
spec recommendation.
|
|
- User-supplied endpoint values HTML-escaped before embedding.
|
|
- Theme attribute (`data-altair-theme`) on `<html>` for CSS hooks.
|
|
|
|
## Usage: Basic
|
|
|
|
```ts
|
|
import { renderAltairShell } from "@suaveplan/api-graphql-ui-altair/html";
|
|
import { buildDefaultAssetRegistry } from "@suaveplan/api-graphql-ui-altair/assets";
|
|
import { parseAltairUiOptions } from "@suaveplan/api-graphql-ui-altair/options";
|
|
|
|
const html = renderAltairShell({
|
|
options: parseAltairUiOptions(),
|
|
assetRegistry: buildDefaultAssetRegistry(),
|
|
});
|
|
```
|
|
|
|
## Usage: Advanced
|
|
|
|
```ts
|
|
import { renderAltairShell } from "@suaveplan/api-graphql-ui-altair/html";
|
|
import {
|
|
buildDefaultAssetRegistry,
|
|
defineAsset,
|
|
} from "@suaveplan/api-graphql-ui-altair/assets";
|
|
import { parseAltairUiOptions } from "@suaveplan/api-graphql-ui-altair/options";
|
|
|
|
const registry = new Map(buildDefaultAssetRegistry());
|
|
registry.set(
|
|
"logo.svg",
|
|
defineAsset("logo.svg", "image/svg+xml", "<svg/>")
|
|
);
|
|
|
|
const html = renderAltairShell({
|
|
options: parseAltairUiOptions({
|
|
theme: "dark",
|
|
initialEnvironments: {
|
|
production: { url: "https://api.example.com/graphql" },
|
|
},
|
|
}),
|
|
assetRegistry: registry,
|
|
});
|
|
```
|
|
|
|
## API Reference
|
|
|
|
- `RenderAltairShellInput` — `{ options: AltairUiOptions; assetRegistry: ReadonlyMap<string, BundledAsset> }`.
|
|
- `renderAltairShell(input): string` — returns the full HTML document
|
|
including the `<!DOCTYPE html>` declaration.
|
|
|
|
## Implementation Notes
|
|
|
|
The `</script>` escape inside the JSON config block uses the HTML5
|
|
spec's recommended sequence `<\/script` so the JSON itself remains
|
|
parseable while the closing-tag-injection vector is closed. All
|
|
user-supplied strings flowing into HTML attributes pass through a
|
|
four-character HTML escape — the structural goal is "no inline script
|
|
ever executes", which the strict CSP then enforces at the browser.
|