Files
skills/docs/persistence/storage/storage-cdn/src/guards/guards.md
2026-05-29 08:20:56 +01:00

3.1 KiB

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

import { isCdnAdapter } from "@suaveplan/storage-cdn";

if (isCdnAdapter(storage)) {
    await storage.purge("a/b.bin");
}

Usage: Advanced

import { assertCdnAdapter, STORAGE_CDN_CODES, StorageCdnError } from "@suaveplan/storage-cdn";

function purgeAfterWrite(storage: unknown, key: string): Promise<void> {
    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.