113 lines
8.0 KiB
Markdown
113 lines
8.0 KiB
Markdown
# @suaveplan/storage-cdn-bunnycdn - BunnyCDN Storage Zone + Pull Zone provider for @suaveplan/storage-cdn. AccessKey-header CRUD against regional Storage Zones (de/ny/la/sg/syd/uk), single + prefix purge via the Bunny.net management API, HMAC-SHA256 Token Authentication signed URLs, Range reads, native streaming, full AbortSignal threading, Retry-After honoured, OTel surface with provider+storage_region attributes.
|
|
|
|
BunnyCDN Storage Zone + Pull Zone provider for `@suaveplan/storage-cdn`. Full `AbstractStorage` and `CdnAdapter` surface — `get`/`set`/`delete`/`exists`/`getMetadata`/`getPartial`/`createReadStream`/`createWriteStream` against the regional Storage Zone with `AccessKey` header auth, plus `purge`/`purgePrefix`/`signUrl`/`edgeUrl` against the public Pull Zone. HMAC-SHA256 Token Authentication (URL-safe base64, no padding) for signed URLs. Single + wildcard prefix purge via the Bunny.net management API. Transient-status retry honouring `Retry-After`. Full OTel surface with `provider="bunnycdn"` and `storage_region` attributes.
|
|
|
|
<!-- begin:auto-docs -->
|
|
## Documentation tree
|
|
|
|
- [bunny-cdn-adapter](./src/bunny-cdn-adapter/bunny-cdn-adapter.md) — `BunnyCdnAdapter` binds `@suaveplan/storage`'s `AbstractStorage` contract to BunnyCDN Storage Zones for storage operati…
|
|
- [bunny-cdn-adapter.base](./src/bunny-cdn-adapter/bunny-cdn-adapter.base.md) — `BunnyCdnAdapterBase` carries the shared internal machinery every `BunnyCdnAdapter` instance needs: the resolved config…
|
|
- [bunny-cdn-adapter.helpers](./src/bunny-cdn-adapter/bunny-cdn-adapter.helpers.md) — Internal helpers used by `BunnyCdnAdapter` and its sibling streams module. Splits boundary concerns (option parsing, he…
|
|
- [bunny-cdn-adapter](./src/bunny-cdn-adapter/bunny-cdn-adapter.md) — `BunnyCdnAdapter` binds `@suaveplan/storage`'s `AbstractStorage` contract to BunnyCDN Storage Zones for storage operati…
|
|
- [bunny-cdn-adapter.streams](./src/bunny-cdn-adapter/bunny-cdn-adapter.streams.md) — Builds the `ReadableStream` and `WritableStream` instances `BunnyCdnAdapter` returns from `createReadStream` / `createW…
|
|
- [error-codes](./src/error-codes/error-codes.md) — Declares the canonical `STORAGE_CDN_BUNNYCDN` error namespace used by every module in this package. Codes are produced…
|
|
- [error-codes](./src/error-codes/error-codes.md) — Declares the canonical `STORAGE_CDN_BUNNYCDN` error namespace used by every module in this package. Codes are produced…
|
|
- [key-sanitizer](./src/key-sanitizer/key-sanitizer.md) — Validates and normalises caller-supplied storage keys before any fetch is issued against BunnyCDN Storage, and provides…
|
|
- [key-sanitizer](./src/key-sanitizer/key-sanitizer.md) — Validates and normalises caller-supplied storage keys before any fetch is issued against BunnyCDN Storage, and provides…
|
|
- [otel](./src/otel/otel.md) — Owns the OpenTelemetry instrument set for `@suaveplan/storage-cdn-bunnycdn`: counters (`reads_total`, `writes_total`, `…
|
|
- [otel](./src/otel/otel.md) — Owns the OpenTelemetry instrument set for `@suaveplan/storage-cdn-bunnycdn`: counters (`reads_total`, `writes_total`, `…
|
|
- [pull-zone-client](./src/pull-zone-client/pull-zone-client.md) — Owns the Bunny.net management-API purge operation. `purgeUrl(ctx, edgeUrl, signal?)` issues `POST…
|
|
- [pull-zone-client](./src/pull-zone-client/pull-zone-client.md) — Owns the Bunny.net management-API purge operation. `purgeUrl(ctx, edgeUrl, signal?)` issues `POST…
|
|
- [registry](./src/registry/registry.md) — Module-augments `@suaveplan/storage/factory`'s `StorageProviderRegistry` and `StorageProviderConfig` to add the `"bunny…
|
|
- [registry](./src/registry/registry.md) — Module-augments `@suaveplan/storage/factory`'s `StorageProviderRegistry` and `StorageProviderConfig` to add the `"bunny…
|
|
- [retry-helper](./src/retry-helper/retry-helper.md) — Coordinates retry logic for HTTP requests against BunnyCDN Storage Zones and the Bunny.net management API. Distinguishe…
|
|
- [retry-helper](./src/retry-helper/retry-helper.md) — Coordinates retry logic for HTTP requests against BunnyCDN Storage Zones and the Bunny.net management API. Distinguishe…
|
|
- [storage-client](./src/storage-client/storage-client.md) — Owns every Storage Zone HTTP operation `BunnyCdnAdapter` needs: PUT, GET, HEAD, DELETE, Range read, and streaming GET.…
|
|
- [storage-client](./src/storage-client/storage-client.md) — Owns every Storage Zone HTTP operation `BunnyCdnAdapter` needs: PUT, GET, HEAD, DELETE, Range read, and streaming GET.…
|
|
- [token-auth](./src/token-auth/token-auth.md) — Computes BunnyCDN Pull Zone Token Authentication query strings — `?token=<urlSafeBase64(sha256(key + path + expires))>&…
|
|
- [token-auth](./src/token-auth/token-auth.md) — Computes BunnyCDN Pull Zone Token Authentication query strings — `?token=<urlSafeBase64(sha256(key + path + expires))>&…
|
|
<!-- end:auto-docs -->
|
|
|
|
## Install
|
|
|
|
```bash
|
|
bun add @suaveplan/storage-cdn-bunnycdn
|
|
```
|
|
|
|
## Quick start
|
|
|
|
```ts
|
|
import { BunnyCdnAdapter } from "@suaveplan/storage-cdn-bunnycdn";
|
|
|
|
const storage = new BunnyCdnAdapter({
|
|
storageZone: "myz",
|
|
storageAccessKey: process.env["BUNNY_STORAGE_KEY"]!,
|
|
pullZoneHostname: "mycdn.b-cdn.net",
|
|
storageRegion: "de",
|
|
tokenAuthKey: process.env["BUNNY_TOKEN_KEY"]!,
|
|
purgeApiKey: process.env["BUNNY_PURGE_KEY"]!,
|
|
});
|
|
|
|
await storage.set("photos/a.jpg", bytes);
|
|
await storage.purge("photos/a.jpg");
|
|
await storage.purgePrefix("photos/");
|
|
const signed = await storage.signUrl("photos/a.jpg", { ttlSeconds: 300 });
|
|
```
|
|
|
|
## Factory registration
|
|
|
|
```ts
|
|
import { registerBunnyCdnProvider } from "@suaveplan/storage-cdn-bunnycdn";
|
|
import { createStorage } from "@suaveplan/storage/factory";
|
|
|
|
registerBunnyCdnProvider();
|
|
const storage = createStorage({ type: "bunnycdn", config });
|
|
```
|
|
|
|
## Modules
|
|
|
|
- [error-codes](./src/error-codes.md) — `STORAGE_CDN_BUNNYCDN_CODES` registry + `StorageCdnBunnycdnError`.
|
|
- [constants](./src/constants/constants.md) — region whitelist, default hosts, retry defaults, `storageHostFor` helper.
|
|
- [storage-client](./src/storage-client/storage-client.md) — PUT/GET/DELETE/HEAD/Range/streaming against the regional Storage Zone.
|
|
- [pull-zone-client](./src/pull-zone-client/pull-zone-client.md) — `purgeUrl` for single + wildcard purge via `api.bunny.net/purge`.
|
|
- [token-auth](./src/token-auth/token-auth.md) — HMAC-SHA256 Token Authentication query builder.
|
|
- [key-sanitizer](./src/key-sanitizer/key-sanitizer.md) — strict key validation + per-segment encoder.
|
|
- [retry-helper](./src/retry-helper/retry-helper.md) — transient classifier + `Retry-After` honour.
|
|
- [otel](./src/otel/otel.md) — meters, histograms, counters, tracer.
|
|
- [bunny-cdn-adapter](./src/bunny-cdn-adapter/bunny-cdn-adapter.md) — main `BunnyCdnAdapter` class.
|
|
- [registry](./src/registry/registry.md) — module-augmentation slot for `createStorage({ type: "bunnycdn", ... })`.
|
|
|
|
## Capabilities matrix
|
|
|
|
```ts
|
|
{
|
|
partialReads: true,
|
|
partialWrites: false,
|
|
nativeStreams: true,
|
|
atomicWrites: false,
|
|
contentAddressable: false,
|
|
cdn: {
|
|
cdnPurge: true,
|
|
cdnPrefixPurge: true,
|
|
cdnSignedUrls: true,
|
|
cdnOriginUploads: true,
|
|
},
|
|
}
|
|
```
|
|
|
|
## Features
|
|
|
|
- **Universal purity** — no `node:*` or DOM-only imports.
|
|
- **Full Storage Zone surface** — origin PUT/GET/DELETE/HEAD with Range, native streaming, AbortSignal.
|
|
- **CDN integration** — single + prefix purge, signed (Token Authentication) URLs, edge URL composition.
|
|
- **Region-aware host selection** — `de` uses the unprefixed host (`storage.bunnycdn.com`); other regions prepend the code (`ny.storage.bunnycdn.com`, …).
|
|
- **Two-key model** — per-zone `storageAccessKey` for CRUD vs. account-level `purgeApiKey` for invalidation; rotated independently.
|
|
- **Retry on transient outcomes** — `408`/`425`/`429`/`5xx` retried with `Retry-After` honoured.
|
|
- **OTel built-in** — `storage_cdn_bunnycdn.*` instruments with `provider="bunnycdn"` and `storage_region` attributes for cross-provider dashboards.
|
|
- **100 / 100 / 100 / 100 Istanbul coverage**.
|
|
|
|
## License
|
|
|
|
MIT — see `LICENSE` at the repo root.
|
|
|