samsar-js 0.48.24 → 0.48.25

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
@@ -153,8 +153,9 @@ const translated = await samsar.translateVideo(
153
153
  {
154
154
  videoSessionId: videoFromImages.data.session_id ?? videoFromImages.data.request_id!,
155
155
  language: 'es',
156
- // Optional: override the outro image in the translated session
157
- outro_image_url: 'https://cdn.example.com/outro.png',
156
+ enable_subtitles: false,
157
+ translate_outro: true,
158
+ translate_footer: true,
158
159
  },
159
160
  { webhookUrl: 'https://example.com/webhook' },
160
161
  );
@@ -550,7 +551,7 @@ Video model support notes:
550
551
 
551
552
  Upcoming `/v2` omni route adapters:
552
553
  - `/v2` is additive; `/v1` is not deprecated.
553
- - `createV2VideoFromText`, `createV2VideoFromImageList`, `updateV2VideoOutroImage`, `updateV2VideoFooterImage`, `addV2VideoOutroImage`, `getV2Status`, `getV2Credits`, `listV2Requests`, and `createV2Session` call the new omni route surface.
554
+ - `createV2VideoFromText`, `createV2VideoFromImageList`, `translateV2Video`, `updateV2VideoOutroImage`, `updateV2VideoFooterImage`, `addV2VideoOutroImage`, `getV2Status`, `getV2Credits`, `listV2Requests`, and `createV2Session` call the new omni route surface.
554
555
  - Programmatic user billing helpers include `createV2UserRechargeCredits`, `refreshV2UserToken`, `createV2UserAppKey`, `refreshV2UserAppKey`, `getV2UserCredits`, `getV2UserUsageLogs`, and `getV2UserPaymentStatus`.
555
556
  - 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.
556
557
 
@@ -571,6 +572,14 @@ const v2ExternalVideo = await platform.createV2VideoFromImageList(
571
572
  { externalUser },
572
573
  );
573
574
 
575
+ const v2Translated = await platform.translateV2Video({
576
+ videoSessionId: v2Video.data.request_id!,
577
+ language: 'es',
578
+ enable_subtitles: false,
579
+ translate_outro: true,
580
+ translate_footer: true,
581
+ });
582
+
574
583
  const v2Status = await platform.getV2Status(v2Video.data.request_id!);
575
584
  console.log(v2Status.data.status);
