samsar-js 0.48.19 → 0.48.21
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 +36 -0
- package/dist/index.d.ts +121 -2
- package/dist/index.js +119 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -512,6 +512,7 @@ Video model support notes:
|
|
|
512
512
|
Upcoming `/v2` omni route adapters:
|
|
513
513
|
- `/v2` is additive; `/v1` is not deprecated.
|
|
514
514
|
- `createV2VideoFromText`, `createV2VideoFromImageList`, `updateV2VideoOutroImage`, `addV2VideoOutroImage`, `getV2Status`, `getV2Credits`, `listV2Requests`, and `createV2Session` call the new omni route surface.
|
|
515
|
+
- Programmatic user billing helpers include `createV2UserRechargeCredits`, `refreshV2UserToken`, `createV2UserAppKey`, `refreshV2UserAppKey`, `getV2UserCredits`, `getV2UserUsageLogs`, and `getV2UserPaymentStatus`.
|
|
515
516
|
- 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
|
|
|
517
518
|
```ts
|
|
@@ -535,6 +536,41 @@ const v2Status = await platform.getV2Status(v2Video.data.request_id!);
|
|
|
535
536
|
console.log(v2Status.data.status);
|
|
536
537
|
```
|
|
537
538
|
|
|
539
|
+
Programmatic user recharge and OAuth-style refresh token rotation:
|
|
540
|
+
|
|
541
|
+
```ts
|
|
542
|
+
const publicClient = new SamsarClient({});
|
|
543
|
+
|
|
544
|
+
const checkout = await publicClient.createV2UserRechargeCredits({
|
|
545
|
+
amount: 25,
|
|
546
|
+
email: 'customer@example.com',
|
|
547
|
+
redirect_url: 'https://example.com/samsar/callback',
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
// After the Stripe webhook calls your redirect_url with authToken, refreshToken, and expiryDate:
|
|
551
|
+
const userClient = new SamsarClient({ apiKey: authToken });
|
|
552
|
+
const refreshed = await userClient.refreshV2UserToken(refreshToken);
|
|
553
|
+
|
|
554
|
+
localStorage.setItem('authToken', refreshed.data.authToken);
|
|
555
|
+
localStorage.setItem('refreshToken', refreshed.data.refreshToken);
|
|
556
|
+
localStorage.setItem('expiryDate', refreshed.data.expiryDate);
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
Long-running app credentials:
|
|
560
|
+
|
|
561
|
+
```ts
|
|
562
|
+
const secret = crypto.randomUUID() + crypto.randomUUID();
|
|
563
|
+
const created = await userClient.createV2UserAppKey({ secret });
|
|
564
|
+
|
|
565
|
+
const appClient = new SamsarClient({
|
|
566
|
+
appKey: created.data.appKey ?? created.data.app_key,
|
|
567
|
+
appSecret: secret,
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
const credits = await appClient.getV2UserCredits();
|
|
571
|
+
const rotated = await appClient.refreshV2UserAppKey();
|
|
572
|
+
```
|
|
573
|
+
|
|
538
574
|
Each method returns `{ data, status, headers, creditsCharged, creditsRemaining, raw }`. Non-2xx responses throw `SamsarRequestError` containing status, body, and credit headers (if present).
|
|
539
575
|
|
|
540
576
|
## Billing notes
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,9 @@ type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Respo
|
|
|
2
2
|
type QueryValue = string | number | boolean | null | undefined;
|
|
3
3
|
type QueryParams = Record<string, QueryValue>;
|
|
4
4
|
export interface SamsarClientOptions {
|
|
5
|
-
apiKey
|
|
5
|
+
apiKey?: string;
|
|
6
|
+
appKey?: string;
|
|
7
|
+
appSecret?: string;
|
|
6
8
|
baseUrl?: string;
|
|
7
9
|
timeoutMs?: number;
|
|
8
10
|
fetch?: FetchLike;
|
|
@@ -13,6 +15,8 @@ export interface SamsarRequestOptions {
|
|
|
13
15
|
idempotencyKey?: string;
|
|
14
16
|
headers?: Record<string, string>;
|
|
15
17
|
externalUserApiKey?: string;
|
|
18
|
+
appKey?: string;
|
|
19
|
+
appSecret?: string;
|
|
16
20
|
signal?: AbortSignal;
|
|
17
21
|
query?: QueryParams;
|
|
18
22
|
}
|
|
@@ -1334,6 +1338,105 @@ export interface V2RequestsListResponse {
|
|
|
1334
1338
|
externalUser?: ExternalUserSummary | null;
|
|
1335
1339
|
[key: string]: unknown;
|
|
1336
1340
|
}
|
|
1341
|
+
export interface V2UserRechargeCreditsRequest {
|
|
1342
|
+
amount: number;
|
|
1343
|
+
email: string;
|
|
1344
|
+
redirect_url?: string;
|
|
1345
|
+
redirectUrl?: string;
|
|
1346
|
+
[key: string]: unknown;
|
|
1347
|
+
}
|
|
1348
|
+
export interface V2UserRechargeCreditsResponse {
|
|
1349
|
+
url: string;
|
|
1350
|
+
checkoutSessionId?: string | null;
|
|
1351
|
+
paymentStatusEndpoint?: string;
|
|
1352
|
+
amount: number;
|
|
1353
|
+
amountCents: number;
|
|
1354
|
+
credits: number;
|
|
1355
|
+
currency: string;
|
|
1356
|
+
redirectUrl?: string;
|
|
1357
|
+
[key: string]: unknown;
|
|
1358
|
+
}
|
|
1359
|
+
export interface V2UserTokenRefreshRequest {
|
|
1360
|
+
refreshToken?: string;
|
|
1361
|
+
refresh_token?: string;
|
|
1362
|
+
}
|
|
1363
|
+
export interface V2UserTokenResponse {
|
|
1364
|
+
tokenType?: 'Bearer' | string;
|
|
1365
|
+
authToken: string;
|
|
1366
|
+
refreshToken: string;
|
|
1367
|
+
expiryDate: string;
|
|
1368
|
+
expiresInSeconds?: number;
|
|
1369
|
+
refreshTokenExpiresAt?: string;
|
|
1370
|
+
[key: string]: unknown;
|
|
1371
|
+
}
|
|
1372
|
+
export interface V2UserAppKeyRequest {
|
|
1373
|
+
secret?: string;
|
|
1374
|
+
appSecret?: string;
|
|
1375
|
+
app_secret?: string;
|
|
1376
|
+
metadata?: Record<string, unknown>;
|
|
1377
|
+
[key: string]: unknown;
|
|
1378
|
+
}
|
|
1379
|
+
export interface V2UserAppKeyRefreshRequest {
|
|
1380
|
+
appKey?: string;
|
|
1381
|
+
app_key?: string;
|
|
1382
|
+
secret?: string;
|
|
1383
|
+
appSecret?: string;
|
|
1384
|
+
app_secret?: string;
|
|
1385
|
+
[key: string]: unknown;
|
|
1386
|
+
}
|
|
1387
|
+
export interface V2UserAppKeyRecord {
|
|
1388
|
+
id?: string;
|
|
1389
|
+
userId?: string;
|
|
1390
|
+
appKeyPrefix?: string | null;
|
|
1391
|
+
appKeyLast4?: string | null;
|
|
1392
|
+
status?: 'active' | 'revoked' | string;
|
|
1393
|
+
expiresAt?: string | null;
|
|
1394
|
+
lastUsedAt?: string | null;
|
|
1395
|
+
refreshedAt?: string | null;
|
|
1396
|
+
revokedAt?: string | null;
|
|
1397
|
+
rotationCount?: number;
|
|
1398
|
+
createdAt?: string | null;
|
|
1399
|
+
updatedAt?: string | null;
|
|
1400
|
+
authScheme?: string;
|
|
1401
|
+
authHeader?: string;
|
|
1402
|
+
secretHeader?: string;
|
|
1403
|
+
[key: string]: unknown;
|
|
1404
|
+
}
|
|
1405
|
+
export interface V2UserAppKeyResponse {
|
|
1406
|
+
app_key?: string;
|
|
1407
|
+
appKey?: string;
|
|
1408
|
+
token_type?: 'AppKey' | string;
|
|
1409
|
+
tokenType?: 'AppKey' | string;
|
|
1410
|
+
expires_at?: string;
|
|
1411
|
+
expiresAt?: string;
|
|
1412
|
+
app_key_record?: V2UserAppKeyRecord;
|
|
1413
|
+
appKeyRecord?: V2UserAppKeyRecord;
|
|
1414
|
+
[key: string]: unknown;
|
|
1415
|
+
}
|
|
1416
|
+
export interface UsageLogItem {
|
|
1417
|
+
id?: string;
|
|
1418
|
+
source?: string;
|
|
1419
|
+
credits?: number;
|
|
1420
|
+
balanceAfter?: number | null;
|
|
1421
|
+
metadata?: Record<string, unknown>;
|
|
1422
|
+
direction?: string;
|
|
1423
|
+
createdAt?: string;
|
|
1424
|
+
updatedAt?: string;
|
|
1425
|
+
[key: string]: unknown;
|
|
1426
|
+
}
|
|
1427
|
+
export interface UsageLogsResponse {
|
|
1428
|
+
items: UsageLogItem[];
|
|
1429
|
+
pagination?: {
|
|
1430
|
+
page?: number;
|
|
1431
|
+
pageSize?: number;
|
|
1432
|
+
totalItems?: number;
|
|
1433
|
+
totalPages?: number;
|
|
1434
|
+
hasNextPage?: boolean;
|
|
1435
|
+
hasPreviousPage?: boolean;
|
|
1436
|
+
[key: string]: unknown;
|
|
1437
|
+
};
|
|
1438
|
+
[key: string]: unknown;
|
|
1439
|
+
}
|
|
1337
1440
|
export interface ExternalArchiveResponse {
|
|
1338
1441
|
request?: ExternalRequestSummary | null;
|
|
1339
1442
|
external_user?: ExternalUserSummary | null;
|
|
@@ -1516,7 +1619,9 @@ export declare class SamsarRequestError extends Error {
|
|
|
1516
1619
|
constructor(message: string, init: SamsarErrorInit);
|
|
1517
1620
|
}
|
|
1518
1621
|
export declare class SamsarClient {
|
|
1519
|
-
private readonly apiKey
|
|
1622
|
+
private readonly apiKey?;
|
|
1623
|
+
private readonly appKey?;
|
|
1624
|
+
private readonly appSecret?;
|
|
1520
1625
|
private readonly baseUrl;
|
|
1521
1626
|
private readonly timeoutMs;
|
|
1522
1627
|
private readonly fetchFn;
|
|
@@ -1535,7 +1640,21 @@ export declare class SamsarClient {
|
|
|
1535
1640
|
getV2<T = Record<string, unknown>>(path: string, options?: V2RequestOptions): Promise<SamsarResult<T>>;
|
|
1536
1641
|
createV2Session(options?: V2RequestOptions): Promise<SamsarResult<V2SessionResponse>>;
|
|
1537
1642
|
getV2Credits(options?: V2RequestOptions): Promise<SamsarResult<CreditsBalanceResponse | ExternalCreditsBalanceResponse>>;
|
|
1643
|
+
getV2UserCredits(options?: V2RequestOptions): Promise<SamsarResult<CreditsBalanceResponse>>;
|
|
1644
|
+
getV2UserUsageLogs(options?: V2RequestOptions & {
|
|
1645
|
+
page?: number;
|
|
1646
|
+
pageSize?: number;
|
|
1647
|
+
limit?: number;
|
|
1648
|
+
}): Promise<SamsarResult<UsageLogsResponse>>;
|
|
1538
1649
|
listV2Requests(options?: V2RequestOptions): Promise<SamsarResult<V2RequestsListResponse>>;
|
|
1650
|
+
createV2UserRechargeCredits(payload: V2UserRechargeCreditsRequest, options?: V2RequestOptions): Promise<SamsarResult<V2UserRechargeCreditsResponse>>;
|
|
1651
|
+
refreshV2UserToken(payload: string | V2UserTokenRefreshRequest, options?: V2RequestOptions): Promise<SamsarResult<V2UserTokenResponse>>;
|
|
1652
|
+
refreshV2UserAuthToken(payload: string | V2UserTokenRefreshRequest, options?: V2RequestOptions): Promise<SamsarResult<V2UserTokenResponse>>;
|
|
1653
|
+
createV2UserAppKey(payload: string | V2UserAppKeyRequest, options?: V2RequestOptions): Promise<SamsarResult<V2UserAppKeyResponse>>;
|
|
1654
|
+
getV2UserAppKey(options?: V2RequestOptions): Promise<SamsarResult<V2UserAppKeyResponse>>;
|
|
1655
|
+
refreshV2UserAppKey(payload?: V2UserAppKeyRefreshRequest, options?: V2RequestOptions): Promise<SamsarResult<V2UserAppKeyResponse>>;
|
|
1656
|
+
revokeV2UserAppKey(options?: V2RequestOptions): Promise<SamsarResult<V2UserAppKeyResponse>>;
|
|
1657
|
+
getV2UserPaymentStatus(payload: PaymentStatusRequest, options?: V2RequestOptions): Promise<SamsarResult<PaymentStatusResponse>>;
|
|
1539
1658
|
createV2LoginToken(options?: V2RequestOptions & {
|
|
1540
1659
|
redirect?: string;
|
|
1541
1660
|
}): Promise<SamsarResult<CreateLoginTokenResponse | ExternalCreateLoginTokenResponse>>;
|
package/dist/index.js
CHANGED
|
@@ -270,10 +270,9 @@ function normalizeSessionPublicationInput(input, context) {
|
|
|
270
270
|
}
|
|
271
271
|
export class SamsarClient {
|
|
272
272
|
constructor(options) {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
this.apiKey = options.apiKey;
|
|
273
|
+
this.apiKey = options?.apiKey?.trim() || undefined;
|
|
274
|
+
this.appKey = options?.appKey?.trim() || undefined;
|
|
275
|
+
this.appSecret = options?.appSecret?.trim() || undefined;
|
|
277
276
|
this.baseUrl = trimTrailingSlash(options.baseUrl ?? DEFAULT_BASE_URL);
|
|
278
277
|
this.timeoutMs = options.timeoutMs ?? 30000;
|
|
279
278
|
this.fetchFn = options.fetch ?? globalThis.fetch;
|
|
@@ -307,9 +306,117 @@ export class SamsarClient {
|
|
|
307
306
|
async getV2Credits(options) {
|
|
308
307
|
return this.getV2('credits', options);
|
|
309
308
|
}
|
|
309
|
+
async getV2UserCredits(options) {
|
|
310
|
+
return this.getV2('user/credits', options);
|
|
311
|
+
}
|
|
312
|
+
async getV2UserUsageLogs(options) {
|
|
313
|
+
const query = {
|
|
314
|
+
...(options?.query ?? {}),
|
|
315
|
+
};
|
|
316
|
+
if (options?.page !== undefined) {
|
|
317
|
+
query.page = options.page;
|
|
318
|
+
}
|
|
319
|
+
if (options?.pageSize !== undefined) {
|
|
320
|
+
query.pageSize = options.pageSize;
|
|
321
|
+
}
|
|
322
|
+
if (options?.limit !== undefined) {
|
|
323
|
+
query.limit = options.limit;
|
|
324
|
+
}
|
|
325
|
+
return this.getV2('user/usage/logs', {
|
|
326
|
+
...(options ?? {}),
|
|
327
|
+
query,
|
|
328
|
+
});
|
|
329
|
+
}
|
|
310
330
|
async listV2Requests(options) {
|
|
311
331
|
return this.getV2('requests', options);
|
|
312
332
|
}
|
|
333
|
+
async createV2UserRechargeCredits(payload, options) {
|
|
334
|
+
const amount = Number(payload?.amount);
|
|
335
|
+
if (!Number.isFinite(amount) || amount <= 0) {
|
|
336
|
+
throw new Error('amount must be a positive dollar amount');
|
|
337
|
+
}
|
|
338
|
+
if (!payload?.email || typeof payload.email !== 'string') {
|
|
339
|
+
throw new Error('email is required');
|
|
340
|
+
}
|
|
341
|
+
const redirectUrl = payload.redirect_url ?? payload.redirectUrl;
|
|
342
|
+
if (!redirectUrl || typeof redirectUrl !== 'string') {
|
|
343
|
+
throw new Error('redirect_url is required');
|
|
344
|
+
}
|
|
345
|
+
return this.postV2('user/recharge_credits', {
|
|
346
|
+
...payload,
|
|
347
|
+
amount,
|
|
348
|
+
email: payload.email.trim(),
|
|
349
|
+
redirect_url: redirectUrl.trim(),
|
|
350
|
+
}, options);
|
|
351
|
+
}
|
|
352
|
+
async refreshV2UserToken(payload, options) {
|
|
353
|
+
const refreshToken = typeof payload === 'string'
|
|
354
|
+
? payload
|
|
355
|
+
: (payload?.refreshToken ?? payload?.refresh_token);
|
|
356
|
+
if (!refreshToken || typeof refreshToken !== 'string') {
|
|
357
|
+
throw new Error('refreshToken is required');
|
|
358
|
+
}
|
|
359
|
+
return this.postV2('user/refresh_token', { refreshToken: refreshToken.trim() }, options);
|
|
360
|
+
}
|
|
361
|
+
async refreshV2UserAuthToken(payload, options) {
|
|
362
|
+
return this.refreshV2UserToken(payload, options);
|
|
363
|
+
}
|
|
364
|
+
async createV2UserAppKey(payload, options) {
|
|
365
|
+
const input = typeof payload === 'string' ? { secret: payload } : (payload ?? {});
|
|
366
|
+
const secret = input.secret ?? input.appSecret ?? input.app_secret;
|
|
367
|
+
if (!secret || typeof secret !== 'string') {
|
|
368
|
+
throw new Error('secret is required');
|
|
369
|
+
}
|
|
370
|
+
if (secret.trim().length < 32) {
|
|
371
|
+
throw new Error('secret must be at least 32 characters');
|
|
372
|
+
}
|
|
373
|
+
return this.postV2('users/app_key', {
|
|
374
|
+
...input,
|
|
375
|
+
secret: secret.trim(),
|
|
376
|
+
}, options);
|
|
377
|
+
}
|
|
378
|
+
async getV2UserAppKey(options) {
|
|
379
|
+
return this.getV2('users/app_key', options);
|
|
380
|
+
}
|
|
381
|
+
async refreshV2UserAppKey(payload, options) {
|
|
382
|
+
const input = payload ?? {};
|
|
383
|
+
const appKey = input.appKey ?? input.app_key ?? options?.appKey ?? this.appKey;
|
|
384
|
+
const secret = input.secret ?? input.appSecret ?? input.app_secret ?? options?.appSecret ?? this.appSecret;
|
|
385
|
+
if (!appKey || typeof appKey !== 'string') {
|
|
386
|
+
throw new Error('appKey is required');
|
|
387
|
+
}
|
|
388
|
+
if (!secret || typeof secret !== 'string') {
|
|
389
|
+
throw new Error('secret is required');
|
|
390
|
+
}
|
|
391
|
+
if (secret.trim().length < 32) {
|
|
392
|
+
throw new Error('secret must be at least 32 characters');
|
|
393
|
+
}
|
|
394
|
+
return this.postV2('users/app_key/refresh', {
|
|
395
|
+
app_key: appKey.trim(),
|
|
396
|
+
secret: secret.trim(),
|
|
397
|
+
}, options);
|
|
398
|
+
}
|
|
399
|
+
async revokeV2UserAppKey(options) {
|
|
400
|
+
return this.request(this.buildV2Url('users/app_key'), { ...(options ?? {}), method: 'DELETE' });
|
|
401
|
+
}
|
|
402
|
+
async getV2UserPaymentStatus(payload, options) {
|
|
403
|
+
const query = {
|
|
404
|
+
...(options?.query ?? {}),
|
|
405
|
+
};
|
|
406
|
+
if (payload?.checkoutSessionId) {
|
|
407
|
+
query.checkoutSessionId = payload.checkoutSessionId;
|
|
408
|
+
}
|
|
409
|
+
if (payload?.paymentIntentId) {
|
|
410
|
+
query.paymentIntentId = payload.paymentIntentId;
|
|
411
|
+
}
|
|
412
|
+
if (payload?.setupIntentId) {
|
|
413
|
+
query.setupIntentId = payload.setupIntentId;
|
|
414
|
+
}
|
|
415
|
+
return this.getV2('user/payment_status', {
|
|
416
|
+
...(options ?? {}),
|
|
417
|
+
query,
|
|
418
|
+
});
|
|
419
|
+
}
|
|
313
420
|
async createV2LoginToken(options) {
|
|
314
421
|
const body = options?.redirect ? { redirect: options.redirect } : {};
|
|
315
422
|
return this.postV2('create_login_token', body, options);
|
|
@@ -1619,10 +1726,17 @@ export class SamsarClient {
|
|
|
1619
1726
|
};
|
|
1620
1727
|
}
|
|
1621
1728
|
buildHeaders(options) {
|
|
1729
|
+
const resolvedAppKey = options.appKey?.trim() || (!this.apiKey ? this.appKey : undefined);
|
|
1730
|
+
const resolvedAppSecret = options.appSecret?.trim() || this.appSecret;
|
|
1622
1731
|
const headers = {
|
|
1623
|
-
Authorization:
|
|
1732
|
+
Authorization: resolvedAppKey
|
|
1733
|
+
? `AppKey ${resolvedAppKey}`
|
|
1734
|
+
: this.apiKey
|
|
1735
|
+
? `Bearer ${this.apiKey}`
|
|
1736
|
+
: undefined,
|
|
1624
1737
|
'Content-Type': options.body ? 'application/json' : undefined,
|
|
1625
1738
|
'x-external-user-api-key': options.externalUserApiKey ?? this.externalUserApiKey,
|
|
1739
|
+
'x-app-secret': resolvedAppKey ? resolvedAppSecret : undefined,
|
|
1626
1740
|
...this.defaultHeaders,
|
|
1627
1741
|
...(options.headers ?? {}),
|
|
1628
1742
|
};
|