@nitida/asset-client 0.20.1 → 0.20.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/access.ts CHANGED
@@ -241,9 +241,24 @@ export function assertPublic(
241
241
  */
242
242
  export function assertSha(asset: { sha?: unknown }, fn: string): void {
243
243
  const sha = asset?.sha;
244
- if (typeof sha === "string" && /^[0-9a-f]{16,64}$/i.test(sha)) return;
245
- const hint =
246
- asset && typeof asset === "object" && "sha256" in asset
244
+ // EXACTAMENTE 16, no `{16,64}`.
245
+ //
246
+ // Las claves del CDN son de 16 hex — el SDK hace `.slice(0, 16)` en cada
247
+ // sitio donde arma una. El rango 17..64 no nombra ninguna clave real, así que
248
+ // aceptarlo era dejar pasar precisamente el error más probable: poner el
249
+ // `sha256` COMPLETO en la propiedad correcta. Medido: eso producía
250
+ // `…/f/v/<64 hex>-m.webp`, una URL que 404ea «lejos de acá» — literalmente lo
251
+ // que el comentario de arriba dice que este guarda existe para impedir.
252
+ //
253
+ // Y lo inducía el propio mensaje: quien lee rápido «Use `{ sha:
254
+ // theSha256.slice(0, 16) }`» y escribe `{ sha: sha256 }` no recibía
255
+ // excepción, recibía la URL rota.
256
+ if (typeof sha === "string" && /^[0-9a-f]{16}$/i.test(sha)) return;
257
+ const looksLikeSha256 =
258
+ typeof sha === "string" && /^[0-9a-f]{64}$/i.test(sha);
259
+ const hint = looksLikeSha256
260
+ ? " ⚠️ You passed a FULL sha256 (64 hex) as `sha`. CDN keys use the first 16: `{ ...asset, sha: asset.sha256.slice(0, 16) }`. Interpolating all 64 builds a URL that 404s."
261
+ : asset && typeof asset === "object" && "sha256" in asset
247
262
  ? " The value you passed has `sha256` but not `sha`. ⚠️ Since `@nitida/sdk@0.30.0` `upload()` returns BOTH, so a fresh upload result works as-is — if you are seeing this, the value came from somewhere else (an older SDK, a hand-built object, or a raw API response). Use `{ sha: theSha256.slice(0, 16) }`, or fetch the DTO with `assets.get(id)`."
248
263
  : ` Got ${JSON.stringify(sha)}.`;
249
264
  throw new Error(
package/src/index.ts CHANGED
@@ -648,7 +648,22 @@ type OriginalHints = {
648
648
  * ```
649
649
  */
650
650
  export function getAssetUrl(
651
- asset: Pick<AssetDTO, "sha"> & OriginalHints & VisibilityHint,
651
+ /**
652
+ * ⭐ `presets` ESTÁ EN EL TIPO PORQUE LA FUNCIÓN LO LEE.
653
+ *
654
+ * `transformFallbackFor` decide con este campo si devolver la clave de
655
+ * variante o caer a `/t/…width=N/`. Sin él en la firma, el tipo PROHIBÍA el
656
+ * campo que la implementación consulta: pasarlo era un error de compilación,
657
+ * y no pasarlo daba `…-x.webp` → 404 en silencio.
658
+ *
659
+ * Medido 2026-08-25 sobre un asset con `presets: "lmoqs"`:
660
+ * sin `presets` → /f/v/<sha>-x.webp 404
661
+ * con `presets` → /t/format=webp,width=3840/<sha>.webp 200
662
+ */
663
+ asset: Pick<AssetDTO, "sha"> &
664
+ OriginalHints &
665
+ VisibilityHint &
666
+ Partial<Pick<AssetDTO, "presets">>,
652
667
  preset: VariantPreset,
653
668
  ): string {
654
669
  // Refuses rather than returning a URL that 404s. See `assertPublic`.