@nitida/asset-client 0.17.0 → 0.18.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/AGENTS.md +26 -0
- package/README.md +6 -3
- package/dist/index.cjs +247 -99
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +243 -85
- package/dist/index.d.ts +243 -85
- package/dist/index.js +241 -99
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/access.ts +200 -0
- package/src/index.ts +208 -1
- package/src/transform.ts +39 -5
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Signed URLs for PRIVATE assets — the `/a/{tenant}/…?exp&sig` tree.
|
|
3
|
+
*
|
|
4
|
+
* ## Who calls this, and who must not
|
|
5
|
+
*
|
|
6
|
+
* The tenant's BACKEND, which knows who the viewer is and holds the signing
|
|
7
|
+
* key. Never a browser: shipping the signing key to the client would let any
|
|
8
|
+
* visitor mint URLs for any private asset of that tenant, which is the whole
|
|
9
|
+
* property the tree exists to provide. This module is deliberately importable
|
|
10
|
+
* from anywhere — it runs on WebCrypto, so browsers, Node, Bun and Workers all
|
|
11
|
+
* work — and that convenience is exactly why the warning is here rather than
|
|
12
|
+
* in a doc nobody reads at the call site.
|
|
13
|
+
*
|
|
14
|
+
* ## Not the same signature as `signTransformUrl`
|
|
15
|
+
*
|
|
16
|
+
* `signTransformUrl` vouches for a WIDTH; this vouches for a VIEWER, until
|
|
17
|
+
* `exp`. They come from the same `signing_key` but not the same key material:
|
|
18
|
+
* the access key is derived (`HMAC(signing_key, "nitida/access/v1")`) so that
|
|
19
|
+
* no crafted transform path can be replayed as an access signature. The full
|
|
20
|
+
* argument lives beside the server implementation in `access-signing.ts`; the
|
|
21
|
+
* short version is that a shared payload with a prefix separator IS
|
|
22
|
+
* collidable, because both fields of the transform message are
|
|
23
|
+
* attacker-influenced path segments.
|
|
24
|
+
*
|
|
25
|
+
* ## `exp` is mandatory
|
|
26
|
+
*
|
|
27
|
+
* A signed URL that never expires is a public URL as soon as someone forwards
|
|
28
|
+
* it. There is no "no expiry" option here, and there will not be one.
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* The per-tenant access key, derived from `signing_key`. Same value the origin
|
|
32
|
+
* computes and hands the edge — nothing needs to be stored or synchronised.
|
|
33
|
+
*/
|
|
34
|
+
declare function deriveAccessKey(signingKey: string): Promise<Uint8Array>;
|
|
35
|
+
/**
|
|
36
|
+
* The signed message. Byte-identical to the server's `accessMessage` and the
|
|
37
|
+
* worker's — three implementations of one string, which is why all three pin
|
|
38
|
+
* the exact bytes in a test.
|
|
39
|
+
*
|
|
40
|
+
* `tenantPrefix` is the base36 segment as it appears in the URL, not the
|
|
41
|
+
* decimal id: tenant 10 lives at `/a/a/`, and the thing being vouched for is a
|
|
42
|
+
* path.
|
|
43
|
+
*/
|
|
44
|
+
declare function accessMessage(tenantPrefix: string, exp: number, resourcePath: string): string;
|
|
45
|
+
type SignAccessOptions = {
|
|
46
|
+
/** Lifetime in seconds. Required — see the header. */
|
|
47
|
+
expiresInSeconds: number;
|
|
48
|
+
/** Injectable clock, for tests that need a URL already dead on arrival. */
|
|
49
|
+
nowSeconds?: number;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Turn a PUBLIC-tree URL into a signed PRIVATE-tree URL.
|
|
53
|
+
*
|
|
54
|
+
* https://8ok.uk/5/v/<sha16>-lg.webp
|
|
55
|
+
* → https://8ok.uk/a/5/v/<sha16>-lg.webp?exp=…&sig=…
|
|
56
|
+
*
|
|
57
|
+
* Accepts a URL that is already under `/a/` and re-signs it, so calling twice
|
|
58
|
+
* is not an error and does not produce `/a/a/`.
|
|
59
|
+
*/
|
|
60
|
+
declare function signAccessUrl(publicUrl: string, signingKey: string, opts: SignAccessOptions): Promise<string>;
|
|
61
|
+
/** What every URL builder accepts so it can refuse a doomed URL. */
|
|
62
|
+
type VisibilityHint = {
|
|
63
|
+
visibility?: "public" | "private";
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Refuse to build a public URL for a private asset.
|
|
67
|
+
*
|
|
68
|
+
* Doctrine of the house: **a silence reads as "you can't"**. Returning
|
|
69
|
+
* `https://8ok.uk/5/v/<sha>-lg.webp` for a private asset is not a smaller
|
|
70
|
+
* failure than throwing — it is a URL that answers 404, in a platform where a
|
|
71
|
+
* 404 has always meant "that file does not exist". The caller then debugs the
|
|
72
|
+
* wrong thing.
|
|
73
|
+
*
|
|
74
|
+
* Only refuses when it was actually TOLD. A caller passing `{ sha }` carries no
|
|
75
|
+
* visibility, and guessing would break every existing call site to protect
|
|
76
|
+
* assets that are not there.
|
|
77
|
+
*/
|
|
78
|
+
declare function assertPublic(asset: VisibilityHint, fn: string,
|
|
79
|
+
/**
|
|
80
|
+
* The call to make instead — declared per call site, not guessed.
|
|
81
|
+
*
|
|
82
|
+
* It matters which one: `getPrivateAssetUrl` signs a STORED preset, and
|
|
83
|
+
* pointing a transform caller at it sends them to a function that cannot do
|
|
84
|
+
* what they asked for. The first version of this message named
|
|
85
|
+
* `getPrivateAssetUrl` for all seven builders; a test caught it.
|
|
86
|
+
*/
|
|
87
|
+
escape: string): void;
|
|
88
|
+
|
|
1
89
|
/**
|
|
2
90
|
* Color palette helpers — render harmonious ambient backgrounds behind
|
|
3
91
|
* product images, inspired by Spotify Now Playing / Apple Music / Pico.
|
|
@@ -92,83 +180,6 @@ declare function iteratePaletteSwatches(palette: AssetPalette | null | undefined
|
|
|
92
180
|
*/
|
|
93
181
|
declare function getPaletteBlurBackground(palette: AssetPalette | null | undefined): string | undefined;
|
|
94
182
|
|
|
95
|
-
/**
|
|
96
|
-
* @nitida/asset-client/slots — slot resolver for tenant-named assets.
|
|
97
|
-
*
|
|
98
|
-
* Slots give tenants a way to attach stable, human-readable names
|
|
99
|
-
* ("webapp.wizard.pool-type.icon-1", "storefront.cr.hero-video.landscape_hd_16x9.mp4")
|
|
100
|
-
* to assets they uploaded. Consumers resolve names → AssetDTOs at
|
|
101
|
-
* build / runtime so their source never hardcodes a CDN URL; an
|
|
102
|
-
* admin rebinds a slot in the platform console and every consumer
|
|
103
|
-
* picks up the swap on cache refresh.
|
|
104
|
-
*
|
|
105
|
-
* Two layers in this package:
|
|
106
|
-
* - `resolveSlot` / `resolveSlots` — universal (server, edge,
|
|
107
|
-
* workers) fetch helpers. Cache 60s by default.
|
|
108
|
-
* - React hooks live in `@nitida/asset-client/react/use-slot`
|
|
109
|
-
* (kept out of this module so the SSR-safe core stays
|
|
110
|
-
* dependency-free of react).
|
|
111
|
-
*/
|
|
112
|
-
|
|
113
|
-
type SlotDTO = {
|
|
114
|
-
slotKey: string;
|
|
115
|
-
/** Preset hint set when the slot was bound (e.g. `thumb` for icon slots). */
|
|
116
|
-
preset: VariantPreset | null;
|
|
117
|
-
description: string | null;
|
|
118
|
-
updatedAt: string;
|
|
119
|
-
asset: AssetDTO;
|
|
120
|
-
};
|
|
121
|
-
type SlotResolution = {
|
|
122
|
-
/** The resolved DTO (`null` when the slot is unbound or asset missing). */
|
|
123
|
-
slot: SlotDTO | null;
|
|
124
|
-
/**
|
|
125
|
-
* Effective preset — what `url` below was built with. Resolution order:
|
|
126
|
-
* 1. caller's `preset` override
|
|
127
|
-
* 2. slot's `preset` hint
|
|
128
|
-
* 3. `lg` for images, `video` for video kind
|
|
129
|
-
*/
|
|
130
|
-
preset: VariantPreset;
|
|
131
|
-
/** The CDN URL the consumer should use. */
|
|
132
|
-
url: string | null;
|
|
133
|
-
};
|
|
134
|
-
/**
|
|
135
|
-
* Configure the resolver process-wide. Call once at boot from your
|
|
136
|
-
* storefront layout / server entry / worker init.
|
|
137
|
-
*
|
|
138
|
-
* configureSlotResolver({
|
|
139
|
-
* endpoint: process.env.AQUIENPZ_URL,
|
|
140
|
-
* apiKey: process.env.AQUIENPZ_API_KEY, // amk_rt_* — server-only
|
|
141
|
-
* tenantCode: "acme-co",
|
|
142
|
-
* });
|
|
143
|
-
*/
|
|
144
|
-
declare function configureSlotResolver(opts: {
|
|
145
|
-
endpoint?: string;
|
|
146
|
-
apiKey?: string;
|
|
147
|
-
tenantCode?: string;
|
|
148
|
-
}): void;
|
|
149
|
-
/** Wipe the in-process cache (test helper or forced refresh). */
|
|
150
|
-
declare function invalidateSlotCache(slotKey?: string): void;
|
|
151
|
-
type ResolveSlotOptions = {
|
|
152
|
-
/** Override preset (caller knows the use case better than the slot binding). */
|
|
153
|
-
preset?: VariantPreset;
|
|
154
|
-
/** TTL for the in-process cache. Default 60s. Set 0 to bypass. */
|
|
155
|
-
ttlMs?: number;
|
|
156
|
-
};
|
|
157
|
-
/**
|
|
158
|
-
* Resolve a single slot to a CDN URL. Returns `{slot: null, url: null}`
|
|
159
|
-
* when the slot is unbound — callers fall back to a placeholder.
|
|
160
|
-
*
|
|
161
|
-
* Cached for `ttlMs` (default 60s). Slot rebindings propagate within the
|
|
162
|
-
* TTL window without an app restart.
|
|
163
|
-
*/
|
|
164
|
-
declare function resolveSlot(slotKey: string, opts?: ResolveSlotOptions): Promise<SlotResolution>;
|
|
165
|
-
/**
|
|
166
|
-
* Bulk-resolve N slot keys in one round-trip. The SDK's `useSlots`
|
|
167
|
-
* React hook calls this so every storefront header (logo + tagline +
|
|
168
|
-
* nav cover + …) loads as one request.
|
|
169
|
-
*/
|
|
170
|
-
declare function resolveSlots(slotKeys: string[], opts?: ResolveSlotOptions): Promise<Record<string, SlotResolution>>;
|
|
171
|
-
|
|
172
183
|
/**
|
|
173
184
|
* On-the-fly transform URL builder.
|
|
174
185
|
*
|
|
@@ -309,7 +320,7 @@ declare function serializeTransform(opts: SignedTransformOptions): string;
|
|
|
309
320
|
* <video src={aq.transformVideo(asset, { width: 1080, height: 1920 })}
|
|
310
321
|
* autoPlay muted loop playsInline />
|
|
311
322
|
*/
|
|
312
|
-
declare function getVideoTransformUrl(asset: Pick<AssetDTO, "sha"
|
|
323
|
+
declare function getVideoTransformUrl(asset: Pick<AssetDTO, "sha"> & VisibilityHint, opts: TransformOptions): string | null;
|
|
313
324
|
/**
|
|
314
325
|
* Build an HLS streaming URL for a VIDEO asset (Phase 5). Returns the
|
|
315
326
|
* master.m3u8 entry point — HLS-aware players (Video.js's
|
|
@@ -368,8 +379,9 @@ declare function getVideoTransformUrl(asset: Pick<AssetDTO, "sha">, opts: Transf
|
|
|
368
379
|
* on demand after the raw is unavailable it reads the `-v.mp4`, which is
|
|
369
380
|
* capped at 1920 wide. `getAssetUrl(sha, "video")` is always <= 1080p.
|
|
370
381
|
*/
|
|
371
|
-
declare function getHlsStreamingUrl(asset: Pick<AssetDTO, "sha"
|
|
372
|
-
|
|
382
|
+
declare function getHlsStreamingUrl(asset: Pick<AssetDTO, "sha"> & VisibilityHint, opts?: Omit<TransformOptions, "format">): string;
|
|
383
|
+
|
|
384
|
+
declare function getTransformUrl(asset: Pick<AssetDTO, "sha"> & VisibilityHint, opts: TransformOptions): string | null;
|
|
373
385
|
/**
|
|
374
386
|
* Build AND sign a transform URL, allowing an off-ladder custom `width`.
|
|
375
387
|
*
|
|
@@ -381,7 +393,7 @@ declare function getTransformUrl(asset: Pick<AssetDTO, "sha">, opts: TransformOp
|
|
|
381
393
|
* Returns `null` only when `opts` serialize to an empty DSL (no transform
|
|
382
394
|
* requested) — same contract as {@link getTransformUrl}.
|
|
383
395
|
*/
|
|
384
|
-
declare function getSignedTransformUrl(asset: Pick<AssetDTO, "sha"
|
|
396
|
+
declare function getSignedTransformUrl(asset: Pick<AssetDTO, "sha"> & VisibilityHint, opts: SignedTransformOptions, signingKey: string): Promise<string> | null;
|
|
385
397
|
/**
|
|
386
398
|
* Sign a transform URL with the tenant's HMAC signing key. Appends
|
|
387
399
|
* `?sig=<hex>` where hex = HMAC-SHA256(signingKey, `<canonical-DSL>/<filename>`).
|
|
@@ -404,7 +416,84 @@ declare function signTransformUrl(unsignedUrl: string, signingKey: string): Prom
|
|
|
404
416
|
* sizes="(max-width: 768px) 100vw, 50vw"
|
|
405
417
|
* />
|
|
406
418
|
*/
|
|
407
|
-
declare function getTransformSrcSet(asset: Pick<AssetDTO, "sha"
|
|
419
|
+
declare function getTransformSrcSet(asset: Pick<AssetDTO, "sha"> & VisibilityHint, widths: number[], extraOpts?: Omit<TransformOptions, "width">): string;
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* @nitida/asset-client/slots — slot resolver for tenant-named assets.
|
|
423
|
+
*
|
|
424
|
+
* Slots give tenants a way to attach stable, human-readable names
|
|
425
|
+
* ("webapp.wizard.pool-type.icon-1", "storefront.cr.hero-video.landscape_hd_16x9.mp4")
|
|
426
|
+
* to assets they uploaded. Consumers resolve names → AssetDTOs at
|
|
427
|
+
* build / runtime so their source never hardcodes a CDN URL; an
|
|
428
|
+
* admin rebinds a slot in the platform console and every consumer
|
|
429
|
+
* picks up the swap on cache refresh.
|
|
430
|
+
*
|
|
431
|
+
* Two layers in this package:
|
|
432
|
+
* - `resolveSlot` / `resolveSlots` — universal (server, edge,
|
|
433
|
+
* workers) fetch helpers. Cache 60s by default.
|
|
434
|
+
* - React hooks live in `@nitida/asset-client/react/use-slot`
|
|
435
|
+
* (kept out of this module so the SSR-safe core stays
|
|
436
|
+
* dependency-free of react).
|
|
437
|
+
*/
|
|
438
|
+
|
|
439
|
+
type SlotDTO = {
|
|
440
|
+
slotKey: string;
|
|
441
|
+
/** Preset hint set when the slot was bound (e.g. `thumb` for icon slots). */
|
|
442
|
+
preset: VariantPreset | null;
|
|
443
|
+
description: string | null;
|
|
444
|
+
updatedAt: string;
|
|
445
|
+
asset: AssetDTO;
|
|
446
|
+
};
|
|
447
|
+
type SlotResolution = {
|
|
448
|
+
/** The resolved DTO (`null` when the slot is unbound or asset missing). */
|
|
449
|
+
slot: SlotDTO | null;
|
|
450
|
+
/**
|
|
451
|
+
* Effective preset — what `url` below was built with. Resolution order:
|
|
452
|
+
* 1. caller's `preset` override
|
|
453
|
+
* 2. slot's `preset` hint
|
|
454
|
+
* 3. `lg` for images, `video` for video kind
|
|
455
|
+
*/
|
|
456
|
+
preset: VariantPreset;
|
|
457
|
+
/** The CDN URL the consumer should use. */
|
|
458
|
+
url: string | null;
|
|
459
|
+
};
|
|
460
|
+
/**
|
|
461
|
+
* Configure the resolver process-wide. Call once at boot from your
|
|
462
|
+
* storefront layout / server entry / worker init.
|
|
463
|
+
*
|
|
464
|
+
* configureSlotResolver({
|
|
465
|
+
* endpoint: process.env.AQUIENPZ_URL,
|
|
466
|
+
* apiKey: process.env.AQUIENPZ_API_KEY, // amk_rt_* — server-only
|
|
467
|
+
* tenantCode: "acme-co",
|
|
468
|
+
* });
|
|
469
|
+
*/
|
|
470
|
+
declare function configureSlotResolver(opts: {
|
|
471
|
+
endpoint?: string;
|
|
472
|
+
apiKey?: string;
|
|
473
|
+
tenantCode?: string;
|
|
474
|
+
}): void;
|
|
475
|
+
/** Wipe the in-process cache (test helper or forced refresh). */
|
|
476
|
+
declare function invalidateSlotCache(slotKey?: string): void;
|
|
477
|
+
type ResolveSlotOptions = {
|
|
478
|
+
/** Override preset (caller knows the use case better than the slot binding). */
|
|
479
|
+
preset?: VariantPreset;
|
|
480
|
+
/** TTL for the in-process cache. Default 60s. Set 0 to bypass. */
|
|
481
|
+
ttlMs?: number;
|
|
482
|
+
};
|
|
483
|
+
/**
|
|
484
|
+
* Resolve a single slot to a CDN URL. Returns `{slot: null, url: null}`
|
|
485
|
+
* when the slot is unbound — callers fall back to a placeholder.
|
|
486
|
+
*
|
|
487
|
+
* Cached for `ttlMs` (default 60s). Slot rebindings propagate within the
|
|
488
|
+
* TTL window without an app restart.
|
|
489
|
+
*/
|
|
490
|
+
declare function resolveSlot(slotKey: string, opts?: ResolveSlotOptions): Promise<SlotResolution>;
|
|
491
|
+
/**
|
|
492
|
+
* Bulk-resolve N slot keys in one round-trip. The SDK's `useSlots`
|
|
493
|
+
* React hook calls this so every storefront header (logo + tagline +
|
|
494
|
+
* nav cover + …) loads as one request.
|
|
495
|
+
*/
|
|
496
|
+
declare function resolveSlots(slotKeys: string[], opts?: ResolveSlotOptions): Promise<Record<string, SlotResolution>>;
|
|
408
497
|
|
|
409
498
|
/**
|
|
410
499
|
* @nitida/asset-client — read helpers for asset URLs.
|
|
@@ -626,6 +715,23 @@ type AssetDTO = {
|
|
|
626
715
|
*/
|
|
627
716
|
presets: string;
|
|
628
717
|
status: "processing" | "ready" | "failed";
|
|
718
|
+
/**
|
|
719
|
+
* Who may fetch the bytes.
|
|
720
|
+
*
|
|
721
|
+
* - `"public"` — the CDN serves it to anyone with the URL. The default,
|
|
722
|
+
* and what all 27 484 assets were until this field existed.
|
|
723
|
+
* - `"private"` — every public door answers **404**: the stored variants,
|
|
724
|
+
* the raw original, the HLS ladder and `/t/`. The bytes are reachable
|
|
725
|
+
* only through a signed URL under `/a/{tenant}/…?exp&sig`, which your
|
|
726
|
+
* BACKEND mints with {@link getPrivateAssetUrl}.
|
|
727
|
+
*
|
|
728
|
+
* Optional so an older server that does not send it is read as `"public"` —
|
|
729
|
+
* which is what such a server means.
|
|
730
|
+
*
|
|
731
|
+
* ⚠️ A 404 on a private asset is not a missing file. It is the feature
|
|
732
|
+
* working. See {@link getPrivateAssetUrl}.
|
|
733
|
+
*/
|
|
734
|
+
visibility?: "public" | "private";
|
|
629
735
|
/** Soft-delete timestamp (ISO). Hidden from catalog when set. */
|
|
630
736
|
deletedAt?: string | null;
|
|
631
737
|
/**
|
|
@@ -695,7 +801,59 @@ type OriginalHints = {
|
|
|
695
801
|
* const url = hasPreset(asset, "thumb") ? getAssetUrl(asset, "thumb") : null;
|
|
696
802
|
* ```
|
|
697
803
|
*/
|
|
698
|
-
declare function getAssetUrl(asset: Pick<AssetDTO, "sha"> & OriginalHints, preset: VariantPreset): string;
|
|
804
|
+
declare function getAssetUrl(asset: Pick<AssetDTO, "sha"> & OriginalHints & VisibilityHint, preset: VariantPreset): string;
|
|
805
|
+
/**
|
|
806
|
+
* The signed URL for one preset of a PRIVATE asset — what every refusal above
|
|
807
|
+
* points at.
|
|
808
|
+
*
|
|
809
|
+
* ```ts
|
|
810
|
+
* // On your BACKEND, once you have decided this viewer may see it:
|
|
811
|
+
* const url = await getPrivateAssetUrl(asset, "lg", tenantSigningKey, {
|
|
812
|
+
* expiresInSeconds: 300,
|
|
813
|
+
* });
|
|
814
|
+
* ```
|
|
815
|
+
*
|
|
816
|
+
* It works on a public asset too — `/a/` is a different door onto the same
|
|
817
|
+
* object — but there is no reason to pay for it: a public URL is cacheable at
|
|
818
|
+
* the edge and costs nothing, a signed one is neither.
|
|
819
|
+
*
|
|
820
|
+
* ⚠️ **Backend only.** Handing the signing key to a browser lets any visitor
|
|
821
|
+
* mint URLs for every private asset the tenant owns, which is the whole
|
|
822
|
+
* property the private tree exists to provide.
|
|
823
|
+
*
|
|
824
|
+
* ⚠️ Needs {@link setTenantId} (or a `NitidaClient` with `tenantId`), like
|
|
825
|
+
* every variant URL builder: the tenant segment is base36 and part of what the
|
|
826
|
+
* signature covers, so a missing tenant does not produce a wrong URL — it
|
|
827
|
+
* produces an unsignable one.
|
|
828
|
+
*/
|
|
829
|
+
declare function getPrivateAssetUrl(asset: Pick<AssetDTO, "sha"> & OriginalHints, preset: VariantPreset, signingKey: string, opts: SignAccessOptions): Promise<string>;
|
|
830
|
+
/**
|
|
831
|
+
* The signed URL for a TRANSFORM of a private asset — an arbitrary width, crop
|
|
832
|
+
* or format, not just the sizes that happen to be materialised.
|
|
833
|
+
*
|
|
834
|
+
* ```ts
|
|
835
|
+
* const url = await getPrivateTransformUrl(
|
|
836
|
+
* asset,
|
|
837
|
+
* { width: 1280, format: "webp" },
|
|
838
|
+
* tenantSigningKey,
|
|
839
|
+
* { expiresInSeconds: 300 },
|
|
840
|
+
* );
|
|
841
|
+
* // → https://8ok.uk/a/5/t/format=webp,width=1280/<sha>.webp?exp=…&sig=…
|
|
842
|
+
* ```
|
|
843
|
+
*
|
|
844
|
+
* Why this exists at all: a private asset that can only be served at the sizes
|
|
845
|
+
* someone already generated is barely a product. The signed tree mirrors the
|
|
846
|
+
* public one, transforms included.
|
|
847
|
+
*
|
|
848
|
+
* Returns `null` when `opts` serialize to an empty DSL — same contract as
|
|
849
|
+
* {@link getTransformUrl}, because "no transform requested" is not an error,
|
|
850
|
+
* it just means you wanted {@link getPrivateAssetUrl}.
|
|
851
|
+
*
|
|
852
|
+
* ⚠️ **Backend only**, like every signer here. And note the width is a plain
|
|
853
|
+
* `number`: a signed URL is a trusted caller, so the edge ladder does not
|
|
854
|
+
* apply — the same rule `getSignedTransformUrl` already follows.
|
|
855
|
+
*/
|
|
856
|
+
declare function getPrivateTransformUrl(asset: Pick<AssetDTO, "sha">, opts: SignedTransformOptions, signingKey: string, signOpts: SignAccessOptions): Promise<string | null>;
|
|
699
857
|
/**
|
|
700
858
|
* Did the processor actually generate this preset?
|
|
701
859
|
*
|
|
@@ -714,7 +872,7 @@ declare function getAssetUrl(asset: Pick<AssetDTO, "sha"> & OriginalHints, prese
|
|
|
714
872
|
* ```
|
|
715
873
|
*/
|
|
716
874
|
declare function hasPreset(asset: Pick<AssetDTO, "presets">, preset: VariantPreset): boolean;
|
|
717
|
-
declare function getAssetSrcSet(asset: Pick<AssetDTO, "sha" | "presets">): string;
|
|
875
|
+
declare function getAssetSrcSet(asset: Pick<AssetDTO, "sha" | "presets"> & VisibilityHint): string;
|
|
718
876
|
/**
|
|
719
877
|
* Compute the dimensions a variant would have given the source asset's
|
|
720
878
|
* width/height and the variant's bounding box. For thumbnails (square
|
|
@@ -731,4 +889,4 @@ declare function getAssetDimensions(asset: Pick<AssetDTO, "w" | "h">): {
|
|
|
731
889
|
height: number;
|
|
732
890
|
} | null;
|
|
733
891
|
|
|
734
|
-
export { type AssetDTO, type AssetPalette, type AssetVariant, type HlsRung, PRESET_EXT, PRESET_LONG, PRESET_MAX_DIM, PRESET_SHORT, type PaletteSwatch, type RequestablePreset, type ResolveSlotOptions, type SignedTransformOptions, type SlotDTO, type SlotResolution, TRANSFORM_WIDTHS, type TransformEffect, type TransformFit, type TransformFormat, type TransformGravity, type TransformOptions, type TransformWidth, type VariantEntryPreset, type VariantPreset, bestTextContrast, computeVariantDimensions, configureSlotResolver, contrastRatio, extractAssetSha, getAmbientGradient, getAssetDimensions, getAssetSrcSet, getAssetUrl, getCdnBase, getHlsLadder, getHlsStreamingUrl, getPaletteBlurBackground, getPaletteCssVars, getSignedTransformUrl, getTenantId, getTextColorForBackground, getTransformSrcSet, getTransformUrl, getVideoTransformUrl, hasPreset, hlsLadderAlignment, invalidateSlotCache, iteratePaletteSwatches, pickAmbientBackground, relativeLuminance, resolveSlot, resolveSlots, serializeTransform, setCdnBase, setTenantId, signTransformUrl };
|
|
892
|
+
export { type AssetDTO, type AssetPalette, type AssetVariant, type HlsRung, PRESET_EXT, PRESET_LONG, PRESET_MAX_DIM, PRESET_SHORT, type PaletteSwatch, 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, 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, iteratePaletteSwatches, pickAmbientBackground, relativeLuminance, resolveSlot, resolveSlots, serializeTransform, setCdnBase, setTenantId, signAccessUrl, signTransformUrl };
|