576
585
  ```
package/dist/index.d.ts CHANGED
@@ -219,10 +219,14 @@ export interface TranslateVideoInput {
219
219
  langauge?: string;
220
220
  langauge_code?: string;
221
221
  langaugeCode?: string;
222
- outro_image_url?: string;
223
- outroImageUrl?: string;
224
- new_outro_image_url?: string;
225
- newOutroImageUrl?: string;
222
+ enable_subtitles?: boolean;
223
+ enableSubtitles?: boolean;
224
+ add_subtitles?: boolean;
225
+ addSubtitles?: boolean;
226
+ translate_outro?: boolean;
227
+ translateOutro?: boolean;
228
+ translate_footer?: boolean;
229
+ translateFooter?: boolean;
226
230
  [key: string]: unknown;
227
231
  }
228
232
  export interface TranslateVideoResponse {
@@ -1717,6 +1721,7 @@ export declare class SamsarClient {
1717
1721
  }): Promise<SamsarResult<CreateLoginTokenResponse | ExternalCreateLoginTokenResponse>>;
1718
1722
  createV2VideoFromText(input: CreateVideoFromTextInput, options?: V2RequestOptions): Promise<SamsarResult<CreateVideoResponse | ExternalRequestResponse>>;
1719
1723
  createV2VideoFromImageList(input: CreateVideoFromImageListInput, options?: V2RequestOptions): Promise<SamsarResult<CreateVideoFromImageListResponse | ExternalRequestResponse>>;
1724
+ translateV2Video(input: TranslateVideoInput, options?: V2RequestOptions): Promise<SamsarResult<TranslateVideoResponse | ExternalRequestResponse>>;
1720
1725
  uploadV2ImageData(imageData: string[], options?: V2RequestOptions): Promise<SamsarResult<{
1721
1726
  image_urls: string[];
1722
1727
  }>>;
package/dist/index.js CHANGED
@@ -126,6 +126,50 @@ function normalizeCreateVideoFromImageListInput(input) {
126
126
  }
127
127
  return normalized;
128
128
  }
129
+ function normalizeTranslateVideoInput(input, context = 'translateVideo') {
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
+ const language = raw.language ??
140
+ raw.language_code ??
141
+ raw.languageCode ??
142
+ raw.langauge ??
143
+ raw.langauge_code ??
144
+ raw.langaugeCode ??
145
+ raw.languageString;
146
+ const enableSubtitles = resolveAliasedInputValue(raw, ['enable_subtitles', 'enableSubtitles', 'add_subtitles', 'addSubtitles'], 'enable_subtitles') ?? false;
147
+ const translateOutro = resolveAliasedInputValue(raw, ['translate_outro', 'translateOutro'], 'translate_outro') ?? true;
148
+ const translateFooter = resolveAliasedInputValue(raw, ['translate_footer', 'translateFooter'], 'translate_footer') ?? true;
149
+ if (!videoSessionId) {
150
+ throw new Error(`videoSessionId is required for ${context}`);
151
+ }
152
+ if (!language) {
153
+ throw new Error(`language is required for ${context}`);
154
+ }
155
+ assertOptionalBoolean(enableSubtitles, 'enable_subtitles', context);
156
+ assertOptionalBoolean(translateOutro, 'translate_outro', context);
157
+ assertOptionalBoolean(translateFooter, 'translate_footer', context);
158
+ const normalizedInput = { ...input };
159
+ delete normalizedInput.outro_image_url;
160
+ delete normalizedInput.outroImageUrl;
161
+ delete normalizedInput.outroImageURL;
162
+ delete normalizedInput.new_outro_image_url;
163
+ delete normalizedInput.newOutroImageUrl;
164
+ return {
165
+ ...normalizedInput,
166
+ videoSessionId: String(videoSessionId),
167
+ language: String(language),
168
+ enable_subtitles: enableSubtitles,
169
+ translate_outro: translateOutro,
170
+ translate_footer: translateFooter,
171
+ };
172
+ }
129
173
  function normalizeUpdateVideoOutroImageInput(input, context = 'updateVideoOutroImage') {
130
174
  const raw = input;
131
175
  const videoSessionId = raw.videoSessionId ??
@@ -490,6 +534,13 @@ export class SamsarClient {
490
534
  webhookUrl: options?.webhookUrl,
491
535
  }, options);
492
536
  }
537
+ async translateV2Video(input, options) {
538
+ const normalizedInput = normalizeTranslateVideoInput(input, 'translateV2Video');
539
+ return this.postV2('translate_video', {
540
+ input: normalizedInput,
541
+ webhookUrl: options?.webhookUrl,
542
+ }, options);
543
+ }
493
544
  async uploadV2ImageData(imageData, options) {
494
545
  if (!Array.isArray(imageData) || imageData.length === 0) {
495
546
  throw new Error('imageData must be a non-empty array of data URLs');
@@ -703,33 +754,10 @@ export class SamsarClient {
703
754
  * Creates a new session_id and queues generation steps for lip sync + transcription + video render.
704
755
  */
705
756
  async translateVideo(input, options) {
706
- const raw = input;
707
- const videoSessionId = raw.videoSessionId ??
708
- raw.video_session_id ??
709
- raw.videoSessionID ??
710
- raw.session_id ??
711
- raw.sessionId ??
712
- raw.sessionID ??
713
- raw.request_id ??
714
- raw.requestId;
715
- const language = raw.language ??
716
- raw.language_code ??
717
- raw.languageCode ??
718
- raw.langauge ??
719
- raw.langauge_code ??
720
- raw.langaugeCode ??
721
- raw.languageString;
722
- if (!videoSessionId) {
723
- throw new Error('videoSessionId is required for translateVideo');
724
- }
725
- if (!language) {
726
- throw new Error('language is required for translateVideo');
727
- }
757
+ const normalizedInput = normalizeTranslateVideoInput(input, 'translateVideo');
728
758
  const body = {
729
759
  input: {
730
- ...input,
731
- videoSessionId: String(videoSessionId),
732
- language: String(language),
760
+ ...normalizedInput,
733
761
  },
734
762
  webhookUrl: options?.webhookUrl,
735
763
  };
@@ -1861,7 +1889,10 @@ export class SamsarClient {
1861
1889
  body: parsedBody,
1862
1890
  });
1863
1891
  }
1864
- throw new SamsarRequestError(`Request to ${url} failed with status ${response.status}`, {
1892
+ const responseMessage = getResponseErrorMessage(parsedBody);
1893
+ throw new SamsarRequestError(responseMessage
1894
+ ? `Request to ${url} failed with status ${response.status}: ${responseMessage}`
1895
+ : `Request to ${url} failed with status ${response.status}`, {
1865
1896
  status: response.status,
1866
1897
  body: parsedBody,
1867
1898
  headers: headerRecord,
@@ -1943,6 +1974,25 @@ function parseMaybeJson(value) {
1943
1974
  return value;
1944
1975
  }
1945
1976
  }
1977
+ function getResponseErrorMessage(body) {
1978
+ if (!body || typeof body !== 'object' || Array.isArray(body)) {
1979
+ return typeof body === 'string' && body.trim() ? body.trim() : null;
1980
+ }
1981
+ const record = body;
1982
+ for (const key of ['message', 'error', 'detail']) {
1983
+ const value = record[key];
1984
+ if (typeof value === 'string' && value.trim()) {
1985
+ return value.trim();
1986
+ }
1987
+ }
1988
+ if (record.error && typeof record.error === 'object' && !Array.isArray(record.error)) {
1989
+ const nestedMessage = record.error.message;
1990
+ if (typeof nestedMessage === 'string' && nestedMessage.trim()) {
1991
+ return nestedMessage.trim();
1992
+ }
1993
+ }
1994
+ return null;
1995
+ }
1946
1996
  function headersToObject(headers) {
1947
1997
  const result = {};
1948
1998
  headers.forEach((value, key) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "samsar-js",
3
- "version": "0.48.24",
3
+ "version": "0.48.25",
4
4
  "description": "TypeScript client for the Samsar Processor API routes.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",