chamelaion 0.2.0 → 0.4.0
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/CHANGELOG.md +22 -0
- package/README.md +3 -3
- package/api-promise.js.map +1 -1
- package/client.d.mts +3 -3
- package/client.d.mts.map +1 -1
- package/client.d.ts +3 -3
- package/client.d.ts.map +1 -1
- package/client.js +17 -65
- package/client.js.map +1 -1
- package/client.mjs +19 -67
- package/client.mjs.map +1 -1
- package/core/api-promise.d.mts.map +1 -1
- package/core/api-promise.d.ts.map +1 -1
- package/core/api-promise.js.map +1 -1
- package/core/api-promise.mjs.map +1 -1
- package/core/error.d.mts.map +1 -1
- package/core/error.d.ts.map +1 -1
- package/core/error.js +2 -2
- package/core/error.js.map +1 -1
- package/core/error.mjs +2 -2
- package/core/error.mjs.map +1 -1
- package/error.js.map +1 -1
- package/index.d.mts +1 -1
- package/index.d.mts.map +1 -1
- package/index.d.ts +1 -1
- package/index.d.ts.map +1 -1
- package/index.js.map +1 -1
- package/index.mjs +1 -1
- package/index.mjs.map +1 -1
- package/internal/builtin-types.d.mts +5 -5
- package/internal/builtin-types.d.mts.map +1 -1
- package/internal/builtin-types.d.ts +5 -5
- package/internal/builtin-types.d.ts.map +1 -1
- package/internal/detect-platform.d.mts.map +1 -1
- package/internal/detect-platform.d.ts.map +1 -1
- package/internal/detect-platform.js.map +1 -1
- package/internal/detect-platform.mjs.map +1 -1
- package/internal/errors.js +5 -6
- package/internal/errors.js.map +1 -1
- package/internal/errors.mjs +5 -6
- package/internal/errors.mjs.map +1 -1
- package/internal/headers.js +2 -2
- package/internal/headers.js.map +1 -1
- package/internal/headers.mjs +2 -2
- package/internal/headers.mjs.map +1 -1
- package/internal/parse.d.mts.map +1 -1
- package/internal/parse.d.ts.map +1 -1
- package/internal/parse.js +1 -7
- package/internal/parse.js.map +1 -1
- package/internal/parse.mjs +1 -7
- package/internal/parse.mjs.map +1 -1
- package/internal/request-options.d.mts.map +1 -1
- package/internal/request-options.d.ts.map +1 -1
- package/internal/request-options.js.map +1 -1
- package/internal/request-options.mjs.map +1 -1
- package/internal/shim-types.d.mts.map +1 -1
- package/internal/shim-types.d.ts.map +1 -1
- package/internal/shims.d.mts.map +1 -1
- package/internal/shims.d.ts.map +1 -1
- package/internal/shims.js.map +1 -1
- package/internal/shims.mjs.map +1 -1
- package/internal/to-file.d.mts.map +1 -1
- package/internal/to-file.d.ts.map +1 -1
- package/internal/to-file.js.map +1 -1
- package/internal/to-file.mjs.map +1 -1
- package/internal/types.d.mts +11 -17
- package/internal/types.d.mts.map +1 -1
- package/internal/types.d.ts +11 -17
- package/internal/types.d.ts.map +1 -1
- package/internal/utils/log.d.mts.map +1 -1
- package/internal/utils/log.d.ts.map +1 -1
- package/internal/utils/log.js +2 -9
- package/internal/utils/log.js.map +1 -1
- package/internal/utils/log.mjs +2 -9
- package/internal/utils/log.mjs.map +1 -1
- package/internal/utils/uuid.d.mts.map +1 -1
- package/internal/utils/uuid.d.ts.map +1 -1
- package/internal/utils/uuid.js +4 -2
- package/internal/utils/uuid.js.map +1 -1
- package/internal/utils/uuid.mjs +4 -2
- package/internal/utils/uuid.mjs.map +1 -1
- package/package.json +2 -2
- package/resource.js.map +1 -1
- package/resources/health.d.mts.map +1 -1
- package/resources/health.d.ts.map +1 -1
- package/resources/health.js.map +1 -1
- package/resources/health.mjs.map +1 -1
- package/resources/index.d.mts +1 -1
- package/resources/index.d.mts.map +1 -1
- package/resources/index.d.ts +1 -1
- package/resources/index.d.ts.map +1 -1
- package/resources/index.js +3 -0
- package/resources/index.js.map +1 -1
- package/resources/index.mjs +4 -1
- package/resources/index.mjs.map +1 -1
- package/resources/lipsync/index.d.mts +1 -1
- package/resources/lipsync/index.d.mts.map +1 -1
- package/resources/lipsync/index.d.ts +1 -1
- package/resources/lipsync/index.d.ts.map +1 -1
- package/resources/lipsync/index.js +2 -0
- package/resources/lipsync/index.js.map +1 -1
- package/resources/lipsync/index.mjs +3 -1
- package/resources/lipsync/index.mjs.map +1 -1
- package/resources/lipsync/lipsync.d.mts +2 -2
- package/resources/lipsync/lipsync.d.mts.map +1 -1
- package/resources/lipsync/lipsync.d.ts +2 -2
- package/resources/lipsync/lipsync.d.ts.map +1 -1
- package/resources/lipsync/lipsync.js.map +1 -1
- package/resources/lipsync/lipsync.mjs.map +1 -1
- package/resources/lipsync/requests.d.mts +1 -1
- package/resources/lipsync/requests.d.mts.map +1 -1
- package/resources/lipsync/requests.d.ts +1 -1
- package/resources/lipsync/requests.d.ts.map +1 -1
- package/resources/lipsync/requests.js.map +1 -1
- package/resources/lipsync/requests.mjs.map +1 -1
- package/resources/users.d.mts.map +1 -1
- package/resources/users.d.ts.map +1 -1
- package/src/api-promise.ts +1 -1
- package/src/client.ts +64 -153
- package/src/core/api-promise.ts +2 -7
- package/src/core/error.ts +24 -22
- package/src/error.ts +1 -1
- package/src/index.ts +1 -15
- package/src/internal/builtin-types.ts +9 -14
- package/src/internal/detect-platform.ts +1 -5
- package/src/internal/errors.ts +7 -7
- package/src/internal/headers.ts +2 -2
- package/src/internal/parse.ts +2 -10
- package/src/internal/request-options.ts +6 -2
- package/src/internal/shim-types.ts +2 -2
- package/src/internal/shims.ts +1 -3
- package/src/internal/to-file.ts +7 -7
- package/src/internal/types.ts +22 -28
- package/src/internal/utils/log.ts +8 -30
- package/src/internal/utils/uuid.ts +5 -3
- package/src/resource.ts +1 -1
- package/src/resources/health.ts +4 -2
- package/src/resources/index.ts +3 -8
- package/src/resources/lipsync/index.ts +2 -7
- package/src/resources/lipsync/lipsync.ts +4 -10
- package/src/resources/lipsync/requests.ts +2 -5
- package/src/resources/users.ts +3 -1
- package/src/uploads.ts +1 -1
- package/src/version.ts +1 -1
- package/uploads.js.map +1 -1
- package/version.d.mts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.js.map +1 -1
- package/version.mjs +1 -1
- package/version.mjs.map +1 -1
package/src/client.ts
CHANGED
|
@@ -19,28 +19,17 @@ import * as API from './resources/index';
|
|
|
19
19
|
import { APIPromise } from './core/api-promise';
|
|
20
20
|
import { Health, HealthCheckResponse } from './resources/health';
|
|
21
21
|
import { UserRetrieveCurrentResponse, Users } from './resources/users';
|
|
22
|
-
import {
|
|
23
|
-
Lipsync,
|
|
24
|
-
LipsyncGenerate,
|
|
25
|
-
LipsyncGenerateParams,
|
|
26
|
-
LipsyncGenerateWithMediaParams,
|
|
27
|
-
} from './resources/lipsync/lipsync';
|
|
22
|
+
import { Lipsync, LipsyncGenerate, LipsyncGenerateParams, LipsyncGenerateWithMediaParams } from './resources/lipsync/lipsync';
|
|
28
23
|
import { type Fetch } from './internal/builtin-types';
|
|
29
24
|
import { HeadersLike, NullableHeaders, buildHeaders } from './internal/headers';
|
|
30
25
|
import { FinalRequestOptions, RequestOptions } from './internal/request-options';
|
|
31
26
|
import { readEnv } from './internal/utils/env';
|
|
32
|
-
import {
|
|
33
|
-
type LogLevel,
|
|
34
|
-
type Logger,
|
|
35
|
-
formatRequestDetails,
|
|
36
|
-
loggerFor,
|
|
37
|
-
parseLogLevel,
|
|
38
|
-
} from './internal/utils/log';
|
|
27
|
+
import { type LogLevel, type Logger, formatRequestDetails, loggerFor, parseLogLevel } from './internal/utils/log';
|
|
39
28
|
import { isEmptyObj } from './internal/utils/values';
|
|
40
29
|
|
|
41
30
|
const environments = {
|
|
42
31
|
production: 'https://api.chamelaion.com/api',
|
|
43
|
-
|
|
32
|
+
staging: 'https://api.dev.chamelaion.com/api',
|
|
44
33
|
};
|
|
45
34
|
type Environment = keyof typeof environments;
|
|
46
35
|
|
|
@@ -60,7 +49,7 @@ export interface ClientOptions {
|
|
|
60
49
|
*
|
|
61
50
|
* Each environment maps to a different base URL:
|
|
62
51
|
* - `production` corresponds to `https://api.chamelaion.com/api`
|
|
63
|
-
* - `
|
|
52
|
+
* - `staging` corresponds to `https://api.dev.chamelaion.com/api`
|
|
64
53
|
*/
|
|
65
54
|
environment?: Environment | undefined;
|
|
66
55
|
|
|
@@ -134,7 +123,7 @@ export interface ClientOptions {
|
|
|
134
123
|
}
|
|
135
124
|
|
|
136
125
|
/**
|
|
137
|
-
* API Client for interfacing with the Chamelaion API.
|
|
126
|
+
* API Client for interfacing with the Chamelaion API.
|
|
138
127
|
*/
|
|
139
128
|
export class Chamelaion {
|
|
140
129
|
bearerToken: string | null;
|
|
@@ -172,6 +161,7 @@ export class Chamelaion {
|
|
|
172
161
|
apiKey = readEnv('CHAMELAION_API_KEY') ?? null,
|
|
173
162
|
...opts
|
|
174
163
|
}: ClientOptions = {}) {
|
|
164
|
+
|
|
175
165
|
const options: ClientOptions = {
|
|
176
166
|
bearerToken,
|
|
177
167
|
apiKey,
|
|
@@ -182,8 +172,8 @@ export class Chamelaion {
|
|
|
182
172
|
|
|
183
173
|
if (baseURL && opts.environment) {
|
|
184
174
|
throw new Errors.ChamelaionError(
|
|
185
|
-
'Ambiguous URL; The `baseURL` option (or CHAMELAION_BASE_URL env var) and the `environment` option are given. If you want to use the environment you must pass baseURL: null'
|
|
186
|
-
)
|
|
175
|
+
'Ambiguous URL; The `baseURL` option (or CHAMELAION_BASE_URL env var) and the `environment` option are given. If you want to use the environment you must pass baseURL: null'
|
|
176
|
+
)
|
|
187
177
|
}
|
|
188
178
|
|
|
189
179
|
this.baseURL = options.baseURL || environments[options.environment || 'production'];
|
|
@@ -192,10 +182,7 @@ export class Chamelaion {
|
|
|
192
182
|
const defaultLogLevel = 'warn';
|
|
193
183
|
// Set default logLevel early so that we can log a warning in parseLogLevel.
|
|
194
184
|
this.logLevel = defaultLogLevel;
|
|
195
|
-
this.logLevel =
|
|
196
|
-
parseLogLevel(options.logLevel, 'ClientOptions.logLevel', this) ??
|
|
197
|
-
parseLogLevel(readEnv('CHAMELAION_LOG'), "process.env['CHAMELAION_LOG']", this) ??
|
|
198
|
-
defaultLogLevel;
|
|
185
|
+
this.logLevel = parseLogLevel(options.logLevel, 'ClientOptions.logLevel', this) ?? parseLogLevel(readEnv('CHAMELAION_LOG'), 'process.env[\'CHAMELAION_LOG\']', this) ?? defaultLogLevel;
|
|
199
186
|
this.fetchOptions = options.fetchOptions;
|
|
200
187
|
this.maxRetries = options.maxRetries ?? 2;
|
|
201
188
|
this.fetch = options.fetch ?? Shims.getDefaultFetch();
|
|
@@ -223,7 +210,7 @@ export class Chamelaion {
|
|
|
223
210
|
fetchOptions: this.fetchOptions,
|
|
224
211
|
bearerToken: this.bearerToken,
|
|
225
212
|
apiKey: this.apiKey,
|
|
226
|
-
...options
|
|
213
|
+
...options
|
|
227
214
|
});
|
|
228
215
|
return client;
|
|
229
216
|
}
|
|
@@ -236,7 +223,7 @@ export class Chamelaion {
|
|
|
236
223
|
}
|
|
237
224
|
|
|
238
225
|
protected defaultQuery(): Record<string, string | undefined> | undefined {
|
|
239
|
-
return this._options.defaultQuery
|
|
226
|
+
return this._options.defaultQuery
|
|
240
227
|
}
|
|
241
228
|
|
|
242
229
|
protected validateHeaders({ values, nulls }: NullableHeaders) {
|
|
@@ -254,19 +241,11 @@ export class Chamelaion {
|
|
|
254
241
|
return;
|
|
255
242
|
}
|
|
256
243
|
|
|
257
|
-
throw new Error(
|
|
258
|
-
'Could not resolve authentication method. Expected either bearerToken or apiKey to be set. Or for one of the "Authorization" or "x-api-key" headers to be explicitly omitted',
|
|
259
|
-
);
|
|
244
|
+
throw new Error('Could not resolve authentication method. Expected either bearerToken or apiKey to be set. Or for one of the "Authorization" or "x-api-key" headers to be explicitly omitted')
|
|
260
245
|
}
|
|
261
246
|
|
|
262
|
-
protected async authHeaders(
|
|
263
|
-
opts:
|
|
264
|
-
schemes: { bearerAuth?: boolean; apiKeyAuth?: boolean },
|
|
265
|
-
): Promise<NullableHeaders | undefined> {
|
|
266
|
-
return buildHeaders([
|
|
267
|
-
schemes.bearerAuth ? await this.bearerAuth(opts) : null,
|
|
268
|
-
schemes.apiKeyAuth ? await this.apiKeyAuth(opts) : null,
|
|
269
|
-
]);
|
|
247
|
+
protected async authHeaders(opts: FinalRequestOptions, schemes: { bearerAuth?: boolean, apiKeyAuth?: boolean }): Promise<NullableHeaders | undefined> {
|
|
248
|
+
return buildHeaders([schemes.bearerAuth ? await this.bearerAuth(opts) : null, schemes.apiKeyAuth ? await this.apiKeyAuth(opts) : null]);
|
|
270
249
|
}
|
|
271
250
|
|
|
272
251
|
protected async bearerAuth(opts: FinalRequestOptions): Promise<NullableHeaders | undefined> {
|
|
@@ -307,11 +286,7 @@ export class Chamelaion {
|
|
|
307
286
|
return Errors.APIError.generate(status, error, message, headers);
|
|
308
287
|
}
|
|
309
288
|
|
|
310
|
-
buildURL(
|
|
311
|
-
path: string,
|
|
312
|
-
query: Record<string, unknown> | null | undefined,
|
|
313
|
-
defaultBaseURL?: string | undefined,
|
|
314
|
-
): string {
|
|
289
|
+
buildURL(path: string, query: Record<string, unknown> | null | undefined, defaultBaseURL?: string | undefined): string {
|
|
315
290
|
const baseURL = (!this.#baseURLOverridden() && defaultBaseURL) || this.baseURL;
|
|
316
291
|
const url =
|
|
317
292
|
isAbsoluteURL(path) ?
|
|
@@ -399,9 +374,7 @@ export class Chamelaion {
|
|
|
399
374
|
|
|
400
375
|
await this.prepareOptions(options);
|
|
401
376
|
|
|
402
|
-
const { req, url, timeout } = await this.buildRequest(options, {
|
|
403
|
-
retryCount: maxRetries - retriesRemaining,
|
|
404
|
-
});
|
|
377
|
+
const { req, url, timeout } = await this.buildRequest(options, { retryCount: maxRetries - retriesRemaining });
|
|
405
378
|
|
|
406
379
|
await this.prepareRequest(req, { url, options });
|
|
407
380
|
|
|
@@ -410,16 +383,7 @@ export class Chamelaion {
|
|
|
410
383
|
const retryLogStr = retryOfRequestLogID === undefined ? '' : `, retryOf: ${retryOfRequestLogID}`;
|
|
411
384
|
const startTime = Date.now();
|
|
412
385
|
|
|
413
|
-
loggerFor(this).debug(
|
|
414
|
-
`[${requestLogID}] sending request`,
|
|
415
|
-
formatRequestDetails({
|
|
416
|
-
retryOfRequestLogID,
|
|
417
|
-
method: options.method,
|
|
418
|
-
url,
|
|
419
|
-
options,
|
|
420
|
-
headers: req.headers,
|
|
421
|
-
}),
|
|
422
|
-
);
|
|
386
|
+
loggerFor(this).debug(`[${requestLogID}] sending request`, formatRequestDetails({ retryOfRequestLogID, method: options.method, url, options, headers: req.headers }));
|
|
423
387
|
|
|
424
388
|
if (options.signal?.aborted) {
|
|
425
389
|
throw new Errors.APIUserAbortError();
|
|
@@ -438,45 +402,21 @@ export class Chamelaion {
|
|
|
438
402
|
// deno throws "TypeError: error sending request for url (https://example/): client error (Connect): tcp connect error: Operation timed out (os error 60): Operation timed out (os error 60)"
|
|
439
403
|
// undici throws "TypeError: fetch failed" with cause "ConnectTimeoutError: Connect Timeout Error (attempted address: example:443, timeout: 1ms)"
|
|
440
404
|
// others do not provide enough information to distinguish timeouts from other connection errors
|
|
441
|
-
const isTimeout =
|
|
442
|
-
isAbortError(response) ||
|
|
443
|
-
/timed? ?out/i.test(String(response) + ('cause' in response ? String(response.cause) : ''));
|
|
405
|
+
const isTimeout = isAbortError(response) || /timed? ?out/i.test(String(response) + ('cause' in response ? String(response.cause) : ''))
|
|
444
406
|
if (retriesRemaining) {
|
|
445
|
-
loggerFor(this).info(
|
|
446
|
-
|
|
447
|
-
);
|
|
448
|
-
loggerFor(this).debug(
|
|
449
|
-
`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (${retryMessage})`,
|
|
450
|
-
formatRequestDetails({
|
|
451
|
-
retryOfRequestLogID,
|
|
452
|
-
url,
|
|
453
|
-
durationMs: headersTime - startTime,
|
|
454
|
-
message: response.message,
|
|
455
|
-
}),
|
|
456
|
-
);
|
|
407
|
+
loggerFor(this).info(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - ${retryMessage}`)
|
|
408
|
+
loggerFor(this).debug(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (${retryMessage})`, formatRequestDetails({ retryOfRequestLogID, url, durationMs: headersTime - startTime, message: response.message }));
|
|
457
409
|
return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID);
|
|
458
410
|
}
|
|
459
|
-
loggerFor(this).info(
|
|
460
|
-
|
|
461
|
-
);
|
|
462
|
-
loggerFor(this).debug(
|
|
463
|
-
`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (error; no more retries left)`,
|
|
464
|
-
formatRequestDetails({
|
|
465
|
-
retryOfRequestLogID,
|
|
466
|
-
url,
|
|
467
|
-
durationMs: headersTime - startTime,
|
|
468
|
-
message: response.message,
|
|
469
|
-
}),
|
|
470
|
-
);
|
|
411
|
+
loggerFor(this).info(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - error; no more retries left`)
|
|
412
|
+
loggerFor(this).debug(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (error; no more retries left)`, formatRequestDetails({ retryOfRequestLogID, url, durationMs: headersTime - startTime, message: response.message }));
|
|
471
413
|
if (isTimeout) {
|
|
472
414
|
throw new Errors.APIConnectionTimeoutError();
|
|
473
415
|
}
|
|
474
416
|
throw new Errors.APIConnectionError({ cause: response });
|
|
475
417
|
}
|
|
476
418
|
|
|
477
|
-
const responseInfo = `[${requestLogID}${retryLogStr}] ${req.method} ${url} ${
|
|
478
|
-
response.ok ? 'succeeded' : 'failed'
|
|
479
|
-
} with status ${response.status} in ${headersTime - startTime}ms`;
|
|
419
|
+
const responseInfo = `[${requestLogID}${retryLogStr}] ${req.method} ${url} ${response.ok ? 'succeeded' : 'failed'} with status ${response.status} in ${headersTime - startTime}ms`;
|
|
480
420
|
|
|
481
421
|
if (!response.ok) {
|
|
482
422
|
const shouldRetry = await this.shouldRetry(response);
|
|
@@ -485,60 +425,27 @@ export class Chamelaion {
|
|
|
485
425
|
|
|
486
426
|
// We don't need the body of this response.
|
|
487
427
|
await Shims.CancelReadableStream(response.body);
|
|
488
|
-
loggerFor(this).info(`${responseInfo} - ${retryMessage}`)
|
|
489
|
-
loggerFor(this).debug(
|
|
490
|
-
|
|
491
|
-
formatRequestDetails({
|
|
492
|
-
retryOfRequestLogID,
|
|
493
|
-
url: response.url,
|
|
494
|
-
status: response.status,
|
|
495
|
-
headers: response.headers,
|
|
496
|
-
durationMs: headersTime - startTime,
|
|
497
|
-
}),
|
|
498
|
-
);
|
|
499
|
-
return this.retryRequest(
|
|
500
|
-
options,
|
|
501
|
-
retriesRemaining,
|
|
502
|
-
retryOfRequestLogID ?? requestLogID,
|
|
503
|
-
response.headers,
|
|
504
|
-
);
|
|
428
|
+
loggerFor(this).info(`${responseInfo} - ${retryMessage}`)
|
|
429
|
+
loggerFor(this).debug(`[${requestLogID}] response error (${retryMessage})`, formatRequestDetails({ retryOfRequestLogID, url: response.url, status: response.status, headers: response.headers, durationMs: headersTime - startTime }));
|
|
430
|
+
return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID, response.headers);
|
|
505
431
|
}
|
|
506
432
|
|
|
507
433
|
const retryMessage = shouldRetry ? `error; no more retries left` : `error; not retryable`;
|
|
508
434
|
|
|
509
|
-
loggerFor(this).info(`${responseInfo} - ${retryMessage}`)
|
|
435
|
+
loggerFor(this).info(`${responseInfo} - ${retryMessage}`)
|
|
510
436
|
|
|
511
437
|
const errText = await response.text().catch((err: any) => castToError(err).message);
|
|
512
438
|
const errJSON = safeJSON(errText) as any;
|
|
513
439
|
const errMessage = errJSON ? undefined : errText;
|
|
514
440
|
|
|
515
|
-
loggerFor(this).debug(
|
|
516
|
-
`[${requestLogID}] response error (${retryMessage})`,
|
|
517
|
-
formatRequestDetails({
|
|
518
|
-
retryOfRequestLogID,
|
|
519
|
-
url: response.url,
|
|
520
|
-
status: response.status,
|
|
521
|
-
headers: response.headers,
|
|
522
|
-
message: errMessage,
|
|
523
|
-
durationMs: Date.now() - startTime,
|
|
524
|
-
}),
|
|
525
|
-
);
|
|
441
|
+
loggerFor(this).debug(`[${requestLogID}] response error (${retryMessage})`, formatRequestDetails({ retryOfRequestLogID, url: response.url, status: response.status, headers: response.headers, message: errMessage, durationMs: Date.now() - startTime }));
|
|
526
442
|
|
|
527
443
|
const err = this.makeStatusError(response.status, errJSON, errMessage, response.headers);
|
|
528
444
|
throw err;
|
|
529
445
|
}
|
|
530
446
|
|
|
531
|
-
loggerFor(this).info(responseInfo)
|
|
532
|
-
loggerFor(this).debug(
|
|
533
|
-
`[${requestLogID}] response start`,
|
|
534
|
-
formatRequestDetails({
|
|
535
|
-
retryOfRequestLogID,
|
|
536
|
-
url: response.url,
|
|
537
|
-
status: response.status,
|
|
538
|
-
headers: response.headers,
|
|
539
|
-
durationMs: headersTime - startTime,
|
|
540
|
-
}),
|
|
541
|
-
);
|
|
447
|
+
loggerFor(this).info(responseInfo)
|
|
448
|
+
loggerFor(this).debug(`[${requestLogID}] response start`, formatRequestDetails({ retryOfRequestLogID, url: response.url, status: response.status, headers: response.headers, durationMs: headersTime - startTime }));
|
|
542
449
|
|
|
543
450
|
return { response, options, controller, requestLogID, retryOfRequestLogID, startTime };
|
|
544
451
|
}
|
|
@@ -555,9 +462,7 @@ export class Chamelaion {
|
|
|
555
462
|
|
|
556
463
|
const timeout = setTimeout(abort, ms);
|
|
557
464
|
|
|
558
|
-
const isReadableBody =
|
|
559
|
-
((globalThis as any).ReadableStream && options.body instanceof (globalThis as any).ReadableStream) ||
|
|
560
|
-
(typeof options.body === 'object' && options.body !== null && Symbol.asyncIterator in options.body);
|
|
465
|
+
const isReadableBody = ((globalThis as any).ReadableStream && options.body instanceof (globalThis as any).ReadableStream) || (typeof options.body === "object" && options.body !== null && Symbol.asyncIterator in options.body);
|
|
561
466
|
|
|
562
467
|
const fetchOptions: RequestInit = {
|
|
563
468
|
signal: controller.signal as any,
|
|
@@ -572,6 +477,7 @@ export class Chamelaion {
|
|
|
572
477
|
}
|
|
573
478
|
|
|
574
479
|
try {
|
|
480
|
+
|
|
575
481
|
// use undefined this binding; fetch errors if bound to something else in browser/cloudflare
|
|
576
482
|
return await this.fetch.call(undefined, url, fetchOptions);
|
|
577
483
|
} finally {
|
|
@@ -672,12 +578,11 @@ export class Chamelaion {
|
|
|
672
578
|
const req: FinalizedRequestInit = {
|
|
673
579
|
method,
|
|
674
580
|
headers: reqHeaders,
|
|
675
|
-
...(options.signal && { signal: options.signal
|
|
676
|
-
...((globalThis as any).ReadableStream &&
|
|
677
|
-
body instanceof (globalThis as any).ReadableStream && { duplex: 'half' }),
|
|
581
|
+
...(options.signal && { signal: options.signal}),
|
|
582
|
+
...((globalThis as any).ReadableStream && body instanceof (globalThis as any).ReadableStream && { duplex: "half" }),
|
|
678
583
|
...(body && { body }),
|
|
679
|
-
...(
|
|
680
|
-
...(
|
|
584
|
+
...(this.fetchOptions as any ?? {}),
|
|
585
|
+
...(options.fetchOptions as any ?? {}),
|
|
681
586
|
};
|
|
682
587
|
|
|
683
588
|
return { req, url, timeout: options.timeout };
|
|
@@ -702,17 +607,15 @@ export class Chamelaion {
|
|
|
702
607
|
|
|
703
608
|
const headers = buildHeaders([
|
|
704
609
|
idempotencyHeaders,
|
|
705
|
-
{
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
},
|
|
712
|
-
await this.authHeaders(options, options.__security ?? { bearerAuth: true, apiKeyAuth: true }),
|
|
610
|
+
{Accept: 'application/json',
|
|
611
|
+
'User-Agent': this.getUserAgent(),
|
|
612
|
+
'X-Stainless-Retry-Count': String(retryCount),
|
|
613
|
+
...(options.timeout ? { 'X-Stainless-Timeout': String(Math.trunc(options.timeout / 1000)) } : {}),
|
|
614
|
+
...getPlatformHeaders()},
|
|
615
|
+
await this.authHeaders(options, options.__security ?? { bearerAuth: true,apiKeyAuth: true }),
|
|
713
616
|
this._options.defaultHeaders,
|
|
714
617
|
bodyHeaders,
|
|
715
|
-
options.headers
|
|
618
|
+
options.headers
|
|
716
619
|
]);
|
|
717
620
|
|
|
718
621
|
this.validateHeaders(headers);
|
|
@@ -739,9 +642,11 @@ export class Chamelaion {
|
|
|
739
642
|
ArrayBuffer.isView(body) ||
|
|
740
643
|
body instanceof ArrayBuffer ||
|
|
741
644
|
body instanceof DataView ||
|
|
742
|
-
(
|
|
645
|
+
(
|
|
646
|
+
typeof body === 'string' &&
|
|
743
647
|
// Preserve legacy string encoding behavior for now
|
|
744
|
-
headers.values.has('content-type')
|
|
648
|
+
headers.values.has('content-type')
|
|
649
|
+
) ||
|
|
745
650
|
// `Blob` is superset of `File`
|
|
746
651
|
((globalThis as any).Blob && body instanceof (globalThis as any).Blob) ||
|
|
747
652
|
// `FormData` -> `multipart/form-data`
|
|
@@ -772,7 +677,7 @@ export class Chamelaion {
|
|
|
772
677
|
}
|
|
773
678
|
|
|
774
679
|
static Chamelaion = this;
|
|
775
|
-
static DEFAULT_TIMEOUT = 60000
|
|
680
|
+
static DEFAULT_TIMEOUT = 60000 // 1 minute
|
|
776
681
|
|
|
777
682
|
static ChamelaionError = Errors.ChamelaionError;
|
|
778
683
|
static APIError = Errors.APIError;
|
|
@@ -809,16 +714,22 @@ Chamelaion.Users = Users;
|
|
|
809
714
|
Chamelaion.Lipsync = Lipsync;
|
|
810
715
|
|
|
811
716
|
export declare namespace Chamelaion {
|
|
812
|
-
|
|
717
|
+
export type RequestOptions = Opts.RequestOptions;
|
|
813
718
|
|
|
814
|
-
|
|
719
|
+
export {
|
|
720
|
+
Health as Health,
|
|
721
|
+
type HealthCheckResponse as HealthCheckResponse
|
|
722
|
+
};
|
|
815
723
|
|
|
816
|
-
|
|
724
|
+
export {
|
|
725
|
+
Users as Users,
|
|
726
|
+
type UserRetrieveCurrentResponse as UserRetrieveCurrentResponse
|
|
727
|
+
};
|
|
817
728
|
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
}
|
|
729
|
+
export {
|
|
730
|
+
Lipsync as Lipsync,
|
|
731
|
+
type LipsyncGenerate as LipsyncGenerate,
|
|
732
|
+
type LipsyncGenerateParams as LipsyncGenerateParams,
|
|
733
|
+
type LipsyncGenerateWithMediaParams as LipsyncGenerateWithMediaParams
|
|
734
|
+
};
|
|
735
|
+
}
|
package/src/core/api-promise.ts
CHANGED
|
@@ -16,10 +16,7 @@ export class APIPromise<T> extends Promise<T> {
|
|
|
16
16
|
constructor(
|
|
17
17
|
client: Chamelaion,
|
|
18
18
|
private responsePromise: Promise<APIResponseProps>,
|
|
19
|
-
private parseResponse: (
|
|
20
|
-
client: Chamelaion,
|
|
21
|
-
props: APIResponseProps,
|
|
22
|
-
) => PromiseOrValue<T> = defaultParseResponse,
|
|
19
|
+
private parseResponse: (client: Chamelaion, props: APIResponseProps) => PromiseOrValue<T> = defaultParseResponse,
|
|
23
20
|
) {
|
|
24
21
|
super((resolve) => {
|
|
25
22
|
// this is maybe a bit weird but this has to be a no-op to not implicitly
|
|
@@ -31,9 +28,7 @@ export class APIPromise<T> extends Promise<T> {
|
|
|
31
28
|
}
|
|
32
29
|
|
|
33
30
|
_thenUnwrap<U>(transform: (data: T, props: APIResponseProps) => U): APIPromise<U> {
|
|
34
|
-
return new APIPromise(this.#client, this.responsePromise, async (client, props) =>
|
|
35
|
-
transform(await this.parseResponse(client, props), props),
|
|
36
|
-
);
|
|
31
|
+
return new APIPromise(this.#client, this.responsePromise, async (client, props) => transform(await this.parseResponse(client, props), props));
|
|
37
32
|
}
|
|
38
33
|
|
|
39
34
|
/**
|
package/src/core/error.ts
CHANGED
|
@@ -2,13 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
import { castToError } from '../internal/errors';
|
|
4
4
|
|
|
5
|
-
export class ChamelaionError extends Error {
|
|
5
|
+
export class ChamelaionError extends Error {
|
|
6
|
+
}
|
|
6
7
|
|
|
7
|
-
export class APIError<
|
|
8
|
-
TStatus extends number | undefined = number | undefined,
|
|
9
|
-
THeaders extends Headers | undefined = Headers | undefined,
|
|
10
|
-
TError extends Object | undefined = Object | undefined,
|
|
11
|
-
> extends ChamelaionError {
|
|
8
|
+
export class APIError<TStatus extends number | undefined = number | undefined, THeaders extends Headers | undefined = Headers | undefined, TError extends Object | undefined = Object | undefined> extends ChamelaionError {
|
|
12
9
|
/** HTTP status for the response that caused the error */
|
|
13
10
|
readonly status: TStatus;
|
|
14
11
|
/** HTTP headers for the response that caused the error */
|
|
@@ -16,6 +13,9 @@ export class APIError<
|
|
|
16
13
|
/** JSON body of the response that caused the error */
|
|
17
14
|
readonly error: TError;
|
|
18
15
|
|
|
16
|
+
|
|
17
|
+
;
|
|
18
|
+
|
|
19
19
|
constructor(status: TStatus, error: TError, message: string | undefined, headers: THeaders) {
|
|
20
20
|
super(`${APIError.makeMessage(status, error, message)}`);
|
|
21
21
|
this.status = status;
|
|
@@ -26,8 +26,7 @@ export class APIError<
|
|
|
26
26
|
private static makeMessage(status: number | undefined, error: any, message: string | undefined) {
|
|
27
27
|
const msg =
|
|
28
28
|
error?.message ?
|
|
29
|
-
typeof error.message === 'string' ?
|
|
30
|
-
error.message
|
|
29
|
+
typeof error.message === 'string' ? error.message
|
|
31
30
|
: JSON.stringify(error.message)
|
|
32
31
|
: error ? JSON.stringify(error)
|
|
33
32
|
: message;
|
|
@@ -44,12 +43,7 @@ export class APIError<
|
|
|
44
43
|
return '(no status code or body)';
|
|
45
44
|
}
|
|
46
45
|
|
|
47
|
-
static generate(
|
|
48
|
-
status: number | undefined,
|
|
49
|
-
errorResponse: Object | undefined,
|
|
50
|
-
message: string | undefined,
|
|
51
|
-
headers: Headers | undefined,
|
|
52
|
-
): APIError {
|
|
46
|
+
static generate(status: number | undefined, errorResponse: Object | undefined, message: string | undefined, headers: Headers | undefined): APIError {
|
|
53
47
|
if (!status || !headers) {
|
|
54
48
|
return new APIConnectionError({ message, cause: castToError(errorResponse) });
|
|
55
49
|
}
|
|
@@ -113,18 +107,26 @@ export class APIConnectionTimeoutError extends APIConnectionError {
|
|
|
113
107
|
}
|
|
114
108
|
}
|
|
115
109
|
|
|
116
|
-
export class BadRequestError extends APIError<400, Headers> {
|
|
110
|
+
export class BadRequestError extends APIError<400, Headers> {
|
|
111
|
+
}
|
|
117
112
|
|
|
118
|
-
export class AuthenticationError extends APIError<401, Headers> {
|
|
113
|
+
export class AuthenticationError extends APIError<401, Headers> {
|
|
114
|
+
}
|
|
119
115
|
|
|
120
|
-
export class PermissionDeniedError extends APIError<403, Headers> {
|
|
116
|
+
export class PermissionDeniedError extends APIError<403, Headers> {
|
|
117
|
+
}
|
|
121
118
|
|
|
122
|
-
export class NotFoundError extends APIError<404, Headers> {
|
|
119
|
+
export class NotFoundError extends APIError<404, Headers> {
|
|
120
|
+
}
|
|
123
121
|
|
|
124
|
-
export class ConflictError extends APIError<409, Headers> {
|
|
122
|
+
export class ConflictError extends APIError<409, Headers> {
|
|
123
|
+
}
|
|
125
124
|
|
|
126
|
-
export class UnprocessableEntityError extends APIError<422, Headers> {
|
|
125
|
+
export class UnprocessableEntityError extends APIError<422, Headers> {
|
|
126
|
+
}
|
|
127
127
|
|
|
128
|
-
export class RateLimitError extends APIError<429, Headers> {
|
|
128
|
+
export class RateLimitError extends APIError<429, Headers> {
|
|
129
|
+
}
|
|
129
130
|
|
|
130
|
-
export class InternalServerError extends APIError<number, Headers> {
|
|
131
|
+
export class InternalServerError extends APIError<number, Headers> {
|
|
132
|
+
}
|
package/src/error.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** @deprecated Import from ./core/error instead */
|
|
2
|
-
export * from
|
|
2
|
+
export * from "./core/error"
|
package/src/index.ts
CHANGED
|
@@ -5,18 +5,4 @@ export { Chamelaion as default } from './client';
|
|
|
5
5
|
export { type Uploadable, toFile } from './core/uploads';
|
|
6
6
|
export { APIPromise } from './core/api-promise';
|
|
7
7
|
export { Chamelaion, type ClientOptions } from './client';
|
|
8
|
-
export {
|
|
9
|
-
ChamelaionError,
|
|
10
|
-
APIError,
|
|
11
|
-
APIConnectionError,
|
|
12
|
-
APIConnectionTimeoutError,
|
|
13
|
-
APIUserAbortError,
|
|
14
|
-
NotFoundError,
|
|
15
|
-
ConflictError,
|
|
16
|
-
RateLimitError,
|
|
17
|
-
BadRequestError,
|
|
18
|
-
AuthenticationError,
|
|
19
|
-
InternalServerError,
|
|
20
|
-
PermissionDeniedError,
|
|
21
|
-
UnprocessableEntityError,
|
|
22
|
-
} from './core/error';
|
|
8
|
+
export { ChamelaionError, APIError, APIConnectionError, APIConnectionTimeoutError, APIUserAbortError, NotFoundError, ConflictError, RateLimitError, BadRequestError, AuthenticationError, InternalServerError, PermissionDeniedError, UnprocessableEntityError } from './core/error';
|
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2
2
|
|
|
3
|
-
export type Fetch = (
|
|
3
|
+
export type Fetch = (
|
|
4
|
+
input: string | URL | Request,
|
|
5
|
+
init?: RequestInit,
|
|
6
|
+
) => Promise<Response>
|
|
4
7
|
|
|
5
8
|
/**
|
|
6
9
|
* An alias to the builtin `RequestInit` type so we can
|
|
7
10
|
* easily alias it in import statements if there are name clashes.
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
*
|
|
12
|
+
* https://developer.mozilla.org/docs/Web/API/RequestInit
|
|
10
13
|
*/
|
|
11
14
|
type _RequestInit = RequestInit;
|
|
12
15
|
|
|
13
16
|
/**
|
|
14
17
|
* An alias to the builtin `Response` type so we can
|
|
15
18
|
* easily alias it in import statements if there are name clashes.
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
*
|
|
20
|
+
* https://developer.mozilla.org/docs/Web/API/Response
|
|
18
21
|
*/
|
|
19
22
|
type _Response = Response;
|
|
20
23
|
|
|
@@ -51,15 +54,7 @@ type _Array<T> = Array<T>;
|
|
|
51
54
|
*/
|
|
52
55
|
type _Record<K extends keyof any, T> = Record<K, T>;
|
|
53
56
|
|
|
54
|
-
export type {
|
|
55
|
-
_Array as Array,
|
|
56
|
-
_BodyInit as BodyInit,
|
|
57
|
-
_HeadersInit as HeadersInit,
|
|
58
|
-
_Record as Record,
|
|
59
|
-
_RequestInfo as RequestInfo,
|
|
60
|
-
_RequestInit as RequestInit,
|
|
61
|
-
_Response as Response,
|
|
62
|
-
};
|
|
57
|
+
export type { _Array as Array, _BodyInit as BodyInit, _HeadersInit as HeadersInit, _Record as Record, _RequestInfo as RequestInfo, _RequestInit as RequestInit, _Response as Response };
|
|
63
58
|
|
|
64
59
|
/**
|
|
65
60
|
* A copy of the builtin `EndingType` type as it isn't fully supported in certain
|
|
@@ -25,11 +25,7 @@ function getDetectedPlatform(): DetectedPlatform {
|
|
|
25
25
|
if (typeof EdgeRuntime !== 'undefined') {
|
|
26
26
|
return 'edge';
|
|
27
27
|
}
|
|
28
|
-
if (
|
|
29
|
-
Object.prototype.toString.call(
|
|
30
|
-
typeof (globalThis as any).process !== 'undefined' ? (globalThis as any).process : 0,
|
|
31
|
-
) === '[object process]'
|
|
32
|
-
) {
|
|
28
|
+
if (Object.prototype.toString.call(typeof (globalThis as any).process !== 'undefined' ? (globalThis as any).process : 0) === '[object process]') {
|
|
33
29
|
return 'node';
|
|
34
30
|
}
|
|
35
31
|
return 'unknown';
|
package/src/internal/errors.ts
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
export function isAbortError(err: unknown) {
|
|
4
4
|
return (
|
|
5
|
-
typeof err === 'object' &&
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
(('name' in err && (err as any).name === 'AbortError') ||
|
|
5
|
+
typeof err === 'object' && err !== null && (
|
|
6
|
+
// Spec-compliant fetch implementations
|
|
7
|
+
('name' in err && (err as any).name === 'AbortError') ||
|
|
9
8
|
// Expo fetch
|
|
10
|
-
('message' in err && String((err as any).message).includes('FetchRequestCanceledException'))
|
|
9
|
+
('message' in err && String((err as any).message).includes('FetchRequestCanceledException'))
|
|
10
|
+
)
|
|
11
11
|
);
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -24,10 +24,10 @@ export const castToError = (err: any): Error => {
|
|
|
24
24
|
if (err.name) error.name = err.name;
|
|
25
25
|
return error;
|
|
26
26
|
}
|
|
27
|
-
} catch {}
|
|
27
|
+
} catch { }
|
|
28
28
|
try {
|
|
29
29
|
return new Error(JSON.stringify(err));
|
|
30
|
-
} catch {}
|
|
30
|
+
} catch { }
|
|
31
31
|
}
|
|
32
32
|
return new Error(err);
|
|
33
33
|
};
|
package/src/internal/headers.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2
2
|
|
|
3
|
-
import { isReadonlyArray } from
|
|
3
|
+
import { isReadonlyArray } from "./utils/values";
|
|
4
4
|
|
|
5
5
|
type HeaderValue = string | undefined | null;
|
|
6
6
|
export type HeadersLike =
|
|
@@ -51,7 +51,7 @@ function* iterateHeaders(headers: HeadersLike): IterableIterator<readonly [strin
|
|
|
51
51
|
}
|
|
52
52
|
for (let row of iter) {
|
|
53
53
|
const name = row[0];
|
|
54
|
-
if (typeof name !==
|
|
54
|
+
if (typeof name !== "string") throw new TypeError("expected header name to be a string")
|
|
55
55
|
const values = isReadonlyArray(row[1]) ? row[1] : [row[1]];
|
|
56
56
|
let didClear = false;
|
|
57
57
|
for (const value of values) {
|
package/src/internal/parse.ts
CHANGED
|
@@ -16,6 +16,7 @@ export type APIResponseProps = {
|
|
|
16
16
|
export async function defaultParseResponse<T>(client: Chamelaion, props: APIResponseProps): Promise<T> {
|
|
17
17
|
const { response, requestLogID, retryOfRequestLogID, startTime } = props;
|
|
18
18
|
const body = await (async () => {
|
|
19
|
+
|
|
19
20
|
// fetch refuses to read the body when the status code is 204.
|
|
20
21
|
if (response.status === 204) {
|
|
21
22
|
return null as T;
|
|
@@ -42,15 +43,6 @@ export async function defaultParseResponse<T>(client: Chamelaion, props: APIResp
|
|
|
42
43
|
const text = await response.text();
|
|
43
44
|
return text as unknown as T;
|
|
44
45
|
})();
|
|
45
|
-
loggerFor(client).debug(
|
|
46
|
-
`[${requestLogID}] response parsed`,
|
|
47
|
-
formatRequestDetails({
|
|
48
|
-
retryOfRequestLogID,
|
|
49
|
-
url: response.url,
|
|
50
|
-
status: response.status,
|
|
51
|
-
body,
|
|
52
|
-
durationMs: Date.now() - startTime,
|
|
53
|
-
}),
|
|
54
|
-
);
|
|
46
|
+
loggerFor(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails({ retryOfRequestLogID, url: response.url, status: response.status, body, durationMs: Date.now() - startTime }));
|
|
55
47
|
return body;
|
|
56
48
|
}
|