samsar-js 0.48.16 → 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 +102 -0
- package/dist/index.d.ts +240 -0
- package/dist/index.js +412 -28
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -43,6 +43,21 @@ const video = await samsar.createVideoFromText(
|
|
|
43
43
|
{ webhookUrl: 'https://example.com/webhook' },
|
|
44
44
|
);
|
|
45
45
|
|
|
46
|
+
// Create a text video with a generated QR outro and bottom CTA footer
|
|
47
|
+
await samsar.createVideoFromText({
|
|
48
|
+
prompt: 'A boutique hotel launch reel with cinematic room details',
|
|
49
|
+
image_model: 'GPTIMAGE2',
|
|
50
|
+
video_model: 'RUNWAYML',
|
|
51
|
+
duration: 20,
|
|
52
|
+
aspect_ratio: '9:16',
|
|
53
|
+
generate_outro_image: true,
|
|
54
|
+
cta_url: 'https://example.com/book',
|
|
55
|
+
cta_text_top: 'Scan to book',
|
|
56
|
+
cta_text_bottom: 'Opening offers',
|
|
57
|
+
add_footer_animation: true,
|
|
58
|
+
footer_metadata: [{ url: 'https://example.com/book', title: 'Book your stay' }],
|
|
59
|
+
});
|
|
60
|
+
|
|
46
61
|
// Create a video from an image list
|
|
47
62
|
const videoFromImages = await samsar.createVideoFromImageList(
|
|
48
63
|
{
|
|
@@ -91,6 +106,31 @@ await samsar.createVideoFromImageList({
|
|
|
91
106
|
],
|
|
92
107
|
});
|
|
93
108
|
|
|
109
|
+
// Update an existing outro with a new provided outro image URL
|
|
110
|
+
await samsar.updateVideoOutroImage(
|
|
111
|
+
{
|
|
112
|
+
videoSessionId: videoFromImages.data.session_id ?? videoFromImages.data.request_id!,
|
|
113
|
+
outro_image_url: 'https://cdn.example.com/outro-v2.png',
|
|
114
|
+
add_outro_animation: true,
|
|
115
|
+
add_outro_focus_area: true,
|
|
116
|
+
outro_focust_area: { x: 680, y: 296, width: 432, height: 432 },
|
|
117
|
+
},
|
|
118
|
+
{ webhookUrl: 'https://example.com/webhook' },
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
// Update an existing outro by generating a new QR CTA outro server-side
|
|
122
|
+
await samsar.updateVideoOutroImage(
|
|
123
|
+
{
|
|
124
|
+
videoSessionId: videoFromImages.data.session_id ?? videoFromImages.data.request_id!,
|
|
125
|
+
generate_outro_image: true,
|
|
126
|
+
cta_url: 'https://example.com/book',
|
|
127
|
+
cta_text_top: 'Scan to book',
|
|
128
|
+
cta_text_bottom: 'Limited availability',
|
|
129
|
+
add_outro_animation: true,
|
|
130
|
+
},
|
|
131
|
+
{ webhookUrl: 'https://example.com/webhook' },
|
|
132
|
+
);
|
|
133
|
+
|
|
94
134
|
// Translate an existing video session into another language
|
|
95
135
|
const translated = await samsar.translateVideo(
|
|
96
136
|
{
|
|
@@ -302,6 +342,24 @@ completedSessions.data.forEach((session) => {
|
|
|
302
342
|
console.log(session.session_id, session.langauge, session.result_url);
|
|
303
343
|
});
|
|
304
344
|
|
|
345
|
+
// Publish, edit, or revoke a completed session in the public publication feed (free endpoints)
|
|
346
|
+
const publication = await samsar.publishPublication({
|
|
347
|
+
session_id: videoFromImages.data.session_id ?? videoFromImages.data.request_id!,
|
|
348
|
+
title: 'Running shoe teaser',
|
|
349
|
+
description: 'Launch-day vertical cut',
|
|
350
|
+
tags: ['launch', 'footwear'],
|
|
351
|
+
creator_handle: 'acme',
|
|
352
|
+
});
|
|
353
|
+
console.log(publication.data.publication?.publication_id);
|
|
354
|
+
|
|
355
|
+
await samsar.editPublication({
|
|
356
|
+
session_id: videoFromImages.data.session_id ?? videoFromImages.data.request_id!,
|
|
357
|
+
title: 'Running shoe teaser - updated',
|
|
358
|
+
tags: ['launch', 'footwear', 'campaign'],
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
await samsar.revokePublication(videoFromImages.data.session_id ?? videoFromImages.data.request_id!);
|
|
362
|
+
|
|
305
363
|
// Image-specific status endpoint
|
|
306
364
|
const rollupStatus = await samsar.getImageStatus(rollup.data.session_id);
|
|
307
365
|
|
|
@@ -365,6 +423,20 @@ const externalRender = await platform.createExternalVideoFromText(externalUser,
|
|
|
365
423
|
enable_subtitles: true,
|
|
366
424
|
});
|
|
367
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
|
+
|
|
368
440
|
// Run an assistant completion against one of that external user's sessions.
|
|
369
441
|
// Credits are deducted from the external user, while the owning Samsar account model config is used internally.
|
|
370
442
|
const externalAssistant = await platform.createExternalAssistantCompletion(
|
|
@@ -428,11 +500,41 @@ console.log(externalLibrary.data.requests.map((request) => request.request_id));
|
|
|
428
500
|
Video model support notes:
|
|
429
501
|
- `createVideoFromText` image model keys include: `GPTIMAGE2`, `IMAGEN4`, `SEEDREAM`, `HUNYUAN`, `NANOBANANA2`.
|
|
430
502
|
- `createVideoFromText` supports all express video models: `RUNWAYML`, `KLINGIMGTOVID3PRO`, `HAILUO`, `HAILUOPRO`, `SEEDANCEI2V` (Seedance 2.0), `VEO3.1I2V`, `VEO3.1I2VFAST`, `SORA2`, `SORA2PRO`.
|
|
503
|
+
- `createVideoFromText` accepts either a provided outro (`outro_image_url`) or server-generated QR outro (`generate_outro_image: true` with `cta_url`). It can also render bottom CTA footer QR cards with `add_footer_animation` and `footer_metadata`; one footer item applies to every generated scene, while multiple items map by scene index.
|
|
431
504
|
- `createVideoFromImageList` supports `VEO3.1I2V`, `SEEDANCEI2V`, `KLING3.0`, and `RUNWAYML` via `video_model`; if omitted, it defaults to `VEO3.1I2V`. `KLINGIMGTOVID3PRO` is also accepted as a compatibility alias for `KLING3.0`. Use `aspect_ratio: '16:9'` or `'9:16'`; omitted or invalid values fall back to `16:9`.
|
|
432
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.
|
|
433
506
|
- `createVideoFromImageList` can render per-scene footer QR cards by setting `add_footer_animation: true` and providing one `footer_metadata` item per image scene.
|
|
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.
|
|
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.
|
|
434
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.
|
|
435
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
|
+
|
|
436
538
|
Each method returns `{ data, status, headers, creditsCharged, creditsRemaining, raw }`. Non-2xx responses throw `SamsarRequestError` containing status, body, and credit headers (if present).
|
|
437
539
|
|
|
438
540
|
## Billing notes
|
package/dist/index.d.ts
CHANGED
|
@@ -50,6 +50,30 @@ export interface CreateVideoFromTextInput {
|
|
|
50
50
|
session_id?: string;
|
|
51
51
|
sessionId?: string;
|
|
52
52
|
sessionID?: string;
|
|
53
|
+
outro_image_url?: string;
|
|
54
|
+
outroImageUrl?: string;
|
|
55
|
+
add_outro_animation?: boolean;
|
|
56
|
+
addOutroAnimation?: boolean;
|
|
57
|
+
add_outro_focus_area?: boolean;
|
|
58
|
+
addOutroFocusArea?: boolean;
|
|
59
|
+
outro_focust_area?: OutroFocusArea | null;
|
|
60
|
+
outro_focus_area?: OutroFocusArea | null;
|
|
61
|
+
outroFocustArea?: OutroFocusArea | null;
|
|
62
|
+
outroFocusArea?: OutroFocusArea | null;
|
|
63
|
+
generate_outro_image?: boolean;
|
|
64
|
+
generateOutroImage?: boolean;
|
|
65
|
+
cta_url?: string;
|
|
66
|
+
ctaUrl?: string;
|
|
67
|
+
cta_text_top?: string;
|
|
68
|
+
ctaTextTop?: string;
|
|
69
|
+
cta_text_bottom?: string;
|
|
70
|
+
ctaTextBottom?: string;
|
|
71
|
+
cta_logo?: string;
|
|
72
|
+
ctaLogo?: string;
|
|
73
|
+
add_footer_animation?: boolean;
|
|
74
|
+
addFooterAnimation?: boolean;
|
|
75
|
+
footer_metadata?: FooterMetadataItem[];
|
|
76
|
+
footerMetadata?: FooterMetadataItem[];
|
|
53
77
|
[key: string]: unknown;
|
|
54
78
|
}
|
|
55
79
|
export interface CreateVideoResponse {
|
|
@@ -200,10 +224,34 @@ export interface UpdateVideoOutroImageInput {
|
|
|
200
224
|
sessionID?: string;
|
|
201
225
|
request_id?: string;
|
|
202
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;
|
|
203
233
|
outro_image_url?: string;
|
|
204
234
|
outroImageUrl?: string;
|
|
205
235
|
new_outro_image_url?: string;
|
|
206
236
|
newOutroImageUrl?: string;
|
|
237
|
+
add_outro_animation?: boolean;
|
|
238
|
+
addOutroAnimation?: boolean;
|
|
239
|
+
add_outro_focus_area?: boolean;
|
|
240
|
+
addOutroFocusArea?: boolean;
|
|
241
|
+
outro_focust_area?: OutroFocusArea | null;
|
|
242
|
+
outro_focus_area?: OutroFocusArea | null;
|
|
243
|
+
outroFocustArea?: OutroFocusArea | null;
|
|
244
|
+
outroFocusArea?: OutroFocusArea | null;
|
|
245
|
+
generate_outro_image?: boolean;
|
|
246
|
+
generateOutroImage?: boolean;
|
|
247
|
+
cta_url?: string;
|
|
248
|
+
ctaUrl?: string;
|
|
249
|
+
cta_text_top?: string;
|
|
250
|
+
ctaTextTop?: string;
|
|
251
|
+
cta_text_bottom?: string;
|
|
252
|
+
ctaTextBottom?: string;
|
|
253
|
+
cta_logo?: string;
|
|
254
|
+
ctaLogo?: string;
|
|
207
255
|
[key: string]: unknown;
|
|
208
256
|
}
|
|
209
257
|
export interface UpdateVideoOutroImageResponse {
|
|
@@ -223,6 +271,12 @@ export interface AddVideoOutroImageInput {
|
|
|
223
271
|
sessionID?: string;
|
|
224
272
|
request_id?: string;
|
|
225
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;
|
|
226
280
|
outro_image_url?: string;
|
|
227
281
|
outroImageUrl?: string;
|
|
228
282
|
new_outro_image_url?: string;
|
|
@@ -316,6 +370,96 @@ export interface CompletedVideoSession {
|
|
|
316
370
|
[key: string]: unknown;
|
|
317
371
|
}
|
|
318
372
|
export type ListCompletedVideoSessionsResponse = CompletedVideoSession[];
|
|
373
|
+
export interface SessionPublicationInput {
|
|
374
|
+
session_id?: string;
|
|
375
|
+
sessionId?: string;
|
|
376
|
+
sessionID?: string;
|
|
377
|
+
video_session_id?: string;
|
|
378
|
+
videoSessionId?: string;
|
|
379
|
+
videoSessionID?: string;
|
|
380
|
+
id?: string;
|
|
381
|
+
title?: string;
|
|
382
|
+
description?: string;
|
|
383
|
+
tags?: string[] | string;
|
|
384
|
+
aspect_ratio?: string;
|
|
385
|
+
aspectRatio?: string;
|
|
386
|
+
creator_handle?: string;
|
|
387
|
+
creatorHandle?: string;
|
|
388
|
+
slug?: string;
|
|
389
|
+
image_hash?: string;
|
|
390
|
+
imageHash?: string;
|
|
391
|
+
splash_image?: string;
|
|
392
|
+
splashImage?: string;
|
|
393
|
+
image_model?: string;
|
|
394
|
+
imageModel?: string;
|
|
395
|
+
video_model?: string;
|
|
396
|
+
videoModel?: string;
|
|
397
|
+
original_prompt?: string;
|
|
398
|
+
originalPrompt?: string;
|
|
399
|
+
prompt?: string;
|
|
400
|
+
session_language?: string;
|
|
401
|
+
sessionLanguage?: string;
|
|
402
|
+
language?: string;
|
|
403
|
+
language_code?: string;
|
|
404
|
+
languageString?: string;
|
|
405
|
+
language_string?: string;
|
|
406
|
+
[key: string]: unknown;
|
|
407
|
+
}
|
|
408
|
+
export interface SessionPublicationSummary {
|
|
409
|
+
id?: string | null;
|
|
410
|
+
publication_id?: string | null;
|
|
411
|
+
session_id?: string | null;
|
|
412
|
+
sessionId?: string | null;
|
|
413
|
+
video_url?: string | null;
|
|
414
|
+
videoUrl?: string | null;
|
|
415
|
+
title?: string | null;
|
|
416
|
+
description?: string;
|
|
417
|
+
tags?: string[];
|
|
418
|
+
creator_handle?: string;
|
|
419
|
+
creatorHandle?: string;
|
|
420
|
+
slug?: string | null;
|
|
421
|
+
image_hash?: string | null;
|
|
422
|
+
imageHash?: string | null;
|
|
423
|
+
splash_image?: string | null;
|
|
424
|
+
splashImage?: string | null;
|
|
425
|
+
image_model?: string | null;
|
|
426
|
+
imageModel?: string | null;
|
|
427
|
+
video_model?: string | null;
|
|
428
|
+
videoModel?: string | null;
|
|
429
|
+
original_prompt?: string;
|
|
430
|
+
originalPrompt?: string;
|
|
431
|
+
session_language?: string | null;
|
|
432
|
+
sessionLanguage?: string | null;
|
|
433
|
+
language_string?: string | null;
|
|
434
|
+
languageString?: string | null;
|
|
435
|
+
aspect_ratio?: string | null;
|
|
436
|
+
aspectRatio?: string | null;
|
|
437
|
+
created_at?: string | null;
|
|
438
|
+
createdAt?: string | null;
|
|
439
|
+
updated_at?: string | null;
|
|
440
|
+
updatedAt?: string | null;
|
|
441
|
+
[key: string]: unknown;
|
|
442
|
+
}
|
|
443
|
+
export interface SessionPublicationSessionSummary {
|
|
444
|
+
id?: string | null;
|
|
445
|
+
session_id?: string | null;
|
|
446
|
+
is_published?: boolean;
|
|
447
|
+
published_publication_id?: string | null;
|
|
448
|
+
published_video_url?: string | null;
|
|
449
|
+
published_at?: string | null;
|
|
450
|
+
[key: string]: unknown;
|
|
451
|
+
}
|
|
452
|
+
export interface SessionPublicationResponse {
|
|
453
|
+
created?: boolean;
|
|
454
|
+
revoked?: boolean;
|
|
455
|
+
publication_id?: string | null;
|
|
456
|
+
publication?: SessionPublicationSummary | null;
|
|
457
|
+
session?: SessionPublicationSessionSummary | null;
|
|
458
|
+
sessionId?: string;
|
|
459
|
+
session_id?: string;
|
|
460
|
+
ispublishedVideo?: boolean;
|
|
461
|
+
[key: string]: unknown;
|
|
462
|
+
}
|
|
319
463
|
export interface SupportedTextToVideoModelsResponse {
|
|
320
464
|
IMAGE_MODELS: SupportedTextToVideoModelOption[];
|
|
321
465
|
VIDEO_MODELS: SupportedTextToVideoModelOption[];
|
|
@@ -1162,6 +1306,34 @@ export interface ExternalRequestsListResponse {
|
|
|
1162
1306
|
externalUser?: ExternalUserSummary | null;
|
|
1163
1307
|
[key: string]: unknown;
|
|
1164
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
|
+
}
|
|
1165
1337
|
export interface ExternalArchiveResponse {
|
|
1166
1338
|
request?: ExternalRequestSummary | null;
|
|
1167
1339
|
external_user?: ExternalUserSummary | null;
|
|
@@ -1351,6 +1523,32 @@ export declare class SamsarClient {
|
|
|
1351
1523
|
private readonly defaultHeaders;
|
|
1352
1524
|
private readonly externalUserApiKey?;
|
|
1353
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>>;
|
|
1354
1552
|
/**
|
|
1355
1553
|
* Create a new video generation job from text.
|
|
1356
1554
|
*/
|
|
@@ -1452,6 +1650,13 @@ export declare class SamsarClient {
|
|
|
1452
1650
|
updateVideoOutroImage(input: UpdateVideoOutroImageInput, options?: {
|
|
1453
1651
|
webhookUrl?: string;
|
|
1454
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>>;
|
|
1455
1660
|
/**
|
|
1456
1661
|
* Add or replace the outro image for an existing video session by cloning it into a new session and
|
|
1457
1662
|
* re-running frame/video generation.
|
|
@@ -1459,6 +1664,12 @@ export declare class SamsarClient {
|
|
|
1459
1664
|
addVideoOutroImage(input: AddVideoOutroImageInput, options?: {
|
|
1460
1665
|
webhookUrl?: string;
|
|
1461
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>>;
|
|
1462
1673
|
/**
|
|
1463
1674
|
* Fetch the latest available render URL for a given video session id.
|
|
1464
1675
|
* Maps to GET /video/fetch_latest_version?session_id={sessionId}.
|
|
@@ -1471,6 +1682,33 @@ export declare class SamsarClient {
|
|
|
1471
1682
|
listCompletedVideoSessions(options?: SamsarRequestOptions & {
|
|
1472
1683
|
limit?: number;
|
|
1473
1684
|
}): Promise<SamsarResult<ListCompletedVideoSessionsResponse>>;
|
|
1685
|
+
/**
|
|
1686
|
+
* Publish a completed Samsar video session to the public publication feed.
|
|
1687
|
+
* This is a free endpoint. The session must belong to the authenticated API key/auth token.
|
|
1688
|
+
*/
|
|
1689
|
+
publishPublication(input: string | SessionPublicationInput, options?: SamsarRequestOptions): Promise<SamsarResult<SessionPublicationResponse>>;
|
|
1690
|
+
/**
|
|
1691
|
+
* Alias for publishPublication, named around the underlying VideoSession resource.
|
|
1692
|
+
*/
|
|
1693
|
+
publishSessionPublication(input: string | SessionPublicationInput, options?: SamsarRequestOptions): Promise<SamsarResult<SessionPublicationResponse>>;
|
|
1694
|
+
/**
|
|
1695
|
+
* Edit an existing publication for a Samsar video session.
|
|
1696
|
+
* Omitted fields keep their current publication values.
|
|
1697
|
+
*/
|
|
1698
|
+
editPublication(input: SessionPublicationInput, options?: SamsarRequestOptions): Promise<SamsarResult<SessionPublicationResponse>>;
|
|
1699
|
+
/**
|
|
1700
|
+
* Alias for editPublication, named around the underlying VideoSession resource.
|
|
1701
|
+
*/
|
|
1702
|
+
editSessionPublication(input: SessionPublicationInput, options?: SamsarRequestOptions): Promise<SamsarResult<SessionPublicationResponse>>;
|
|
1703
|
+
/**
|
|
1704
|
+
* Revoke a publication for a Samsar video session.
|
|
1705
|
+
* This deletes the publication record and clears published fields on the session.
|
|
1706
|
+
*/
|
|
1707
|
+
revokePublication(input: string | SessionPublicationInput, options?: SamsarRequestOptions): Promise<SamsarResult<SessionPublicationResponse>>;
|
|
1708
|
+
/**
|
|
1709
|
+
* Alias for revokePublication, named around the underlying VideoSession resource.
|
|
1710
|
+
*/
|
|
1711
|
+
revokeSessionPublication(input: string | SessionPublicationInput, options?: SamsarRequestOptions): Promise<SamsarResult<SessionPublicationResponse>>;
|
|
1474
1712
|
/**
|
|
1475
1713
|
* Fetch the supported image/video model keys for the text_to_video route.
|
|
1476
1714
|
* Maps to GET /video/supported_models.
|
|
@@ -1667,5 +1905,7 @@ export declare class SamsarClient {
|
|
|
1667
1905
|
private buildHeaders;
|
|
1668
1906
|
private buildUrl;
|
|
1669
1907
|
private buildRootUrl;
|
|
1908
|
+
private withV2ExternalUser;
|
|
1909
|
+
private buildV2Url;
|
|
1670
1910
|
}
|
|
1671
1911
|
export default SamsarClient;
|
package/dist/index.js
CHANGED
|
@@ -34,11 +34,53 @@ function resolveAliasedInputValue(raw, aliases, canonicalName) {
|
|
|
34
34
|
}
|
|
35
35
|
return hasResolved ? resolved : undefined;
|
|
36
36
|
}
|
|
37
|
-
function assertOptionalBoolean(value, fieldName) {
|
|
37
|
+
function assertOptionalBoolean(value, fieldName, context = 'createVideoFromImageList') {
|
|
38
38
|
if (value !== undefined && typeof value !== 'boolean') {
|
|
39
|
-
throw new Error(`${fieldName} must be a boolean for
|
|
39
|
+
throw new Error(`${fieldName} must be a boolean for ${context}`);
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
|
+
function normalizeCreateVideoFromTextInput(input) {
|
|
43
|
+
const raw = input;
|
|
44
|
+
const normalized = { ...input };
|
|
45
|
+
const aliases = [
|
|
46
|
+
['session_id', ['session_id', 'sessionId', 'sessionID']],
|
|
47
|
+
['aspect_ratio', ['aspect_ratio', 'aspectRatio']],
|
|
48
|
+
['outro_image_url', ['outro_image_url', 'outroImageUrl']],
|
|
49
|
+
['add_outro_animation', ['add_outro_animation', 'addOutroAnimation']],
|
|
50
|
+
['add_outro_focus_area', ['add_outro_focus_area', 'addOutroFocusArea']],
|
|
51
|
+
['outro_focust_area', ['outro_focust_area', 'outro_focus_area', 'outroFocustArea', 'outroFocusArea']],
|
|
52
|
+
['generate_outro_image', ['generate_outro_image', 'generateOutroImage']],
|
|
53
|
+
['cta_url', ['cta_url', 'ctaUrl']],
|
|
54
|
+
['cta_text_top', ['cta_text_top', 'ctaTextTop']],
|
|
55
|
+
['cta_text_bottom', ['cta_text_bottom', 'ctaTextBottom']],
|
|
56
|
+
['cta_logo', ['cta_logo', 'ctaLogo']],
|
|
57
|
+
['add_footer_animation', ['add_footer_animation', 'addFooterAnimation']],
|
|
58
|
+
['footer_metadata', ['footer_metadata', 'footerMetadata']],
|
|
59
|
+
['enable_subtitles', ['enable_subtitles', 'enableSubtitles']],
|
|
60
|
+
['font_key', ['font_key', 'fontKey']],
|
|
61
|
+
];
|
|
62
|
+
for (const [canonicalName, aliasList] of aliases) {
|
|
63
|
+
const value = resolveAliasedInputValue(raw, aliasList, canonicalName);
|
|
64
|
+
if (value !== undefined) {
|
|
65
|
+
normalized[canonicalName] = value;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
assertOptionalBoolean(normalized.enable_subtitles, 'enable_subtitles', 'createVideoFromText');
|
|
69
|
+
assertOptionalBoolean(normalized.add_outro_animation, 'add_outro_animation', 'createVideoFromText');
|
|
70
|
+
assertOptionalBoolean(normalized.add_outro_focus_area, 'add_outro_focus_area', 'createVideoFromText');
|
|
71
|
+
assertOptionalBoolean(normalized.generate_outro_image, 'generate_outro_image', 'createVideoFromText');
|
|
72
|
+
assertOptionalBoolean(normalized.add_footer_animation, 'add_footer_animation', 'createVideoFromText');
|
|
73
|
+
if (normalized.generate_outro_image === true) {
|
|
74
|
+
const ctaUrl = typeof normalized.cta_url === 'string' ? normalized.cta_url.trim() : '';
|
|
75
|
+
if (!ctaUrl) {
|
|
76
|
+
throw new Error('cta_url is required when generate_outro_image is true for createVideoFromText');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else if (normalized.add_outro_focus_area === true && normalized.add_outro_animation !== true) {
|
|
80
|
+
throw new Error('add_outro_focus_area requires add_outro_animation to be true for createVideoFromText');
|
|
81
|
+
}
|
|
82
|
+
return normalized;
|
|
83
|
+
}
|
|
42
84
|
function normalizeCreateVideoFromImageListInput(input) {
|
|
43
85
|
const raw = input;
|
|
44
86
|
if (!Array.isArray(input.image_urls) || input.image_urls.length === 0) {
|
|
@@ -57,6 +99,8 @@ function normalizeCreateVideoFromImageListInput(input) {
|
|
|
57
99
|
['cta_text_top', ['cta_text_top', 'ctaTextTop']],
|
|
58
100
|
['cta_text_bottom', ['cta_text_bottom', 'ctaTextBottom']],
|
|
59
101
|
['cta_logo', ['cta_logo', 'ctaLogo']],
|
|
102
|
+
['add_footer_animation', ['add_footer_animation', 'addFooterAnimation']],
|
|
103
|
+
['footer_metadata', ['footer_metadata', 'footerMetadata']],
|
|
60
104
|
['enable_subtitles', ['enable_subtitles', 'enableSubtitles']],
|
|
61
105
|
['font_key', ['font_key', 'fontKey']],
|
|
62
106
|
];
|
|
@@ -70,6 +114,7 @@ function normalizeCreateVideoFromImageListInput(input) {
|
|
|
70
114
|
assertOptionalBoolean(normalized.add_outro_animation, 'add_outro_animation');
|
|
71
115
|
assertOptionalBoolean(normalized.add_outro_focus_area, 'add_outro_focus_area');
|
|
72
116
|
assertOptionalBoolean(normalized.generate_outro_image, 'generate_outro_image');
|
|
117
|
+
assertOptionalBoolean(normalized.add_footer_animation, 'add_footer_animation');
|
|
73
118
|
if (normalized.generate_outro_image === true) {
|
|
74
119
|
const ctaUrl = typeof normalized.cta_url === 'string' ? normalized.cta_url.trim() : '';
|
|
75
120
|
if (!ctaUrl) {
|
|
@@ -81,6 +126,148 @@ function normalizeCreateVideoFromImageListInput(input) {
|
|
|
81
126
|
}
|
|
82
127
|
return normalized;
|
|
83
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
|
+
}
|
|
219
|
+
function normalizeSessionPublicationInput(input, context) {
|
|
220
|
+
if (typeof input !== 'string' && (!input || typeof input !== 'object' || Array.isArray(input))) {
|
|
221
|
+
throw new Error(`input must be a session id or object for ${context}`);
|
|
222
|
+
}
|
|
223
|
+
const raw = typeof input === 'string' ? { session_id: input } : { ...input };
|
|
224
|
+
const sessionId = resolveAliasedInputValue(raw, [
|
|
225
|
+
'session_id',
|
|
226
|
+
'sessionId',
|
|
227
|
+
'sessionID',
|
|
228
|
+
'video_session_id',
|
|
229
|
+
'videoSessionId',
|
|
230
|
+
'videoSessionID',
|
|
231
|
+
'id',
|
|
232
|
+
], 'session_id');
|
|
233
|
+
const normalizedSessionId = typeof sessionId === 'string' ? sessionId.trim() : '';
|
|
234
|
+
if (!normalizedSessionId) {
|
|
235
|
+
throw new Error(`session_id is required for ${context}`);
|
|
236
|
+
}
|
|
237
|
+
const normalized = {
|
|
238
|
+
...raw,
|
|
239
|
+
session_id: normalizedSessionId,
|
|
240
|
+
};
|
|
241
|
+
const aliases = [
|
|
242
|
+
['aspect_ratio', ['aspect_ratio', 'aspectRatio']],
|
|
243
|
+
['creator_handle', ['creator_handle', 'creatorHandle']],
|
|
244
|
+
['image_hash', ['image_hash', 'imageHash']],
|
|
245
|
+
['splash_image', ['splash_image', 'splashImage']],
|
|
246
|
+
['image_model', ['image_model', 'imageModel']],
|
|
247
|
+
['video_model', ['video_model', 'videoModel']],
|
|
248
|
+
['original_prompt', ['original_prompt', 'originalPrompt', 'prompt']],
|
|
249
|
+
['session_language', ['session_language', 'sessionLanguage', 'language', 'language_code']],
|
|
250
|
+
['language_string', ['language_string', 'languageString']],
|
|
251
|
+
];
|
|
252
|
+
for (const [canonicalName, aliasList] of aliases) {
|
|
253
|
+
const value = resolveAliasedInputValue(raw, aliasList, canonicalName);
|
|
254
|
+
if (value !== undefined) {
|
|
255
|
+
normalized[canonicalName] = value;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
if (normalized.tags !== undefined &&
|
|
259
|
+
!Array.isArray(normalized.tags) &&
|
|
260
|
+
typeof normalized.tags !== 'string') {
|
|
261
|
+
throw new Error(`tags must be a string or string array for ${context}`);
|
|
262
|
+
}
|
|
263
|
+
if (Array.isArray(normalized.tags)) {
|
|
264
|
+
normalized.tags = normalized.tags
|
|
265
|
+
.filter((tag) => typeof tag === 'string')
|
|
266
|
+
.map((tag) => tag.trim())
|
|
267
|
+
.filter(Boolean);
|
|
268
|
+
}
|
|
269
|
+
return normalized;
|
|
270
|
+
}
|
|
84
271
|
export class SamsarClient {
|
|
85
272
|
constructor(options) {
|
|
86
273
|
if (!options?.apiKey) {
|
|
@@ -96,12 +283,92 @@ export class SamsarClient {
|
|
|
96
283
|
throw new Error('A fetch implementation is required. Provide one via the "fetch" option when running outside environments with global fetch.');
|
|
97
284
|
}
|
|
98
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
|
+
}
|
|
99
365
|
/**
|
|
100
366
|
* Create a new video generation job from text.
|
|
101
367
|
*/
|
|
102
368
|
async createVideoFromText(input, options) {
|
|
369
|
+
const normalizedInput = normalizeCreateVideoFromTextInput(input);
|
|
103
370
|
const body = {
|
|
104
|
-
input,
|
|
371
|
+
input: normalizedInput,
|
|
105
372
|
webhookUrl: options?.webhookUrl,
|
|
106
373
|
};
|
|
107
374
|
return this.post('video/create', body, options);
|
|
@@ -140,9 +407,10 @@ export class SamsarClient {
|
|
|
140
407
|
* Create a text-to-video request attributed to an external user while billing against the shared API key.
|
|
141
408
|
*/
|
|
142
409
|
async createExternalVideoFromText(externalUser, input, options) {
|
|
410
|
+
const normalizedInput = normalizeCreateVideoFromTextInput(input);
|
|
143
411
|
const body = {
|
|
144
412
|
external_user: normalizeExternalUserIdentity(externalUser),
|
|
145
|
-
input,
|
|
413
|
+
input: normalizedInput,
|
|
146
414
|
webhookUrl: options?.webhookUrl,
|
|
147
415
|
};
|
|
148
416
|
return this.post('external_users/text_to_video', body, options);
|
|
@@ -464,31 +732,9 @@ export class SamsarClient {
|
|
|
464
732
|
* only the final video render step.
|
|
465
733
|
*/
|
|
466
734
|
async updateVideoOutroImage(input, options) {
|
|
467
|
-
const
|
|
468
|
-
const videoSessionId = raw.videoSessionId ??
|
|
469
|
-
raw.video_session_id ??
|
|
470
|
-
raw.videoSessionID ??
|
|
471
|
-
raw.session_id ??
|
|
472
|
-
raw.sessionId ??
|
|
473
|
-
raw.sessionID ??
|
|
474
|
-
raw.request_id ??
|
|
475
|
-
raw.requestId;
|
|
476
|
-
const outroImageUrl = raw.outro_image_url ??
|
|
477
|
-
raw.outroImageUrl ??
|
|
478
|
-
raw.new_outro_image_url ??
|
|
479
|
-
raw.newOutroImageUrl;
|
|
480
|
-
if (!videoSessionId) {
|
|
481
|
-
throw new Error('videoSessionId is required for updateVideoOutroImage');
|
|
482
|
-
}
|
|
483
|
-
if (!outroImageUrl) {
|
|
484
|
-
throw new Error('outro_image_url is required for updateVideoOutroImage');
|
|
485
|
-
}
|
|
735
|
+
const normalizedInput = normalizeUpdateVideoOutroImageInput(input, 'updateVideoOutroImage');
|
|
486
736
|
const body = {
|
|
487
|
-
input:
|
|
488
|
-
...input,
|
|
489
|
-
videoSessionId: String(videoSessionId),
|
|
490
|
-
outro_image_url: String(outroImageUrl),
|
|
491
|
-
},
|
|
737
|
+
input: normalizedInput,
|
|
492
738
|
webhookUrl: options?.webhookUrl,
|
|
493
739
|
};
|
|
494
740
|
const response = await this.post('video/update_outro_image', body, options);
|
|
@@ -512,6 +758,19 @@ export class SamsarClient {
|
|
|
512
758
|
}
|
|
513
759
|
return response;
|
|
514
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
|
+
}
|
|
515
774
|
/**
|
|
516
775
|
* Add or replace the outro image for an existing video session by cloning it into a new session and
|
|
517
776
|
* re-running frame/video generation.
|
|
@@ -595,6 +854,76 @@ export class SamsarClient {
|
|
|
595
854
|
}
|
|
596
855
|
return response;
|
|
597
856
|
}
|
|
857
|
+
/**
|
|
858
|
+
* Add or replace an outro image for an external-user video request by resolving the external request id.
|
|
859
|
+
*/
|
|
860
|
+
async addExternalVideoOutroImage(externalUser, input, options) {
|
|
861
|
+
const raw = input;
|
|
862
|
+
const videoSessionId = raw.videoSessionId ??
|
|
863
|
+
raw.video_session_id ??
|
|
864
|
+
raw.videoSessionID ??
|
|
865
|
+
raw.session_id ??
|
|
866
|
+
raw.sessionId ??
|
|
867
|
+
raw.sessionID ??
|
|
868
|
+
raw.request_id ??
|
|
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;
|
|
876
|
+
const outroImageUrl = raw.outro_image_url ??
|
|
877
|
+
raw.outroImageUrl ??
|
|
878
|
+
raw.new_outro_image_url ??
|
|
879
|
+
raw.newOutroImageUrl;
|
|
880
|
+
const rawAddOutroAnimation = raw.add_outro_animation ??
|
|
881
|
+
raw.addOutroAnimation;
|
|
882
|
+
const rawAddOutroFocusArea = raw.add_outro_focus_area ??
|
|
883
|
+
raw.addOutroFocusArea;
|
|
884
|
+
const rawOutroFocusArea = raw.outro_focust_area ??
|
|
885
|
+
raw.outro_focus_area ??
|
|
886
|
+
raw.outroFocustArea ??
|
|
887
|
+
raw.outroFocusArea;
|
|
888
|
+
if (!videoSessionId) {
|
|
889
|
+
throw new Error('videoSessionId is required for addExternalVideoOutroImage');
|
|
890
|
+
}
|
|
891
|
+
if (!outroImageUrl) {
|
|
892
|
+
throw new Error('outro_image_url is required for addExternalVideoOutroImage');
|
|
893
|
+
}
|
|
894
|
+
if (rawAddOutroAnimation !== undefined && typeof rawAddOutroAnimation !== 'boolean') {
|
|
895
|
+
throw new Error('add_outro_animation must be a boolean for addExternalVideoOutroImage');
|
|
896
|
+
}
|
|
897
|
+
if (rawAddOutroFocusArea !== undefined && typeof rawAddOutroFocusArea !== 'boolean') {
|
|
898
|
+
throw new Error('add_outro_focus_area must be a boolean for addExternalVideoOutroImage');
|
|
899
|
+
}
|
|
900
|
+
if (rawAddOutroFocusArea === true && rawAddOutroAnimation !== true) {
|
|
901
|
+
throw new Error('add_outro_focus_area requires add_outro_animation to be true for addExternalVideoOutroImage');
|
|
902
|
+
}
|
|
903
|
+
if (rawAddOutroFocusArea === true) {
|
|
904
|
+
if (!rawOutroFocusArea || typeof rawOutroFocusArea !== 'object' || Array.isArray(rawOutroFocusArea)) {
|
|
905
|
+
throw new Error('outro_focust_area must be an object with x, y, width, height for addExternalVideoOutroImage');
|
|
906
|
+
}
|
|
907
|
+
const { x, y, width, height } = rawOutroFocusArea;
|
|
908
|
+
const isInvalid = [x, y, width, height].some((value) => typeof value !== 'number' || !Number.isFinite(value));
|
|
909
|
+
if (isInvalid) {
|
|
910
|
+
throw new Error('outro_focust_area x, y, width, height must be valid numbers for addExternalVideoOutroImage');
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
const body = {
|
|
914
|
+
external_user: normalizeExternalUserIdentity(externalUser),
|
|
915
|
+
input: {
|
|
916
|
+
...input,
|
|
917
|
+
videoSessionId: String(videoSessionId),
|
|
918
|
+
outro_image_url: String(outroImageUrl),
|
|
919
|
+
...(rawAddOutroAnimation !== undefined ? { add_outro_animation: rawAddOutroAnimation === true } : {}),
|
|
920
|
+
...(rawAddOutroFocusArea !== undefined ? { add_outro_focus_area: rawAddOutroFocusArea === true } : {}),
|
|
921
|
+
...(rawOutroFocusArea !== undefined ? { outro_focust_area: rawOutroFocusArea } : {}),
|
|
922
|
+
},
|
|
923
|
+
webhookUrl: options?.webhookUrl,
|
|
924
|
+
};
|
|
925
|
+
return this.post('external_users/add_outro_image', body, options);
|
|
926
|
+
}
|
|
598
927
|
/**
|
|
599
928
|
* Fetch the latest available render URL for a given video session id.
|
|
600
929
|
* Maps to GET /video/fetch_latest_version?session_id={sessionId}.
|
|
@@ -669,6 +998,48 @@ export class SamsarClient {
|
|
|
669
998
|
data: normalizedData,
|
|
670
999
|
};
|
|
671
1000
|
}
|
|
1001
|
+
/**
|
|
1002
|
+
* Publish a completed Samsar video session to the public publication feed.
|
|
1003
|
+
* This is a free endpoint. The session must belong to the authenticated API key/auth token.
|
|
1004
|
+
*/
|
|
1005
|
+
async publishPublication(input, options) {
|
|
1006
|
+
const payload = normalizeSessionPublicationInput(input, 'publishPublication');
|
|
1007
|
+
return this.post('publications/publish', payload, options);
|
|
1008
|
+
}
|
|
1009
|
+
/**
|
|
1010
|
+
* Alias for publishPublication, named around the underlying VideoSession resource.
|
|
1011
|
+
*/
|
|
1012
|
+
async publishSessionPublication(input, options) {
|
|
1013
|
+
return this.publishPublication(input, options);
|
|
1014
|
+
}
|
|
1015
|
+
/**
|
|
1016
|
+
* Edit an existing publication for a Samsar video session.
|
|
1017
|
+
* Omitted fields keep their current publication values.
|
|
1018
|
+
*/
|
|
1019
|
+
async editPublication(input, options) {
|
|
1020
|
+
const payload = normalizeSessionPublicationInput(input, 'editPublication');
|
|
1021
|
+
return this.post('publications/edit', payload, options);
|
|
1022
|
+
}
|
|
1023
|
+
/**
|
|
1024
|
+
* Alias for editPublication, named around the underlying VideoSession resource.
|
|
1025
|
+
*/
|
|
1026
|
+
async editSessionPublication(input, options) {
|
|
1027
|
+
return this.editPublication(input, options);
|
|
1028
|
+
}
|
|
1029
|
+
/**
|
|
1030
|
+
* Revoke a publication for a Samsar video session.
|
|
1031
|
+
* This deletes the publication record and clears published fields on the session.
|
|
1032
|
+
*/
|
|
1033
|
+
async revokePublication(input, options) {
|
|
1034
|
+
const payload = normalizeSessionPublicationInput(input, 'revokePublication');
|
|
1035
|
+
return this.post('publications/revoke', payload, options);
|
|
1036
|
+
}
|
|
1037
|
+
/**
|
|
1038
|
+
* Alias for revokePublication, named around the underlying VideoSession resource.
|
|
1039
|
+
*/
|
|
1040
|
+
async revokeSessionPublication(input, options) {
|
|
1041
|
+
return this.revokePublication(input, options);
|
|
1042
|
+
}
|
|
672
1043
|
/**
|
|
673
1044
|
* Fetch the supported image/video model keys for the text_to_video route.
|
|
674
1045
|
* Maps to GET /video/supported_models.
|
|
@@ -1279,6 +1650,19 @@ export class SamsarClient {
|
|
|
1279
1650
|
const rootUrl = baseUrl.endsWith('/v1') ? baseUrl.slice(0, -3) : baseUrl;
|
|
1280
1651
|
return `${rootUrl}/${cleanedPath}`;
|
|
1281
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
|
+
}
|
|
1282
1666
|
}
|
|
1283
1667
|
function trimTrailingSlash(url) {
|
|
1284
1668
|
return url.replace(/\/+$/, '');
|