@nitida/sdk 0.26.0 → 0.27.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 +62 -0
- package/README.md +63 -2
- package/dist/index.d.ts +73 -9
- package/dist/index.js +56 -8
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +2 -2
- package/dist/server.js +56 -8
- package/dist/server.js.map +1 -1
- package/dist/web.d.ts +2 -2
- package/dist/web.js +56 -8
- package/dist/web.js.map +1 -1
- package/package.json +2 -2
- package/skills/nitida-sdk/SKILL.md +71 -5
- package/src/audio-compat.ts +37 -0
- package/src/index.ts +51 -9
- package/src/server/index.ts +9 -0
- package/src/web/index.ts +9 -0
package/dist/web.js
CHANGED
|
@@ -15,11 +15,22 @@ import {
|
|
|
15
15
|
setCdnBase,
|
|
16
16
|
setTenantId
|
|
17
17
|
} from "@nitida/asset-client";
|
|
18
|
+
|
|
19
|
+
// src/audio-compat.ts
|
|
20
|
+
function isUniversallyPlayableAudio(mime) {
|
|
21
|
+
const base = (mime.split(";")[0] ?? "").trim().toLowerCase();
|
|
22
|
+
return base === "audio/mpeg" || base === "audio/mp4" || base === "audio/aac";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// src/index.ts
|
|
18
26
|
import {
|
|
27
|
+
accessMessage,
|
|
28
|
+
assertPublic,
|
|
19
29
|
bestTextContrast,
|
|
20
30
|
computeVariantDimensions,
|
|
21
31
|
configureSlotResolver as configureSlotResolver2,
|
|
22
32
|
contrastRatio,
|
|
33
|
+
deriveAccessKey,
|
|
23
34
|
extractAssetSha,
|
|
24
35
|
getAmbientGradient,
|
|
25
36
|
getAssetDimensions,
|
|
@@ -30,6 +41,8 @@ import {
|
|
|
30
41
|
getHlsStreamingUrl as getHlsStreamingUrl2,
|
|
31
42
|
getPaletteBlurBackground,
|
|
32
43
|
getPaletteCssVars,
|
|
44
|
+
getPrivateAssetUrl,
|
|
45
|
+
getPrivateTransformUrl,
|
|
33
46
|
getSignedTransformUrl as getSignedTransformUrl2,
|
|
34
47
|
getTenantId,
|
|
35
48
|
getTextColorForBackground,
|
|
@@ -51,6 +64,7 @@ import {
|
|
|
51
64
|
serializeTransform,
|
|
52
65
|
setCdnBase as setCdnBase2,
|
|
53
66
|
setTenantId as setTenantId2,
|
|
67
|
+
signAccessUrl,
|
|
54
68
|
signTransformUrl,
|
|
55
69
|
TRANSFORM_WIDTHS
|
|
56
70
|
} from "@nitida/asset-client";
|
|
@@ -256,9 +270,10 @@ var AssetsApi = class {
|
|
|
256
270
|
return Array.isArray(dto.variants) ? dto.variants : [];
|
|
257
271
|
}
|
|
258
272
|
/**
|
|
259
|
-
* Add or rebuild variants on an existing asset.
|
|
260
|
-
*
|
|
261
|
-
* the thumb variant without touching
|
|
273
|
+
* Add or rebuild variants on an existing asset. Presets are MERGED
|
|
274
|
+
* with what's there, for images AND for video — passing
|
|
275
|
+
* `{ presets: ["thumb"] }` adds the thumb variant without touching
|
|
276
|
+
* `lg`, `sm`, `original`, etc.
|
|
262
277
|
*
|
|
263
278
|
* // Day 0: upload original-only logo
|
|
264
279
|
* const { assetId } = await aq.upload(logoFile); // defaults to ["original"]
|
|
@@ -277,10 +292,18 @@ var AssetsApi = class {
|
|
|
277
292
|
* reading the source bytes from the permanent `original` variant —
|
|
278
293
|
* no need to re-upload.
|
|
279
294
|
*
|
|
280
|
-
* Video presets are filtered to `["poster","video","aiproxy"]`
|
|
281
|
-
* dispatched to a background job (the call returns immediately
|
|
295
|
+
* Video presets are filtered to `["poster","video","aiproxy","probe"]`
|
|
296
|
+
* and dispatched to a background job (the call returns immediately
|
|
282
297
|
* with a dispatch handle; poll `aq.assets.get(id).status` for
|
|
283
298
|
* completion).
|
|
299
|
+
*
|
|
300
|
+
* ⚠️ Before 2026-08-22 the video path REPLACED the whole variant
|
|
301
|
+
* registry instead of merging, so a partial regenerate silently
|
|
302
|
+
* deregistered `poster`, `video` and — irrecoverably — `hls`, which
|
|
303
|
+
* is not a {@link RequestablePreset} and therefore cannot be asked
|
|
304
|
+
* for again. The objects kept serving from the CDN; only the
|
|
305
|
+
* registry died. Fixed server-side; a client on an older server
|
|
306
|
+
* still loses them.
|
|
284
307
|
*/
|
|
285
308
|
async regenerate(assetId, opts = {}) {
|
|
286
309
|
const r = await fetch(
|
|
@@ -548,7 +571,7 @@ var NitidaClient = class {
|
|
|
548
571
|
}
|
|
549
572
|
if (!this.opts.signingKey) {
|
|
550
573
|
throw new Error(
|
|
551
|
-
"aq.transform({ sign: true }) requires `signingKey` in NitidaClientOptions.
|
|
574
|
+
"aq.transform({ sign: true }) requires `signingKey` in NitidaClientOptions. No signingKey on this client. The key is minted by POST /admin/projects/:code/rotate-signing-key, which needs a system-scope credential the platform operator holds \u2014 your own admin key gets 403 SYSTEM_KEY_REQUIRED, so ask for it. Then pass it to the SDK constructor on a SERVER-side instance only."
|
|
552
575
|
);
|
|
553
576
|
}
|
|
554
577
|
return getSignedTransformUrl(asset, opts, this.opts.signingKey) ?? Promise.resolve(this.urlFor(asset, "lg"));
|
|
@@ -800,12 +823,30 @@ var NitidaClient = class {
|
|
|
800
823
|
* `presets` string. Falls back through the preference order
|
|
801
824
|
* lg → md → sm → thumb → original (for images)
|
|
802
825
|
* video → poster (for videos)
|
|
803
|
-
*
|
|
826
|
+
* original → mp3 (for audio ALREADY playable everywhere)
|
|
827
|
+
* mp3 → original (for any other audio)
|
|
804
828
|
* so an upload that was processed with e.g. `["original"]` still
|
|
805
829
|
* returns a non-404 URL in `aq.upload`'s result.
|
|
830
|
+
*
|
|
831
|
+
* ⭐ Why audio branches on the source mime (changed 2026-08-22).
|
|
832
|
+
*
|
|
833
|
+
* It used to be `mp3 → original` unconditionally, so `upload().cdnUrl`
|
|
834
|
+
* handed back the server's auto-generated mp3 — libmp3lame, mono ~96 kbps —
|
|
835
|
+
* even when the caller had uploaded an MP3 or an AAC that already plays in
|
|
836
|
+
* every target browser. A consumer asking for "my file" silently received a
|
|
837
|
+
* re-encoded, lower-quality one, with no error to notice.
|
|
838
|
+
*
|
|
839
|
+
* Measured across the platform: of 126 audio assets carrying an mp3 variant,
|
|
840
|
+
* **105 had an `audio/mpeg` source** — an MP3 re-encoded into an MP3, for
|
|
841
|
+
* zero compatibility gain.
|
|
842
|
+
*
|
|
843
|
+
* The mp3 still wins for `audio/webm`/Opus and anything exotic, which is the
|
|
844
|
+
* case it was built for: Chrome records webm/Opus, which iOS Safari cannot
|
|
845
|
+
* decode. That guarantee is preserved exactly; only the needless downgrade
|
|
846
|
+
* is gone.
|
|
806
847
|
*/
|
|
807
848
|
bestPresetForAsset(asset, mime) {
|
|
808
|
-
const order = mime.startsWith("video/") ? ["video", "poster"] : mime.startsWith("audio/") ? ["mp3", "original"] : ["lg", "md", "sm", "thumb", "xl", "original"];
|
|
849
|
+
const order = mime.startsWith("video/") ? ["video", "poster"] : mime.startsWith("audio/") ? isUniversallyPlayableAudio(mime) ? ["original", "mp3"] : ["mp3", "original"] : ["lg", "md", "sm", "thumb", "xl", "original"];
|
|
809
850
|
return order.find((p) => hasPreset(asset, p)) ?? this.defaultPresetForMime(mime);
|
|
810
851
|
}
|
|
811
852
|
};
|
|
@@ -879,12 +920,15 @@ export {
|
|
|
879
920
|
PRESET_MAX_DIM,
|
|
880
921
|
PRESET_SHORT,
|
|
881
922
|
TRANSFORM_WIDTHS,
|
|
923
|
+
accessMessage,
|
|
924
|
+
assertPublic,
|
|
882
925
|
bestTextContrast,
|
|
883
926
|
compressImage,
|
|
884
927
|
compressImages,
|
|
885
928
|
computeVariantDimensions,
|
|
886
929
|
configureSlotResolver2 as configureSlotResolver,
|
|
887
930
|
contrastRatio,
|
|
931
|
+
deriveAccessKey,
|
|
888
932
|
extractAssetSha,
|
|
889
933
|
getAmbientGradient,
|
|
890
934
|
getAssetDimensions,
|
|
@@ -895,6 +939,8 @@ export {
|
|
|
895
939
|
getHlsStreamingUrl2 as getHlsStreamingUrl,
|
|
896
940
|
getPaletteBlurBackground,
|
|
897
941
|
getPaletteCssVars,
|
|
942
|
+
getPrivateAssetUrl,
|
|
943
|
+
getPrivateTransformUrl,
|
|
898
944
|
getSignedTransformUrl2 as getSignedTransformUrl,
|
|
899
945
|
getTenantId,
|
|
900
946
|
getTextColorForBackground,
|
|
@@ -904,6 +950,7 @@ export {
|
|
|
904
950
|
hasPreset2 as hasPreset,
|
|
905
951
|
hlsLadderAlignment,
|
|
906
952
|
invalidateSlotCache2 as invalidateSlotCache,
|
|
953
|
+
isUniversallyPlayableAudio,
|
|
907
954
|
iteratePaletteSwatches,
|
|
908
955
|
mimeFromFileName,
|
|
909
956
|
pickAmbientBackground,
|
|
@@ -913,6 +960,7 @@ export {
|
|
|
913
960
|
serializeTransform,
|
|
914
961
|
setCdnBase2 as setCdnBase,
|
|
915
962
|
setTenantId2 as setTenantId,
|
|
963
|
+
signAccessUrl,
|
|
916
964
|
signTransformUrl
|
|
917
965
|
};
|
|
918
966
|
//# sourceMappingURL=web.js.map
|