@proveanything/smartlinks 1.15.15 → 1.15.16

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.
@@ -1,4 +1,4 @@
1
- import { Asset, AssetResponse, UploadAssetOptions, UploadFromUrlOptions, ListAssetsOptions, GetAssetOptions, RemoveAssetOptions, AdminListAssetsOptions, AdminListAssetsResponse, UpdateAssetOptions, ReplaceAssetFileOptions, DeleteAssetOptions, BulkDeleteAssetsOptions, RequestUploadTokenOptions, UploadTokenResponse, PublicTokenUploadOptions } from "../types/asset";
1
+ import { Asset, AssetResponse, UploadAssetOptions, UploadFromUrlOptions, ListAssetsOptions, GetAssetOptions, RemoveAssetOptions, AdminListAssetsOptions, AdminListAssetsResponse, UpdateAssetOptions, ReplaceAssetFileOptions, DeleteAssetOptions, BulkDeleteAssetsOptions, RequestUploadTokenOptions, UploadTokenResponse, PublicTokenUploadOptions, CreateResumableUploadOptions, ResumableUploadHandle } from "../types/asset";
2
2
  export declare namespace asset {
3
3
  /**
4
4
  * Error type for asset uploads
@@ -136,4 +136,27 @@ export declare namespace asset {
136
136
  * has `reviewRequired: true`.
137
137
  */
138
138
  function publicUploadWithToken(options: PublicTokenUploadOptions): Promise<Asset>;
139
+ /** Thrown by a resumable `start()`/`resume()` when the caller pauses mid-transfer. */
140
+ class UploadPausedError extends Error {
141
+ constructor();
142
+ }
143
+ /**
144
+ * Open a resumable upload for a large file (e.g. video). The bytes are chunked
145
+ * directly to storage and can be paused/resumed — including after a page reload
146
+ * or app restart, by persisting `handle.id` and calling {@link resumeUpload}.
147
+ *
148
+ * @example
149
+ * ```ts
150
+ * const handle = await asset.createResumableUpload({ file, scope, appId })
151
+ * localStorage.setItem('pendingUpload', handle.id) // survives reload
152
+ * const uploaded = await handle.start({ onProgress: p => setPct(p) })
153
+ * ```
154
+ */
155
+ function createResumableUpload(options: CreateResumableUploadOptions): Promise<ResumableUploadHandle>;
156
+ /**
157
+ * Resume a previously-created resumable upload after a reload/app restart.
158
+ * Pass the persisted `handle.id` and the same `File`; the transfer continues
159
+ * from the offset storage already holds rather than restarting.
160
+ */
161
+ function resumeUpload(handleId: string, file: File): Promise<ResumableUploadHandle>;
139
162
  }
package/dist/api/asset.js CHANGED
@@ -104,6 +104,14 @@ export var asset;
104
104
  }
105
105
  };
106
106
  xhr.onerror = () => reject(new AssetUploadError("Network error during asset upload", 'NETWORK_ERROR'));
107
+ if (options.signal) {
108
+ if (options.signal.aborted) {
109
+ xhr.abort();
110
+ return reject(new AssetUploadError("Upload aborted", 'NETWORK_ERROR'));
111
+ }
112
+ options.signal.addEventListener('abort', () => xhr.abort(), { once: true });
113
+ xhr.onabort = () => reject(new AssetUploadError("Upload aborted", 'NETWORK_ERROR'));
114
+ }
107
115
  xhr.send(formData);
108
116
  });
109
117
  }
@@ -529,4 +537,174 @@ export var asset;
529
537
  return response.json();
530
538
  }
531
539
  asset.publicUploadWithToken = publicUploadWithToken;
