samsar-js 0.48.18 → 0.48.19
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/README.md +41 -0
- package/dist/index.d.ts +81 -0
- package/dist/index.js +256 -71
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -423,6 +423,20 @@ const externalRender = await platform.createExternalVideoFromText(externalUser,
|
|
|
423
423
|
enable_subtitles: true,
|
|
424
424
|
});
|
|
425
425
|
|
|
426
|
+
// Update an external user's existing outro by generating a new QR CTA outro
|
|
427
|
+
const externalOutroUpdate = await platform.updateExternalVideoOutroImage(externalUser, {
|
|
428
|
+
request_id: externalRender.data.request_id,
|
|
429
|
+
generate_outro_image: true,
|
|
430
|
+
cta_url: 'https://example.com/shop',
|
|
431
|
+
cta_text_top: 'Scan to shop',
|
|
432
|
+
cta_text_bottom: 'Limited drop',
|
|
433
|
+
add_outro_animation: true,
|
|
434
|
+
});
|
|
435
|
+
console.log(externalOutroUpdate.data.request_id);
|
|
436
|
+
|
|
437
|
+
// Repeated video routes accept the returned extreq_ id or the normalized external id.
|
|
438
|
+
// The API resolves ownership through external request mappings and GlobalSession records.
|
|
439
|
+
|
|
426
440
|
// Run an assistant completion against one of that external user's sessions.
|
|
427
441
|
// Credits are deducted from the external user, while the owning Samsar account model config is used internally.
|
|
428
442
|
const externalAssistant = await platform.createExternalAssistantCompletion(
|
|
@@ -491,9 +505,36 @@ Video model support notes:
|
|
|
491
505
|
- `createVideoFromImageList` accepts either a provided outro (`outro_image_url`) or server-generated QR outro (`generate_outro_image: true` with `cta_url`). Do not combine the two modes in a single request.
|
|
492
506
|
- `createVideoFromImageList` can render per-scene footer QR cards by setting `add_footer_animation: true` and providing one `footer_metadata` item per image scene.
|
|
493
507
|
- `updateVideoOutroImage` accepts either a replacement outro image URL (`outro_image_url`, `outroImageUrl`, `new_outro_image_url`) or a generated QR CTA outro (`generate_outro_image: true` with `cta_url`, or just `cta_url` when no outro image URL is supplied). Generated outro updates reuse the existing session image layers for tiling and only queue frame/video regeneration.
|
|
508
|
+
- Main video methods and external-user methods accept the same generated outro and footer parameters. The API can resolve either internal session ids or external `extreq_...` ids on repeated video routes, so client code can keep using `translateVideo`, `joinVideos`, `addVideoOutroImage`, and `updateVideoOutroImage`; the explicit external variants are available when you want to call `/external_users/*` directly. Do not strip the `extreq_` prefix.
|
|
494
509
|
- `publishPublication`, `editPublication`, and `revokePublication` manage public feed publications for completed sessions through free `/publications/*` endpoints. They work with account API keys, customer sub-account API keys, and client auth tokens when the session belongs to the authenticated actor.
|
|
495
510
|
- Image-list video pricing is per rendered second: `VEO3.1I2V` and `SEEDANCEI2V` are 75 credits/sec, `KLING3.0` is 50 credits/sec, and `RUNWAYML` is 25 credits/sec.
|
|
496
511
|
|
|
512
|
+
Upcoming `/v2` omni route adapters:
|
|
513
|
+
- `/v2` is additive; `/v1` is not deprecated.
|
|
514
|
+
- `createV2VideoFromText`, `createV2VideoFromImageList`, `updateV2VideoOutroImage`, `addV2VideoOutroImage`, `getV2Status`, `getV2Credits`, `listV2Requests`, and `createV2Session` call the new omni route surface.
|
|
515
|
+
- Omit `externalUser` for internal account billing, pass `externalUser` to scope an external user with the account API key, or authenticate the client directly with an external-user auth token/API key.
|
|
516
|
+
|
|
517
|
+
```ts
|
|
518
|
+
const v2Video = await platform.createV2VideoFromImageList({
|
|
519
|
+
image_urls: ['https://cdn.example.com/a.png', 'https://cdn.example.com/b.png'],
|
|
520
|
+
video_model: 'RUNWAYML',
|
|
521
|
+
generate_outro_image: true,
|
|
522
|
+
cta_url: 'https://example.com/book',
|
|
523
|
+
cta_text_top: 'Scan to book',
|
|
524
|
+
});
|
|
525
|
+
|
|
526
|
+
const v2ExternalVideo = await platform.createV2VideoFromImageList(
|
|
527
|
+
{
|
|
528
|
+
image_urls: ['https://cdn.example.com/a.png', 'https://cdn.example.com/b.png'],
|
|
529
|
+
video_model: 'KLING3.0',
|
|
530
|
+
},
|
|
531
|
+
{ externalUser },
|
|
532
|
+
);
|
|
533
|
+
|
|
534
|
+
const v2Status = await platform.getV2Status(v2Video.data.request_id!);
|
|
535
|
+
console.log(v2Status.data.status);
|
|
536
|
+
```
|
|
537
|
+
|
|
497
538
|
Each method returns `{ data, status, headers, creditsCharged, creditsRemaining, raw }`. Non-2xx responses throw `SamsarRequestError` containing status, body, and credit headers (if present).
|
|
498
539
|
|
|
499
540
|
## Billing notes
|
package/dist/index.d.ts
CHANGED
|
@@ -224,6 +224,12 @@ export interface UpdateVideoOutroImageInput {
|
|
|
224
224
|
sessionID?: string;
|
|
225
225
|
request_id?: string;
|
|
226
226
|
requestId?: string;
|
|
227
|
+
source_request_id?: string;
|
|
228
|
+
sourceRequestId?: string;
|
|
229
|
+
external_request_id?: string;
|
|
230
|
+
externalRequestId?: string;
|
|
231
|
+
external_session_id?: string;
|
|
232
|
+
externalSessionId?: string;
|
|
227
233
|
outro_image_url?: string;
|
|
228
234
|
outroImageUrl?: string;
|
|
229
235
|
new_outro_image_url?: string;
|
|
@@ -265,6 +271,12 @@ export interface AddVideoOutroImageInput {
|
|
|
265
271
|
sessionID?: string;
|
|
266
272
|
request_id?: string;
|
|
267
273
|
requestId?: string;
|
|
274
|
+
source_request_id?: string;
|
|
275
|
+
sourceRequestId?: string;
|
|
276
|
+
external_request_id?: string;
|
|
277
|
+
externalRequestId?: string;
|
|
278
|
+
external_session_id?: string;
|
|
279
|
+
externalSessionId?: string;
|
|
268
280
|
outro_image_url?: string;
|
|
269
281
|
outroImageUrl?: string;
|
|
270
282
|
new_outro_image_url?: string;
|
|
@@ -1294,6 +1306,34 @@ export interface ExternalRequestsListResponse {
|
|
|
1294
1306
|
externalUser?: ExternalUserSummary | null;
|
|
1295
1307
|
[key: string]: unknown;
|
|
1296
1308
|
}
|
|
1309
|
+
export interface V2RequestOptions extends SamsarRequestOptions {
|
|
1310
|
+
externalUser?: ExternalUserIdentity | null;
|
|
1311
|
+
webhookUrl?: string;
|
|
1312
|
+
}
|
|
1313
|
+
export interface V2SessionResponse {
|
|
1314
|
+
account_type?: 'internal' | 'external' | string;
|
|
1315
|
+
auth_type?: string;
|
|
1316
|
+
user?: {
|
|
1317
|
+
id?: string;
|
|
1318
|
+
email?: string | null;
|
|
1319
|
+
displayName?: string | null;
|
|
1320
|
+
username?: string | null;
|
|
1321
|
+
pfpUrl?: string | null;
|
|
1322
|
+
preferredLanguage?: string | null;
|
|
1323
|
+
[key: string]: unknown;
|
|
1324
|
+
};
|
|
1325
|
+
external_api_key?: string | null;
|
|
1326
|
+
external_user?: ExternalUserSummary | null;
|
|
1327
|
+
externalUser?: ExternalUserSummary | null;
|
|
1328
|
+
remainingCredits?: number | null;
|
|
1329
|
+
[key: string]: unknown;
|
|
1330
|
+
}
|
|
1331
|
+
export interface V2RequestsListResponse {
|
|
1332
|
+
requests: Array<ExternalRequestSummary | Record<string, unknown>>;
|
|
1333
|
+
external_user?: ExternalUserSummary | null;
|
|
1334
|
+
externalUser?: ExternalUserSummary | null;
|
|
1335
|
+
[key: string]: unknown;
|
|
1336
|
+
}
|
|
1297
1337
|
export interface ExternalArchiveResponse {
|
|
1298
1338
|
request?: ExternalRequestSummary | null;
|
|
1299
1339
|
external_user?: ExternalUserSummary | null;
|
|
@@ -1483,6 +1523,32 @@ export declare class SamsarClient {
|
|
|
1483
1523
|
private readonly defaultHeaders;
|
|
1484
1524
|
private readonly externalUserApiKey?;
|
|
1485
1525
|
constructor(options: SamsarClientOptions);
|
|
1526
|
+
/**
|
|
1527
|
+
* Low-level POST adapter for the upcoming /v2 omni routes.
|
|
1528
|
+
* Pass options.externalUser to include an external_user payload; omit it for internal-account calls
|
|
1529
|
+
* or when authenticating directly with an external-user auth token/API key.
|
|
1530
|
+
*/
|
|
1531
|
+
postV2<T = Record<string, unknown>>(path: string, payload?: Record<string, unknown>, options?: V2RequestOptions): Promise<SamsarResult<T>>;
|
|
1532
|
+
/**
|
|
1533
|
+
* Low-level GET adapter for the upcoming /v2 omni routes.
|
|
1534
|
+
*/
|
|
1535
|
+
getV2<T = Record<string, unknown>>(path: string, options?: V2RequestOptions): Promise<SamsarResult<T>>;
|
|
1536
|
+
createV2Session(options?: V2RequestOptions): Promise<SamsarResult<V2SessionResponse>>;
|
|
1537
|
+
getV2Credits(options?: V2RequestOptions): Promise<SamsarResult<CreditsBalanceResponse | ExternalCreditsBalanceResponse>>;
|
|
1538
|
+
listV2Requests(options?: V2RequestOptions): Promise<SamsarResult<V2RequestsListResponse>>;
|
|
1539
|
+
createV2LoginToken(options?: V2RequestOptions & {
|
|
1540
|
+
redirect?: string;
|
|
1541
|
+
}): Promise<SamsarResult<CreateLoginTokenResponse | ExternalCreateLoginTokenResponse>>;
|
|
1542
|
+
createV2VideoFromText(input: CreateVideoFromTextInput, options?: V2RequestOptions): Promise<SamsarResult<CreateVideoResponse | ExternalRequestResponse>>;
|
|
1543
|
+
createV2VideoFromImageList(input: CreateVideoFromImageListInput, options?: V2RequestOptions): Promise<SamsarResult<CreateVideoFromImageListResponse | ExternalRequestResponse>>;
|
|
1544
|
+
uploadV2ImageData(imageData: string[], options?: V2RequestOptions): Promise<SamsarResult<{
|
|
1545
|
+
image_urls: string[];
|
|
1546
|
+
}>>;
|
|
1547
|
+
updateV2VideoOutroImage(input: UpdateVideoOutroImageInput, options?: V2RequestOptions): Promise<SamsarResult<UpdateVideoOutroImageResponse | ExternalRequestResponse>>;
|
|
1548
|
+
addV2VideoOutroImage(input: AddVideoOutroImageInput, options?: V2RequestOptions): Promise<SamsarResult<AddVideoOutroImageResponse | ExternalRequestResponse>>;
|
|
1549
|
+
getV2Status(requestId: string, options?: V2RequestOptions & {
|
|
1550
|
+
queryParams?: QueryParams;
|
|
1551
|
+
}): Promise<SamsarResult<GlobalStatusResponse | ExternalStatusResponse>>;
|
|
1486
1552
|
/**
|
|
1487
1553
|
* Create a new video generation job from text.
|
|
1488
1554
|
*/
|
|
@@ -1584,6 +1650,13 @@ export declare class SamsarClient {
|
|
|
1584
1650
|
updateVideoOutroImage(input: UpdateVideoOutroImageInput, options?: {
|
|
1585
1651
|
webhookUrl?: string;
|
|
1586
1652
|
} & SamsarRequestOptions): Promise<SamsarResult<UpdateVideoOutroImageResponse>>;
|
|
1653
|
+
/**
|
|
1654
|
+
* Update the outro image for an external-user video request by resolving the external request id
|
|
1655
|
+
* through /external_users/update_outro_image.
|
|
1656
|
+
*/
|
|
1657
|
+
updateExternalVideoOutroImage(externalUser: ExternalUserIdentity, input: UpdateVideoOutroImageInput, options?: {
|
|
1658
|
+
webhookUrl?: string;
|
|
1659
|
+
} & SamsarRequestOptions): Promise<SamsarResult<ExternalRequestResponse>>;
|
|
1587
1660
|
/**
|
|
1588
1661
|
* Add or replace the outro image for an existing video session by cloning it into a new session and
|
|
1589
1662
|
* re-running frame/video generation.
|
|
@@ -1591,6 +1664,12 @@ export declare class SamsarClient {
|
|
|
1591
1664
|
addVideoOutroImage(input: AddVideoOutroImageInput, options?: {
|
|
1592
1665
|
webhookUrl?: string;
|
|
1593
1666
|
} & SamsarRequestOptions): Promise<SamsarResult<AddVideoOutroImageResponse>>;
|
|
1667
|
+
/**
|
|
1668
|
+
* Add or replace an outro image for an external-user video request by resolving the external request id.
|
|
1669
|
+
*/
|
|
1670
|
+
addExternalVideoOutroImage(externalUser: ExternalUserIdentity, input: AddVideoOutroImageInput, options?: {
|
|
1671
|
+
webhookUrl?: string;
|
|
1672
|
+
} & SamsarRequestOptions): Promise<SamsarResult<ExternalRequestResponse>>;
|
|
1594
1673
|
/**
|
|
1595
1674
|
* Fetch the latest available render URL for a given video session id.
|
|
1596
1675
|
* Maps to GET /video/fetch_latest_version?session_id={sessionId}.
|
|
@@ -1826,5 +1905,7 @@ export declare class SamsarClient {
|
|
|
1826
1905
|
private buildHeaders;
|
|
1827
1906
|
private buildUrl;
|
|
1828
1907
|
private buildRootUrl;
|
|
1908
|
+
private withV2ExternalUser;
|
|
1909
|
+
private buildV2Url;
|
|
1829
1910
|
}
|
|
1830
1911
|
export default SamsarClient;
|
package/dist/index.js
CHANGED
|
@@ -126,6 +126,96 @@ function normalizeCreateVideoFromImageListInput(input) {
|
|
|
126
126
|
}
|
|
127
127
|
return normalized;
|
|
128
128
|
}
|
|
129
|
+
function normalizeUpdateVideoOutroImageInput(input, context = 'updateVideoOutroImage') {
|
|
130
|
+
const raw = input;
|
|
131
|
+
const videoSessionId = raw.videoSessionId ??
|
|
132
|
+
raw.video_session_id ??
|
|
133
|
+
raw.videoSessionID ??
|
|
134
|
+
raw.session_id ??
|
|
135
|
+
raw.sessionId ??
|
|
136
|
+
raw.sessionID ??
|
|
137
|
+
raw.request_id ??
|
|
138
|
+
raw.requestId ??
|
|
139
|
+
raw.source_request_id ??
|
|
140
|
+
raw.sourceRequestId ??
|
|
141
|
+
raw.external_request_id ??
|
|
142
|
+
raw.externalRequestId ??
|
|
143
|
+
raw.external_session_id ??
|
|
144
|
+
raw.externalSessionId;
|
|
145
|
+
const outroImageUrl = raw.outro_image_url ??
|
|
146
|
+
raw.outroImageUrl ??
|
|
147
|
+
raw.new_outro_image_url ??
|
|
148
|
+
raw.newOutroImageUrl;
|
|
149
|
+
const rawGenerateOutroImage = raw.generate_outro_image ??
|
|
150
|
+
raw.generateOutroImage;
|
|
151
|
+
const rawAddOutroAnimation = raw.add_outro_animation ??
|
|
152
|
+
raw.addOutroAnimation;
|
|
153
|
+
const rawAddOutroFocusArea = raw.add_outro_focus_area ??
|
|
154
|
+
raw.addOutroFocusArea;
|
|
155
|
+
const rawOutroFocusArea = raw.outro_focust_area ??
|
|
156
|
+
raw.outro_focus_area ??
|
|
157
|
+
raw.outroFocustArea ??
|
|
158
|
+
raw.outroFocusArea;
|
|
159
|
+
const ctaUrl = raw.cta_url ??
|
|
160
|
+
raw.ctaUrl;
|
|
161
|
+
const ctaTextTop = raw.cta_text_top ??
|
|
162
|
+
raw.ctaTextTop;
|
|
163
|
+
const ctaTextBottom = raw.cta_text_bottom ??
|
|
164
|
+
raw.ctaTextBottom;
|
|
165
|
+
const ctaLogo = raw.cta_logo ??
|
|
166
|
+
raw.ctaLogo;
|
|
167
|
+
const generateOutroImage = rawGenerateOutroImage === true ||
|
|
168
|
+
(rawGenerateOutroImage === undefined && !outroImageUrl && Boolean(ctaUrl));
|
|
169
|
+
if (!videoSessionId) {
|
|
170
|
+
throw new Error(`videoSessionId is required for ${context}`);
|
|
171
|
+
}
|
|
172
|
+
if (rawGenerateOutroImage !== undefined && typeof rawGenerateOutroImage !== 'boolean') {
|
|
173
|
+
throw new Error(`generate_outro_image must be a boolean for ${context}`);
|
|
174
|
+
}
|
|
175
|
+
if (rawAddOutroAnimation !== undefined && typeof rawAddOutroAnimation !== 'boolean') {
|
|
176
|
+
throw new Error(`add_outro_animation must be a boolean for ${context}`);
|
|
177
|
+
}
|
|
178
|
+
if (rawAddOutroFocusArea !== undefined && typeof rawAddOutroFocusArea !== 'boolean') {
|
|
179
|
+
throw new Error(`add_outro_focus_area must be a boolean for ${context}`);
|
|
180
|
+
}
|
|
181
|
+
if (generateOutroImage && outroImageUrl) {
|
|
182
|
+
throw new Error(`Use either generate_outro_image with cta_url or outro_image_url for ${context}`);
|
|
183
|
+
}
|
|
184
|
+
if (!generateOutroImage && !outroImageUrl) {
|
|
185
|
+
throw new Error(`outro_image_url is required for ${context} unless generate_outro_image is true`);
|
|
186
|
+
}
|
|
187
|
+
if (generateOutroImage) {
|
|
188
|
+
if (!ctaUrl || !String(ctaUrl).trim()) {
|
|
189
|
+
throw new Error(`cta_url is required when generate_outro_image is true for ${context}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
else if (rawAddOutroFocusArea === true && rawAddOutroAnimation !== true) {
|
|
193
|
+
throw new Error(`add_outro_focus_area requires add_outro_animation to be true for ${context}`);
|
|
194
|
+
}
|
|
195
|
+
if (!generateOutroImage && rawAddOutroFocusArea === true) {
|
|
196
|
+
if (!rawOutroFocusArea || typeof rawOutroFocusArea !== 'object' || Array.isArray(rawOutroFocusArea)) {
|
|
197
|
+
throw new Error(`outro_focust_area must be an object with x, y, width, height for ${context}`);
|
|
198
|
+
}
|
|
199
|
+
const { x, y, width, height } = rawOutroFocusArea;
|
|
200
|
+
const isInvalid = [x, y, width, height].some((value) => typeof value !== 'number' || !Number.isFinite(value));
|
|
201
|
+
if (isInvalid) {
|
|
202
|
+
throw new Error(`outro_focust_area x, y, width, height must be valid numbers for ${context}`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
...input,
|
|
207
|
+
videoSessionId: String(videoSessionId),
|
|
208
|
+
...(outroImageUrl ? { outro_image_url: String(outroImageUrl) } : {}),
|
|
209
|
+
generate_outro_image: generateOutroImage,
|
|
210
|
+
...(generateOutroImage ? { cta_url: String(ctaUrl).trim() } : {}),
|
|
211
|
+
...(ctaTextTop ? { cta_text_top: String(ctaTextTop) } : {}),
|
|
212
|
+
...(ctaTextBottom ? { cta_text_bottom: String(ctaTextBottom) } : {}),
|
|
213
|
+
...(ctaLogo ? { cta_logo: String(ctaLogo) } : {}),
|
|
214
|
+
...(rawAddOutroAnimation !== undefined ? { add_outro_animation: rawAddOutroAnimation === true } : {}),
|
|
215
|
+
...(rawAddOutroFocusArea !== undefined ? { add_outro_focus_area: rawAddOutroFocusArea === true } : {}),
|
|
216
|
+
...(rawOutroFocusArea !== undefined ? { outro_focust_area: rawOutroFocusArea } : {}),
|
|
217
|
+
};
|
|
218
|
+
}
|
|
129
219
|
function normalizeSessionPublicationInput(input, context) {
|
|
130
220
|
if (typeof input !== 'string' && (!input || typeof input !== 'object' || Array.isArray(input))) {
|
|
131
221
|
throw new Error(`input must be a session id or object for ${context}`);
|
|
@@ -193,6 +283,85 @@ export class SamsarClient {
|
|
|
193
283
|
throw new Error('A fetch implementation is required. Provide one via the "fetch" option when running outside environments with global fetch.');
|
|
194
284
|
}
|
|
195
285
|
}
|
|
286
|
+
/**
|
|
287
|
+
* Low-level POST adapter for the upcoming /v2 omni routes.
|
|
288
|
+
* Pass options.externalUser to include an external_user payload; omit it for internal-account calls
|
|
289
|
+
* or when authenticating directly with an external-user auth token/API key.
|
|
290
|
+
*/
|
|
291
|
+
async postV2(path, payload = {}, options) {
|
|
292
|
+
return this.post(this.buildV2Url(path), this.withV2ExternalUser(payload, options), options);
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Low-level GET adapter for the upcoming /v2 omni routes.
|
|
296
|
+
*/
|
|
297
|
+
async getV2(path, options) {
|
|
298
|
+
const query = {
|
|
299
|
+
...(options?.externalUser ? buildExternalUserQuery(options.externalUser) : {}),
|
|
300
|
+
...(options?.query ?? {}),
|
|
301
|
+
};
|
|
302
|
+
return this.get(this.buildV2Url(path), { ...(options ?? {}), query });
|
|
303
|
+
}
|
|
304
|
+
async createV2Session(options) {
|
|
305
|
+
return this.postV2('session', {}, options);
|
|
306
|
+
}
|
|
307
|
+
async getV2Credits(options) {
|
|
308
|
+
return this.getV2('credits', options);
|
|
309
|
+
}
|
|
310
|
+
async listV2Requests(options) {
|
|
311
|
+
return this.getV2('requests', options);
|
|
312
|
+
}
|
|
313
|
+
async createV2LoginToken(options) {
|
|
314
|
+
const body = options?.redirect ? { redirect: options.redirect } : {};
|
|
315
|
+
return this.postV2('create_login_token', body, options);
|
|
316
|
+
}
|
|
317
|
+
async createV2VideoFromText(input, options) {
|
|
318
|
+
const normalizedInput = normalizeCreateVideoFromTextInput(input);
|
|
319
|
+
return this.postV2('text_to_video', {
|
|
320
|
+
input: normalizedInput,
|
|
321
|
+
webhookUrl: options?.webhookUrl,
|
|
322
|
+
}, options);
|
|
323
|
+
}
|
|
324
|
+
async createV2VideoFromImageList(input, options) {
|
|
325
|
+
const normalizedInput = normalizeCreateVideoFromImageListInput(input);
|
|
326
|
+
return this.postV2('image_list_to_video', {
|
|
327
|
+
input: normalizedInput,
|
|
328
|
+
webhookUrl: options?.webhookUrl,
|
|
329
|
+
}, options);
|
|
330
|
+
}
|
|
331
|
+
async uploadV2ImageData(imageData, options) {
|
|
332
|
+
if (!Array.isArray(imageData) || imageData.length === 0) {
|
|
333
|
+
throw new Error('imageData must be a non-empty array of data URLs');
|
|
334
|
+
}
|
|
335
|
+
return this.postV2('upload_image_data', {
|
|
336
|
+
input: {
|
|
337
|
+
image_data: imageData,
|
|
338
|
+
},
|
|
339
|
+
}, options);
|
|
340
|
+
}
|
|
341
|
+
async updateV2VideoOutroImage(input, options) {
|
|
342
|
+
const normalizedInput = normalizeUpdateVideoOutroImageInput(input, 'updateV2VideoOutroImage');
|
|
343
|
+
return this.postV2('update_outro_image', {
|
|
344
|
+
input: normalizedInput,
|
|
345
|
+
webhookUrl: options?.webhookUrl,
|
|
346
|
+
}, options);
|
|
347
|
+
}
|
|
348
|
+
async addV2VideoOutroImage(input, options) {
|
|
349
|
+
return this.postV2('add_outro_image', {
|
|
350
|
+
input,
|
|
351
|
+
webhookUrl: options?.webhookUrl,
|
|
352
|
+
}, options);
|
|
353
|
+
}
|
|
354
|
+
async getV2Status(requestId, options) {
|
|
355
|
+
const queryParams = {
|
|
356
|
+
...(options?.externalUser ? buildExternalUserQuery(options.externalUser) : {}),
|
|
357
|
+
...(options?.queryParams ?? {}),
|
|
358
|
+
};
|
|
359
|
+
return this.getStatus(requestId, {
|
|
360
|
+
...options,
|
|
361
|
+
path: this.buildV2Url('status'),
|
|
362
|
+
queryParams,
|
|
363
|
+
});
|
|
364
|
+
}
|
|
196
365
|
/**
|
|
197
366
|
* Create a new video generation job from text.
|
|
198
367
|
*/
|
|
@@ -563,6 +732,50 @@ export class SamsarClient {
|
|
|
563
732
|
* only the final video render step.
|
|
564
733
|
*/
|
|
565
734
|
async updateVideoOutroImage(input, options) {
|
|
735
|
+
const normalizedInput = normalizeUpdateVideoOutroImageInput(input, 'updateVideoOutroImage');
|
|
736
|
+
const body = {
|
|
737
|
+
input: normalizedInput,
|
|
738
|
+
webhookUrl: options?.webhookUrl,
|
|
739
|
+
};
|
|
740
|
+
const response = await this.post('video/update_outro_image', body, options);
|
|
741
|
+
const data = response.data;
|
|
742
|
+
if (data && typeof data === 'object') {
|
|
743
|
+
const sessionId = typeof data.sessionID === 'string'
|
|
744
|
+
? data.sessionID
|
|
745
|
+
: typeof data.session_id === 'string'
|
|
746
|
+
? data.session_id
|
|
747
|
+
: typeof data.request_id === 'string'
|
|
748
|
+
? data.request_id
|
|
749
|
+
: undefined;
|
|
750
|
+
const normalizedSessionId = sessionId ? String(sessionId) : undefined;
|
|
751
|
+
const normalizedData = {
|
|
752
|
+
...data,
|
|
753
|
+
sessionID: data.sessionID ?? normalizedSessionId ?? '',
|
|
754
|
+
session_id: data.session_id ?? normalizedSessionId,
|
|
755
|
+
request_id: data.request_id ?? normalizedSessionId,
|
|
756
|
+
};
|
|
757
|
+
return { ...response, data: normalizedData };
|
|
758
|
+
}
|
|
759
|
+
return response;
|
|
760
|
+
}
|
|
761
|
+
/**
|
|
762
|
+
* Update the outro image for an external-user video request by resolving the external request id
|
|
763
|
+
* through /external_users/update_outro_image.
|
|
764
|
+
*/
|
|
765
|
+
async updateExternalVideoOutroImage(externalUser, input, options) {
|
|
766
|
+
const normalizedInput = normalizeUpdateVideoOutroImageInput(input, 'updateExternalVideoOutroImage');
|
|
767
|
+
const body = {
|
|
768
|
+
external_user: normalizeExternalUserIdentity(externalUser),
|
|
769
|
+
input: normalizedInput,
|
|
770
|
+
webhookUrl: options?.webhookUrl,
|
|
771
|
+
};
|
|
772
|
+
return this.post('external_users/update_outro_image', body, options);
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* Add or replace the outro image for an existing video session by cloning it into a new session and
|
|
776
|
+
* re-running frame/video generation.
|
|
777
|
+
*/
|
|
778
|
+
async addVideoOutroImage(input, options) {
|
|
566
779
|
const raw = input;
|
|
567
780
|
const videoSessionId = raw.videoSessionId ??
|
|
568
781
|
raw.video_session_id ??
|
|
@@ -576,8 +789,6 @@ export class SamsarClient {
|
|
|
576
789
|
raw.outroImageUrl ??
|
|
577
790
|
raw.new_outro_image_url ??
|
|
578
791
|
raw.newOutroImageUrl;
|
|
579
|
-
const rawGenerateOutroImage = raw.generate_outro_image ??
|
|
580
|
-
raw.generateOutroImage;
|
|
581
792
|
const rawAddOutroAnimation = raw.add_outro_animation ??
|
|
582
793
|
raw.addOutroAnimation;
|
|
583
794
|
const rawAddOutroFocusArea = raw.add_outro_focus_area ??
|
|
@@ -586,69 +797,43 @@ export class SamsarClient {
|
|
|
586
797
|
raw.outro_focus_area ??
|
|
587
798
|
raw.outroFocustArea ??
|
|
588
799
|
raw.outroFocusArea;
|
|
589
|
-
const ctaUrl = raw.cta_url ??
|
|
590
|
-
raw.ctaUrl;
|
|
591
|
-
const ctaTextTop = raw.cta_text_top ??
|
|
592
|
-
raw.ctaTextTop;
|
|
593
|
-
const ctaTextBottom = raw.cta_text_bottom ??
|
|
594
|
-
raw.ctaTextBottom;
|
|
595
|
-
const ctaLogo = raw.cta_logo ??
|
|
596
|
-
raw.ctaLogo;
|
|
597
|
-
const generateOutroImage = rawGenerateOutroImage === true ||
|
|
598
|
-
(rawGenerateOutroImage === undefined && !outroImageUrl && Boolean(ctaUrl));
|
|
599
800
|
if (!videoSessionId) {
|
|
600
|
-
throw new Error('videoSessionId is required for
|
|
801
|
+
throw new Error('videoSessionId is required for addVideoOutroImage');
|
|
601
802
|
}
|
|
602
|
-
if (
|
|
603
|
-
throw new Error('
|
|
803
|
+
if (!outroImageUrl) {
|
|
804
|
+
throw new Error('outro_image_url is required for addVideoOutroImage');
|
|
604
805
|
}
|
|
605
806
|
if (rawAddOutroAnimation !== undefined && typeof rawAddOutroAnimation !== 'boolean') {
|
|
606
|
-
throw new Error('add_outro_animation must be a boolean for
|
|
807
|
+
throw new Error('add_outro_animation must be a boolean for addVideoOutroImage');
|
|
607
808
|
}
|
|
608
809
|
if (rawAddOutroFocusArea !== undefined && typeof rawAddOutroFocusArea !== 'boolean') {
|
|
609
|
-
throw new Error('add_outro_focus_area must be a boolean for
|
|
610
|
-
}
|
|
611
|
-
if (generateOutroImage && outroImageUrl) {
|
|
612
|
-
throw new Error('Use either generate_outro_image with cta_url or outro_image_url for updateVideoOutroImage');
|
|
613
|
-
}
|
|
614
|
-
if (!generateOutroImage && !outroImageUrl) {
|
|
615
|
-
throw new Error('outro_image_url is required for updateVideoOutroImage unless generate_outro_image is true');
|
|
616
|
-
}
|
|
617
|
-
if (generateOutroImage) {
|
|
618
|
-
if (!ctaUrl || !String(ctaUrl).trim()) {
|
|
619
|
-
throw new Error('cta_url is required when generate_outro_image is true for updateVideoOutroImage');
|
|
620
|
-
}
|
|
810
|
+
throw new Error('add_outro_focus_area must be a boolean for addVideoOutroImage');
|
|
621
811
|
}
|
|
622
|
-
|
|
623
|
-
throw new Error('add_outro_focus_area requires add_outro_animation to be true for
|
|
812
|
+
if (rawAddOutroFocusArea === true && rawAddOutroAnimation !== true) {
|
|
813
|
+
throw new Error('add_outro_focus_area requires add_outro_animation to be true for addVideoOutroImage');
|
|
624
814
|
}
|
|
625
|
-
if (
|
|
815
|
+
if (rawAddOutroFocusArea === true) {
|
|
626
816
|
if (!rawOutroFocusArea || typeof rawOutroFocusArea !== 'object' || Array.isArray(rawOutroFocusArea)) {
|
|
627
|
-
throw new Error('outro_focust_area must be an object with x, y, width, height for
|
|
817
|
+
throw new Error('outro_focust_area must be an object with x, y, width, height for addVideoOutroImage');
|
|
628
818
|
}
|
|
629
819
|
const { x, y, width, height } = rawOutroFocusArea;
|
|
630
820
|
const isInvalid = [x, y, width, height].some((value) => typeof value !== 'number' || !Number.isFinite(value));
|
|
631
821
|
if (isInvalid) {
|
|
632
|
-
throw new Error('outro_focust_area x, y, width, height must be valid numbers for
|
|
822
|
+
throw new Error('outro_focust_area x, y, width, height must be valid numbers for addVideoOutroImage');
|
|
633
823
|
}
|
|
634
824
|
}
|
|
635
825
|
const body = {
|
|
636
826
|
input: {
|
|
637
827
|
...input,
|
|
638
828
|
videoSessionId: String(videoSessionId),
|
|
639
|
-
|
|
640
|
-
generate_outro_image: generateOutroImage,
|
|
641
|
-
...(generateOutroImage ? { cta_url: String(ctaUrl).trim() } : {}),
|
|
642
|
-
...(ctaTextTop ? { cta_text_top: String(ctaTextTop) } : {}),
|
|
643
|
-
...(ctaTextBottom ? { cta_text_bottom: String(ctaTextBottom) } : {}),
|
|
644
|
-
...(ctaLogo ? { cta_logo: String(ctaLogo) } : {}),
|
|
829
|
+
outro_image_url: String(outroImageUrl),
|
|
645
830
|
...(rawAddOutroAnimation !== undefined ? { add_outro_animation: rawAddOutroAnimation === true } : {}),
|
|
646
831
|
...(rawAddOutroFocusArea !== undefined ? { add_outro_focus_area: rawAddOutroFocusArea === true } : {}),
|
|
647
832
|
...(rawOutroFocusArea !== undefined ? { outro_focust_area: rawOutroFocusArea } : {}),
|
|
648
833
|
},
|
|
649
834
|
webhookUrl: options?.webhookUrl,
|
|
650
835
|
};
|
|
651
|
-
const response = await this.post('video/
|
|
836
|
+
const response = await this.post('video/add_outro_image', body, options);
|
|
652
837
|
const data = response.data;
|
|
653
838
|
if (data && typeof data === 'object') {
|
|
654
839
|
const sessionId = typeof data.sessionID === 'string'
|
|
@@ -670,10 +855,9 @@ export class SamsarClient {
|
|
|
670
855
|
return response;
|
|
671
856
|
}
|
|
672
857
|
/**
|
|
673
|
-
* Add or replace
|
|
674
|
-
* re-running frame/video generation.
|
|
858
|
+
* Add or replace an outro image for an external-user video request by resolving the external request id.
|
|
675
859
|
*/
|
|
676
|
-
async
|
|
860
|
+
async addExternalVideoOutroImage(externalUser, input, options) {
|
|
677
861
|
const raw = input;
|
|
678
862
|
const videoSessionId = raw.videoSessionId ??
|
|
679
863
|
raw.video_session_id ??
|
|
@@ -682,7 +866,13 @@ export class SamsarClient {
|
|
|
682
866
|
raw.sessionId ??
|
|
683
867
|
raw.sessionID ??
|
|
684
868
|
raw.request_id ??
|
|
685
|
-
raw.requestId
|
|
869
|
+
raw.requestId ??
|
|
870
|
+
raw.source_request_id ??
|
|
871
|
+
raw.sourceRequestId ??
|
|
872
|
+
raw.external_request_id ??
|
|
873
|
+
raw.externalRequestId ??
|
|
874
|
+
raw.external_session_id ??
|
|
875
|
+
raw.externalSessionId;
|
|
686
876
|
const outroImageUrl = raw.outro_image_url ??
|
|
687
877
|
raw.outroImageUrl ??
|
|
688
878
|
raw.new_outro_image_url ??
|
|
@@ -696,31 +886,32 @@ export class SamsarClient {
|
|
|
696
886
|
raw.outroFocustArea ??
|
|
697
887
|
raw.outroFocusArea;
|
|
698
888
|
if (!videoSessionId) {
|
|
699
|
-
throw new Error('videoSessionId is required for
|
|
889
|
+
throw new Error('videoSessionId is required for addExternalVideoOutroImage');
|
|
700
890
|
}
|
|
701
891
|
if (!outroImageUrl) {
|
|
702
|
-
throw new Error('outro_image_url is required for
|
|
892
|
+
throw new Error('outro_image_url is required for addExternalVideoOutroImage');
|
|
703
893
|
}
|
|
704
894
|
if (rawAddOutroAnimation !== undefined && typeof rawAddOutroAnimation !== 'boolean') {
|
|
705
|
-
throw new Error('add_outro_animation must be a boolean for
|
|
895
|
+
throw new Error('add_outro_animation must be a boolean for addExternalVideoOutroImage');
|
|
706
896
|
}
|
|
707
897
|
if (rawAddOutroFocusArea !== undefined && typeof rawAddOutroFocusArea !== 'boolean') {
|
|
708
|
-
throw new Error('add_outro_focus_area must be a boolean for
|
|
898
|
+
throw new Error('add_outro_focus_area must be a boolean for addExternalVideoOutroImage');
|
|
709
899
|
}
|
|
710
900
|
if (rawAddOutroFocusArea === true && rawAddOutroAnimation !== true) {
|
|
711
|
-
throw new Error('add_outro_focus_area requires add_outro_animation to be true for
|
|
901
|
+
throw new Error('add_outro_focus_area requires add_outro_animation to be true for addExternalVideoOutroImage');
|
|
712
902
|
}
|
|
713
903
|
if (rawAddOutroFocusArea === true) {
|
|
714
904
|
if (!rawOutroFocusArea || typeof rawOutroFocusArea !== 'object' || Array.isArray(rawOutroFocusArea)) {
|
|
715
|
-
throw new Error('outro_focust_area must be an object with x, y, width, height for
|
|
905
|
+
throw new Error('outro_focust_area must be an object with x, y, width, height for addExternalVideoOutroImage');
|
|
716
906
|
}
|
|
717
907
|
const { x, y, width, height } = rawOutroFocusArea;
|
|
718
908
|
const isInvalid = [x, y, width, height].some((value) => typeof value !== 'number' || !Number.isFinite(value));
|
|
719
909
|
if (isInvalid) {
|
|
720
|
-
throw new Error('outro_focust_area x, y, width, height must be valid numbers for
|
|
910
|
+
throw new Error('outro_focust_area x, y, width, height must be valid numbers for addExternalVideoOutroImage');
|
|
721
911
|
}
|
|
722
912
|
}
|
|
723
913
|
const body = {
|
|
914
|
+
external_user: normalizeExternalUserIdentity(externalUser),
|
|
724
915
|
input: {
|
|
725
916
|
...input,
|
|
726
917
|
videoSessionId: String(videoSessionId),
|
|
@@ -731,26 +922,7 @@ export class SamsarClient {
|
|
|
731
922
|
},
|
|
732
923
|
webhookUrl: options?.webhookUrl,
|
|
733
924
|
};
|
|
734
|
-
|
|
735
|
-
const data = response.data;
|
|
736
|
-
if (data && typeof data === 'object') {
|
|
737
|
-
const sessionId = typeof data.sessionID === 'string'
|
|
738
|
-
? data.sessionID
|
|
739
|
-
: typeof data.session_id === 'string'
|
|
740
|
-
? data.session_id
|
|
741
|
-
: typeof data.request_id === 'string'
|
|
742
|
-
? data.request_id
|
|
743
|
-
: undefined;
|
|
744
|
-
const normalizedSessionId = sessionId ? String(sessionId) : undefined;
|
|
745
|
-
const normalizedData = {
|
|
746
|
-
...data,
|
|
747
|
-
sessionID: data.sessionID ?? normalizedSessionId ?? '',
|
|
748
|
-
session_id: data.session_id ?? normalizedSessionId,
|
|
749
|
-
request_id: data.request_id ?? normalizedSessionId,
|
|
750
|
-
};
|
|
751
|
-
return { ...response, data: normalizedData };
|
|
752
|
-
}
|
|
753
|
-
return response;
|
|
925
|
+
return this.post('external_users/add_outro_image', body, options);
|
|
754
926
|
}
|
|
755
927
|
/**
|
|
756
928
|
* Fetch the latest available render URL for a given video session id.
|
|
@@ -1478,6 +1650,19 @@ export class SamsarClient {
|
|
|
1478
1650
|
const rootUrl = baseUrl.endsWith('/v1') ? baseUrl.slice(0, -3) : baseUrl;
|
|
1479
1651
|
return `${rootUrl}/${cleanedPath}`;
|
|
1480
1652
|
}
|
|
1653
|
+
withV2ExternalUser(body, options) {
|
|
1654
|
+
if (!options?.externalUser) {
|
|
1655
|
+
return body;
|
|
1656
|
+
}
|
|
1657
|
+
return {
|
|
1658
|
+
...body,
|
|
1659
|
+
external_user: normalizeExternalUserIdentity(options.externalUser),
|
|
1660
|
+
};
|
|
1661
|
+
}
|
|
1662
|
+
buildV2Url(path) {
|
|
1663
|
+
const cleanedPath = path.replace(/^\/+/, '');
|
|
1664
|
+
return this.buildRootUrl(`v2/${cleanedPath}`);
|
|
1665
|
+
}
|
|
1481
1666
|
}
|
|
1482
1667
|
function trimTrailingSlash(url) {
|
|
1483
1668
|
return url.replace(/\/+$/, '');
|