# guards _(no submodules)_ ## Purpose Ships two type-guards for `CdnAdapter`: the non-throwing `isCdnAdapter` predicate and the throwing `assertCdnAdapter` assertion. Consumers that accept a structural `StorageLike` and need to opt into CDN features at the call site use these to narrow safely. The throwing variant raises a canonical `StorageCdnError` so the rejection has the same diagnostic surface as every other CDN error. Without these helpers each consumer would re-implement `value instanceof CdnAdapter` checks and the assertion variant would either silently degrade or throw a plain `Error` — both bad outcomes for operator dashboards. ## Features - Two functions, both tiny — `isCdnAdapter` and `assertCdnAdapter`. - Predicate form returns `value is CdnAdapter` so TypeScript narrows cleanly inside the `if` branch. - Assertion form uses TypeScript `asserts` syntax so the caller's flow is narrowed after the call without needing an explicit `if`. - Both rely on `instanceof CdnAdapter` — no structural duck typing, so third-party look-alikes don't sneak through. ## Usage: Basic ```ts import { isCdnAdapter } from "@suaveplan/storage-cdn"; if (isCdnAdapter(storage)) { await storage.purge("a/b.bin"); } ``` ## Usage: Advanced ```ts import { assertCdnAdapter, STORAGE_CDN_CODES, StorageCdnError } from "@suaveplan/storage-cdn"; function purgeAfterWrite(storage: unknown, key: string): Promise { assertCdnAdapter(storage); // throws if not a CdnAdapter return storage.purge(key); } try { await purgeAfterWrite(new MemoryStorage(), "k"); } catch (err) { if (err instanceof StorageCdnError && err.code === STORAGE_CDN_CODES.INVALID_OPTIONS) { // caller passed the wrong storage type — surface a clear message. } } ``` ## API Reference ### `isCdnAdapter(value: unknown): value is CdnAdapter` Returns `true` when `value instanceof CdnAdapter`. Inside the `if` branch TypeScript narrows `value` to `CdnAdapter`. Safe to call with `null`, `undefined`, primitives, or arbitrary objects — all yield `false`. ### `assertCdnAdapter(value: unknown): asserts value is CdnAdapter` Throws `StorageCdnError(STORAGE_CDN.INVALID_OPTIONS)` when `value` is not a `CdnAdapter`. After the call, TypeScript treats `value` as `CdnAdapter`. ## Implementation Notes - Both functions rely strictly on `instanceof`. Structural duck typing would let any object with `purge`, `signUrl`, `edgeUrl` methods pass — acceptable for many type guards, but the CdnAdapter contract includes the full `AbstractStorage` surface and the capabilities matrix, so instanceof is the right floor. - The assertion uses the canonical `STORAGE_CDN.INVALID_OPTIONS` code rather than inventing a new "not a CdnAdapter" code — the configuration mistake is the caller passing the wrong type, which is exactly what that code is for. - The functions intentionally don't call `Object.getPrototypeOf` or similar; the `instanceof` check is sufficient and avoids dragging in prototype-chain edge cases (cross-realm objects, etc.) which provider packages would have to defend against anyway.