540
+ // ---------------------------------------------------------------------------
541
+ // Resumable uploads (large files, e.g. video) — GCS-backed, chunked, resumable
542
+ // ---------------------------------------------------------------------------
543
+ const RESUMABLE_CHUNK_SIZE = 8 * 1024 * 1024; // 8 MiB — must be a multiple of 256 KiB (GCS rule)
544
+ const RESUMABLE_MAX_RETRIES = 5;
545
+ /** Thrown by a resumable `start()`/`resume()` when the caller pauses mid-transfer. */
546
+ class UploadPausedError extends Error {
547
+ constructor() { super('Upload paused'); this.name = 'UploadPausedError'; }
548
+ }
549
+ asset.UploadPausedError = UploadPausedError;
550
+ function backoff(attempt) {
551
+ const ms = Math.min(30000, 1000 * Math.pow(2, attempt - 1));
552
+ return new Promise(r => setTimeout(r, ms));
553
+ }
554
+ class ResumableUpload {
555
+ constructor(uploadId, // signed JWT — capability for finalize
556
+ sessionUrl, // GCS resumable session URI
557
+ file, finalizePath, finalizeBody) {
558
+ this.uploadId = uploadId;
559
+ this.sessionUrl = sessionUrl;
560
+ this.file = file;
561
+ this.finalizePath = finalizePath;
562
+ this.finalizeBody = finalizeBody;
563
+ this._paused = false;
564
+ this._offset = 0;
565
+ }
566
+ get id() {
567
+ const st = { u: this.uploadId, s: this.sessionUrl, n: this.file.name, z: this.file.size, f: this.finalizePath };
568
+ return JSON.stringify(st);
569
+ }
570
+ get size() { return this.file.size; }
571
+ pause() { this._paused = true; }
572
+ resume(options) {
573
+ this._paused = false;
574
+ return this.start(options);
575
+ }
576
+ async start(options) {
577
+ this._paused = false;
578
+ const onProgress = options === null || options === void 0 ? void 0 : options.onProgress;
579
+ const signal = options === null || options === void 0 ? void 0 : options.signal;
580
+ // Probe the storage offset first — this is what makes resume work after a reload.
581
+ this._offset = await this.probeOffset(signal);
582
+ while (this._offset < this.file.size) {
583
+ if (signal === null || signal === void 0 ? void 0 : signal.aborted)
584
+ throw new AssetUploadError('Upload aborted', 'NETWORK_ERROR');
585
+ if (this._paused)
586
+ throw new UploadPausedError();
587
+ const end = Math.min(this._offset + RESUMABLE_CHUNK_SIZE, this.file.size);
588
+ const complete = await this.putChunk(this._offset, end, signal);
589
+ this._offset = end;
590
+ if (onProgress)
591
+ onProgress(Math.round((this._offset / this.file.size) * 100));
592
+ if (complete)
593
+ break;
594
+ }
595
+ return post(this.finalizePath, this.finalizeBody);
596
+ }
597
+ // PUT with `bytes * /total` returns the current stored offset (or completion).
598
+ async probeOffset(signal) {
599
+ const res = await this.putWithRetry({ 'Content-Range': `bytes */${this.file.size}` }, undefined, signal);
600
+ if (res.status === 200 || res.status === 201)
601
+ return this.file.size;
602
+ if (res.status === 308) {
603
+ const range = res.headers.get('Range');
604
+ const m = range && /bytes=0-(\d+)/.exec(range);
605
+ return m ? parseInt(m[1], 10) + 1 : 0;
606
+ }
607
+ if (res.status === 404 || res.status === 410)
608
+ throw new AssetUploadError('Upload session expired', 'UNKNOWN');
609
+ throw new AssetUploadError(`Unexpected resume-probe status ${res.status}`, 'UNKNOWN');
610
+ }
611
+ // Returns true when the final chunk completed the upload (2xx from GCS).
612
+ async putChunk(start, end, signal) {
613
+ const blob = this.file.slice(start, end);
614
+ const res = await this.putWithRetry({ 'Content-Range': `bytes ${start}-${end - 1}/${this.file.size}` }, blob, signal);
615
+ if (res.status === 200 || res.status === 201)
616
+ return true;
617
+ if (res.status === 308)
618
+ return false;
619
+ throw new AssetUploadError(`Chunk upload failed (${res.status})`, res.status === 413 ? 'FILE_TOO_LARGE' : 'UNKNOWN');
620
+ }
621
+ async putWithRetry(headers, body, signal) {
622
+ let attempt = 0;
623
+ while (true) {
624
+ if (signal === null || signal === void 0 ? void 0 : signal.aborted)
625
+ throw new AssetUploadError('Upload aborted', 'NETWORK_ERROR');
626
+ try {
627
+ const res = await fetch(this.sessionUrl, { method: 'PUT', headers, body, signal });
628
+ if (res.status >= 500 && attempt < RESUMABLE_MAX_RETRIES) {
629
+ attempt++;
630
+ await backoff(attempt);
631
+ continue;
632
+ }
633
+ return res;
634
+ }
635
+ catch (err) {
636
+ if (signal === null || signal === void 0 ? void 0 : signal.aborted)
637
+ throw new AssetUploadError('Upload aborted', 'NETWORK_ERROR');
638
+ if (attempt < RESUMABLE_MAX_RETRIES) {
639
+ attempt++;
640
+ await backoff(attempt);
641
+ continue;
642
+ }
643
+ throw new AssetUploadError('Network error during resumable upload', 'NETWORK_ERROR');
644
+ }
645
+ }
646
+ }
647
+ }
648
+ function resumableBasePath(opts) {
649
+ const prefix = (opts.admin && !opts.token) ? '/admin' : '/public';
650
+ return `${prefix}/collection/${encodeURIComponent(opts.collectionId)}/asset/resumable`;
651
+ }
652
+ /**
653
+ * Open a resumable upload for a large file (e.g. video). The bytes are chunked
654
+ * directly to storage and can be paused/resumed — including after a page reload
655
+ * or app restart, by persisting `handle.id` and calling {@link resumeUpload}.
656
+ *
657
+ * @example
658
+ * ```ts
659
+ * const handle = await asset.createResumableUpload({ file, scope, appId })
660
+ * localStorage.setItem('pendingUpload', handle.id) // survives reload
661
+ * const uploaded = await handle.start({ onProgress: p => setPct(p) })
662
+ * ```
663
+ */
664
+ async function createResumableUpload(options) {
665
+ const { file, scope, name, appId, token, admin } = options;
666
+ const base = resumableBasePath({ admin, token, collectionId: scope.collectionId });
667
+ const startBody = {
668
+ filename: name || file.name,
669
+ mime: file.type || 'application/octet-stream',
670
+ appId,
671
+ };
672
+ if (scope.type !== 'collection')
673
+ startBody.productId = scope.productId;
674
+ if (scope.type === 'proof')
675
+ startBody.proofId = scope.proofId;
676
+ const started = await post(base, startBody, token ? { 'X-Upload-Token': token } : undefined);
677
+ const finalizePath = `${base}/${encodeURIComponent(started.uploadId)}/complete`;
678
+ const finalizeBody = {};
679
+ if (name)
680
+ finalizeBody.name = name;
681
+ if (options.metadata)
682
+ finalizeBody.metadata = options.metadata;
683
+ return new ResumableUpload(started.uploadId, started.sessionUrl, file, finalizePath, finalizeBody);
684
+ }
685
+ asset.createResumableUpload = createResumableUpload;
686
+ /**
687
+ * Resume a previously-created resumable upload after a reload/app restart.
688
+ * Pass the persisted `handle.id` and the same `File`; the transfer continues
689
+ * from the offset storage already holds rather than restarting.
690
+ */
691
+ async function resumeUpload(handleId, file) {
692
+ let st;
693
+ try {
694
+ st = JSON.parse(handleId);
695
+ }
696
+ catch (_b) {
697
+ throw new AssetUploadError('Invalid resumable upload handle', 'UNKNOWN');
698
+ }
699
+ if (!st.u || !st.s || !st.f)
700
+ throw new AssetUploadError('Invalid resumable upload handle', 'UNKNOWN');
701
+ if (typeof st.z === 'number' && file.size !== st.z) {
702
+ throw new AssetUploadError('Resumed file does not match the original upload', 'UNKNOWN');
703
+ }
704
+ const finalizeBody = {};
705
+ if (st.n)
706
+ finalizeBody.name = st.n;
707
+ return new ResumableUpload(st.u, st.s, file, st.f, finalizeBody);
708
+ }
709
+ asset.resumeUpload = resumeUpload;
532
710
  })(asset || (asset = {}));
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 1.15.15 | Generated: 2026-07-29T17:46:34.198Z
3
+ Version: 1.15.16 | Generated: 2026-08-15T11:42:50.997Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -2459,6 +2459,7 @@ interface UploadAssetOptions {
2459
2459
  onProgress?: (percent: number) => void
2460
2460
  appId?: string
2461
2461
  admin?: boolean
2462
+ signal?: AbortSignal
2462
2463
  }
