2.8 KiB
assets
(no submodules)
Purpose
Bundled static-asset registry for the GraphiQL UI plugin. The HTML shell
references two assets (graphiql.js, graphiql.css) via hashed filenames
under <uiEndpoint>/assets/. Hash bytes come from FNV-1a-32 of the asset
content — non-cryptographic, used purely for cache-busting on deploy.
The asset payloads are shipped inline as TypeScript template strings so
the package has zero filesystem requirements at runtime. Operators who
want a richer GraphiQL distribution (the full React app) can swap
GRAPHIQL_ASSETS content on a fork without touching the rest of the
plugin.
Features
GRAPHIQL_ASSETS— frozenMap<name, asset>exposing every shipped static.hashedAssetPath(name)— builds<stem>.<hash>.<ext>for embedding in the HTML shell.resolveAsset(filename)— server-side lookup. Tolerates stale hashes during rolling deploys (resolves any matching stem+ext to the current asset).fnv1a32(input)— public so callers can hash their own additions in consistent shape.
Usage: Basic
import { GRAPHIQL_ASSETS, resolveAsset } from "@suaveplan/api-graphql-ui-graphiql";
for (const asset of GRAPHIQL_ASSETS.values()) {
console.log(asset.name, asset.hash, asset.contentType);
}
const css = resolveAsset("graphiql.css");
Usage: Advanced
import { fnv1a32, hashedAssetPath, resolveAsset } from "@suaveplan/api-graphql-ui-graphiql";
// Build the served filename for the JS asset.
const path = `/graphql/ui/assets/${hashedAssetPath("graphiql.js")}`;
// Verify integrity in a custom asset middleware.
const asset = resolveAsset("graphiql.js");
if (fnv1a32(asset.content) !== asset.hash) {
throw new Error("asset content drift");
}
API Reference
interface GraphiqlAsset { name, content, contentType, hash }.GRAPHIQL_ASSETS: ReadonlyMap<string, GraphiqlAsset>.fnv1a32(input: string): string— 8-char lowercase hex hash.hashedAssetPath(name: string): string— throwsASSET_MISSINGifnameis not registered.resolveAsset(filename: string): GraphiqlAsset— throwsASSET_MISSINGon lookup failure.
Implementation Notes
The stale-hash tolerance is intentional. Picture a CDN-cached index.html
served before a deploy with the new asset bundle — that index.html
references graphiql.<old-hash>.js. Returning 404 on the old hash would
break the in-flight session for ~CDN-TTL seconds. The resolver instead
serves the new bytes under the old name, traded against a slightly larger
attack surface (an adversary who knows the asset name+ext can fetch the
asset at any hash). The Cache-Control header on the response is
immutable for the matched name, so the browser still caches the
content correctly.