# sign-url _(no submodules)_ ## Purpose Owns the boundary validation for `CdnAdapter.signUrl` callers. Wraps the Zod `SignUrlOptionsSchema` parse and converts schema failures into the canonical `StorageCdnError` codes — `STORAGE_CDN.INVALID_TTL` when `ttlSeconds <= 0` or non-integer, `STORAGE_CDN.INVALID_OPTIONS` for any other schema failure. Provider adapters invoke `parseSignUrlOptions` at the top of their `signUrl` implementations so every provider returns the same diagnostic surface on invalid input. Without this module, every provider would either replicate the Zod parse boilerplate or invent its own error mapping — neither outcome is good for operators trying to write provider-agnostic alerting rules. ## Features - One exported function (`parseSignUrlOptions`) — keeps the public surface trivial. - Distinct error codes for `ttlSeconds` failures vs. everything else, so monitoring rules can alert separately on "TTL out of range" vs. "caller is misconfigured". - Returns a clean `SignUrlOptions` value with optional fields strictly omitted (not `undefined`) to satisfy `exactOptionalPropertyTypes`. ## Usage: Basic ```ts import { parseSignUrlOptions } from "@suaveplan/storage-cdn"; const parsed = parseSignUrlOptions({ ttlSeconds: 60, method: "GET" }); ``` ## Usage: Advanced ```ts import { CdnAdapter, parseSignUrlOptions, STORAGE_CDN_CODES, StorageCdnError, } from "@suaveplan/storage-cdn"; class MyCdn extends CdnAdapter { public override async signUrl(key: string, options: SignUrlOptions): Promise { const opts = parseSignUrlOptions(options); // throws on bad input const url = await this.client.presign(key, opts.method ?? "GET", opts.ttlSeconds); return url; } } try { await myCdn.signUrl("a/b.bin", { ttlSeconds: 0 }); } catch (err) { if (err instanceof StorageCdnError && err.code === STORAGE_CDN_CODES.INVALID_TTL) { // distinct from INVALID_OPTIONS — alert pipeline can fire a specific rule. } } ``` ## API Reference ### `parseSignUrlOptions(options: SignUrlOptions): SignUrlOptions` Validates `options` against `SignUrlOptionsSchema`. On success, returns a fresh `SignUrlOptions` value with optional fields strictly omitted (not set to `undefined`). On failure, throws: - `StorageCdnError(STORAGE_CDN.INVALID_TTL)` when the `ttlSeconds` issue is present. - `StorageCdnError(STORAGE_CDN.INVALID_OPTIONS)` otherwise (e.g. method outside whitelist, empty `responseContentType`). ## Implementation Notes - The Zod parse runs once per call — the schema is module-level so there is no per-call construction overhead. - The `ttlSeconds` detection scans the issues array for any issue whose path begins with `ttlSeconds`. This catches both "out of range" and "not an integer" — both surface as `INVALID_TTL` because they are the same caller mistake (passing a bad TTL). - Optional-field reconstruction explicitly skips fields the caller omitted; this preserves the `exactOptionalPropertyTypes` invariant downstream (some providers' API clients hard-fail on `method: undefined`). - The function is intentionally narrow — it does not sign anything. Real signing is provider-specific and lives in the provider package.