samsar-js 0.48.30 → 0.48.31
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 +25 -1
- package/dist/index.d.ts +40 -0
- package/dist/index.js +136 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -346,6 +346,24 @@ const images = await samsar.extendImageList({
|
|
|
346
346
|
aspect_ratio: '16:9',
|
|
347
347
|
});
|
|
348
348
|
|
|
349
|
+
// Assign a short SEO-friendly image title
|
|
350
|
+
const imageTitle = await samsar.assignImageTitle({
|
|
351
|
+
image_url: 'https://example.com/product-photo.png',
|
|
352
|
+
metadata: {
|
|
353
|
+
product: 'linen travel shirt',
|
|
354
|
+
collection: 'spring essentials',
|
|
355
|
+
},
|
|
356
|
+
});
|
|
357
|
+
console.log(imageTitle.data.content); // "Linen Travel Shirt"
|
|
358
|
+
|
|
359
|
+
// Binary uploads are also supported in browser/Node 18+ runtimes
|
|
360
|
+
const fileTitle = await samsar.assignImageTitle({
|
|
361
|
+
image: fileOrBlob,
|
|
362
|
+
fileName: 'product-photo.png',
|
|
363
|
+
mimeType: 'image/png',
|
|
364
|
+
metadata: { product: 'linen travel shirt' },
|
|
365
|
+
});
|
|
366
|
+
|
|
349
367
|
// Create a reusable receipt template from one sample receipt image (free endpoint)
|
|
350
368
|
const receiptTemplate = await samsar.createReceiptTemplate({
|
|
351
369
|
image_url: 'https://example.com/receipt-template.png',
|
|
@@ -579,7 +597,7 @@ Video model support notes:
|
|
|
579
597
|
|
|
580
598
|
Upcoming `/v2` omni route adapters:
|
|
581
599
|
- `/v2` is additive; `/v1` is not deprecated.
|
|
582
|
-
- `createV2VideoFromText`, `createV2VideoFromImageList`, `translateV2Video`, `cloneV2Video`, `regenerateV2VideoAvatar`, `updateV2VideoOutroImage`, `updateV2VideoFooterImage`, `addV2VideoOutroImage`, `getV2Status`, `getV2StatusDetailed`, `getV2Credits`, `listV2Requests`, and `createV2Session` call the new omni route surface.
|
|
600
|
+
- `createV2VideoFromText`, `createV2VideoFromImageList`, `assignV2ImageTitle`, `translateV2Video`, `cloneV2Video`, `regenerateV2VideoAvatar`, `updateV2VideoOutroImage`, `updateV2VideoFooterImage`, `addV2VideoOutroImage`, `getV2Status`, `getV2StatusDetailed`, `getV2Credits`, `listV2Requests`, and `createV2Session` call the new omni route surface.
|
|
583
601
|
- Step-controlled video helpers include `createV2StepVideoFromText`, `createV2StepTextToVideo`, `createV2StepVideoFromImage`, `createV2StepImageToVideo`, `getV2StepVideoStatus`, `getV2StepVideoStatusDetailed`, and `processNextV2StepVideo`. They default to 1-step express rendering by sending `auto_render_full_video: true` and `manual_step_stages: []`; pass `{ stepMode: 'two_step' }` or `manual_step_stages: ['ai_video_generation']` to require an explicit second-step approval before image-to-video generation.
|
|
584
602
|
- Programmatic user helpers include `createV2ExternalUser`, `createV2UserRechargeCredits`, `refreshV2UserToken`, `createV2UserAppKey`, `refreshV2UserAppKey`, `getV2UserCredits`, `getV2UserUsageLogs`, and `getV2UserPaymentStatus`.
|
|
585
603
|
- 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.
|
|
@@ -601,6 +619,12 @@ const v2ExternalVideo = await platform.createV2VideoFromImageList(
|
|
|
601
619
|
{ externalUser },
|
|
602
620
|
);
|
|
603
621
|
|
|
622
|
+
const v2ImageTitle = await platform.assignV2ImageTitle({
|
|
623
|
+
image_url: 'https://cdn.example.com/product-frame.png',
|
|
624
|
+
metadata: { product: 'travel shirt', channel: 'marketplace' },
|
|
625
|
+
});
|
|
626
|
+
console.log(v2ImageTitle.data.content);
|
|
627
|
+
|
|
604
628
|
const v2Translated = await platform.translateV2Video({
|
|
605
629
|
videoSessionId: v2Video.data.request_id!,
|
|
606
630
|
language: 'es',
|
package/dist/index.d.ts
CHANGED
|
@@ -975,6 +975,33 @@ export interface EnhanceImageResponse {
|
|
|
975
975
|
remainingCredits?: number;
|
|
976
976
|
[key: string]: unknown;
|
|
977
977
|
}
|
|
978
|
+
export type AssignImageTitleMimeType = 'image/png' | 'image/jpeg' | 'image/webp' | 'image/gif';
|
|
979
|
+
export type AssignImageTitleBinaryInput = Blob | ArrayBuffer | Uint8Array;
|
|
980
|
+
export interface AssignImageTitleRequest {
|
|
981
|
+
image?: string | AssignImageTitleBinaryInput;
|
|
982
|
+
file?: AssignImageTitleBinaryInput;
|
|
983
|
+
image_file?: AssignImageTitleBinaryInput;
|
|
984
|
+
imageFile?: AssignImageTitleBinaryInput;
|
|
985
|
+
image_url?: string;
|
|
986
|
+
imageUrl?: string;
|
|
987
|
+
url?: string;
|
|
988
|
+
image_data?: string;
|
|
989
|
+
imageData?: string;
|
|
990
|
+
image_data_url?: string;
|
|
991
|
+
imageDataUrl?: string;
|
|
992
|
+
metadata?: Record<string, unknown> | string;
|
|
993
|
+
metadata_json?: Record<string, unknown> | string;
|
|
994
|
+
metadataJson?: Record<string, unknown> | string;
|
|
995
|
+
fileName?: string;
|
|
996
|
+
filename?: string;
|
|
997
|
+
mimeType?: AssignImageTitleMimeType | string;
|
|
998
|
+
[key: string]: unknown;
|
|
999
|
+
}
|
|
1000
|
+
export interface AssignImageTitleResponse {
|
|
1001
|
+
content: string;
|
|
1002
|
+
title?: string;
|
|
1003
|
+
[key: string]: unknown;
|
|
1004
|
+
}
|
|
978
1005
|
export interface ExtendImageListRequest {
|
|
979
1006
|
image_urls: string[];
|
|
980
1007
|
num_images: number;
|
|
@@ -1978,6 +2005,12 @@ export declare class SamsarClient {
|
|
|
1978
2005
|
uploadV2ImageData(imageData: string[], options?: V2RequestOptions): Promise<SamsarResult<{
|
|
1979
2006
|
image_urls: string[];
|
|
1980
2007
|
}>>;
|
|
2008
|
+
/**
|
|
2009
|
+
* Assign a short SEO-friendly title to an image using the /v2 image route.
|
|
2010
|
+
* Supports image_url/image_data JSON payloads or binary image/FormData uploads.
|
|
2011
|
+
*/
|
|
2012
|
+
assignV2ImageTitle(payload: AssignImageTitleRequest | FormData, options?: V2RequestOptions): Promise<SamsarResult<AssignImageTitleResponse>>;
|
|
2013
|
+
assignV2TitleToImage(payload: AssignImageTitleRequest | FormData, options?: V2RequestOptions): Promise<SamsarResult<AssignImageTitleResponse>>;
|
|
1981
2014
|
updateV2VideoOutroImage(input: UpdateVideoOutroImageInput, options?: V2RequestOptions): Promise<SamsarResult<UpdateVideoOutroImageResponse | ExternalRequestResponse>>;
|
|
1982
2015
|
updateV2VideoFooterImage(input: UpdateVideoFooterImageInput, options?: V2RequestOptions): Promise<SamsarResult<UpdateVideoFooterImageResponse | ExternalRequestResponse>>;
|
|
1983
2016
|
addV2VideoOutroImage(input: AddVideoOutroImageInput, options?: V2RequestOptions): Promise<SamsarResult<AddVideoOutroImageResponse | ExternalRequestResponse>>;
|
|
@@ -2263,6 +2296,12 @@ export declare class SamsarClient {
|
|
|
2263
2296
|
* Enhance an image by upscaling it with the specified resolution.
|
|
2264
2297
|
*/
|
|
2265
2298
|
enhanceImage(payload: EnhanceImageRequest, options?: SamsarRequestOptions): Promise<SamsarResult<EnhanceImageResponse>>;
|
|
2299
|
+
/**
|
|
2300
|
+
* Assign a short SEO-friendly title to an image.
|
|
2301
|
+
* Supports image_url/image_data JSON payloads or binary image/FormData uploads.
|
|
2302
|
+
*/
|
|
2303
|
+
assignImageTitle(payload: AssignImageTitleRequest | FormData, options?: SamsarRequestOptions): Promise<SamsarResult<AssignImageTitleResponse>>;
|
|
2304
|
+
assignTitleToImage(payload: AssignImageTitleRequest | FormData, options?: SamsarRequestOptions): Promise<SamsarResult<AssignImageTitleResponse>>;
|
|
2266
2305
|
/**
|
|
2267
2306
|
* Add or extend a saved image list for the authenticated API key.
|
|
2268
2307
|
*/
|
|
@@ -2379,6 +2418,7 @@ export declare class SamsarClient {
|
|
|
2379
2418
|
}): Promise<SamsarResult<GlobalStatusResponse>>;
|
|
2380
2419
|
private get;
|
|
2381
2420
|
private post;
|
|
2421
|
+
private postForm;
|
|
2382
2422
|
private request;
|
|
2383
2423
|
private buildHeaders;
|
|
2384
2424
|
private buildUrl;
|
package/dist/index.js
CHANGED
|
@@ -792,6 +792,22 @@ export class SamsarClient {
|
|
|
792
792
|
},
|
|
793
793
|
}, options);
|
|
794
794
|
}
|
|
795
|
+
/**
|
|
796
|
+
* Assign a short SEO-friendly title to an image using the /v2 image route.
|
|
797
|
+
* Supports image_url/image_data JSON payloads or binary image/FormData uploads.
|
|
798
|
+
*/
|
|
799
|
+
async assignV2ImageTitle(payload, options) {
|
|
800
|
+
const body = buildAssignImageTitleBody(payload);
|
|
801
|
+
if (isFormDataBody(body)) {
|
|
802
|
+
return this.postForm(this.buildV2Url('image/assign_title'), body, options);
|
|
803
|
+
}
|
|
804
|
+
return this.postV2('image/assign_title', {
|
|
805
|
+
input: body,
|
|
806
|
+
}, options);
|
|
807
|
+
}
|
|
808
|
+
async assignV2TitleToImage(payload, options) {
|
|
809
|
+
return this.assignV2ImageTitle(payload, options);
|
|
810
|
+
}
|
|
795
811
|
async updateV2VideoOutroImage(input, options) {
|
|
796
812
|
const normalizedInput = normalizeUpdateVideoOutroImageInput(input, 'updateV2VideoOutroImage');
|
|
797
813
|
return this.postV2('update_outro_image', {
|
|
@@ -1758,6 +1774,20 @@ export class SamsarClient {
|
|
|
1758
1774
|
async enhanceImage(payload, options) {
|
|
1759
1775
|
return this.post('image/enhance', payload, options);
|
|
1760
1776
|
}
|
|
1777
|
+
/**
|
|
1778
|
+
* Assign a short SEO-friendly title to an image.
|
|
1779
|
+
* Supports image_url/image_data JSON payloads or binary image/FormData uploads.
|
|
1780
|
+
*/
|
|
1781
|
+
async assignImageTitle(payload, options) {
|
|
1782
|
+
const body = buildAssignImageTitleBody(payload);
|
|
1783
|
+
if (isFormDataBody(body)) {
|
|
1784
|
+
return this.postForm('image/assign_title', body, options);
|
|
1785
|
+
}
|
|
1786
|
+
return this.post('image/assign_title', body, options);
|
|
1787
|
+
}
|
|
1788
|
+
async assignTitleToImage(payload, options) {
|
|
1789
|
+
return this.assignImageTitle(payload, options);
|
|
1790
|
+
}
|
|
1761
1791
|
/**
|
|
1762
1792
|
* Add or extend a saved image list for the authenticated API key.
|
|
1763
1793
|
*/
|
|
@@ -2132,6 +2162,13 @@ export class SamsarClient {
|
|
|
2132
2162
|
body: JSON.stringify(body),
|
|
2133
2163
|
});
|
|
2134
2164
|
}
|
|
2165
|
+
async postForm(path, body, options) {
|
|
2166
|
+
return this.request(path, {
|
|
2167
|
+
...(options ?? {}),
|
|
2168
|
+
method: 'POST',
|
|
2169
|
+
body,
|
|
2170
|
+
});
|
|
2171
|
+
}
|
|
2135
2172
|
async request(path, options) {
|
|
2136
2173
|
const url = this.buildUrl(path, options.query);
|
|
2137
2174
|
const controller = new AbortController();
|
|
@@ -2221,7 +2258,7 @@ export class SamsarClient {
|
|
|
2221
2258
|
: this.apiKey
|
|
2222
2259
|
? `Bearer ${this.apiKey}`
|
|
2223
2260
|
: undefined,
|
|
2224
|
-
'Content-Type': options.body ? 'application/json' : undefined,
|
|
2261
|
+
'Content-Type': options.body && !isFormDataBody(options.body) ? 'application/json' : undefined,
|
|
2225
2262
|
'x-external-user-api-key': options.externalUserApiKey ?? this.externalUserApiKey,
|
|
2226
2263
|
'x-app-secret': resolvedAppKey ? resolvedAppSecret : undefined,
|
|
2227
2264
|
...this.defaultHeaders,
|
|
@@ -2288,6 +2325,104 @@ export class SamsarClient {
|
|
|
2288
2325
|
function trimTrailingSlash(url) {
|
|
2289
2326
|
return url.replace(/\/+$/, '');
|
|
2290
2327
|
}
|
|
2328
|
+
function buildAssignImageTitleBody(payload) {
|
|
2329
|
+
if (isFormDataBody(payload)) {
|
|
2330
|
+
return payload;
|
|
2331
|
+
}
|
|
2332
|
+
const input = (payload ?? {});
|
|
2333
|
+
const image = input.image ??
|
|
2334
|
+
input.file ??
|
|
2335
|
+
input.image_file ??
|
|
2336
|
+
input.imageFile;
|
|
2337
|
+
if (isBinaryAssignImageTitleInput(image)) {
|
|
2338
|
+
return buildAssignImageTitleFormData(input, image);
|
|
2339
|
+
}
|
|
2340
|
+
const stringImage = getTrimmedString(image);
|
|
2341
|
+
const imageData = stringImage?.startsWith('data:image/')
|
|
2342
|
+
? stringImage
|
|
2343
|
+
: getTrimmedString(input.image_data) ??
|
|
2344
|
+
getTrimmedString(input.imageData) ??
|
|
2345
|
+
getTrimmedString(input.image_data_url) ??
|
|
2346
|
+
getTrimmedString(input.imageDataUrl);
|
|
2347
|
+
const imageUrl = stringImage && !stringImage.startsWith('data:image/')
|
|
2348
|
+
? stringImage
|
|
2349
|
+
: getTrimmedString(input.image_url) ??
|
|
2350
|
+
getTrimmedString(input.imageUrl) ??
|
|
2351
|
+
getTrimmedString(input.url);
|
|
2352
|
+
const metadata = input.metadata ?? input.metadata_json ?? input.metadataJson;
|
|
2353
|
+
if (!imageData && !imageUrl) {
|
|
2354
|
+
throw new Error('image, image_data, or image_url is required for assignImageTitle');
|
|
2355
|
+
}
|
|
2356
|
+
return {
|
|
2357
|
+
...(imageData ? { image_data: imageData } : {}),
|
|
2358
|
+
...(imageUrl ? { image_url: imageUrl } : {}),
|
|
2359
|
+
...(metadata !== undefined ? { metadata } : {}),
|
|
2360
|
+
};
|
|
2361
|
+
}
|
|
2362
|
+
function buildAssignImageTitleFormData(input, image) {
|
|
2363
|
+
if (typeof FormData === 'undefined') {
|
|
2364
|
+
throw new Error('FormData is required for binary assignImageTitle uploads');
|
|
2365
|
+
}
|
|
2366
|
+
const metadata = input.metadata ?? input.metadata_json ?? input.metadataJson;
|
|
2367
|
+
const mimeType = getTrimmedString(input.mimeType) ?? getBlobType(image);
|
|
2368
|
+
if (!mimeType || !isSupportedAssignImageTitleMimeType(mimeType)) {
|
|
2369
|
+
throw new Error('mimeType must be image/png, image/jpeg, image/webp, or image/gif for binary assignImageTitle uploads');
|
|
2370
|
+
}
|
|
2371
|
+
const blob = toAssignImageTitleBlob(image, mimeType);
|
|
2372
|
+
const fileName = getTrimmedString(input.fileName) ??
|
|
2373
|
+
getTrimmedString(input.filename) ??
|
|
2374
|
+
`image.${mimeTypeToExtension(mimeType)}`;
|
|
2375
|
+
const formData = new FormData();
|
|
2376
|
+
formData.append('image', blob, fileName);
|
|
2377
|
+
if (metadata !== undefined) {
|
|
2378
|
+
formData.append('metadata', typeof metadata === 'string' ? metadata : JSON.stringify(metadata));
|
|
2379
|
+
}
|
|
2380
|
+
return formData;
|
|
2381
|
+
}
|
|
2382
|
+
function isBinaryAssignImageTitleInput(value) {
|
|
2383
|
+
return (isBlobValue(value) ||
|
|
2384
|
+
value instanceof ArrayBuffer ||
|
|
2385
|
+
value instanceof Uint8Array);
|
|
2386
|
+
}
|
|
2387
|
+
function toAssignImageTitleBlob(value, mimeType) {
|
|
2388
|
+
if (isBlobValue(value)) {
|
|
2389
|
+
if (value.type === mimeType) {
|
|
2390
|
+
return value;
|
|
2391
|
+
}
|
|
2392
|
+
return new Blob([value], { type: mimeType });
|
|
2393
|
+
}
|
|
2394
|
+
if (value instanceof Uint8Array) {
|
|
2395
|
+
const arrayBuffer = value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength);
|
|
2396
|
+
return new Blob([arrayBuffer], { type: mimeType });
|
|
2397
|
+
}
|
|
2398
|
+
return new Blob([value], { type: mimeType });
|
|
2399
|
+
}
|
|
2400
|
+
function getBlobType(value) {
|
|
2401
|
+
return isBlobValue(value) ? getTrimmedString(value.type) : undefined;
|
|
2402
|
+
}
|
|
2403
|
+
function isBlobValue(value) {
|
|
2404
|
+
return typeof Blob !== 'undefined' && value instanceof Blob;
|
|
2405
|
+
}
|
|
2406
|
+
function isFormDataBody(body) {
|
|
2407
|
+
return typeof FormData !== 'undefined' && body instanceof FormData;
|
|
2408
|
+
}
|
|
2409
|
+
function isSupportedAssignImageTitleMimeType(value) {
|
|
2410
|
+
const normalized = value.trim().toLowerCase();
|
|
2411
|
+
return ['image/png', 'image/jpeg', 'image/jpg', 'image/webp', 'image/gif'].includes(normalized);
|
|
2412
|
+
}
|
|
2413
|
+
function mimeTypeToExtension(value) {
|
|
2414
|
+
const normalized = value.trim().toLowerCase();
|
|
2415
|
+
if (normalized === 'image/jpeg' || normalized === 'image/jpg') {
|
|
2416
|
+
return 'jpg';
|
|
2417
|
+
}
|
|
2418
|
+
if (normalized === 'image/webp') {
|
|
2419
|
+
return 'webp';
|
|
2420
|
+
}
|
|
2421
|
+
if (normalized === 'image/gif') {
|
|
2422
|
+
return 'gif';
|
|
2423
|
+
}
|
|
2424
|
+
return 'png';
|
|
2425
|
+
}
|
|
2291
2426
|
function parseMaybeJson(value) {
|
|
2292
2427
|
try {
|
|
2293
2428
|
return JSON.parse(value);
|