first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
# pull-zone-client
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Owns the Bunny.net management-API purge operation. `purgeUrl(ctx, edgeUrl, signal?)` issues `POST https://api.bunny.net/purge?url=<encodedEdgeUrl>` with the account-level `AccessKey` header. The caller composes the absolute edge URL (e.g. `https://<pullZoneHostname>/<key>` or the same URL with a trailing `*` for prefix purge) — keeping URL composition out of this module means the same helper handles single-key and wildcard purges without branching.
The function `purgeApiKey` from the bundle is **required**; missing it throws `STORAGE_CDN_BUNNYCDN.PURGE_API_KEY_MISSING` before any fetch happens.
## Features
- Single function with a tight contract — no class state.
- `purgeApiKey` enforced at the top; missing or empty key → `PURGE_API_KEY_MISSING` (no fetch issued).
- 401/403 → `PURGE_AUTH_FAILED`, other non-ok → `UPSTREAM_ERROR`.
- Errors carry `zone`, `region`, and `httpStatus` for diagnostics.
- AbortSignal threaded into the fetch init.
## Usage: Basic
```ts
import { purgeUrl } from "@suaveplan/storage-cdn-bunnycdn";
await purgeUrl(
{ fetch, purgeApiKey: "key-1234", pullZoneHostname: "mycdn.b-cdn.net", zone: "myz", region: "de" },
"https://mycdn.b-cdn.net/a/b.bin",
);
```
## Usage: Advanced
```ts
import { purgeUrl } from "@suaveplan/storage-cdn-bunnycdn";
async function purgePrefix(ctx, prefix: string) {
// BunnyCDN's purge endpoint treats `*` as a wildcard suffix.
await purgeUrl(ctx, `https://${ctx.pullZoneHostname}/${encodeURI(prefix)}*`);
}
async function purgeSafelyWithKeyRotation(ctx, edgeUrl: string) {
try {
await purgeUrl(ctx, edgeUrl);
} catch (err) {
if (err instanceof StorageCdnBunnycdnError && err.code === STORAGE_CDN_BUNNYCDN_CODES.PURGE_AUTH_FAILED) {
const refreshed = await rotateAccessKey();
await purgeUrl({ ...ctx, purgeApiKey: refreshed }, edgeUrl);
return;
}
throw err;
}
}
```
## API Reference
### `interface PullZoneCtx`
`{ fetch, purgeApiKey, pullZoneHostname, zone, region }`. `purgeApiKey` is `string | undefined`; absent value triggers `PURGE_API_KEY_MISSING`.
### `purgeUrl(ctx, edgeUrl, signal?): Promise<void>`
- `2xx` → resolves.
- `401`/`403` → `STORAGE_CDN_BUNNYCDN.PURGE_AUTH_FAILED`.
- other non-ok → `STORAGE_CDN_BUNNYCDN.UPSTREAM_ERROR`.
- Missing `purgeApiKey` → `STORAGE_CDN_BUNNYCDN.PURGE_API_KEY_MISSING` (no fetch issued).
## Implementation Notes
- Purge URL composition is the caller's responsibility because the same endpoint handles both single keys and prefix purges (caller appends `*` for prefix mode). Pushing composition into the helper would force every caller through an enum or a flag.
- The `AccessKey` header is the account-level key from the Bunny.net dashboard, NOT the per-zone storage key. They're rotated independently and have different scopes; conflating them is the typical "purge stopped working after I rotated the storage key" bug.
- 404 on purge is treated as success at the *caller* level (we don't see it here because the BunnyCDN API returns `200 OK` even when the object was already evicted) — operators relying on a 404 signal should switch to the management API's status endpoint.
- The `pullZoneHostname` field is unused inside this function but is part of the bundle so callers can build edge URLs without a second context object.