@nitida/sdk 0.25.3 → 0.26.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 +34 -0
- package/README.md +148 -15
- package/dist/expo.d.ts +32 -3
- package/dist/expo.js.map +1 -1
- package/dist/index.d.ts +12 -5
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +2 -2
- package/dist/server.js +23 -0
- package/dist/server.js.map +1 -1
- package/dist/web.d.ts +2 -2
- package/dist/web.js +25 -0
- package/dist/web.js.map +1 -1
- package/package.json +3 -7
- package/skills/nitida-sdk/SKILL.md +31 -4
- package/src/expo/index.ts +32 -3
- package/src/index.ts +24 -5
- package/src/server/index.ts +45 -1
- package/src/web/index.ts +57 -3
package/src/expo/index.ts
CHANGED
|
@@ -26,6 +26,33 @@
|
|
|
26
26
|
* const { assetId } = await upload.start();
|
|
27
27
|
* await aq.slots.bind("storefront.tour.video", { assetId, preset: "video" });
|
|
28
28
|
*
|
|
29
|
+
* ⚠️ THIS PATH PUTS A RUNTIME KEY ON THE DEVICE. Read before shipping.
|
|
30
|
+
*
|
|
31
|
+
* `createExpoUploader` reads `client.opts.apiKey` and hands it to the native
|
|
32
|
+
* session as its `authToken` (see below — it is four lines, and they are the
|
|
33
|
+
* whole story). The native uploader talks to the API directly, so it needs a
|
|
34
|
+
* credential the OS can replay hours later from a background task. There is no
|
|
35
|
+
* BFF in that loop to inject one.
|
|
36
|
+
*
|
|
37
|
+
* That is the opposite of what every other surface here does, and the opposite
|
|
38
|
+
* of what `@nitida/sdk/web` chose when it hit the SAME constraint: `/web`
|
|
39
|
+
* deliberately does NOT expose the multipart uploader, because it needs a raw
|
|
40
|
+
* `authToken` a BFF cannot supply. `/expo` exposes it anyway, because
|
|
41
|
+
* background-surviving uploads are the entire reason a native session exists.
|
|
42
|
+
*
|
|
43
|
+
* So, concretely, an `amk_rt_*` key in your app bundle is readable by anyone
|
|
44
|
+
* who unzips the IPA/APK, and it is a WRITE key to a paid platform.
|
|
45
|
+
*
|
|
46
|
+
* - Uploading big video in the background is worth it to you ⇒ use this, and
|
|
47
|
+
* scope the key to one tenant so a leak is contained and revocable.
|
|
48
|
+
* - It is not ⇒ build the client from `@nitida/sdk/web` pointed at your own
|
|
49
|
+
* route and call `aq.upload(file)`. No key on the device. You lose survival
|
|
50
|
+
* across backgrounding and OS kill; the upload dies with the JS thread.
|
|
51
|
+
*
|
|
52
|
+
* The real fix — a BFF-minted short-lived token the native session can carry —
|
|
53
|
+
* is not built. It is the same gap `/web` documents. Ask; there is no public
|
|
54
|
+
* tracker.
|
|
55
|
+
*
|
|
29
56
|
* Peer dep: `@aquienpz/asset-uploader-expo` (lazy — apps that don't
|
|
30
57
|
* use the mobile SDK skip the install).
|
|
31
58
|
* @module @nitida/sdk/expo
|
|
@@ -44,9 +71,11 @@ export type ExpoUploadOptions = Omit<
|
|
|
44
71
|
|
|
45
72
|
/**
|
|
46
73
|
* Spawn a native-backed `UploadTask` bound to a configured client.
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
74
|
+
*
|
|
75
|
+
* ⚠️ It reaches into the client for `apiKey` and uses it as the session's
|
|
76
|
+
* `authToken`, so the client you pass MUST have been built with a real runtime
|
|
77
|
+
* key — which means that key is on the device. See the module header for what
|
|
78
|
+
* that costs and what the alternative is.
|
|
50
79
|
*/
|
|
51
80
|
export function createExpoUploader(
|
|
52
81
|
client: NitidaClient,
|
package/src/index.ts
CHANGED
|
@@ -48,6 +48,7 @@ import {
|
|
|
48
48
|
getVideoTransformUrl,
|
|
49
49
|
hasPreset,
|
|
50
50
|
invalidateSlotCache,
|
|
51
|
+
type RequestablePreset,
|
|
51
52
|
type ResolveSlotOptions,
|
|
52
53
|
resolveSlot,
|
|
53
54
|
resolveSlots,
|
|
@@ -57,6 +58,7 @@ import {
|
|
|
57
58
|
setCdnBase,
|
|
58
59
|
setTenantId,
|
|
59
60
|
type TransformOptions,
|
|
61
|
+
type VariantEntryPreset,
|
|
60
62
|
type VariantPreset,
|
|
61
63
|
} from "@nitida/asset-client";
|
|
62
64
|
|
|
@@ -203,6 +205,7 @@ export type {
|
|
|
203
205
|
AssetVariant,
|
|
204
206
|
HlsRung,
|
|
205
207
|
PaletteSwatch,
|
|
208
|
+
RequestablePreset,
|
|
206
209
|
ResolveSlotOptions,
|
|
207
210
|
SignedTransformOptions,
|
|
208
211
|
SlotDTO,
|
|
@@ -213,6 +216,7 @@ export type {
|
|
|
213
216
|
TransformGravity,
|
|
214
217
|
TransformOptions,
|
|
215
218
|
TransformWidth,
|
|
219
|
+
VariantEntryPreset,
|
|
216
220
|
VariantPreset,
|
|
217
221
|
} from "@nitida/asset-client";
|
|
218
222
|
export {
|
|
@@ -464,8 +468,11 @@ export type PresignUploadUrlOptions = {
|
|
|
464
468
|
/**
|
|
465
469
|
* Variant ladder to generate after `/assets/process`. Defaults to
|
|
466
470
|
* `["original"]` server-side when omitted — same contract as `aq.upload`.
|
|
471
|
+
*
|
|
472
|
+
* {@link RequestablePreset}, not {@link VariantPreset}: `hls` and `mp3` are
|
|
473
|
+
* things a variant can BE, never things you can ask for, and asking is a 400.
|
|
467
474
|
*/
|
|
468
|
-
presets?:
|
|
475
|
+
presets?: RequestablePreset[];
|
|
469
476
|
/**
|
|
470
477
|
* Pre-compression size of the source (useful when the browser ran
|
|
471
478
|
* compressorjs / heic2any before computing `bytes`). Recorded
|
|
@@ -646,7 +653,7 @@ class AssetsApi {
|
|
|
646
653
|
*/
|
|
647
654
|
async regenerate(
|
|
648
655
|
assetId: string,
|
|
649
|
-
opts: { presets?:
|
|
656
|
+
opts: { presets?: RequestablePreset[] } = {},
|
|
650
657
|
): Promise<RegenerateResult> {
|
|
651
658
|
const r = await fetch(
|
|
652
659
|
endpointHref(this.opts, `/assets/${assetId}/regenerate`),
|
|
@@ -945,8 +952,12 @@ export type UploadOptions = {
|
|
|
945
952
|
* Idempotent: you can always add missing variants later via
|
|
946
953
|
* `aq.assets.regenerate(id, { presets: [...] })`. The platform
|
|
947
954
|
* stores the source so regeneration doesn't require re-uploading.
|
|
955
|
+
*
|
|
956
|
+
* {@link RequestablePreset}, not {@link VariantPreset}. `hls` and `mp3` are
|
|
957
|
+
* produced FOR you — the ladder when a video transcodes, the mp3 alongside
|
|
958
|
+
* any audio original — and asking for either is a 400.
|
|
948
959
|
*/
|
|
949
|
-
presets?:
|
|
960
|
+
presets?: RequestablePreset[];
|
|
950
961
|
/**
|
|
951
962
|
* Max time to wait for the asset to transition to `ready` (or `failed`)
|
|
952
963
|
* after dispatch. Default `5 * 60_000` (5 min). Bump higher for large
|
|
@@ -973,8 +984,16 @@ export type UploadOptions = {
|
|
|
973
984
|
video?: UploadVideoOptions;
|
|
974
985
|
};
|
|
975
986
|
|
|
976
|
-
/**
|
|
977
|
-
|
|
987
|
+
/**
|
|
988
|
+
* Default preset set the SDK sends to `/assets/upload-url` when the caller
|
|
989
|
+
* omits `presets`.
|
|
990
|
+
*
|
|
991
|
+
* Typed `RequestablePreset[]`, not `VariantPreset[]` — it is a REQUEST. The
|
|
992
|
+
* distinction caught this very line the moment it was introduced: it was the
|
|
993
|
+
* wrong type here, and a `VariantPreset[]` default could have carried `hls`
|
|
994
|
+
* into a request that answers 400.
|
|
995
|
+
*/
|
|
996
|
+
const DEFAULT_UPLOAD_PRESETS: RequestablePreset[] = ["original"];
|
|
978
997
|
|
|
979
998
|
export type UploadResult = {
|
|
980
999
|
assetId: string;
|
package/src/server/index.ts
CHANGED
|
@@ -75,49 +75,93 @@ export class NitidaClient extends BaseNitidaClient {
|
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
// This subpath MIRRORS THE ROOT. Every export of `@nitida/sdk` is here.
|
|
80
|
+
//
|
|
81
|
+
// It is a COMPLETE entry point, not an additive module — a Node consumer is
|
|
82
|
+
// told to import from here and must never have to reach past it. It did:
|
|
83
|
+
// `getHlsLadder` was on the root and missing here, an example in the docs
|
|
84
|
+
// imported it from `/server`, and an agent evaluating the SDK got a
|
|
85
|
+
// SyntaxError at RUNTIME. Measured on 2026-08-21, this list was short by 28
|
|
86
|
+
// of the root's 72 — the whole palette family, every slot helper, the HLS
|
|
87
|
+
// ladder helpers and the preset constants.
|
|
88
|
+
//
|
|
89
|
+
// The completeness is now ASSERTED by scripts/check-published-doc-symbols.ts,
|
|
90
|
+
// which also owns the deny list: an omission has to be justified there, in
|
|
91
|
+
// writing, or the build fails. Do not hand-edit this list to be shorter.
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
78
93
|
export {
|
|
79
94
|
type AssetDTO,
|
|
95
|
+
type AssetPalette,
|
|
80
96
|
type AssetVariant,
|
|
97
|
+
bestTextContrast,
|
|
81
98
|
type ComposeMarketingComposition,
|
|
82
99
|
type ComposeMarketingOptions,
|
|
83
100
|
type ComposeMarketingResult,
|
|
84
101
|
type ComposeMarketingSegment,
|
|
85
102
|
type CompressOptions,
|
|
86
|
-
// URL builders & related types (re-export from asset-client via root).
|
|
87
103
|
computeVariantDimensions,
|
|
104
|
+
configureSlotResolver,
|
|
105
|
+
contrastRatio,
|
|
88
106
|
extractAssetSha,
|
|
107
|
+
getAmbientGradient,
|
|
89
108
|
getAssetDimensions,
|
|
90
109
|
getAssetSrcSet,
|
|
91
110
|
getAssetUrl,
|
|
111
|
+
getCdnBase,
|
|
112
|
+
getHlsLadder,
|
|
92
113
|
getHlsStreamingUrl,
|
|
114
|
+
getPaletteBlurBackground,
|
|
115
|
+
getPaletteCssVars,
|
|
93
116
|
getSignedTransformUrl,
|
|
94
117
|
getTenantId,
|
|
118
|
+
getTextColorForBackground,
|
|
95
119
|
getTransformSrcSet,
|
|
96
120
|
getTransformUrl,
|
|
97
121
|
getVideoTransformUrl,
|
|
122
|
+
type HlsRung,
|
|
98
123
|
hasPreset,
|
|
124
|
+
hlsLadderAlignment,
|
|
125
|
+
invalidateSlotCache,
|
|
126
|
+
iteratePaletteSwatches,
|
|
127
|
+
mimeFromFileName,
|
|
99
128
|
type NitidaClientOptions,
|
|
129
|
+
type PaletteSwatch,
|
|
130
|
+
PRESET_EXT,
|
|
131
|
+
PRESET_LONG,
|
|
132
|
+
PRESET_MAX_DIM,
|
|
133
|
+
PRESET_SHORT,
|
|
100
134
|
type PresignUploadUrlOptions,
|
|
135
|
+
pickAmbientBackground,
|
|
101
136
|
type RegenerateResult,
|
|
137
|
+
type RequestablePreset,
|
|
102
138
|
type ResolveSlotOptions,
|
|
139
|
+
relativeLuminance,
|
|
140
|
+
resolveSlot,
|
|
141
|
+
resolveSlots,
|
|
103
142
|
type SignedTransformOptions,
|
|
104
143
|
type SlotDTO,
|
|
105
144
|
type SlotHistoryEntry,
|
|
106
145
|
type SlotResolution,
|
|
107
146
|
serializeTransform,
|
|
147
|
+
setCdnBase,
|
|
108
148
|
setTenantId,
|
|
109
149
|
signTransformUrl,
|
|
150
|
+
TRANSFORM_WIDTHS,
|
|
110
151
|
type TransformEffect,
|
|
111
152
|
type TransformFit,
|
|
112
153
|
type TransformFormat,
|
|
113
154
|
type TransformGravity,
|
|
114
155
|
type TransformOptions,
|
|
156
|
+
type TransformWidth,
|
|
115
157
|
type UploadOptions,
|
|
116
158
|
type UploadResult,
|
|
117
159
|
type UploadUrlResult,
|
|
160
|
+
type UploadVideoOptions,
|
|
118
161
|
type UsageDailyPoint,
|
|
119
162
|
type UsagePerKey,
|
|
120
163
|
type UsageSnapshot,
|
|
121
164
|
type UsageWindow,
|
|
165
|
+
type VariantEntryPreset,
|
|
122
166
|
type VariantPreset,
|
|
123
167
|
} from "..";
|
package/src/web/index.ts
CHANGED
|
@@ -88,43 +88,97 @@ export class NitidaClient extends BaseNitidaClient {
|
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
//
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
// This subpath MIRRORS THE ROOT — which is what the sentence that used to sit
|
|
93
|
+
// here already promised: "browser consumers can satisfy 100% of their needs
|
|
94
|
+
// through this single subpath". Measured on 2026-08-21, it did not: this list
|
|
95
|
+
// was short by 37 of the root's 72, including every palette helper, every slot
|
|
96
|
+
// helper, the HLS ladder helpers, the preset constants and `setTenantId` —
|
|
97
|
+
// without which a browser app cannot build a video URL at all.
|
|
98
|
+
//
|
|
99
|
+
// ONE deliberate omission, and it is enforced as such rather than left to
|
|
100
|
+
// memory: `NitidaClientOptions`. That is the root options type and it CARRIES
|
|
101
|
+
// `apiKey`. The entire point of this subpath is that the apiKey-bearing shape
|
|
102
|
+
// is unreachable from browser code; `WebClientOptions` above is the one to
|
|
103
|
+
// use. Exporting the other from here is a mixed message even though the
|
|
104
|
+
// constructor would still reject it.
|
|
105
|
+
//
|
|
106
|
+
// The mirror and that single denial are both ASSERTED by
|
|
107
|
+
// scripts/check-published-doc-symbols.ts. Adding a new omission means adding a
|
|
108
|
+
// written reason there, or the build fails.
|
|
109
|
+
// ---------------------------------------------------------------------------
|
|
94
110
|
export {
|
|
95
111
|
type AssetDTO,
|
|
112
|
+
type AssetPalette,
|
|
96
113
|
type AssetVariant,
|
|
114
|
+
bestTextContrast,
|
|
115
|
+
type ComposeMarketingComposition,
|
|
116
|
+
type ComposeMarketingOptions,
|
|
117
|
+
type ComposeMarketingResult,
|
|
118
|
+
type ComposeMarketingSegment,
|
|
97
119
|
type CompressOptions as ClientCompressOptions,
|
|
98
120
|
computeVariantDimensions,
|
|
121
|
+
configureSlotResolver,
|
|
122
|
+
contrastRatio,
|
|
99
123
|
extractAssetSha,
|
|
124
|
+
getAmbientGradient,
|
|
100
125
|
getAssetDimensions,
|
|
101
126
|
getAssetSrcSet,
|
|
102
127
|
getAssetUrl,
|
|
128
|
+
getCdnBase,
|
|
129
|
+
getHlsLadder,
|
|
103
130
|
getHlsStreamingUrl,
|
|
131
|
+
getPaletteBlurBackground,
|
|
132
|
+
getPaletteCssVars,
|
|
104
133
|
getSignedTransformUrl,
|
|
134
|
+
getTenantId,
|
|
135
|
+
getTextColorForBackground,
|
|
105
136
|
getTransformSrcSet,
|
|
106
137
|
getTransformUrl,
|
|
107
138
|
getVideoTransformUrl,
|
|
139
|
+
type HlsRung,
|
|
108
140
|
hasPreset,
|
|
141
|
+
hlsLadderAlignment,
|
|
142
|
+
invalidateSlotCache,
|
|
143
|
+
iteratePaletteSwatches,
|
|
144
|
+
mimeFromFileName,
|
|
145
|
+
type PaletteSwatch,
|
|
146
|
+
PRESET_EXT,
|
|
147
|
+
PRESET_LONG,
|
|
148
|
+
PRESET_MAX_DIM,
|
|
149
|
+
PRESET_SHORT,
|
|
150
|
+
type PresignUploadUrlOptions,
|
|
151
|
+
pickAmbientBackground,
|
|
109
152
|
type RegenerateResult,
|
|
153
|
+
type RequestablePreset,
|
|
110
154
|
type ResolveSlotOptions,
|
|
155
|
+
relativeLuminance,
|
|
156
|
+
resolveSlot,
|
|
157
|
+
resolveSlots,
|
|
111
158
|
type SignedTransformOptions,
|
|
112
159
|
type SlotDTO,
|
|
113
160
|
type SlotHistoryEntry,
|
|
114
161
|
type SlotResolution,
|
|
115
162
|
serializeTransform,
|
|
163
|
+
setCdnBase,
|
|
164
|
+
setTenantId,
|
|
116
165
|
signTransformUrl,
|
|
166
|
+
TRANSFORM_WIDTHS,
|
|
117
167
|
type TransformEffect,
|
|
118
168
|
type TransformFit,
|
|
119
169
|
type TransformFormat,
|
|
120
170
|
type TransformGravity,
|
|
121
171
|
type TransformOptions,
|
|
172
|
+
type TransformWidth,
|
|
122
173
|
type UploadOptions,
|
|
123
174
|
type UploadResult,
|
|
175
|
+
type UploadUrlResult,
|
|
176
|
+
type UploadVideoOptions,
|
|
124
177
|
type UsageDailyPoint,
|
|
125
178
|
type UsagePerKey,
|
|
126
179
|
type UsageSnapshot,
|
|
127
180
|
type UsageWindow,
|
|
181
|
+
type VariantEntryPreset,
|
|
128
182
|
type VariantPreset,
|
|
129
183
|
} from "..";
|
|
130
184
|
|