2463
2464
  ```
2464
2465
 
@@ -2639,6 +2640,43 @@ interface PublicTokenUploadOptions {
2639
2640
  }
2640
2641
  ```
2641
2642
 
2643
+ **CreateResumableUploadOptions** (interface)
2644
+ ```typescript
2645
+ interface CreateResumableUploadOptions {
2646
+ file: File
2647
+ scope:
2648
+ | { type: 'collection'; collectionId: string }
2649
+ | { type: 'product'; collectionId: string; productId: string }
2650
+ | { type: 'proof'; collectionId: string; productId: string; proofId: string }
2651
+ name?: string
2652
+ metadata?: Record<string, any>
2653
+ appId?: string
2654
+ admin?: boolean
2655
+ * Upload token id (from {@link requestUploadToken}) for public/unauthenticated
2656
+ * uploads. When provided, the public resumable route is used.
2657
+ token?: string
2658
+ }
2659
+ ```
2660
+
2661
+ **ResumableStartOptions** (interface)
2662
+ ```typescript
2663
+ interface ResumableStartOptions {
2664
+ onProgress?: (percent: number) => void
2665
+ signal?: AbortSignal
2666
+ }
2667
+ ```
2668
+
2669
+ **ResumableUploadHandle** (interface)
2670
+ ```typescript
2671
+ interface ResumableUploadHandle {
2672
+ readonly id: string
2673
+ readonly size: number
2674
+ start(options?: ResumableStartOptions): Promise<Asset>
2675
+ pause(): void
2676
+ resume(options?: ResumableStartOptions): Promise<Asset>
2677
+ }
2678
+ ```
2679
+
2642
2680
  **AssetResponse** = `Asset`
