@runappsai/sdk 0.8.0 → 0.8.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runappsai/sdk",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "description": "JavaScript / TypeScript client for the RunApps AI Gateway",
5
5
  "license": "MIT",
6
6
  "author": "RunApps",
package/src/files.ts CHANGED
@@ -48,6 +48,14 @@ export interface FileRead {
48
48
  etag?: string;
49
49
  }
50
50
 
51
+ export interface SignOptions {
52
+ /** How long the link stays valid, in seconds. Default 3600, at most 7 days. */
53
+ expiresIn?: number;
54
+ /** When true the link downloads instead of displaying inline. */
55
+ download?: boolean;
56
+ signal?: AbortSignal;
57
+ }
58
+
51
59
  export interface ListOptions {
52
60
  prefix?: string;
53
61
  cursor?: string;
@@ -343,6 +351,37 @@ export class FilesService {
343
351
  return this.run("files.copy", async () => this.transport.postJSON<FileObject>((await this.base()) + "/copy", { from, to }, init));
344
352
  }
345
353
 
354
+ /**
355
+ * A time-limited link to a private file that needs no token: put it in
356
+ * `<img src>`, `<video src>` or `<a href download>`. The link is for
357
+ * this user's copy of the file in this app; it expires after
358
+ * `expiresIn` seconds (default one hour, at most seven days) and is
359
+ * never cached, so it always shows the current bytes. For a permanent
360
+ * public address use the FileObject's `url` instead.
361
+ */
362
+ async url(path: string, opts?: SignOptions): Promise<string> {
363
+ const urls = await this.urls([path], opts);
364
+ const u = urls[path];
365
+ if (!u) throw new Error("RunApps: no signed URL returned for " + path);
366
+ return u;
367
+ }
368
+
369
+ /** Signed links for several paths at once (up to 200): `{ path: url }`. */
370
+ async urls(paths: string[], opts?: SignOptions): Promise<Record<string, string>> {
371
+ const body: { paths: string[]; expires_in?: number } = { paths };
372
+ if (opts?.expiresIn) body.expires_in = Math.floor(opts.expiresIn);
373
+ const r = await this.run("files.sign", async () => this.transport.postJSON<{ urls: Record<string, string> }>(
374
+ (await this.base()) + "/sign",
375
+ body,
376
+ opts?.signal ? { signal: opts.signal } : undefined,
377
+ ));
378
+ const out: Record<string, string> = {};
379
+ for (const [p, u] of Object.entries(r.urls || {})) {
380
+ out[p] = opts?.download ? u + (u.includes("?") ? "&" : "?") + "download=1" : u;
381
+ }
382
+ return out;
383
+ }
384
+
346
385
  /**
347
386
  * Ask the gateway to fetch `srcURL` and store the body at `path`.
348
387
  * Saves a round trip vs downloading then re-uploading. `srcURL`
package/src/index.ts CHANGED
@@ -168,6 +168,7 @@ export type {
168
168
  FileObject,
169
169
  FileListResult,
170
170
  PutOptions as FilePutOptions,
171
+ SignOptions as FileSignOptions,
171
172
  ListOptions as FileListOptions,
172
173
  PutFromURLOptions as FilePutFromURLOptions,
173
174
  BatchOp as FileBatchOp,