# cdn-client _(no submodules)_ ## Purpose Wraps the two Rackspace CDN management operations the adapter actually needs at runtime: `getCdnMetadata` (HEAD on the container's CDN URL to fetch `X-Cdn-Uri`, `X-Cdn-Ssl-Uri`, `X-Ttl`, `X-Cdn-Enabled`) and `purgeObject` (DELETE against the per-object CDN URL to invalidate the edge cache). Both functions accept a `CdnClientContext` that bundles the resolved `cdnEndpoint`, `token`, `container`, and `region`, so the calling code (the adapter) constructs the bundle once per operation and never has to thread the fields by hand. ## Features - Two focused functions — no class to instantiate. - `getCdnMetadata` returns `null` on 404, the parsed metadata otherwise. - `purgeObject` resolves on 2xx and on 404 (already absent), throws `PURGE_RATE_LIMITED` on 429, and `UPSTREAM_ERROR` on other non-ok statuses. - AbortSignal threaded into both fetch invocations. - All errors carry `container`/`region`/`httpStatus` for diagnostics. ## Usage: Basic ```ts import { purgeObject } from "@suaveplan/storage-cdn-rackspace"; await purgeObject( { fetch, token: "tok", cdnEndpoint: "https://cdn.example.com/", container: "myc", region: "LON" }, "a%2Fb.bin", ); ``` ## Usage: Advanced ```ts import { getCdnMetadata, purgeObject } from "@suaveplan/storage-cdn-rackspace"; async function purgeAfterUpload(ctx, key: string) { const meta = await getCdnMetadata(ctx); if (meta?.cdnEnabled !== true) return; // nothing to invalidate await purgeObject(ctx, encodeURIComponent(key)); } ``` ## API Reference ### `interface CdnClientContext` `{ fetch, token, cdnEndpoint, container, region }` — `cdnEndpoint` is the management endpoint resolved from the service catalog. ### `interface CdnContainerMetadata` `{ cdnUri, cdnSslUri, ttl, cdnEnabled }` — parsed verbatim from `X-Cdn-*` headers; missing headers default to empty string / 0 / false. ### `getCdnMetadata(ctx, signal?): Promise` Returns `null` on 404, parsed metadata on 2xx, throws on other non-ok. ### `purgeObject(ctx, encodedKey, signal?): Promise` Issues `DELETE /`. Resolves on 2xx or 404. Throws `STORAGE_CDN_RACKSPACE.PURGE_RATE_LIMITED` on 429. Other non-ok statuses surface as `UPSTREAM_ERROR`. ## Implementation Notes - The `encodedKey` parameter is already URL-encoded by the caller — this module does not re-encode, which would double-escape values. - 404 on purge is treated as success because Rackspace returns 404 for objects already evicted or never CDN-served; surfacing that as an error would force every caller to handle it specially. - 429 is its own error code rather than `UPSTREAM_ERROR` because the management API has historically been rate-limited at ~25/min and operators want a dedicated alert rule. - `cdnEnabled` parsing is case-insensitive (`true`/`True`/`TRUE`) — Rackspace has been inconsistent across documentation versions. - The functions are intentionally not bundled into a class because there is no state worth caching across calls — the auth client already caches everything that survives between operations.