Initial Commit
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
# `html/render-shell`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
Renders the GraphiQL HTML shell. The output embeds the configured GraphQL
|
||||
endpoint, subscription endpoint, theme, and editor passthroughs into a
|
||||
`<script id="graphiql-config" type="application/json">` block — NOT inline
|
||||
JavaScript — which the bundled `graphiql.js` parses at boot. This split
|
||||
keeps `script-src 'self'` viable.
|
||||
|
||||
The shell is intentionally minimalist. The bundled bootstrap drives the
|
||||
explorer end-to-end (text area for the query, JSON pre for the response).
|
||||
Operators who want the full React-based GraphiQL distribution can swap
|
||||
out the asset payload on a fork.
|
||||
|
||||
## Features
|
||||
|
||||
- Single-call render — `renderShell(options)` returns the full document.
|
||||
- Defensive escaping — every caller-supplied string (default query,
|
||||
endpoints, theme, editor options blob) is HTML-escaped.
|
||||
- No external host references — every `src` / `href` points inside
|
||||
`<uiEndpoint>/assets/`.
|
||||
- Asset paths embed FNV-1a hashes for cache-busting.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import {
|
||||
parseGraphiqlUiOptions,
|
||||
renderShell,
|
||||
} from "@suaveplan/api-graphql-ui-graphiql";
|
||||
|
||||
const html = renderShell(parseGraphiqlUiOptions({}));
|
||||
// html starts with <!DOCTYPE html> and references /graphql/ui/assets/...
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import {
|
||||
parseGraphiqlUiOptions,
|
||||
renderShell,
|
||||
} from "@suaveplan/api-graphql-ui-graphiql";
|
||||
|
||||
const html = renderShell(
|
||||
parseGraphiqlUiOptions({
|
||||
uiEndpoint: "/explorer",
|
||||
graphqlEndpoint: "/api/v2/gql",
|
||||
subscriptionEndpoint: "/api/v2/gql/ws",
|
||||
theme: "dark",
|
||||
defaultQuery: "{ viewer { id name } }",
|
||||
editorOptions: { lineWrapping: true, tabSize: 2 },
|
||||
})
|
||||
);
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `renderShell(options: GraphiqlUiOptions): string` — produces the
|
||||
fully-substituted HTML document.
|
||||
- `escapeHtml(input: string): string` — replaces `&`, `<`, `>`, `"`,
|
||||
and `'` with HTML entities.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The config block uses `application/json` so the bootstrap can call
|
||||
`JSON.parse(node.textContent)` without sniffing or eval. Escaping the
|
||||
JSON via `escapeHtml` is technically over-protective (JSON inside a
|
||||
`<script type="application/json">` block doesn't need entity encoding
|
||||
of `<`/`>`/`&` for syntax correctness, but it does need it for
|
||||
defense-in-depth when the JSON contains a `</script>` substring) — we
|
||||
err on the safe side and run every embedded string through
|
||||
`escapeHtml`.
|
||||
Reference in New Issue
Block a user