Initial Commit
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
# cdn-client
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## 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<CdnContainerMetadata | null>`
|
||||
|
||||
Returns `null` on 404, parsed metadata on 2xx, throws on other non-ok.
|
||||
|
||||
### `purgeObject(ctx, encodedKey, signal?): Promise<void>`
|
||||
|
||||
Issues `DELETE <cdnEndpoint><container>/<encodedKey>`. 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.
|
||||
Reference in New Issue
Block a user