2643
2681
 
2644
2682
  ### attestation
@@ -8479,6 +8517,12 @@ Request a single-use upload token for a public (unauthenticated) upload. The tok
8479
8517
  **publicUploadWithToken**(options: PublicTokenUploadOptions) → `Promise<Asset>`
8480
8518
  Upload a file using a single-use upload token (no admin auth required). Assets are created with `status: 'pending_review'` when the token policy has `reviewRequired: true`.
8481
8519
 
8520
+ **createResumableUpload**(options: CreateResumableUploadOptions) → `Promise<ResumableUploadHandle>`
8521
+ Open a resumable upload for a large file (e.g. video). The bytes are chunked directly to storage and can be paused/resumed — including after a page reload or app restart, by persisting `handle.id` and calling {@link resumeUpload}. ```ts const handle = await asset.createResumableUpload({ file, scope, appId }) localStorage.setItem('pendingUpload', handle.id) // survives reload const uploaded = await handle.start({ onProgress: p => setPct(p) }) ```
8522
+
8523
+ **resumeUpload**(handleId: string, file: File) → `Promise<ResumableUploadHandle>`
8524
+ Resume a previously-created resumable upload after a reload/app restart. Pass the persisted `handle.id` and the same `File`; the transfer continues from the offset storage already holds rather than restarting.
8525
+
8482
8526
  ### async
8483
8527
 
