@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/dist/client.js CHANGED
@@ -1,12 +1,10 @@
1
1
  import createClient, {} from 'openapi-fetch';
2
+ import { DEFAULT_BASE_URL, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT_MS, DEFAULT_WAIT } from "./defaults.js";
2
3
  import { VidexoError, errorFromResponse, sdkError } from "./errors.js";
3
4
  import { abortableSleep, redacted, runtimeFetch, send } from "./transport.js";
4
5
  import { sendUpload, sizeOf } from "./uploads.js";
5
6
  import { verifyWebhook } from "./webhooks.js";
6
- export const DEFAULT_BASE_URL = 'https://api.videxo.io';
7
- export const DEFAULT_MAX_RETRIES = 2;
8
- export const DEFAULT_TIMEOUT_MS = 60_000;
9
- export const DEFAULT_WAIT = Object.freeze({ timeoutMs: 10 * 60_000, intervalMs: 2_000 });
7
+ export { DEFAULT_BASE_URL, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT_MS, DEFAULT_WAIT };
10
8
  const TERMINAL = new Set(['succeeded', 'failed', 'cancelled']);
11
9
  const OUTPUT_ALIAS = /^out_[A-Za-z0-9_]{1,48}$/;
12
10
  /** What an API key may hold: printable ASCII without spaces (the `Authorization` header carries it as is). */
