@nitida/asset-client 0.21.0 → 0.24.0

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/dist/index.d.cts CHANGED
@@ -56,8 +56,22 @@ declare function deriveAccessKey(signingKey: string): Promise<Uint8Array>;
56
56
  * path.
57
57
  */
58
58
  declare function accessMessage(tenantPrefix: string, exp: number, resourcePath: string): string;
59
+ /**
60
+ * The longest life a signed URL may claim: **7 days**.
61
+ *
62
+ * ⚠️ Must equal `MAX_SIGNED_TRANSFORM_TTL_SECONDS` on the origin and
63
+ * `MAX_SIGNED_URL_TTL_SECONDS` in the CDN worker — one policy, three runtimes,
64
+ * pinned in all three suites. Both verifiers refuse anything longer, so a
65
+ * bigger number here would only mint a URL that 401s.
66
+ *
67
+ * Why there is a ceiling at all: `expiresInSeconds` was validated as
68
+ * "> 0" and nothing else, so `{ expiresInSeconds: 315_360_000 }` produced a
69
+ * ten-year link that every check called valid. "Has an expiry" and "expires"
70
+ * are different properties, and only the second makes a leaked link die.
71
+ */
72
+ declare const MAX_SIGNED_URL_TTL_SECONDS: number;
59
73
  type SignAccessOptions = {
60
- /** Lifetime in seconds. Required — see the header. */
74
+ /** Lifetime in seconds, 1 .. 604 800. Required — see the header. */
61
75
  expiresInSeconds: number;
62
76
  /** Injectable clock, for tests that need a URL already dead on arrival. */
63
77
  nowSeconds?: number;
@@ -248,13 +262,24 @@ declare function getPaletteBlurBackground(palette: AssetPalette | null | undefin
248
262
  * Requesting any OTHER width returns HTTP 400 at the edge (unsigned URLs). These are the
249
263
  * 1× base ladder values; DPR ×2/×3 multiples are applied + whitelisted server-side. Import
250
264
  * this instead of hardcoding magic widths so an unsupported size is caught in review/IDE.
265
+ *
266
+ * ⭐ **180 es el `apple-touch-icon`, y está acá por eso.** Apple pide 180×180 para
267
+ * el icono de pantalla de inicio en un iPhone 3×, y el monorepo de neo ya lo
268
+ * estandarizó: `webapp-storefront` commitea un `apple-icon.png` de 180×180 por
269
+ * tenant. Sin este escalón, una app que sirve el icono desde el CDN tiene que
270
+ * elegir entre 160 (iOS lo agranda, sale borroso) y 240 (lo achica, sale bien
271
+ * pero pesa de más). Medido 2026-08-29 sobre la foto de un agente: 240² en PNG
272
+ * son 57,5 KB contra 6,5 KB del WebP a 400², así que el tamaño de más no es
273
+ * gratis. El caso real: `apps/bio-web/src/lib/seo/favicon.ts`, que sirve **la
274
+ * foto del propio negocio** como icono de su página.
251
275
  */
252
- declare const TRANSFORM_WIDTHS: readonly [96, 128, 160, 240, 256, 320, 400, 480, 600, 640, 800, 960, 1080, 1200, 1280, 1440, 1600, 1920, 2560, 3840];
276
+ declare const TRANSFORM_WIDTHS: readonly [96, 128, 160, 180, 240, 256, 320, 400, 480, 600, 640, 800, 960, 1080, 1200, 1280, 1440, 1600, 1920, 2560, 3840];
253
277
  /**
254
278
  * A CDN-whitelisted transform width — the only widths `TransformOptions.width`
255
279
  * accepts. Off-ladder widths are a compile error; for signed URLs that need a
256
- * custom width, use {@link SignedTransformOptions} (number) via
257
- * {@link getSignedTransformUrl} / `aq.transform(asset, opts, { sign: true })`.
280
+ * signature, use {@link getSignedTransformUrl} /
281
+ * `aq.transform(asset, opts, { sign: true, expiresInSeconds })` — which names
282
+ * the caller but does NOT widen the ladder.
258
283
  */
259
284
  type TransformWidth = (typeof TRANSFORM_WIDTHS)[number];
260
285
  type TransformFit = "cover" | "contain" | "fill" | "inside" | "outside";
@@ -265,9 +290,9 @@ type TransformOptions = {
265
290
  /**
266
291
  * Target max-side width in CSS pixels (multiplied by `dpr` server-side).
267
292
  * MUST be a {@link TRANSFORM_WIDTHS} value — off-ladder widths are rejected
268
- * (HTTP 400) by the edge whitelist for unsigned URLs, so the type forbids
269
- * them at compile time. For SIGNED URLs with a custom width, use
270
- * {@link SignedTransformOptions} (which widens this to `number`).
293
+ * (HTTP 400) by the edge whitelist, so the type forbids them at compile
294
+ * time. Signing does NOT lift this: since doc blindaje WS-6 the edge
295
+ * validates signed and unsigned requests identically.
271
296
  */
272
297
  width?: TransformWidth;
273
298
  /** Target max-side height. Multiplied by `dpr` server-side. */
@@ -278,8 +303,37 @@ type TransformOptions = {
278
303
  gravity?: TransformGravity;
279
304
  /** Output format. `auto` → the platform's policy decides. */
280
305
  format?: TransformFormat;
281
- /** Output quality. `auto` → format-specific default. */
282
- quality?: "auto" | number;
306
+ /**
307
+ * ⛔ **`quality` no existe en este tipo, y eso es deliberado.**
308
+ *
309
+ * No es un dial del encoder: elige QUÉ BYTES decodifica el servidor. Con un
310
+ * número, `/t/` salta a la variante almacenada más chica que cubra el pedido
311
+ * — que ya pasó por una compresión — y la salida es una segunda generación.
312
+ * Sobre un asset CON escalera eso es pérdida pura (medido: +2…+8 % de peso y
313
+ * −0,50…−0,85 dB). Y `"auto"` era un no-op: byte a byte idéntico a omitir la
314
+ * clave, mismo sha256.
315
+ *
316
+ * El único uso legítimo —un presupuesto de bytes medido, sobre un asset SIN
317
+ * escalera— tiene su propia puerta, que no se puede llamar a ciegas:
318
+ * {@link getByteBudgetTransformUrl}.
319
+ *
320
+ * ## Por qué no alcanzaba con documentarlo
321
+ *
322
+ * Estuvo `@deprecated` con la medición al lado durante exactamente una
323
+ * versión, y eso ya era mejor que nada. Pero un aviso **avisa**; no impide.
324
+ * `getTransformUrl` recibe un `Pick<AssetDTO, "sha">` —un sha y nada más—,
325
+ * así que un `quality: 75` en el call site era **ciego**: nadie ahí, humano o
326
+ * modelo, podía saber si ese asset tenía escalera. La misma línea era
327
+ * correcta o dañina según un dato que no estaba en la llamada.
328
+ *
329
+ * Y hay un llamador que no lee tildados: **un modelo generando código.**
330
+ * `quality` es el parámetro que todo el mundo espera encontrar en una API de
331
+ * imágenes, así que se escribe solo. Next.js llegó a la misma conclusión por
332
+ * el mismo camino y dejó de recomendar `quality` por imagen: la configuración
333
+ * ya decide, y un valor por llamada sólo agrega formas de equivocarse.
334
+ *
335
+ * ⇒ El parámetro no se documenta como peligroso. **No se puede escribir.**
336
+ */
283
337
  /** Device pixel ratio. Width/height are multiplied by this before resize. */
284
338
  dpr?: 1 | 2 | 3;
285
339
  /**
@@ -312,20 +366,48 @@ type TransformOptions = {
312
366
  duration?: number;
313
367
  };
314
368
  /**
315
- * Like {@link TransformOptions} but with `width` widened to any `number` —
316
- * the escape hatch for SIGNED URLs that need an off-ladder custom width.
317
- *
318
- * The edge whitelist only rejects off-ladder widths on UNSIGNED URLs; a valid
319
- * `?sig=` earns the whitelist bypass at the edge (the server still
320
- * does the real HMAC check). So a custom width is ONLY safe when the URL is
321
- * signed hence this type is accepted exclusively by the signing helpers
322
- * ({@link getSignedTransformUrl} / `aq.transform(asset, opts, { sign: true })`),
323
- * never by the plain unsigned {@link getTransformUrl}.
369
+ * Options for a SIGNED transform URL.
370
+ *
371
+ * ⚠️ **`width` is the same ladder as unsigned**, since `@nitida/asset-client`
372
+ * 0.22.0. This type used to widen it to any `number`, because a valid `?sig=`
373
+ * made the CDN edge skip its whitelist entirely so a signature bought an
374
+ * off-ladder size. It does not any more: the edge validates every `/t/`
375
+ * request identically and answers 400 for an off-ladder width whether or not
376
+ * it is signed (doc blindaje WS-6). Keeping the wide type would only let
377
+ * TypeScript bless a URL that 400s.
378
+ *
379
+ * A signature now buys IDENTITY: which tenant asked, proven with its key, until
380
+ * `exp`. That is what a strict tenant and the paid-effect cost guard require.
324
381
  */
325
- type SignedTransformOptions = Omit<TransformOptions, "width"> & {
326
- /** Off-ladder width — valid ONLY on signed URLs (edge whitelist bypass). */
382
+ type SignedTransformOptions = TransformOptions;
383
+ /**
384
+ * `width` widened to any `number` — the PRIVATE tree's option type.
385
+ *
386
+ * ⚠️ Not an escape hatch for the public tree: `/t/` answers 400 for an
387
+ * off-ladder width, signed or not (doc blindaje WS-6). What this is for is the
388
+ * `/a/<tenant>/t/…` tree, where the ladder deliberately does NOT apply — the
389
+ * request arrives HMAC-verified against the tenant's key, so only a key-holder
390
+ * can ask, and "any width/crop/format, not just the materialised ones" is the
391
+ * written promise of `getPrivateTransformUrl`.
392
+ *
393
+ * Also used by the two builders that take an explicit ladder the caller chose
394
+ * (`getTransformSrcSet`) or that are documented as unchecked
395
+ * (`getTransformUrlUnchecked`).
396
+ */
397
+ type PrivateTransformOptions = Omit<TransformOptions, "width"> & {
327
398
  width?: number;
328
399
  };
400
+ /**
401
+ * `TransformOptions` + el `quality` que el tipo público ya no admite.
402
+ *
403
+ * INTERNO. Existe porque el serializador tiene que poder emitir `quality=` para
404
+ * {@link getByteBudgetTransformUrl}; no porque un llamador deba construirlo.
405
+ */
406
+ type WithPinnedQuality<T> = T & {
407
+ quality: number;
408
+ };
409
+ /** @deprecated internal alias kept for the builders below. */
410
+ type AnyWidthTransformOptions = PrivateTransformOptions;
329
411
  /**
330
412
  * Serialize transform options into the canonical DSL path segment.
331
413
  * Empty options return an empty string (caller should fall back to a
@@ -352,7 +434,7 @@ type SignedTransformOptions = Omit<TransformOptions, "width"> & {
352
434
  * to be an aquienpz asset.
353
435
  */
354
436
  declare function extractAssetSha(url: string | null | undefined): string | null;
355
- declare function serializeTransform(opts: SignedTransformOptions): string;
437
+ declare function serializeTransform(opts: AnyWidthTransformOptions | WithPinnedQuality<AnyWidthTransformOptions>): string;
356
438
  /**
357
439
  * Build a transform URL for a VIDEO asset. Same DSL shape as image
358
440
  * transforms; the server branches on the asset's `kind` column. Video
@@ -426,20 +508,115 @@ declare function getHlsStreamingUrl(asset: Pick<AssetDTO, "sha"> & VisibilityHin
426
508
 
427
509
  declare function getTransformUrl(asset: Pick<AssetDTO, "sha"> & VisibilityHint, opts: TransformOptions): string | null;
428
510
  /**
429
- * Build AND sign a transform URL, allowing an off-ladder custom `width`.
511
+ * ¿Este asset tiene variantes de tamaño almacenadas, o sea algo a lo que `/t/`
512
+ * pueda saltar?
430
513
  *
431
- * This is the escape hatch for {@link SignedTransformOptions}: off-ladder
432
- * widths only pass the edge whitelist when the URL is signed, so building one
433
- * and signing it must happen together. For on-ladder widths prefer the plain
434
- * {@link getTransformUrl} (+ {@link signTransformUrl} if you need a signature).
514
+ * `null` cuando **no se sabe** un DTO sin `presets` no dice que no las tenga,
515
+ * dice que no lo trae. Tres estados, tres respuestas: un booleano acá mentiría
516
+ * en un tercio de los casos, y mentiría hacia el lado inseguro.
435
517
  *
436
- * Returns `null` only when `opts` serialize to an empty DSL (no transform
437
- * requested) same contract as {@link getTransformUrl}.
518
+ * ⚠️ **Se pregunta con `hasPreset`, JAMÁS con `presets.includes("s")`.** La
519
+ * cadena lleva tokens de varias letras —`transform-<hex>`, `upscale_…`, `pr`—
520
+ * que donan `s`, `m`, `l` y `o` de regalo. Ese es el falso positivo que
521
+ * `test/presets-false-positives.test.ts` existe para cazar.
438
522
  */
439
- declare function getSignedTransformUrl(asset: Pick<AssetDTO, "sha"> & VisibilityHint, opts: SignedTransformOptions, signingKey: string): Promise<string> | null;
523
+ declare function hasSizeLadder(asset: {
524
+ presets?: string | null;
525
+ }): boolean | null;
526
+ /**
527
+ * ⭐ **La ÚNICA puerta por la que se puede pinnear un `quality` numérico** —
528
+ * y está construida para que no se pueda usar mal.
529
+ *
530
+ * ## El problema que resuelve
531
+ *
532
+ * `getTransformUrl` recibe un `Pick<AssetDTO, "sha">`: **un sha y nada más.**
533
+ * Con eso, un `quality: 75` en el call site es CIEGO — la misma línea es un
534
+ * ajuste honesto del encoder sobre un asset sin escalera, y una segunda
535
+ * compresión silenciosa sobre uno con escalera. Nada en el tipo, en el nombre
536
+ * ni en el editor distinguía los dos casos. Un aviso avisa; esto impide.
537
+ *
538
+ * ## Las dos barreras
539
+ *
540
+ * 1. **En COMPILACIÓN**: el parámetro exige `presets: string`. Un
541
+ * `{ sha }` pelado —la llamada ciega— ya no compila. Para pasar por acá hay
542
+ * que tener el DTO en la mano, y tener el DTO es saber la respuesta.
543
+ * 2. **En EJECUCIÓN**: si el asset tiene cualquier preset de tamaño, **tira**.
544
+ * Si `presets` no vino, **tira** — «no sé» nunca se resuelve como «dale».
545
+ *
546
+ * ## Cuándo es legítimo, con el número
547
+ *
548
+ * Un presupuesto de bytes que alguien MIDIÓ, sobre un asset subido con
549
+ * `presets: ["original"]`. Ahí no hay a qué saltar y el pin hace lo que su
550
+ * nombre dice. Medido 2026-08-31 contra producción, ancho 1 920, las seis
551
+ * respuestas `x-transform-source: original`:
552
+ *
553
+ * | quality | bytes | vs auto | PSNR |
554
+ * |---|---|---|---|
555
+ * | 40 | 82 112 | **−33,6 %** | 35,32 dB |
556
+ * | 60 | 106 892 | −13,5 % | 36,85 dB |
557
+ * | *(auto)* | 123 614 | — | 37,65 dB |
558
+ * | 90 | 269 026 | +117,6 % | 41,46 dB |
559
+ *
560
+ * Monótona y sin sorpresas: −33,6 % de peso por −2,32 dB. **Eso sí es un
561
+ * intercambio**, y es la razón por la que el parámetro no se borró del todo.
562
+ *
563
+ * @throws si el asset tiene escalera, si no se sabe si la tiene, o si
564
+ * `quality` no está en 1..100.
565
+ */
566
+ declare function getByteBudgetTransformUrl(asset: Pick<AssetDTO, "sha"> & {
567
+ presets: string;
568
+ } & VisibilityHint, opts: WithPinnedQuality<TransformOptions>): string | null;
569
+ declare function getSignedTransformUrl(asset: Pick<AssetDTO, "sha"> & VisibilityHint, opts: SignedTransformOptions, signingKey: string, signOpts: SignTransformOptions): Promise<string> | null;
570
+ /**
571
+ * The longest life a signed transform URL may claim: **7 days**.
572
+ *
573
+ * ⚠️ Must equal `MAX_SIGNED_TRANSFORM_TTL_SECONDS` on the origin
574
+ * (`transform.signing.ts`), which enforces it on every verify — asking for
575
+ * more here would only build a URL the platform answers 401 to, which is why
576
+ * this throws instead.
577
+ */
578
+ declare const MAX_SIGNED_TRANSFORM_TTL_SECONDS: number;
579
+ /**
580
+ * The shortest, so that the minute-rounding below can never mint a dead URL.
581
+ * 120 s = two rounding steps of headroom.
582
+ */
583
+ declare const MIN_SIGNED_TRANSFORM_TTL_SECONDS = 120;
584
+ type SignTransformOptions = {
585
+ /**
586
+ * Lifetime in seconds, 120 .. 604 800. Required — there is no "forever"
587
+ * option, for the same reason `signAccessUrl` has none: a signed URL that
588
+ * never expires is a public URL the moment someone forwards it.
589
+ */
590
+ expiresInSeconds: number;
591
+ /**
592
+ * The tenant this signature speaks for. Defaults to the process-global
593
+ * (`setTenantId`, or a `NitidaClient` with `tenantId`) — the tenant is part
594
+ * of the signed message, so it cannot be guessed from the asset.
595
+ */
596
+ tenantId?: number;
597
+ /** Injectable clock, for tests that need a URL already dead on arrival. */
598
+ nowSeconds?: number;
599
+ };
600
+ /**
601
+ * The public name of a signing key, derived from the key itself, so a signer
602
+ * never has to be told a second value. Byte-identical to the origin's
603
+ * `deriveKid`.
604
+ */
605
+ declare function deriveTransformKid(signingKey: string): Promise<string>;
606
+ /**
607
+ * The signed message. Byte-identical to the origin's `transformMessage`.
608
+ *
609
+ * nitida/transform/v2 \n <tenantPrefix> \n <exp> \n <dsl>/<filename>
610
+ */
611
+ declare function transformMessage(args: {
612
+ tenantPrefix: string;
613
+ exp: number;
614
+ canonicalDsl: string;
615
+ filename: string;
616
+ }): string;
440
617
  /**
441
618
  * Sign a transform URL with the tenant's HMAC signing key. Appends
442
- * `?sig=<hex>` where hex = HMAC-SHA256(signingKey, `<canonical-DSL>/<filename>`).
619
+ * `?kid=<8 hex>&exp=<unix seconds>&sig=<64 hex>`.
443
620
  *
444
621
  * Must agree byte-for-byte with the server's `verifyTransformSignature`.
445
622
  * Uses WebCrypto, so works in browsers, Node ≥ 16, Bun, and Workers.
@@ -447,8 +624,20 @@ declare function getSignedTransformUrl(asset: Pick<AssetDTO, "sha"> & Visibility
447
624
  * The canonical DSL is the one already produced by `serializeTransform`
448
625
  * (sort keys + lowercase strings), so signing a URL built by `getTransformUrl`
449
626
  * is automatic — the same canonical form is in the URL path.
627
+ *
628
+ * ## ⚠️ `exp` IS ROUNDED DOWN TO THE MINUTE, AND THAT IS LOAD-BEARING
629
+ *
630
+ * The edge cache key for `/t/` is the FULL URL. A per-request `exp` would make
631
+ * every render of the same image a distinct cache entry — turning a path that
632
+ * reaches the origin roughly never into one that reaches it on every view.
633
+ * Rounding down to the minute means every renderer signing the same URL in the
634
+ * same minute produces the same bytes, so the entry is shared. Down, never up,
635
+ * so the URL never outlives the lifetime the caller asked for.
636
+ *
637
+ * A build-time signer that wants ONE stable URL per deploy should pass a fixed
638
+ * `nowSeconds` (the build timestamp) rather than a longer lifetime.
450
639
  */
451
- declare function signTransformUrl(unsignedUrl: string, signingKey: string): Promise<string>;
640
+ declare function signTransformUrl(unsignedUrl: string, signingKey: string, opts: SignTransformOptions): Promise<string>;
452
641
  /**
453
642
  * Build a responsive `srcSet` string by generating one transform URL per
454
643
  * width. All other options apply to every URL.
@@ -583,19 +772,23 @@ type VariantPreset = "thumb" | "sm" | "md" | "lg" | "xl" | "original" | "poster"
583
772
  * **`probe` is requestable and was not on `VariantPreset` at all**, so the type
584
773
  * forbade a request the server has always accepted.
585
774
  *
586
- * Verified 2026-08-21 against the Elysia schemas of all four write routes —
587
- * `/assets/process`, the presign route, `/assets/:id/regenerate` and both
588
- * multipart routes. All four accept exactly this list and nothing else, with
589
- * no drift between them.
775
+ * Generated from the Elysia schemas of all four write routes — `/assets/process`,
776
+ * the presign route, `/assets/:id/regenerate` and both multipart routes —
777
+ * by `scripts/gen-docs.ts` (doc derivar WS-4). `bun run gen:docs` rewrites it;
778
+ * `--check` fails the build if a route's schema drifts and nobody reran it.
779
+ * `probe` is still frames at evenly spaced offsets, stored under indexed keys
780
+ * (`-pr0.jpg`, `-pr1.jpg`, …) — requestable, and deliberately absent from the
781
+ * compact `presets` wire string, so it is here and not on `VariantPreset`.
590
782
  */
591
- type RequestablePreset = Exclude<VariantPreset, "hls" | "mp3"> | "probe";
783
+ declare const REQUESTABLE_PRESETS: readonly ["aiproxy", "lg", "md", "original", "poster", "probe", "sm", "thumb", "video", "xl"];
784
+ type RequestablePreset = (typeof REQUESTABLE_PRESETS)[number];
592
785
  /**
593
- * The same set as {@link RequestablePreset}, at RUNTIME.
594
- *
595
- * The type stops the mistake in TypeScript. It cannot stop it anywhere else,
596
- * and "anywhere else" is where it keeps happening: a preset list assembled
597
- * from config, from a route body, from JSON, or from a script's argv arrives
598
- * as `string[]`, and the only way past the type was a cast.
786
+ * `REQUESTABLE_PRESETS` (above) is the same set as `RequestablePreset`, at
787
+ * RUNTIME. The type stops the mistake in TypeScript. It cannot stop it
788
+ * anywhere else, and "anywhere else" is where it keeps happening: a preset
789
+ * list assembled from config, from a route body, from JSON, or from a
790
+ * script's argv arrives as `string[]`, and the only way past the type was a
791
+ * cast.
599
792
  *
600
793
  * Measured in neo-real-estate on 2026-08-23, in THREE independent files:
601
794
  *
@@ -607,7 +800,6 @@ type RequestablePreset = Exclude<VariantPreset, "hls" | "mp3"> | "probe";
607
800
  *
608
801
  * So the narrowing lives here, once, instead of being re-invented per repo.
609
802
  */
610
- declare const REQUESTABLE_PRESETS: readonly RequestablePreset[];
611
803
  /** Type guard for a single value. */
612
804
  declare const isRequestablePreset: (v: string) => v is RequestablePreset;
613
805
  /**
@@ -957,7 +1149,7 @@ declare function getPrivateAssetUrl(asset: Pick<AssetDTO, "sha"> & OriginalHints
957
1149
  * `number`: a signed URL is a trusted caller, so the edge ladder does not
958
1150
  * apply — the same rule `getSignedTransformUrl` already follows.
959
1151
  */
960
- declare function getPrivateTransformUrl(asset: Pick<AssetDTO, "sha">, opts: SignedTransformOptions, signingKey: string, signOpts: SignAccessOptions): Promise<string | null>;
1152
+ declare function getPrivateTransformUrl(asset: Pick<AssetDTO, "sha">, opts: PrivateTransformOptions, signingKey: string, signOpts: SignAccessOptions): Promise<string | null>;
961
1153
  /**
962
1154
  * Did the processor actually generate this preset?
963
1155
  *
@@ -995,4 +1187,4 @@ declare function getAssetDimensions(asset: Pick<AssetDTO, "w" | "h">): {
995
1187
  height: number;
996
1188
  } | null;
997
1189
 
998
- export { type AssetDTO, type AssetPalette, type AssetVariant, type HlsRung, PRESET_EXT, PRESET_LONG, PRESET_MAX_DIM, PRESET_SHORT, type PaletteSwatch, REQUESTABLE_PRESETS, type RequestablePreset, type ResolveSlotOptions, type SignAccessOptions, type SignedTransformOptions, type SlotDTO, type SlotResolution, TRANSFORM_WIDTHS, type TransformEffect, type TransformFit, type TransformFormat, type TransformGravity, type TransformOptions, type TransformWidth, type VariantEntryPreset, type VariantPreset, type VisibilityHint, accessMessage, assertPublic, assertSha, bestTextContrast, computeVariantDimensions, configureSlotResolver, contrastRatio, deriveAccessKey, extractAssetSha, getAmbientGradient, getAssetDimensions, getAssetSrcSet, getAssetUrl, getCdnBase, getHlsLadder, getHlsStreamingUrl, getPaletteBlurBackground, getPaletteCssVars, getPrivateAssetUrl, getPrivateTransformUrl, getSignedTransformUrl, getTenantId, getTextColorForBackground, getTransformSrcSet, getTransformUrl, getVideoTransformUrl, hasPreset, hlsLadderAlignment, invalidateSlotCache, isRequestablePreset, iteratePaletteSwatches, pickAmbientBackground, relativeLuminance, resolveSlot, resolveSlots, serializeTransform, setCdnBase, setTenantId, signAccessUrl, signTransformUrl, toRequestablePresets };
1190
+ export { type AssetDTO, type AssetPalette, type AssetVariant, type HlsRung, MAX_SIGNED_TRANSFORM_TTL_SECONDS, MAX_SIGNED_URL_TTL_SECONDS, MIN_SIGNED_TRANSFORM_TTL_SECONDS, PRESET_EXT, PRESET_LONG, PRESET_MAX_DIM, PRESET_SHORT, type PaletteSwatch, type PrivateTransformOptions, REQUESTABLE_PRESETS, type RequestablePreset, type ResolveSlotOptions, type SignAccessOptions, type SignTransformOptions, type SignedTransformOptions, type SlotDTO, type SlotResolution, TRANSFORM_WIDTHS, type TransformEffect, type TransformFit, type TransformFormat, type TransformGravity, type TransformOptions, type TransformWidth, type VariantEntryPreset, type VariantPreset, type VisibilityHint, accessMessage, assertPublic, assertSha, bestTextContrast, computeVariantDimensions, configureSlotResolver, contrastRatio, deriveAccessKey, deriveTransformKid, extractAssetSha, getAmbientGradient, getAssetDimensions, getAssetSrcSet, getAssetUrl, getByteBudgetTransformUrl, getCdnBase, getHlsLadder, getHlsStreamingUrl, getPaletteBlurBackground, getPaletteCssVars, getPrivateAssetUrl, getPrivateTransformUrl, getSignedTransformUrl, getTenantId, getTextColorForBackground, getTransformSrcSet, getTransformUrl, getVideoTransformUrl, hasPreset, hasSizeLadder, hlsLadderAlignment, invalidateSlotCache, isRequestablePreset, iteratePaletteSwatches, pickAmbientBackground, relativeLuminance, resolveSlot, resolveSlots, serializeTransform, setCdnBase, setTenantId, signAccessUrl, signTransformUrl, toRequestablePresets, transformMessage };