samsar-js 0.48.26 → 0.48.27

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 CHANGED
@@ -77,7 +77,7 @@ const videoFromImages = await samsar.createVideoFromImageList(
77
77
  await samsar.createVideoFromImageList({
78
78
  image_urls: ['https://example.com/a.jpg', 'https://example.com/b.jpg'],
79
79
  prompt: 'Product launch teaser with a clean final CTA',
80
- video_model: 'KLING3.0',
80
+ video_model: 'KLINGIMGTOVID3PRO',
81
81
  aspect_ratio: '16:9',
82
82
  outro_image_url: 'https://cdn.example.com/outro.png',
83
83
  add_outro_animation: true,
@@ -94,6 +94,7 @@ await samsar.createVideoFromImageList({
94
94
  prompt: 'Travel offer reel with a scannable booking outro',
95
95
  video_model: 'RUNWAYML',
96
96
  aspect_ratio: '9:16',
97
+ add_narrator_avatar: true,
97
98
  generate_outro_image: true,
98
99
  cta_url: 'https://example.com/book',
99
100
  cta_text_top: 'Scan to book',
@@ -434,6 +435,7 @@ const platform = new SamsarClient({
434
435
 
435
436
  const externalUser = {
436
437
  provider: 'whop',
438
+ unique_key: 'whop:usr_123',
437
439
  external_user_id: 'usr_123',
438
440
  external_app_id: 'app_abc',
439
441
  username: 'roy24x7',
@@ -544,25 +546,28 @@ console.log(externalLibrary.data.requests.map((request) => request.request_id));
544
546
  ```
545
547
 
546
548
  Video model support notes:
547
- - `createVideoFromText` image model keys include: `GPTIMAGE2`, `IMAGEN4`, `SEEDREAM`, `HUNYUAN`, `NANOBANANA2`.
548
- - `createVideoFromText` supports all express video models: `RUNWAYML`, `KLINGIMGTOVID3PRO`, `HAILUO`, `HAILUOPRO`, `SEEDANCEI2V` (Seedance 2.0), `VEO3.1I2V`, `VEO3.1I2VFAST`, `SORA2`, `SORA2PRO`.
549
+ - `createVideoFromText` image model keys include: `GPTIMAGE2`, `IMAGEN4`, `SEEDREAM`, `NANOBANANA2`, `CUSTOM_TEXT_TO_IMAGE`.
550
+ - `createVideoFromText` supports these video models: `VEO3.1I2V`, `VEO3.1I2VFAST`, `SEEDANCEI2V` (Seedance 2.0), `KLINGIMGTOVID3PRO`, `RUNWAYML`, and `CUSTOM_IMAGE_TO_VIDEO`.
549
551
  - `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.
550
- - `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`.
552
+ - `createVideoFromImageList` supports `VEO3.1I2V`, `VEO3.1I2VFAST`, `SEEDANCEI2V`, `KLINGIMGTOVID3PRO`, `RUNWAYML`, and `CUSTOM_IMAGE_TO_VIDEO` via `video_model`; if omitted, it defaults to `VEO3.1I2V`. Use `aspect_ratio: '16:9'` or `'9:16'`; omitted or invalid values fall back to `16:9`.
551
553
  - `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.
552
554
  - `createVideoFromImageList` can render per-scene footer QR cards by setting `add_footer_animation: true` and providing one `footer_metadata` item per image scene.
555
+ - `createVideoFromImageList` accepts `limit_single_narrator: true` to keep all narration under one narrator identity. `add_narrator_avatar: true` automatically enables `limit_single_narrator`, generates an influencer-style human narrator avatar, and overlays it bottom-center or centered in the footer row when footer metadata is present.
553
556
  - `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.
554
557
  - `updateVideoFooterImage` updates the footer CTA on a cloned session with `cta_text`, `cta_logo`, and/or `cta_url`, or removes all scene footers with `remove_footer: true`. Footer updates queue only frame/video regeneration.
555
558
  - `cloneVideo` creates a deep copy of a completed session and queues only the final video render so the clone receives a new rendered video path and URL. It does not charge credits.
556
559
  - 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`, `addSubtitles`, `removeSubtitles`, `addVideoOutroImage`, `updateVideoOutroImage`, and `updateVideoFooterImage`; the explicit external variants are available when you want to call `/external_users/*` directly. Do not strip the `extreq_` prefix.
557
560
  - Completed video status, latest-version, and completed-session list responses expose `has_subtitles` and `result_language` when the session metadata is available.
558
561
  - `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.
559
- - 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.
562
+ - Text-to-video and image-list video pricing use the same per-rendered-second rates for standard express models: `VEO3.1I2V` is 60 credits/sec, `VEO3.1I2VFAST` is 36 credits/sec, `SEEDANCEI2V` is 30 credits/sec, `KLINGIMGTOVID3PRO` is 36 credits/sec, and `RUNWAYML` is 30 credits/sec. Image-list narrator avatar generation adds 4 credits/sec when `add_narrator_avatar` is true.
563
+ - Standard express video models expose a per-second pricing distribution through `EXPRESS_VIDEO_PRICING_DISTRIBUTION_PER_SECOND_BY_MODEL`: pipeline 4, inference 4, image gen/edit 2, speech 2, music 2, effects and lipsync 2, and video as the model-specific remainder.
560
564
 
561
565
  Upcoming `/v2` omni route adapters:
562
566
  - `/v2` is additive; `/v1` is not deprecated.
563
567
  - `createV2VideoFromText`, `createV2VideoFromImageList`, `translateV2Video`, `cloneV2Video`, `updateV2VideoOutroImage`, `updateV2VideoFooterImage`, `addV2VideoOutroImage`, `getV2Status`, `getV2Credits`, `listV2Requests`, and `createV2Session` call the new omni route surface.
564
- - Programmatic user billing helpers include `createV2UserRechargeCredits`, `refreshV2UserToken`, `createV2UserAppKey`, `refreshV2UserAppKey`, `getV2UserCredits`, `getV2UserUsageLogs`, and `getV2UserPaymentStatus`.
565
- - 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.
568
+ - Step-controlled video helpers include `createV2StepVideoFromText`, `createV2StepTextToVideo`, `createV2StepVideoFromImage`, `createV2StepImageToVideo`, `getV2StepVideoStatus`, and `processNextV2StepVideo`.
569
+ - Programmatic user helpers include `createV2ExternalUser`, `createV2UserRechargeCredits`, `refreshV2UserToken`, `createV2UserAppKey`, `refreshV2UserAppKey`, `getV2UserCredits`, `getV2UserUsageLogs`, and `getV2UserPaymentStatus`.
570
+ - 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. V2 external users can be referenced by `unique_key`; if `unique_key` is omitted during creation, the server uses `external_user_id` as the key.
566
571
 
567
572
  ```ts
568
573
  const v2Video = await platform.createV2VideoFromImageList({
@@ -576,7 +581,7 @@ const v2Video = await platform.createV2VideoFromImageList({
576
581
  const v2ExternalVideo = await platform.createV2VideoFromImageList(
577
582
  {
578
583
  image_urls: ['https://cdn.example.com/a.png', 'https://cdn.example.com/b.png'],
579
- video_model: 'KLING3.0',
584
+ video_model: 'KLINGIMGTOVID3PRO',
580
585
  },
581
586
  { externalUser },
582
587
  );
@@ -597,6 +602,56 @@ const v2Status = await platform.getV2Status(v2Video.data.request_id!);
597
602
  console.log(v2Status.data.status);
598
603
  ```
599
604
 
605
+ Step-controlled video generation pauses after each completed stage until you call `processNextV2StepVideo`:
606
+
607
+ ```ts
608
+ const stepVideo = await platform.createV2StepVideoFromText({
609
+ prompt: 'A 20 second launch teaser for a new travel app',
610
+ image_model: 'GPTIMAGE2',
611
+ video_model: 'RUNWAYML',
612
+ duration: 20,
613
+ aspect_ratio: '16:9',
614
+ enable_subtitles: true,
615
+ });
616
+
617
+ let stepStatus = await platform.getV2StepVideoStatus(stepVideo.data.request_id);
618
+ if (stepStatus.data.step_status === 'COMPLETED') {
619
+ console.log(stepStatus.data.current_step, stepStatus.data.current_step_resources);
620
+ stepStatus = await platform.processNextV2StepVideo(stepVideo.data.request_id);
621
+ }
622
+
623
+ const stepImageVideo = await platform.createV2StepVideoFromImage({
624
+ image_url: 'https://cdn.example.com/product-frame.png',
625
+ prompt: 'Turn this product frame into a cinematic ad',
626
+ video_model: 'KLINGIMGTOVID3PRO',
627
+ aspect_ratio: '16:9',
628
+ });
629
+ console.log(stepImageVideo.data.step?.current_step);
630
+ ```
631
+
632
+ Create and reference a V2 external user:
633
+
634
+ ```ts
635
+ const createdExternalUser = await platform.createV2ExternalUser({
636
+ unique_key: 'wallet:0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
637
+ email: 'member@example.com',
638
+ display_name: 'Member Name',
639
+ });
640
+
641
+ const v2RegisteredExternalVideo = await platform.createV2VideoFromImageList(
642
+ {
643
+ image_urls: ['https://cdn.example.com/a.png', 'https://cdn.example.com/b.png'],
644
+ video_model: 'RUNWAYML',
645
+ },
646
+ {
647
+ externalUser: {
648
+ unique_key: createdExternalUser.data.unique_key!,
649
+ },
650
+ },
651
+ );
652
+ console.log(v2RegisteredExternalVideo.data.request_id);
653
+ ```
654
+
600
655
  Programmatic user recharge and OAuth-style refresh token rotation:
601
656
 
602
657
  ```ts
@@ -0,0 +1,24 @@
1
+ export declare const EXPRESS_VIDEO_FIXED_PRICING_COMPONENTS_PER_SECOND: {
2
+ readonly pipeline: 4;
3
+ readonly inference: 4;
4
+ readonly image_gen_edit: 2;
5
+ readonly speech: 2;
6
+ readonly music: 2;
7
+ readonly effects_and_lipsync: 2;
8
+ };
9
+ export type ExpressVideoPricingDistribution = typeof EXPRESS_VIDEO_FIXED_PRICING_COMPONENTS_PER_SECOND & {
10
+ video: number;
11
+ total: number;
12
+ };
13
+ export declare const EXPRESS_VIDEO_FIXED_COMPONENTS_TOTAL_PER_SECOND: number;
14
+ export declare const EXPRESS_VIDEO_CREDITS_PER_SECOND_BY_MODEL: {
15
+ readonly 'VEO3.1I2V': 60;
16
+ readonly 'VEO3.1I2VFAST': 36;
17
+ readonly SEEDANCEI2V: 30;
18
+ readonly KLINGIMGTOVID3PRO: 36;
19
+ readonly KLINGIMGTOVIDTURBO: 36;
20
+ readonly RUNWAYML: 30;
21
+ };
22
+ export declare const EXPRESS_VIDEO_PRICING_DISTRIBUTION_PER_SECOND_BY_MODEL: Record<string, ExpressVideoPricingDistribution>;
23
+ export declare function getExpressVideoCreditsPerSecond(model: string | null | undefined): 60 | 36 | 30;
24
+ export declare function getExpressVideoPricingDistributionPerSecond(model: string | null | undefined): ExpressVideoPricingDistribution;
@@ -0,0 +1,34 @@
1
+ export const EXPRESS_VIDEO_FIXED_PRICING_COMPONENTS_PER_SECOND = {
2
+ pipeline: 4,
3
+ inference: 4,
4
+ image_gen_edit: 2,
5
+ speech: 2,
6
+ music: 2,
7
+ effects_and_lipsync: 2,
8
+ };
9
+ export const EXPRESS_VIDEO_FIXED_COMPONENTS_TOTAL_PER_SECOND = Object.values(EXPRESS_VIDEO_FIXED_PRICING_COMPONENTS_PER_SECOND).reduce((total, value) => total + value, 0);
10
+ export const EXPRESS_VIDEO_CREDITS_PER_SECOND_BY_MODEL = {
11
+ 'VEO3.1I2V': 60,
12
+ 'VEO3.1I2VFAST': 36,
13
+ SEEDANCEI2V: 30,
14
+ KLINGIMGTOVID3PRO: 36,
15
+ KLINGIMGTOVIDTURBO: 36,
16
+ RUNWAYML: 30,
17
+ };
18
+ export const EXPRESS_VIDEO_PRICING_DISTRIBUTION_PER_SECOND_BY_MODEL = Object.fromEntries(Object.entries(EXPRESS_VIDEO_CREDITS_PER_SECOND_BY_MODEL)
19
+ .map(([model, total]) => [
20
+ model,
21
+ {
22
+ ...EXPRESS_VIDEO_FIXED_PRICING_COMPONENTS_PER_SECOND,
23
+ video: total - EXPRESS_VIDEO_FIXED_COMPONENTS_TOTAL_PER_SECOND,
24
+ total,
25
+ },
26
+ ]));
27
+ export function getExpressVideoCreditsPerSecond(model) {
28
+ const modelKey = typeof model === 'string' ? model.trim().toUpperCase() : '';
29
+ return EXPRESS_VIDEO_CREDITS_PER_SECOND_BY_MODEL[modelKey] ?? null;
30
+ }
31
+ export function getExpressVideoPricingDistributionPerSecond(model) {
32
+ const modelKey = typeof model === 'string' ? model.trim().toUpperCase() : '';
33
+ return EXPRESS_VIDEO_PRICING_DISTRIBUTION_PER_SECOND_BY_MODEL[modelKey] ?? null;
34
+ }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export { EXPRESS_VIDEO_CREDITS_PER_SECOND_BY_MODEL, EXPRESS_VIDEO_FIXED_COMPONENTS_TOTAL_PER_SECOND, EXPRESS_VIDEO_FIXED_PRICING_COMPONENTS_PER_SECOND, EXPRESS_VIDEO_PRICING_DISTRIBUTION_PER_SECOND_BY_MODEL, getExpressVideoCreditsPerSecond, getExpressVideoPricingDistributionPerSecond, } from './express-video-pricing.js';
2
+ export type { ExpressVideoPricingDistribution } from './express-video-pricing.js';
1
3
  type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
2
4
  type QueryValue = string | number | boolean | null | undefined;
3
5
  type QueryParams = Record<string, QueryValue>;
@@ -109,7 +111,7 @@ export interface FooterMetadataItem {
109
111
  footerLogoImagePath?: string;
110
112
  }
111
113
  export type ImageListToVideoAspectRatio = '16:9' | '9:16';
112
- export type ImageListToVideoModel = 'VEO3.1I2V' | 'SEEDANCEI2V' | 'KLING3.0' | 'KLINGIMGTOVID3PRO' | 'RUNWAYML';
114
+ export type ImageListToVideoModel = 'VEO3.1I2V' | 'VEO3.1I2VFAST' | 'SEEDANCEI2V' | 'KLINGIMGTOVID3PRO' | 'RUNWAYML' | 'CUSTOM_IMAGE_TO_VIDEO';
113
115
  export interface ImageListToVideoItem {
114
116
  image_url?: string;
115
117
  imageUrl?: string;
@@ -182,6 +184,10 @@ export interface CreateVideoFromImageListInput {
182
184
  addFooterAnimation?: boolean;
183
185
  footer_metadata?: FooterMetadataItem[];
184
186
  footerMetadata?: FooterMetadataItem[];
187
+ limit_single_narrator?: boolean;
188
+ limitSingleNarrator?: boolean;
189
+ add_narrator_avatar?: boolean;
190
+ addNarratorAvatar?: boolean;
185
191
  [key: string]: unknown;
186
192
  }
187
193
  export interface TranscriptBuilderPayload {
@@ -203,6 +209,12 @@ export interface CreateVideoFromImageListResponse {
203
209
  remainingCredits?: number | null;
204
210
  [key: string]: unknown;
205
211
  }
212
+ export interface CreateV2StepImageToVideoInput extends Omit<CreateVideoFromImageListInput, 'image_urls'> {
213
+ image_urls?: Array<string | ImageListToVideoItem>;
214
+ image_url?: string;
215
+ imageUrl?: string;
216
+ image?: string;
217
+ }
206
218
  export interface TranslateVideoInput {
207
219
  videoSessionId?: string;
208
220
  video_session_id?: string;
@@ -552,6 +564,7 @@ export interface SupportedTextToVideoModelOption {
552
564
  label: string;
553
565
  value: string;
554
566
  basePrice: number | null;
567
+ pricingDistribution?: Record<string, number> | null;
555
568
  [key: string]: unknown;
556
569
  }
557
570
  export interface EnhanceMessageRequest {
@@ -1197,6 +1210,8 @@ export interface GlobalStatusResponse {
1197
1210
  }
1198
1211
  export interface ExternalUserIdentity {
1199
1212
  provider: string;
1213
+ unique_key?: string;
1214
+ uniqueKey?: string;
1200
1215
  external_user_id?: string;
1201
1216
  externalUserId?: string;
1202
1217
  external_app_id?: string;
@@ -1222,6 +1237,7 @@ export interface ExternalUserSummary {
1222
1237
  id?: string | null;
1223
1238
  provider?: string;
1224
1239
  external_user_id?: string;
1240
+ unique_key?: string | null;
1225
1241
  external_app_id?: string | null;
1226
1242
  external_company_id?: string | null;
1227
1243
  email?: string | null;
@@ -1392,9 +1408,48 @@ export interface ExternalRequestsListResponse {
1392
1408
  [key: string]: unknown;
1393
1409
  }
1394
1410
  export interface V2RequestOptions extends SamsarRequestOptions {
1395
- externalUser?: ExternalUserIdentity | null;
1411
+ externalUser?: V2ExternalUserIdentity | null;
1396
1412
  webhookUrl?: string;
1397
1413
  }
1414
+ export type V2StepVideoStage = 'prompt_generation' | 'image_generation' | 'speech_generation' | 'music_generation' | 'ai_video_generation' | 'lip_sync_generation' | 'sound_effect_generation' | 'video_generation';
1415
+ export type V2StepVideoStatus = 'INIT' | 'PENDING' | 'COMPLETED' | 'FAILED' | string;
1416
+ export interface V2StepVideoState {
1417
+ enabled?: boolean;
1418
+ route_type?: 'text_to_video' | 'image_to_video' | string | null;
1419
+ status?: V2StepVideoStatus;
1420
+ current_step?: V2StepVideoStage | string | null;
1421
+ current_step_label?: string | null;
1422
+ next_step?: V2StepVideoStage | string | null;
1423
+ waiting_for_process_next?: boolean;
1424
+ updated_at?: string | null;
1425
+ [key: string]: unknown;
1426
+ }
1427
+ export interface V2StepVideoResourceBlock {
1428
+ step?: V2StepVideoStage | string;
1429
+ label?: string;
1430
+ status?: V2StepVideoStatus;
1431
+ completed_at?: string | null;
1432
+ resources?: Record<string, unknown>;
1433
+ [key: string]: unknown;
1434
+ }
1435
+ export interface V2StepVideoStatusResponse extends GlobalStatusResponse {
1436
+ step_status?: V2StepVideoStatus;
1437
+ current_step?: V2StepVideoStage | string | null;
1438
+ current_step_label?: string | null;
1439
+ next_step?: V2StepVideoStage | string | null;
1440
+ waiting_for_process_next?: boolean;
1441
+ process_next_url?: string;
1442
+ step?: V2StepVideoState;
1443
+ current_step_resources?: V2StepVideoResourceBlock | null;
1444
+ completed_step_resources?: Record<string, V2StepVideoResourceBlock>;
1445
+ }
1446
+ export interface V2StepVideoCreateResponse extends CreateVideoResponse {
1447
+ status?: V2StepVideoStatus;
1448
+ step?: V2StepVideoState;
1449
+ }
1450
+ export interface V2ExternalUserIdentity extends Omit<ExternalUserIdentity, 'provider'> {
1451
+ provider?: string;
1452
+ }
1398
1453
  export interface V2SessionResponse {
1399
1454
  account_type?: 'internal' | 'external' | string;
1400
1455
  auth_type?: string;
@@ -1450,6 +1505,27 @@ export interface V2UserTokenResponse {
1450
1505
  refreshTokenExpiresAt?: string;
1451
1506
  [key: string]: unknown;
1452
1507
  }
1508
+ export interface V2CreateExternalUserRequest extends V2ExternalUserIdentity {
1509
+ external_user?: V2ExternalUserIdentity | null;
1510
+ externalUser?: V2ExternalUserIdentity | null;
1511
+ }
1512
+ export interface V2CreateExternalUserReference {
1513
+ provider?: string | null;
1514
+ unique_key?: string | null;
1515
+ external_user_id?: string | null;
1516
+ external_app_id?: string | null;
1517
+ [key: string]: unknown;
1518
+ }
1519
+ export interface V2CreateExternalUserResponse {
1520
+ unique_key?: string | null;
1521
+ provider?: string | null;
1522
+ external_user_id?: string | null;
1523
+ external_app_id?: string | null;
1524
+ external_user?: ExternalUserSummary | null;
1525
+ externalUser?: ExternalUserSummary | null;
1526
+ reference?: V2CreateExternalUserReference;
1527
+ [key: string]: unknown;
1528
+ }
1453
1529
  export interface V2UserAppKeyRequest {
1454
1530
  secret?: string;
1455
1531
  appSecret?: string;
@@ -1592,6 +1668,7 @@ export interface VerifiedClientSessionResponse {
1592
1668
  avatarUrl?: string | null;
1593
1669
  provider?: string | null;
1594
1670
  externalUserId?: string | null;
1671
+ uniqueKey?: string | null;
1595
1672
  externalAppId?: string | null;
1596
1673
  externalCompanyId?: string | null;
1597
1674
  generationCredits?: number;
@@ -1728,6 +1805,7 @@ export declare class SamsarClient {
1728
1805
  limit?: number;
1729
1806
  }): Promise<SamsarResult<UsageLogsResponse>>;
1730
1807
  listV2Requests(options?: V2RequestOptions): Promise<SamsarResult<V2RequestsListResponse>>;
1808
+ createV2ExternalUser(payload: V2CreateExternalUserRequest, options?: V2RequestOptions): Promise<SamsarResult<V2CreateExternalUserResponse>>;
1731
1809
  createV2UserRechargeCredits(payload: V2UserRechargeCreditsRequest, options?: V2RequestOptions): Promise<SamsarResult<V2UserRechargeCreditsResponse>>;
1732
1810
  refreshV2UserToken(payload: string | V2UserTokenRefreshRequest, options?: V2RequestOptions): Promise<SamsarResult<V2UserTokenResponse>>;
1733
1811
  refreshV2UserAuthToken(payload: string | V2UserTokenRefreshRequest, options?: V2RequestOptions): Promise<SamsarResult<V2UserTokenResponse>>;
@@ -1741,6 +1819,12 @@ export declare class SamsarClient {
1741
1819
  }): Promise<SamsarResult<CreateLoginTokenResponse | ExternalCreateLoginTokenResponse>>;
1742
1820
  createV2VideoFromText(input: CreateVideoFromTextInput, options?: V2RequestOptions): Promise<SamsarResult<CreateVideoResponse | ExternalRequestResponse>>;
1743
1821
  createV2VideoFromImageList(input: CreateVideoFromImageListInput, options?: V2RequestOptions): Promise<SamsarResult<CreateVideoFromImageListResponse | ExternalRequestResponse>>;
1822
+ createV2StepVideoFromText(input: CreateVideoFromTextInput, options?: V2RequestOptions): Promise<SamsarResult<V2StepVideoCreateResponse>>;
1823
+ createV2StepTextToVideo(input: CreateVideoFromTextInput, options?: V2RequestOptions): Promise<SamsarResult<V2StepVideoCreateResponse>>;
1824
+ createV2StepVideoFromImage(input: CreateV2StepImageToVideoInput, options?: V2RequestOptions): Promise<SamsarResult<V2StepVideoCreateResponse>>;
1825
+ createV2StepImageToVideo(input: CreateV2StepImageToVideoInput, options?: V2RequestOptions): Promise<SamsarResult<V2StepVideoCreateResponse>>;
1826
+ getV2StepVideoStatus(requestId: string, options?: V2RequestOptions): Promise<SamsarResult<V2StepVideoStatusResponse>>;
1827
+ processNextV2StepVideo(requestId: string, options?: V2RequestOptions): Promise<SamsarResult<V2StepVideoStatusResponse>>;
1744
1828
  translateV2Video(input: TranslateVideoInput, options?: V2RequestOptions): Promise<SamsarResult<TranslateVideoResponse | ExternalRequestResponse>>;
1745
1829
  cloneV2Video(input: CloneVideoInput, options?: V2RequestOptions): Promise<SamsarResult<CloneVideoResponse>>;
1746
1830
  uploadV2ImageData(imageData: string[], options?: V2RequestOptions): Promise<SamsarResult<{
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  const DEFAULT_BASE_URL = 'https://api.samsar.one/v1';
2
+ export { EXPRESS_VIDEO_CREDITS_PER_SECOND_BY_MODEL, EXPRESS_VIDEO_FIXED_COMPONENTS_TOTAL_PER_SECOND, EXPRESS_VIDEO_FIXED_PRICING_COMPONENTS_PER_SECOND, EXPRESS_VIDEO_PRICING_DISTRIBUTION_PER_SECOND_BY_MODEL, getExpressVideoCreditsPerSecond, getExpressVideoPricingDistributionPerSecond, } from './express-video-pricing.js';
2
3
  const DEBUG = (() => {
3
4
  const env = globalThis?.process?.env;
4
5
  return env?.SAMSAR_SDK_DEBUG === '1';
@@ -101,6 +102,8 @@ function normalizeCreateVideoFromImageListInput(input) {
101
102
  ['cta_logo', ['cta_logo', 'ctaLogo']],
102
103
  ['add_footer_animation', ['add_footer_animation', 'addFooterAnimation']],
103
104
  ['footer_metadata', ['footer_metadata', 'footerMetadata']],
105
+ ['limit_single_narrator', ['limit_single_narrator', 'limitSingleNarrator']],
106
+ ['add_narrator_avatar', ['add_narrator_avatar', 'addNarratorAvatar']],
104
107
  ['enable_subtitles', ['enable_subtitles', 'enableSubtitles']],
105
108
  ['font_key', ['font_key', 'fontKey']],
106
109
  ];
@@ -115,6 +118,11 @@ function normalizeCreateVideoFromImageListInput(input) {
115
118
  assertOptionalBoolean(normalized.add_outro_focus_area, 'add_outro_focus_area');
116
119
  assertOptionalBoolean(normalized.generate_outro_image, 'generate_outro_image');
117
120
  assertOptionalBoolean(normalized.add_footer_animation, 'add_footer_animation');
121
+ assertOptionalBoolean(normalized.limit_single_narrator, 'limit_single_narrator');
122
+ assertOptionalBoolean(normalized.add_narrator_avatar, 'add_narrator_avatar');
123
+ if (normalized.add_narrator_avatar === true) {
124
+ normalized.limit_single_narrator = true;
125
+ }
118
126
  if (normalized.generate_outro_image === true) {
119
127
  const ctaUrl = typeof normalized.cta_url === 'string' ? normalized.cta_url.trim() : '';
120
128
  if (!ctaUrl) {
@@ -126,6 +134,23 @@ function normalizeCreateVideoFromImageListInput(input) {
126
134
  }
127
135
  return normalized;
128
136
  }
137
+ function normalizeCreateV2StepImageToVideoInput(input) {
138
+ const raw = input;
139
+ const normalized = { ...input };
140
+ if (!Array.isArray(input.image_urls) || input.image_urls.length === 0) {
141
+ const imageUrl = getTrimmedString(raw.image_url) ??
142
+ getTrimmedString(raw.imageUrl) ??
143
+ getTrimmedString(raw.image);
144
+ if (!imageUrl) {
145
+ throw new Error('image_url or image_urls is required for createV2StepVideoFromImage');
146
+ }
147
+ normalized.image_urls = [imageUrl];
148
+ }
149
+ delete normalized.image_url;
150
+ delete normalized.imageUrl;
151
+ delete normalized.image;
152
+ return normalizeCreateVideoFromImageListInput(normalized);
153
+ }
129
154
  function normalizeTranslateVideoInput(input, context = 'translateVideo') {
130
155
  const raw = input;
131
156
  const videoSessionId = raw.videoSessionId ??
@@ -416,7 +441,9 @@ export class SamsarClient {
416
441
  */
417
442
  async getV2(path, options) {
418
443
  const query = {
419
- ...(options?.externalUser ? buildExternalUserQuery(options.externalUser) : {}),
444
+ ...(options?.externalUser
445
+ ? buildExternalUserQuery(options.externalUser, { requireProvider: false })
446
+ : {}),
420
447
  ...(options?.query ?? {}),
421
448
  };
422
449
  return this.get(this.buildV2Url(path), { ...(options ?? {}), query });
@@ -451,6 +478,27 @@ export class SamsarClient {
451
478
  async listV2Requests(options) {
452
479
  return this.getV2('requests', options);
453
480
  }
481
+ async createV2ExternalUser(payload, options) {
482
+ const input = payload ?? {};
483
+ const nestedExternalUser = (input.external_user ?? input.externalUser ?? {});
484
+ const uniqueKey = getTrimmedString(nestedExternalUser.unique_key ??
485
+ nestedExternalUser.uniqueKey ??
486
+ input.unique_key ??
487
+ input.uniqueKey);
488
+ const externalUserId = getTrimmedString(nestedExternalUser.external_user_id ??
489
+ nestedExternalUser.externalUserId ??
490
+ input.external_user_id ??
491
+ input.externalUserId);
492
+ const referenceKey = uniqueKey ?? externalUserId;
493
+ if (!referenceKey) {
494
+ throw new Error('unique_key or external_user_id is required');
495
+ }
496
+ return this.postV2('user/create_external_user', {
497
+ ...input,
498
+ unique_key: referenceKey,
499
+ ...(externalUserId ? { external_user_id: externalUserId } : {}),
500
+ }, options);
501
+ }
454
502
  async createV2UserRechargeCredits(payload, options) {
455
503
  const amount = Number(payload?.amount);
456
504
  if (!Number.isFinite(amount) || amount <= 0) {
@@ -556,6 +604,40 @@ export class SamsarClient {
556
604
  webhookUrl: options?.webhookUrl,
557
605
  }, options);
558
606
  }
607
+ async createV2StepVideoFromText(input, options) {
608
+ const normalizedInput = normalizeCreateVideoFromTextInput(input);
609
+ return this.postV2('video/step/text_to_video', {
610
+ input: normalizedInput,
611
+ webhookUrl: options?.webhookUrl,
612
+ }, options);
613
+ }
614
+ async createV2StepTextToVideo(input, options) {
615
+ return this.createV2StepVideoFromText(input, options);
616
+ }
617
+ async createV2StepVideoFromImage(input, options) {
618
+ const normalizedInput = normalizeCreateV2StepImageToVideoInput(input);
619
+ return this.postV2('video/step/image_to_video', {
620
+ input: normalizedInput,
621
+ webhookUrl: options?.webhookUrl,
622
+ }, options);
623
+ }
624
+ async createV2StepImageToVideo(input, options) {
625
+ return this.createV2StepVideoFromImage(input, options);
626
+ }
627
+ async getV2StepVideoStatus(requestId, options) {
628
+ const normalizedRequestId = getTrimmedString(requestId);
629
+ if (!normalizedRequestId) {
630
+ throw new Error('requestId is required');
631
+ }
632
+ return this.getV2(`video/step/${encodeURIComponent(normalizedRequestId)}/status`, options);
633
+ }
634
+ async processNextV2StepVideo(requestId, options) {
635
+ const normalizedRequestId = getTrimmedString(requestId);
636
+ if (!normalizedRequestId) {
637
+ throw new Error('requestId is required');
638
+ }
639
+ return this.postV2(`video/step/${encodeURIComponent(normalizedRequestId)}/process_next`, {}, options);
640
+ }
559
641
  async translateV2Video(input, options) {
560
642
  const normalizedInput = normalizeTranslateVideoInput(input, 'translateV2Video');
561
643
  return this.postV2('translate_video', {
@@ -602,7 +684,9 @@ export class SamsarClient {
602
684
  }
603
685
  async getV2Status(requestId, options) {
604
686
  const queryParams = {
605
- ...(options?.externalUser ? buildExternalUserQuery(options.externalUser) : {}),
687
+ ...(options?.externalUser
688
+ ? buildExternalUserQuery(options.externalUser, { requireProvider: false })
689
+ : {}),
606
690
  ...(options?.queryParams ?? {}),
607
691
  };
608
692
  return this.getStatus(requestId, {
@@ -2015,9 +2099,29 @@ export class SamsarClient {
2015
2099
  if (!options?.externalUser) {
2016
2100
  return body;
2017
2101
  }
2102
+ const externalUser = normalizeExternalUserIdentity(options.externalUser, {
2103
+ requireProvider: false,
2104
+ });
2105
+ if (!externalUser.provider) {
2106
+ const referenceKey = externalUser.unique_key ?? externalUser.external_user_id;
2107
+ return {
2108
+ ...body,
2109
+ unique_key: referenceKey,
2110
+ ...(externalUser.external_user_id ? { external_user_id: externalUser.external_user_id } : {}),
2111
+ ...(externalUser.external_app_id ? { external_app_id: externalUser.external_app_id } : {}),
2112
+ ...(externalUser.external_company_id ? { external_company_id: externalUser.external_company_id } : {}),
2113
+ ...(externalUser.external_account_id ? { external_account_id: externalUser.external_account_id } : {}),
2114
+ ...(externalUser.email ? { email: externalUser.email } : {}),
2115
+ ...(externalUser.username ? { username: externalUser.username } : {}),
2116
+ ...(externalUser.display_name ? { display_name: externalUser.display_name } : {}),
2117
+ ...(externalUser.avatar_url ? { avatar_url: externalUser.avatar_url } : {}),
2118
+ ...(externalUser.user_type ? { user_type: externalUser.user_type } : {}),
2119
+ ...(externalUser.metadata ? { metadata: externalUser.metadata } : {}),
2120
+ };
2121
+ }
2018
2122
  return {
2019
2123
  ...body,
2020
- external_user: normalizeExternalUserIdentity(options.externalUser),
2124
+ external_user: externalUser,
2021
2125
  };
2022
2126
  }
2023
2127
  buildV2Url(path) {
@@ -2066,6 +2170,13 @@ function parseNumber(value) {
2066
2170
  const num = value !== undefined ? Number(value) : NaN;
2067
2171
  return Number.isFinite(num) ? num : undefined;
2068
2172
  }
2173
+ function getTrimmedString(value) {
2174
+ if (typeof value !== 'string') {
2175
+ return undefined;
2176
+ }
2177
+ const trimmed = value.trim();
2178
+ return trimmed || undefined;
2179
+ }
2069
2180
  function removeEmptyHeaders(headers) {
2070
2181
  const normalized = {};
2071
2182
  for (const [key, value] of Object.entries(headers)) {
@@ -2075,15 +2186,22 @@ function removeEmptyHeaders(headers) {
2075
2186
  }
2076
2187
  return normalized;
2077
2188
  }
2078
- function normalizeExternalUserIdentity(externalUser) {
2079
- const externalUserId = externalUser.external_user_id ??
2080
- externalUser.externalUserId;
2081
- if (!externalUser?.provider || !externalUserId) {
2082
- throw new Error('externalUser.provider and externalUser.external_user_id are required');
2189
+ function normalizeExternalUserIdentity(externalUser, { requireProvider = true } = {}) {
2190
+ const provider = getTrimmedString(externalUser.provider);
2191
+ const uniqueKey = getTrimmedString(externalUser.unique_key ??
2192
+ externalUser.uniqueKey);
2193
+ const externalUserId = getTrimmedString(externalUser.external_user_id) ??
2194
+ getTrimmedString(externalUser.externalUserId) ??
2195
+ uniqueKey;
2196
+ if ((requireProvider && !provider) || !externalUserId) {
2197
+ throw new Error(requireProvider
2198
+ ? 'externalUser.provider and externalUser.external_user_id or externalUser.unique_key are required'
2199
+ : 'externalUser.external_user_id or externalUser.unique_key is required');
2083
2200
  }
2084
2201
  return {
2085
- provider: externalUser.provider,
2202
+ ...(provider ? { provider } : {}),
2086
2203
  external_user_id: externalUserId,
2204
+ ...(uniqueKey ? { unique_key: uniqueKey } : {}),
2087
2205
  ...(externalUser.external_app_id || externalUser.externalAppId
2088
2206
  ? { external_app_id: externalUser.external_app_id ?? externalUser.externalAppId }
2089
2207
  : {}),
@@ -2112,11 +2230,12 @@ function normalizeExternalUserIdentity(externalUser) {
2112
2230
  ...(externalUser.metadata ? { metadata: externalUser.metadata } : {}),
2113
2231
  };
2114
2232
  }
2115
- function buildExternalUserQuery(externalUser) {
2116
- const normalized = normalizeExternalUserIdentity(externalUser);
2233
+ function buildExternalUserQuery(externalUser, { requireProvider = true } = {}) {
2234
+ const normalized = normalizeExternalUserIdentity(externalUser, { requireProvider });
2117
2235
  return {
2118
2236
  provider: normalized.provider,
2119
2237
  external_user_id: normalized.external_user_id,
2238
+ unique_key: normalized.unique_key ?? undefined,
2120
2239
  external_app_id: normalized.external_app_id ?? undefined,
2121
2240
  external_company_id: normalized.external_company_id ?? undefined,
2122
2241
  external_account_id: normalized.external_account_id ?? undefined,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "samsar-js",
3
- "version": "0.48.26",
3
+ "version": "0.48.27",
4
4
  "description": "TypeScript client for the Samsar Processor API routes.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",