@nitida/asset-client 0.20.4 → 0.21.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.cjs +5 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +43 -0
package/src/index.ts
CHANGED
|
@@ -378,6 +378,15 @@ export function hlsLadderAlignment(rungs: HlsRung[]): {
|
|
|
378
378
|
*/
|
|
379
379
|
export type AssetDTO = {
|
|
380
380
|
id: string;
|
|
381
|
+
/**
|
|
382
|
+
* ⭐ The same value as `id`, under the name the WRITE side uses.
|
|
383
|
+
*
|
|
384
|
+
* `upload()` returns `assetId`; the read endpoints returned only `id`, so
|
|
385
|
+
* what `assets.byHash()` handed back could not be fed to `assets.get()`
|
|
386
|
+
* without renaming a field. Optional here because a DTO produced by an older
|
|
387
|
+
* server will not carry it — read `dto.assetId ?? dto.id`.
|
|
388
|
+
*/
|
|
389
|
+
assetId?: string;
|
|
381
390
|
/** First 16 hex chars of sha256 — used to derive CDN URLs. */
|
|
382
391
|
sha: string;
|
|
383
392
|
kind: "image" | "video" | "document" | "audio" | "other";
|
|
@@ -611,6 +620,13 @@ type OriginalHints = {
|
|
|
611
620
|
oext?: string | null;
|
|
612
621
|
/** Full variant list — carries the stored URL verbatim. Authoritative. */
|
|
613
622
|
variants?: AssetVariant[];
|
|
623
|
+
/**
|
|
624
|
+
* What the asset IS. Optional because these builders accept a minimal
|
|
625
|
+
* `{ sha }`, and absent means "we cannot know" — never "assume the worst".
|
|
626
|
+
* Used to refuse `hls` on something that can never have a ladder; see the
|
|
627
|
+
* `hls` branch of `getAssetUrl`.
|
|
628
|
+
*/
|
|
629
|
+
kind?: AssetDTO["kind"];
|
|
614
630
|
};
|
|
615
631
|
|
|
616
632
|
/**
|
|
@@ -768,6 +784,33 @@ function buildPublicAssetUrl(
|
|
|
768
784
|
// missing. Both are real; neither is a guess.
|
|
769
785
|
const stored = asset.variants?.find((v) => v.preset === "hls")?.url;
|
|
770
786
|
if (stored) return stored;
|
|
787
|
+
// No stored ladder. Before falling through to the transform route, refuse
|
|
788
|
+
// the kinds that can never HAVE one.
|
|
789
|
+
//
|
|
790
|
+
// `/t/format=hls/<sha>.m3u8` on an IMAGE does not 404 — measured against
|
|
791
|
+
// production 2026-08-25, it answers **200 with `content-type: image/webp`**
|
|
792
|
+
// (306 kB, cached `immutable` for a year) because the edge's transform
|
|
793
|
+
// planner short-circuits every image to the image pipeline before it ever
|
|
794
|
+
// looks at `format`. So the polite lie this branch was written to avoid
|
|
795
|
+
// comes back through the other door: not a 404, but a WebP wearing an
|
|
796
|
+
// `.m3u8` filename, which is worse — a player cannot even tell it failed.
|
|
797
|
+
//
|
|
798
|
+
// HLS is built when a VIDEO transcodes; audio gets `mp3`, images get the
|
|
799
|
+
// ladder of resized variants. The stored-URL check above runs FIRST on
|
|
800
|
+
// purpose: if a DTO really carries an `hls` variant, the data beats this
|
|
801
|
+
// inference and we hand it over whatever `kind` claims. We only refuse
|
|
802
|
+
// when we would otherwise fabricate a URL we already know is wrong.
|
|
803
|
+
if (asset.kind != null && asset.kind !== "video") {
|
|
804
|
+
throw new Error(
|
|
805
|
+
`${caller}: this asset is \`${asset.kind}\`, and only a video has an ` +
|
|
806
|
+
"HLS ladder. Asking for `hls` here would build " +
|
|
807
|
+
"`/t/format=hls/<sha>.m3u8`, which does NOT 404 — the edge answers " +
|
|
808
|
+
"200 with the image bytes under an .m3u8 name, so a player fails " +
|
|
809
|
+
"with no way to see why. For an image use a size preset " +
|
|
810
|
+
`(\`${caller}(asset, "md")\`) or a transform ` +
|
|
811
|
+
"(`getTransformUrl`); for audio use `mp3`.",
|
|
812
|
+
);
|
|
813
|
+
}
|
|
771
814
|
return `${cdnBaseUrl}/t/format=hls/${asset.sha}.m3u8`;
|
|
772
815
|
}
|
|
773
816
|
return `${cdnBaseUrl}/${variantPrefix(caller)}${asset.sha}-${PRESET_SHORT[preset]}.${PRESET_EXT[preset]}`;
|