@videxo/sdk 0.1.0 → 0.2.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/README.md +12 -3
- package/dist/app-client.d.ts +112 -0
- package/dist/app-client.js +311 -0
- package/dist/client.d.ts +55 -11
- package/dist/client.js +76 -4
- package/dist/defaults.d.ts +7 -0
- package/dist/defaults.js +6 -0
- package/dist/generated/openapi.d.ts +3511 -907
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -2
- package/dist/types.d.ts +14 -0
- package/dist/uploads.d.ts +13 -0
- package/dist/uploads.js +73 -1
- package/package.json +6 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { DEFAULT_BASE_URL, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT_MS, DEFAULT_WAIT, Fonts, Jobs, Outputs, Presets, Uploads, Videxo, Webhooks, type CreateOptions, type RequestOptions, type UploadOptions, type VidexoOptions, type WaitOptions, } from './client.ts';
|
|
1
|
+
export { DEFAULT_BASE_URL, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT_MS, DEFAULT_WAIT, ClientTokens, Fonts, Jobs, Outputs, Presets, Uploads, Videxo, Webhooks, type ClientTokenForJobOptions, type ClientTokenForUploadOptions, type CreateOptions, type RequestOptions, type UploadOptions, type VidexoOptions, type WaitOptions, } from './client.ts';
|
|
2
2
|
export { SDK_ERROR_CODES, VidexoError, VidexoWebhookError, type ApiErrorCode, type SdkErrorCode, type VidexoErrorCode, type VidexoWebhookErrorCode, } from './errors.ts';
|
|
3
3
|
export { MAX_RETRY_AFTER_SECONDS, type RetryPolicy } from './transport.ts';
|
|
4
|
-
export { sendUpload, type SendUploadOptions, type UploadData } from './uploads.ts';
|
|
4
|
+
export { sendUpload, type SendUploadOptions, type UploadData, type UploadProgress } from './uploads.ts';
|
|
5
5
|
export { WEBHOOK_TOLERANCE_SECONDS, verifyWebhook, type VerifyWebhookOptions, type WebhookHeaders } from './webhooks.ts';
|
|
6
6
|
export type * from './types.ts';
|
|
7
7
|
export type { components, paths } from './generated/openapi.ts';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// @videxo/sdk: the TypeScript client of the Videxo API (README.md). Runs on Node 20+, Bun, Deno and
|
|
2
|
-
// Workers, and `sendUpload()` in browsers: it uses only fetch, Web Streams and WebCrypto.
|
|
3
|
-
|
|
2
|
+
// Workers, and `sendUpload()` in browsers: it uses only fetch, Web Streams and WebCrypto. Apps and web
|
|
3
|
+
// pages use the separate entry `@videxo/sdk/client` (src/app-client.ts), with a client token.
|
|
4
|
+
export { DEFAULT_BASE_URL, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT_MS, DEFAULT_WAIT, ClientTokens, Fonts, Jobs, Outputs, Presets, Uploads, Videxo, Webhooks, } from "./client.js";
|
|
4
5
|
export { SDK_ERROR_CODES, VidexoError, VidexoWebhookError, } from "./errors.js";
|
|
5
6
|
export { MAX_RETRY_AFTER_SECONDS } from "./transport.js";
|
|
6
7
|
export { sendUpload } from "./uploads.js";
|
package/dist/types.d.ts
CHANGED
|
@@ -28,6 +28,13 @@ export type StoryboardRequest = JsonBody<paths['/v1/storyboard']['post']>;
|
|
|
28
28
|
export type GifRequest = JsonBody<paths['/v1/gif']['post']>;
|
|
29
29
|
export type AudioRequest = JsonBody<paths['/v1/audio']['post']>;
|
|
30
30
|
export type ConcatRequest = JsonBody<paths['/v1/concat']['post']>;
|
|
31
|
+
export type SlideshowRequest = JsonBody<paths['/v1/slideshow']['post']>;
|
|
32
|
+
export type ProbeRequest = JsonBody<paths['/v1/probe']['post']>;
|
|
33
|
+
/** The Job, with what ffprobe read in `probe` once it succeeded. */
|
|
34
|
+
export type ProbeResponse = Schemas['ProbeResponse'];
|
|
35
|
+
export type MediaMetadata = NonNullable<ProbeResponse['probe']>;
|
|
36
|
+
export type MediaStream = Schemas['MediaStream'];
|
|
37
|
+
export type ScenesRequest = JsonBody<paths['/v1/scenes']['post']>;
|
|
31
38
|
export type Font = Schemas['Font'];
|
|
32
39
|
export type FontList = Schemas['FontList'];
|
|
33
40
|
export type Preset = Schemas['Preset'];
|
|
@@ -43,6 +50,13 @@ export type CompletedUpload = {
|
|
|
43
50
|
content_type: string;
|
|
44
51
|
expires_at: string;
|
|
45
52
|
};
|
|
53
|
+
export type ClientToken = Schemas['ClientToken'];
|
|
54
|
+
export type ClientGrant = Schemas['ClientGrant'];
|
|
55
|
+
export type CreateClientTokenRequest = JsonBody<paths['/v1/client-tokens']['post']>;
|
|
56
|
+
export type ClientTokenInfo = Schemas['ClientTokenInfo'];
|
|
57
|
+
export type ClientJob = Schemas['ClientJob'];
|
|
58
|
+
export type ClientJobOutput = Schemas['ClientJobOutput'];
|
|
59
|
+
export type ClientJobList = Schemas['ClientJobList'];
|
|
46
60
|
export type Problem = Schemas['Problem'];
|
|
47
61
|
export type FieldError = Schemas['FieldError'];
|
|
48
62
|
export type CommandProblem = Schemas['CommandProblem'];
|
package/dist/uploads.d.ts
CHANGED
|
@@ -9,6 +9,11 @@ export type SendUploadOptions = {
|
|
|
9
9
|
/** No timeout by default: a large file may take a while. */
|
|
10
10
|
timeoutMs?: number | null;
|
|
11
11
|
};
|
|
12
|
+
/** How far an upload has come. */
|
|
13
|
+
export type UploadProgress = {
|
|
14
|
+
loaded: number;
|
|
15
|
+
total: number;
|
|
16
|
+
};
|
|
12
17
|
/** The byte length of `data`, when it can be known without reading it. */
|
|
13
18
|
export declare function sizeOf(data: UploadData): number | null;
|
|
14
19
|
/**
|
|
@@ -17,3 +22,11 @@ export declare function sizeOf(data: UploadData): number | null;
|
|
|
17
22
|
* once the bytes start to flow, so this request is never retried.
|
|
18
23
|
*/
|
|
19
24
|
export declare function sendUpload(uploadUrl: string, data: UploadData, options?: SendUploadOptions): Promise<CompletedUpload>;
|
|
25
|
+
/**
|
|
26
|
+
* `sendUpload` that reports its progress. A browser sends through `XMLHttpRequest`, the one API that
|
|
27
|
+
* reports upload progress there; elsewhere the bytes are counted as a stream hands them over. A
|
|
28
|
+
* custom `fetch` always goes through `fetch`; in a browser it reports the end only.
|
|
29
|
+
*/
|
|
30
|
+
export declare function sendUploadWithProgress(uploadUrl: string, data: UploadData, total: number, options: SendUploadOptions & {
|
|
31
|
+
onProgress(progress: UploadProgress): void;
|
|
32
|
+
}): Promise<CompletedUpload>;
|
package/dist/uploads.js
CHANGED
|
@@ -25,7 +25,9 @@ export async function sendUpload(uploadUrl, data, options = {}) {
|
|
|
25
25
|
const request = new Request(uploadUrl, init);
|
|
26
26
|
const userFetch = options.fetch;
|
|
27
27
|
const response = await send({ fetch: userFetch ? (input, init) => userFetch(input, init) : runtimeFetch, maxRetries: 0, timeoutMs: options.timeoutMs ?? null }, request, { retry: 'never', signal: options.signal, buffer: true });
|
|
28
|
-
|
|
28
|
+
return completedUpload(response, await response.text());
|
|
29
|
+
}
|
|
30
|
+
function completedUpload(response, text) {
|
|
29
31
|
let body = text;
|
|
30
32
|
try {
|
|
31
33
|
body = JSON.parse(text);
|
|
@@ -40,3 +42,73 @@ export async function sendUpload(uploadUrl, data, options = {}) {
|
|
|
40
42
|
throw sdkError('invalid_response', 'The upload URL answered without the completed upload.', { status: response.status, body });
|
|
41
43
|
return value;
|
|
42
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* `sendUpload` that reports its progress. A browser sends through `XMLHttpRequest`, the one API that
|
|
47
|
+
* reports upload progress there; elsewhere the bytes are counted as a stream hands them over. A
|
|
48
|
+
* custom `fetch` always goes through `fetch`; in a browser it reports the end only.
|
|
49
|
+
*/
|
|
50
|
+
export function sendUploadWithProgress(uploadUrl, data, total, options) {
|
|
51
|
+
const { onProgress, ...sending } = options;
|
|
52
|
+
const stream = typeof ReadableStream !== 'undefined' && data instanceof ReadableStream;
|
|
53
|
+
const Xhr = globalThis.XMLHttpRequest;
|
|
54
|
+
if (Xhr && !stream) {
|
|
55
|
+
if (!options.fetch || options.fetch === runtimeFetch)
|
|
56
|
+
return sendWithXhr(new Xhr(), uploadUrl, data, total, options);
|
|
57
|
+
// A custom fetch in a browser: not every browser can send a stream as a request body, so the bytes
|
|
58
|
+
// go as they are and the progress comes once, when they are all sent.
|
|
59
|
+
return sendUpload(uploadUrl, data, sending).then((completed) => {
|
|
60
|
+
onProgress({ loaded: total, total });
|
|
61
|
+
return completed;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
const source = stream ? data : new Response(data).body;
|
|
65
|
+
let loaded = 0;
|
|
66
|
+
const counted = source.pipeThrough(new TransformStream({
|
|
67
|
+
transform(chunk, controller) {
|
|
68
|
+
loaded += chunk.byteLength;
|
|
69
|
+
controller.enqueue(chunk);
|
|
70
|
+
onProgress({ loaded, total });
|
|
71
|
+
},
|
|
72
|
+
}));
|
|
73
|
+
return sendUpload(uploadUrl, counted, sending);
|
|
74
|
+
}
|
|
75
|
+
function sendWithXhr(xhr, uploadUrl, data, total, options) {
|
|
76
|
+
return new Promise((resolve, reject) => {
|
|
77
|
+
if (options.signal?.aborted)
|
|
78
|
+
return reject(sdkError('aborted', 'The upload was aborted.', { cause: options.signal.reason }));
|
|
79
|
+
const onAbort = () => xhr.abort();
|
|
80
|
+
const done = () => options.signal?.removeEventListener('abort', onAbort);
|
|
81
|
+
options.signal?.addEventListener('abort', onAbort, { once: true });
|
|
82
|
+
xhr.open('PUT', uploadUrl);
|
|
83
|
+
xhr.setRequestHeader('Content-Type', options.contentType ?? 'application/octet-stream');
|
|
84
|
+
if (options.timeoutMs)
|
|
85
|
+
xhr.timeout = options.timeoutMs;
|
|
86
|
+
xhr.upload.onprogress = (event) => options.onProgress({ loaded: event.loaded, total: event.lengthComputable ? event.total : total });
|
|
87
|
+
xhr.onload = () => {
|
|
88
|
+
done();
|
|
89
|
+
const headers = new Headers();
|
|
90
|
+
const requestId = xhr.getResponseHeader('request-id');
|
|
91
|
+
if (requestId)
|
|
92
|
+
headers.set('request-id', requestId);
|
|
93
|
+
try {
|
|
94
|
+
resolve(completedUpload({ ok: xhr.status >= 200 && xhr.status < 300, status: xhr.status, statusText: xhr.statusText, headers }, xhr.responseText));
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
reject(error);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
xhr.onerror = () => {
|
|
101
|
+
done();
|
|
102
|
+
reject(sdkError('network_error', 'The upload failed: the connection was lost.'));
|
|
103
|
+
};
|
|
104
|
+
xhr.ontimeout = () => {
|
|
105
|
+
done();
|
|
106
|
+
reject(sdkError('timeout', `The upload got no answer within ${options.timeoutMs} ms.`));
|
|
107
|
+
};
|
|
108
|
+
xhr.onabort = () => {
|
|
109
|
+
done();
|
|
110
|
+
reject(sdkError('aborted', 'The upload was aborted.', { cause: options.signal?.reason }));
|
|
111
|
+
};
|
|
112
|
+
xhr.send(data);
|
|
113
|
+
});
|
|
114
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@videxo/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "The TypeScript client of the Videxo API: hosted ffmpeg jobs over HTTP.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Videxo",
|
|
@@ -23,6 +23,11 @@
|
|
|
23
23
|
"import": "./dist/index.js",
|
|
24
24
|
"default": "./dist/index.js"
|
|
25
25
|
},
|
|
26
|
+
"./client": {
|
|
27
|
+
"types": "./dist/app-client.d.ts",
|
|
28
|
+
"import": "./dist/app-client.js",
|
|
29
|
+
"default": "./dist/app-client.js"
|
|
30
|
+
},
|
|
26
31
|
"./package.json": "./package.json"
|
|
27
32
|
},
|
|
28
33
|
"files": [
|