@@ -28,6 +26,7 @@ export class Videxo {
28
26
  uploads;
29
27
  outputs;
30
28
  webhooks;
29
+ clientTokens;
31
30
  /** @internal */
32
31
  transport;
33
32
  /** @internal */
@@ -57,6 +56,7 @@ export class Videxo {
57
56
  this.uploads = new Uploads(this);
58
57
  this.outputs = new Outputs(this);
59
58
  this.webhooks = new Webhooks();
59
+ this.clientTokens = new ClientTokens(this);
60
60
  }
61
61
  /** @internal The per-request `fetch` that openapi-fetch calls: the transport with this call's policy. */
62
62
  fetchFor(retry, options = {}) {
@@ -112,6 +112,29 @@ export class Videxo {
112
112
  concat(body, options) {
113
113
  return this.createAt('/v1/concat', body, options);
114
114
  }
115
+ /** `POST /v1/slideshow`: the still `images` as one video, each held for a time, with an optional motion. */
116
+ slideshow(body, options) {
117
+ return this.createAt('/v1/slideshow', body, options);
118
+ }
119
+ /**
120
+ * `POST /v1/probe`: the container, duration and streams of `input`, read with ffprobe. The api waits
121
+ * up to 25 seconds; a job still running then is waited for here (`wait`), and its document read from
122
+ * its output file. A job that failed is answered, not thrown: `probe` is null and `error` says why.
123
+ */
124
+ async probe(body, options = {}) {
125
+ const answer = await this.createAt('/v1/probe', body, options);
126
+ if (TERMINAL.has(answer.state))
127
+ return answer;
128
+ const job = await this.jobs.wait(answer.id, { ...options.wait, signal: options.signal });
129
+ if (job.state !== 'succeeded')
130
+ return { ...job, probe: null };
131
+ const file = await this.outputs.download(job.id, 'out_metadata', { signal: options.signal });
132
+ return { ...job, probe: (await file.json()) };
133
+ }
134
+ /** `POST /v1/scenes`: the scenes of `input`, with their times and scores, as a JSON file. */
135
+ scenes(body, options) {
136
+ return this.createAt('/v1/scenes', body, options);
137
+ }
115
138
  }
116
139
  export class Jobs {
117
140
  #videxo;
@@ -323,6 +346,55 @@ export class Outputs {
323
346
  throw sdkError('output_ambiguous', `Several files of job ${jobId} are named ${output}: ${aliases.join(', ')}.`);
324
347
  }
325
348
  }
349
+ /**
350
+ * Client tokens for apps and web pages (ADR 016): short-lived, narrowly scoped, minted here on your
351
+ * server. Hand the answer's `token` and `id` to the app, which uses `@videxo/sdk/client`. Minting
352
+ * supersedes nothing, so a lost answer is retried by minting again.
353
+ */
354
+ export class ClientTokens {
355
+ #videxo;
356
+ constructor(videxo) {
357
+ this.#videxo = videxo;
358
+ }
359
+ /** `POST /v1/client-tokens`: a token with the grant you describe; `continues` refreshes a chain. */
360
+ create(grant, options = {}) {
361
+ const videxo = this.#videxo;
362
+ return videxo.unwrap(videxo.client.POST('/v1/client-tokens', { body: grant, fetch: videxo.fetchFor('safe', options) }));
363
+ }
364
+ /** A token for one upload by `subject`: what an app needs before it knows of any job. */
365
+ forUpload({ subject, maxSizeBytes, contentTypes, ttlSeconds, ...options }) {
366
+ return this.create({
367
+ subject,
368
+ uploads: { max_count: 1, max_size_bytes: maxSizeBytes, ...(contentTypes ? { content_types: contentTypes } : {}) },
369
+ ...(ttlSeconds === undefined ? {} : { ttl_seconds: ttlSeconds }),
370
+ }, options);
371
+ }
372
+ /** A token that reads one job: a new one, or with `continues` the next of the app's chain, adding the job. */
373
+ forJob(jobId, { subject, continues, ttlSeconds, ...options } = {}) {
374
+ return this.create({
375
+ jobs: { read: [jobId] },
376
+ ...(subject === undefined ? {} : { subject }),
377
+ ...(continues === undefined ? {} : { continues }),
378
+ ...(ttlSeconds === undefined ? {} : { ttl_seconds: ttlSeconds }),
379
+ }, options);
380
+ }
381
+ /** `DELETE /v1/client-tokens/{id}`: ends the token and its whole chain. Revoking again is fine. */
382
+ async revoke(id, options = {}) {
383
+ const videxo = this.#videxo;
384
+ const pending = videxo.client.DELETE('/v1/client-tokens/{id}', { params: { path: { id } }, fetch: videxo.fetchFor('safe', options) });
385
+ const { response, error } = (await pending.catch((failure) => {
386
+ throw redacted(videxo.transport, failure);
387
+ }));
388
+ if (!response.ok)
389
+ throw errorFromResponse(response, error);
390
+ }
391
+ /** `POST /v1/client-tokens/revoke`: ends every chain of the end user; answers how many tokens. */
392
+ async revokeSubject(subject, options = {}) {
393
+ const videxo = this.#videxo;
394
+ const { revoked } = await videxo.unwrap(videxo.client.POST('/v1/client-tokens/revoke', { body: { subject }, fetch: videxo.fetchFor('safe', options) }));
395
+ return revoked;
396
+ }
397
+ }
326
398
  export class Webhooks {
327
399
  /** Checks a delivery's Standard Webhooks signature and answers its event (`verifyWebhook`). */
328
400
  verify(body, headers, secret, options) {
@@ -0,0 +1,7 @@
1
+ export declare const DEFAULT_BASE_URL = "https://api.videxo.io";
2
+ export declare const DEFAULT_MAX_RETRIES = 2;
3
+ export declare const DEFAULT_TIMEOUT_MS = 60000;
4
+ export declare const DEFAULT_WAIT: Readonly<{
5
+ timeoutMs: number;
6
+ intervalMs: 2000;
7
+ }>;
@@ -0,0 +1,6 @@
1
+ // The defaults the keyed client and the app client share, apart from both so that one can be
2
+ // bundled without the other.
3
+ export const DEFAULT_BASE_URL = 'https://api.videxo.io';
4
+ export const DEFAULT_MAX_RETRIES = 2;
5
+ export const DEFAULT_TIMEOUT_MS = 60_000;
6
+ export const DEFAULT_WAIT = Object.freeze({ timeoutMs: 10 * 60_000, intervalMs: 2_000 });