8484
8528
  **enqueueAsyncJob**(collectionId: string,
package/dist/openapi.yaml CHANGED
@@ -17731,6 +17731,8 @@ components:
17731
17731
  type: string
17732
17732
  admin:
17733
17733
  type: boolean
17734
+ signal:
17735
+ $ref: "#/components/schemas/AbortSignal"
17734
17736
  required:
17735
17737
  - file
17736
17738
  UploadFromUrlOptions:
@@ -17996,6 +17998,39 @@ components:
17996
17998
  - collectionId
17997
17999
  - tokenId
17998
18000
  - file
18001
+ CreateResumableUploadOptions:
18002
+ type: object
18003
+ properties:
18004
+ file:
18005
+ $ref: "#/components/schemas/File"
18006
+ name:
18007
+ type: string
18008
+ metadata:
18009
+ type: object
18010
+ additionalProperties: true
18011
+ appId:
18012
+ type: string
18013
+ admin:
18014
+ type: boolean
18015
+ token:
18016
+ type: string
18017
+ required:
18018
+ - file
18019
+ ResumableStartOptions:
18020
+ type: object
18021
+ properties:
18022
+ signal:
18023
+ $ref: "#/components/schemas/AbortSignal"
18024
+ ResumableUploadHandle:
18025
+ type: object
18026
+ properties:
18027
+ id:
18028
+ type: string
18029
+ size:
18030
+ type: number
18031
+ required:
18032
+ - id
18033
+ - size
17999
18034
  AttestationResponse:
18000
18035
  type: object
18001
18036
  properties:
@@ -122,6 +122,8 @@ export interface UploadAssetOptions {
122
122
  appId?: string;
123
123
  /** Optional: Upload via admin route instead of public */
124
124
  admin?: boolean;
125
+ /** Optional: Abort the in-flight upload (browser fetch/XHR only) */
126
+ signal?: AbortSignal;
125
127
  }
126
128
  /**
127
129
  * Options for uploading an asset from a URL.
@@ -304,3 +306,57 @@ export interface PublicTokenUploadOptions {
304
306
  metadata?: Record<string, any>;
305
307
  onProgress?: (percent: number) => void;
306
308
  }
309
+ /**
310
+ * Options for opening a resumable upload. Mirrors {@link UploadAssetOptions}
311
+ * but the transfer is chunked directly to storage and can be paused/resumed,
312
+ * including after a page reload or app restart.
313
+ */
314
+ export interface CreateResumableUploadOptions {
315
+ file: File;
316
+ scope: {
317
+ type: 'collection';
318
+ collectionId: string;
319
+ } | {
320
+ type: 'product';
321
+ collectionId: string;
322
+ productId: string;
323
+ } | {
324
+ type: 'proof';
325
+ collectionId: string;
326
+ productId: string;
327
+ proofId: string;
328
+ };
329
+ name?: string;
330
+ metadata?: Record<string, any>;
331
+ appId?: string;
332
+ /** Upload via admin route (default) or, when set, the public token route. */
333
+ admin?: boolean;
334
+ /**
335
+ * Upload token id (from {@link requestUploadToken}) for public/unauthenticated
336
+ * uploads. When provided, the public resumable route is used.
337
+ */
338
+ token?: string;
339
+ }
340
+ export interface ResumableStartOptions {
341
+ /** Progress callback (0-100), driven by bytes confirmed by storage. */
342
+ onProgress?: (percent: number) => void;
343
+ /** Abort the in-flight transfer. */
344
+ signal?: AbortSignal;
345
+ }
346
+ /**
347
+ * A handle to a resumable upload. `id` is durable — persist it (e.g. in
348
+ * IndexedDB) alongside a reference to the file and pass it to
349
+ * {@link asset.resumeUpload} after a reload to continue mid-file.
350
+ */
351
+ export interface ResumableUploadHandle {
352
+ /** Durable, persistable upload id (survives reload/app restart). */
353
+ readonly id: string;
354
+ /** Total bytes of the file being uploaded. */
355
+ readonly size: number;
356
+ /** Begin (or continue) uploading, resuming from the storage offset. */
357
+ start(options?: ResumableStartOptions): Promise<Asset>;
358
+ /** Pause after the current chunk. */
359
+ pause(): void;
360
+ /** Resume a paused transfer. */
361
+ resume(options?: ResumableStartOptions): Promise<Asset>;
362
+ }
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 1.15.15 | Generated: 2026-07-29T17:46:34.198Z
3
+ Version: 1.15.16 | Generated: 2026-08-15T11:42:50.997Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -2459,6 +2459,7 @@ interface UploadAssetOptions {
2459
2459
  onProgress?: (percent: number) => void
2460
2460
  appId?: string
2461
2461
  admin?: boolean
2462
+ signal?: AbortSignal
2462
2463
  }
2463
2464
  ```
2464
2465
 
@@ -2639,6 +2640,43 @@ interface PublicTokenUploadOptions {
2639
2640
  }
2640
2641
  ```
2641
2642
 
2643
+ **CreateResumableUploadOptions** (interface)
2644
+ ```typescript
2645
+ interface CreateResumableUploadOptions {
2646
+ file: File
2647
+ scope:
2648
+ | { type: 'collection'; collectionId: string }
2649
+ | { type: 'product'; collectionId: string; productId: string }
2650
+ | { type: 'proof'; collectionId: string; productId: string; proofId: string }
2651
+ name?: string
2652
+ metadata?: Record<string, any>
2653
+ appId?: string
2654
+ admin?: boolean
2655
+ * Upload token id (from {@link requestUploadToken}) for public/unauthenticated
2656
+ * uploads. When provided, the public resumable route is used.
2657
+ token?: string
2658
+ }
2659
+ ```
2660
+
2661
+ **ResumableStartOptions** (interface)
2662
+ ```typescript
2663
+ interface ResumableStartOptions {
2664
+ onProgress?: (percent: number) => void
2665
+ signal?: AbortSignal
2666
+ }
2667
+ ```
2668
+
2669
+ **ResumableUploadHandle** (interface)
2670
+ ```typescript
2671
+ interface ResumableUploadHandle {
2672
+ readonly id: string
2673
+ readonly size: number
2674
+ start(options?: ResumableStartOptions): Promise<Asset>
2675
+ pause(): void
2676
+ resume(options?: ResumableStartOptions): Promise<Asset>
2677
+ }
2678
+ ```
2679
+
2642
2680
  **AssetResponse** = `Asset`
2643
2681
 
2644
2682
  ### attestation
@@ -8479,6 +8517,12 @@ Request a single-use upload token for a public (unauthenticated) upload. The tok
8479
8517
  **publicUploadWithToken**(options: PublicTokenUploadOptions) → `Promise<Asset>`
8480
8518
  Upload a file using a single-use upload token (no admin auth required). Assets are created with `status: 'pending_review'` when the token policy has `reviewRequired: true`.
8481
8519
 
8520
+ **createResumableUpload**(options: CreateResumableUploadOptions) → `Promise<ResumableUploadHandle>`
8521
+ Open a resumable upload for a large file (e.g. video). The bytes are chunked directly to storage and can be paused/resumed — including after a page reload or app restart, by persisting `handle.id` and calling {@link resumeUpload}. ```ts const handle = await asset.createResumableUpload({ file, scope, appId }) localStorage.setItem('pendingUpload', handle.id) // survives reload const uploaded = await handle.start({ onProgress: p => setPct(p) }) ```
8522
+
8523
+ **resumeUpload**(handleId: string, file: File) → `Promise<ResumableUploadHandle>`
8524
+ Resume a previously-created resumable upload after a reload/app restart. Pass the persisted `handle.id` and the same `File`; the transfer continues from the offset storage already holds rather than restarting.
8525
+
8482
8526
  ### async
8483
8527
 
8484
8528
  **enqueueAsyncJob**(collectionId: string,
package/openapi.yaml CHANGED
@@ -17731,6 +17731,8 @@ components:
17731
17731
  type: string
17732
17732
  admin:
17733
17733
  type: boolean
17734
+ signal:
17735
+ $ref: "#/components/schemas/AbortSignal"
17734
17736
  required:
17735
17737
  - file
17736
17738
  UploadFromUrlOptions:
@@ -17996,6 +17998,39 @@ components:
17996
17998
  - collectionId
17997
17999
  - tokenId
17998
18000
  - file
18001
+ CreateResumableUploadOptions:
18002
+ type: object
18003
+ properties:
18004
+ file:
18005
+ $ref: "#/components/schemas/File"
18006
+ name:
18007
+ type: string
18008
+ metadata:
18009
+ type: object
18010
+ additionalProperties: true
18011
+ appId:
18012
+ type: string
18013
+ admin:
18014
+ type: boolean
18015
+ token:
18016
+ type: string
18017
+ required:
18018
+ - file
18019
+ ResumableStartOptions:
18020
+ type: object
18021
+ properties:
18022
+ signal:
18023
+ $ref: "#/components/schemas/AbortSignal"
18024
+ ResumableUploadHandle:
18025
+ type: object
18026
+ properties:
18027
+ id:
18028
+ type: string
18029
+ size:
18030
+ type: number
18031
+ required:
18032
+ - id
18033
+ - size
17999
18034
  AttestationResponse:
18000
18035
  type: object
18001
18036
  properties:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proveanything/smartlinks",
3
- "version": "1.15.15",
3
+ "version": "1.15.16",
4
4
  "description": "Official JavaScript/TypeScript SDK for the Smartlinks API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",