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

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 — frozen Map<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 — throws ASSET_MISSING if name is not registered.
  • resolveAsset(filename: string): GraphiqlAsset — throws ASSET_MISSING on 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.