2.9 KiB
assets — Bundled asset registry, resolver, CDN-clean check
(no submodules)
Purpose
assets ships the Altair shell as a static-asset map keyed by logical
filename. Every entry carries a content-type, the payload bytes, and a
short SHA-256 hash derived once at module init so cache-bust URLs are
stable across deploys with unchanged payloads. The shell is shipped
inline (no FS reads at request time, no CDN fetches) which preserves
the Altair plugin's hermetic-bundle guarantee — the package can boot in
air-gapped, offline-first environments and still serve a usable UI.
Features
- Default registry:
altair.js+altair.css. defineAsset(name, contentType, body)returns a frozenBundledAsset.resolveAsset(registry, uiEndpointBase, name)produces aResolvedAssetwith a hash-busted URL.- Missing names throw
GraphqlUiAltairError(ASSET_MISSING). findExternalHostReferencesis the CDN-clean conformance check.- Hash derivation is SHA-256, truncated to 16 hex chars — same
cardinality as a
git rev-parse --short=16.
Usage: Basic
import {
buildDefaultAssetRegistry,
resolveAsset,
} from "@suaveplan/api-graphql-ui-altair/assets";
const registry = buildDefaultAssetRegistry();
const jsAsset = resolveAsset(registry, "/graphql/ui", "altair.js");
console.log(jsAsset.url); // /graphql/ui/assets/<hash>/altair.js
Usage: Advanced
import {
buildDefaultAssetRegistry,
defineAsset,
findExternalHostReferences,
} from "@suaveplan/api-graphql-ui-altair/assets";
// Extend the registry with an operator-specific asset.
const registry = new Map(buildDefaultAssetRegistry());
registry.set(
"logo.svg",
defineAsset(
"logo.svg",
"image/svg+xml",
'<svg xmlns="http://www.w3.org/2000/svg" />'
)
);
const offenders = findExternalHostReferences(registry);
if (offenders.length > 0) {
throw new Error("CDN leak: " + offenders.join(", "));
}
API Reference
BundledAsset—{ name, contentType, body, hash }.ResolvedAsset extends BundledAsset— addsurl.defineAsset(name, contentType, body): BundledAsset.buildDefaultAssetRegistry(): ReadonlyMap<string, BundledAsset>.resolveAsset(registry, uiEndpointBase, name): ResolvedAsset— throwsGraphqlUiAltairError(ASSET_MISSING) on misses.findExternalHostReferences(registry): readonly string[].
Implementation Notes
The asset bodies are held as JavaScript template literals so the build
emits them as plain string constants — no FS access at boot, no
process.cwd() dependence. The hash is computed via node:crypto to
match the same hashing the rest of the project's static-asset
pipeline uses; the truncation to 16 hex chars is intentional — a
collision in a single deploy's asset set is vanishingly unlikely and
the shorter URL is easier on the eyes in production logs.