@proveanything/smartlinks 1.1.22 → 1.1.24

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/API_SUMMARY.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 1.1.22 | Generated: 2026-01-07T12:13:29.397Z
3
+ Version: 1.1.24 | Generated: 2026-01-11T11:29:10.460Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -125,15 +125,84 @@ interface AppConfigurationResponse {
125
125
 
126
126
  ### asset
127
127
 
128
- **AssetResponse** (interface)
128
+ **Asset** (interface)
129
129
  ```typescript
130
- interface AssetResponse {
130
+ interface Asset {
131
131
  id: string
132
- name: string
133
132
  url: string
133
+ name: string
134
+ mimeType?: string
135
+ size?: number
136
+ createdAt?: string
137
+ metadata?: Record<string, any>
138
+ assetType?: string
139
+ type?: string
140
+ collectionId?: string
141
+ hash?: string
142
+ thumbnails?: {
143
+ x100?: string
144
+ x200?: string
145
+ x512?: string
146
+ [key: string]: string | undefined
147
+ }
148
+ site?: string
149
+ cleanName?: string
150
+ }
151
+ ```
152
+
153
+ **UploadAssetOptions** (interface)
154
+ ```typescript
155
+ interface UploadAssetOptions {
156
+ file: File
157
+ scope:
158
+ | { type: 'collection'; collectionId: string }
159
+ | { type: 'product'; collectionId: string; productId: string }
160
+ | { type: 'proof'; collectionId: string; productId: string; proofId: string }
161
+ name?: string
162
+ metadata?: Record<string, any>
163
+ onProgress?: (percent: number) => void
164
+ appId?: string
165
+ }
166
+ ```
167
+
168
+ **ListAssetsOptions** (interface)
169
+ ```typescript
170
+ interface ListAssetsOptions {
171
+ scope:
172
+ | { type: 'collection'; collectionId: string }
173
+ | { type: 'product'; collectionId: string; productId: string }
174
+ | { type: 'proof'; collectionId: string; productId: string; proofId: string }
175
+ appId?: string
176
+ mimeTypePrefix?: string
177
+ limit?: number
178
+ offset?: number
179
+ }
180
+ ```
181
+
182
+ **GetAssetOptions** (interface)
183
+ ```typescript
184
+ interface GetAssetOptions {
185
+ assetId: string
186
+ scope:
187
+ | { type: 'collection'; collectionId: string }
188
+ | { type: 'product'; collectionId: string; productId: string }
189
+ | { type: 'proof'; collectionId: string; productId: string; proofId: string }
190
+ }
191
+ ```
192
+
193
+ **RemoveAssetOptions** (interface)
194
+ ```typescript
195
+ interface RemoveAssetOptions {
196
+ assetId: string
197
+ scope:
198
+ | { type: 'collection'; collectionId: string }
199
+ | { type: 'product'; collectionId: string; productId: string }
200
+ | { type: 'proof'; collectionId: string; productId: string; proofId: string }
134
201
  }
135
202
  ```
136
203
 
204
+ **AssetResponse** = `Asset`
205
+
137
206
  ### attestation
138
207
 
139
208
  **AttestationResponse** (interface)
@@ -851,6 +920,38 @@ interface UserSearchResponse {
851
920
  }
852
921
  ```
853
922
 
923
+ **ContactPublic** (interface)
924
+ ```typescript
925
+ interface ContactPublic {
926
+ contactId: string
927
+ firstName?: string | null
928
+ lastName?: string | null
929
+ displayName?: string | null
930
+ company?: string | null
931
+ avatarUrl?: string | null
932
+ locale?: string | null
933
+ timezone?: string | null
934
+ email?: string | null
935
+ phone?: string | null
936
+ externalIds?: Record<string, any>
937
+ customFields?: ContactCustomFields
938
+ }
939
+ ```
940
+
941
+ **PublicGetMyContactResponse** (interface)
942
+ ```typescript
943
+ interface PublicGetMyContactResponse {
944
+ ok: boolean; contact: ContactPublic | null
945
+ }
946
+ ```
947
+
948
+ **PublicUpdateMyContactResponse** (interface)
949
+ ```typescript
950
+ interface PublicUpdateMyContactResponse {
951
+ ok: boolean; contact: ContactPublic
952
+ }
953
+ ```
954
+
854
955
  **ContactCustomFields** = `Record<string, any>`
855
956
 
856
957
  **ContactResponse** = `Contact`
@@ -861,6 +962,8 @@ interface UserSearchResponse {
861
962
 
862
963
  **PublicContactUpsertRequest** = `Partial<`
863
964
 
965
+ **ContactPatch** = `Partial<`
966
+
864
967
  ### error
865
968
 
866
969
  **ErrorResponse** (interface)
@@ -1518,12 +1621,18 @@ interface TemplateBase {
1518
1621
  collectionId: string
1519
1622
  name: string
1520
1623
  description?: string
1521
- type: string
1624
+ type: 'pdf' | 'email' | 'multichannel' | 'label'
1522
1625
  resizeMode?: string
1523
1626
  pdf?: {
1524
1627
  base: { url: string }
1525
1628
  orientation: 'portrait' | 'landscape'
1526
1629
  }
1630
+ channels?: {
1631
+ email?: {subject: string; body: string},
1632
+ sms?: { body: string },
1633
+ push: { title: string; body: string, url?: string, iconUrl?: string },
1634
+ wallet?: { header: string; body: string; imageUri?: string }
1635
+ }
1527
1636
  subject?: string
1528
1637
  body?: string
1529
1638
  css?: string
@@ -1760,27 +1869,36 @@ Post a chat message to the AI (admin or public)
1760
1869
 
1761
1870
  ### asset
1762
1871
 
1872
+ **upload**(options: UploadAssetOptions) → `Promise<Asset>`
1873
+ Upload an asset file
1874
+
1763
1875
  **getForCollection**(collectionId: string,
1764
1876
  assetId: string) → `Promise<AssetResponse>`
1877
+ Upload an asset file
1765
1878
 
1766
1879
  **listForCollection**(collectionId: string) → `Promise<AssetResponse[]>`
1880
+ Upload an asset file
1767
1881
 
1768
1882
  **getForProduct**(collectionId: string,
1769
1883
  productId: string,
1770
1884
  assetId: string) → `Promise<AssetResponse>`
1885
+ Upload an asset file
1771
1886
 
1772
1887
  **listForProduct**(collectionId: string,
1773
1888
  productId: string) → `Promise<AssetResponse[]>`
1889
+ Upload an asset file
1774
1890
 
1775
1891
  **getForProof**(collectionId: string,
1776
1892
  productId: string,
1777
1893
  proofId: string,
1778
1894
  assetId: string) → `Promise<AssetResponse>`
1895
+ Upload an asset file
1779
1896
 
1780
1897
  **listForProof**(collectionId: string,
1781
1898
  productId: string,
1782
1899
  proofId: string,
1783
1900
  appId?: string) → `Promise<AssetResponse[]>`
1901
+ Upload an asset file
1784
1902
 
1785
1903
  **uploadAsset**(collectionId: string,
1786
1904
  productId: string,
@@ -1790,6 +1908,15 @@ Post a chat message to the AI (admin or public)
1790
1908
  onProgress?: (percent: number) → `void`
1791
1909
  Uploads an asset file to a proof, with optional extraData as JSON. Supports progress reporting via onProgress callback (browser only).
1792
1910
 
1911
+ **list**(options: ListAssetsOptions) → `Promise<Asset[]>`
1912
+ List assets for a given scope
1913
+
1914
+ **get**(options: GetAssetOptions) → `Promise<Asset>`
1915
+ Get an asset by id within a scope (public)
1916
+
1917
+ **remove**(options: RemoveAssetOptions) → `Promise<void>`
1918
+ Remove an asset by id within a scope (admin)
1919
+
1793
1920
  ### async
1794
1921
 
1795
1922
  **enqueueAsyncJob**(collectionId: string,
@@ -2166,6 +2293,11 @@ Logging: Append many communication events for a list of IDs. POST /admin/collect
2166
2293
  **publicUpsert**(collectionId: string,
2167
2294
  data: PublicContactUpsertRequest) → `Promise<PublicContactUpsertResponse>`
2168
2295
 
2296
+ **publicGetMine**(collectionId: string) → `Promise<PublicGetMyContactResponse>`
2297
+
2298
+ **publicUpdateMine**(collectionId: string,
2299
+ data: ContactPatch) → `Promise<PublicUpdateMyContactResponse>`
2300
+
2169
2301
  **erase**(collectionId: string, contactId: string, body?: any) → `Promise<ContactResponse>`
2170
2302
 
2171
2303
  **getUser**(collectionId: string,
package/README.md CHANGED
@@ -96,22 +96,88 @@ await product.update('collectionId', 'productId', { description: 'Updated' })
96
96
  await product.remove('collectionId', 'productId')
97
97
  ```
98
98
 
99
- ### Assets (upload)
99
+ ### Assets
100
100
 
101
- Browser-side upload to a proof with progress callback:
101
+ Upload, list, get, and remove assets within a scope (collection/product/proof).
102
+
103
+ #### Upload (new)
102
104
 
103
105
  ```ts
104
106
  import { asset } from '@proveanything/smartlinks'
105
107
 
106
- const result = await asset.uploadAsset(
107
- 'collectionId',
108
- 'productId',
109
- 'proofId',
108
+ const uploaded = await asset.upload({
110
109
  file, // File from an <input type="file">
111
- { description: 'Uploaded via SDK' },
112
- (progress) => console.log(`Upload: ${progress}%`)
113
- )
114
- console.log('Uploaded asset:', result)
110
+ scope: { type: 'proof', collectionId, productId, proofId },
111
+ name: 'hero.png',
112
+ metadata: { description: 'Uploaded via SDK' },
113
+ onProgress: (p) => console.log(`Upload: ${p}%`),
114
+ // appId: 'microapp-123' // optional
115
+ })
116
+ console.log('Uploaded asset:', uploaded)
117
+ ```
118
+
119
+ Deprecated upload helper (wraps to the new `upload` internally):
120
+
121
+ ```ts
122
+ // @deprecated Use asset.upload(options)
123
+ const legacy = await asset.uploadAsset(collectionId, productId, proofId, file)
124
+ ```
125
+
126
+ #### List
127
+
128
+ ```ts
129
+ // Collection assets, first 20 images
130
+ const list1 = await asset.list({
131
+ scope: { type: 'collection', collectionId },
132
+ mimeTypePrefix: 'image/',
133
+ limit: 20,
134
+ })
135
+
136
+ // Product assets, filter by appId
137
+ const list2 = await asset.list({
138
+ scope: { type: 'product', collectionId, productId },
139
+ appId: 'microapp-123',
140
+ })
141
+ ```
142
+
143
+ #### Get (scoped)
144
+
145
+ ```ts
146
+ const a = await asset.get({
147
+ assetId,
148
+ scope: { type: 'proof', collectionId, productId, proofId },
149
+ })
150
+ ```
151
+
152
+ #### Remove (scoped, admin)
153
+
154
+ ```ts
155
+ await asset.remove({
156
+ assetId,
157
+ scope: { type: 'product', collectionId, productId },
158
+ })
159
+ ```
160
+
161
+ #### Asset response example
162
+
163
+ ```json
164
+ {
165
+ "name": "Screenshot 2025-09-15 at 15.21.14",
166
+ "assetType": "Image",
167
+ "type": "png",
168
+ "collectionId": "ChaseAtlantic",
169
+ "url": "https://cdn.smartlinks.app/sites%2FChaseAtlantic%2Fimages%2F2025%2F9%2FScreenshot%202025-09-15%20at%2015%2C21%2C14-1757946214537.png",
170
+ "createdAt": "2005-10-10T23:15:03",
171
+ "hash": "fb98140a6b41ee69b824f29cc8b6795444246f871e4ab2379528b34a4d16284e",
172
+ "thumbnails": {
173
+ "x100": "https://cdn.smartlinks.app/..._100x100.png",
174
+ "x200": "https://cdn.smartlinks.app/..._200x200.png",
175
+ "x512": "https://cdn.smartlinks.app/..._512x512.png"
176
+ },
177
+ "id": "7k1cGErrlmQ94J8yDlVj",
178
+ "site": "ChaseAtlantic",
179
+ "cleanName": "Screenshot 2025-09-15 at 15.21"
180
+ }
115
181
  ```
116
182
 
117
183
  ### AI helpers
@@ -1,5 +1,19 @@
1
- import { AssetResponse } from "../types/asset";
1
+ import { Asset, AssetResponse, UploadAssetOptions, ListAssetsOptions, GetAssetOptions, RemoveAssetOptions } from "../types/asset";
2
2
  export declare namespace asset {
3
+ /**
4
+ * Error type for asset uploads
5
+ */
6
+ class AssetUploadError extends Error {
7
+ readonly code: 'FILE_TOO_LARGE' | 'INVALID_TYPE' | 'NETWORK_ERROR' | 'UNAUTHORIZED' | 'QUOTA_EXCEEDED' | 'UNKNOWN';
8
+ readonly details?: Record<string, any> | undefined;
9
+ constructor(message: string, code: 'FILE_TOO_LARGE' | 'INVALID_TYPE' | 'NETWORK_ERROR' | 'UNAUTHORIZED' | 'QUOTA_EXCEEDED' | 'UNKNOWN', details?: Record<string, any> | undefined);
10
+ }
11
+ /**
12
+ * Upload an asset file
13
+ * @returns The uploaded asset with its public URL
14
+ * @throws AssetUploadError if upload fails
15
+ */
16
+ function upload(options: UploadAssetOptions): Promise<Asset>;
3
17
  function getForCollection(collectionId: string, assetId: string): Promise<AssetResponse>;
4
18
  function listForCollection(collectionId: string): Promise<AssetResponse[]>;
5
19
  function getForProduct(collectionId: string, productId: string, assetId: string): Promise<AssetResponse>;
@@ -8,6 +22,7 @@ export declare namespace asset {
8
22
  function listForProof(collectionId: string, productId: string, proofId: string, appId?: string): Promise<AssetResponse[]>;
9
23
  /**
10
24
  * Uploads an asset file to a proof, with optional extraData as JSON.
25
+ * @deprecated Use `asset.upload(options)` instead.
11
26
  * Supports progress reporting via onProgress callback (browser only).
12
27
  * @param collectionId - The collection ID
13
28
  * @param productId - The product ID
@@ -18,4 +33,16 @@ export declare namespace asset {
18
33
  * @returns Promise resolving to an AssetResponse object
19
34
  */
20
35
  function uploadAsset(collectionId: string, productId: string, proofId: string, file: File, extraData?: Record<string, any>, onProgress?: (percent: number) => void): Promise<AssetResponse>;
36
+ /**
37
+ * List assets for a given scope
38
+ */
39
+ function list(options: ListAssetsOptions): Promise<Asset[]>;
40
+ /**
41
+ * Get an asset by id within a scope (public)
42
+ */
43
+ function get(options: GetAssetOptions): Promise<Asset>;
44
+ /**
45
+ * Remove an asset by id within a scope (admin)
46
+ */
47
+ function remove(options: RemoveAssetOptions): Promise<void>;
21
48
  }
package/dist/api/asset.js CHANGED
@@ -1,6 +1,114 @@
1
- import { request, getApiHeaders } from "../http";
1
+ import { request, post, del, getApiHeaders } from "../http";
2
2
  export var asset;
3
3
  (function (asset) {
4
+ /**
5
+ * Error type for asset uploads
6
+ */
7
+ class AssetUploadError extends Error {
8
+ constructor(message, code, details) {
9
+ super(message);
10
+ this.code = code;
11
+ this.details = details;
12
+ this.name = 'AssetUploadError';
13
+ }
14
+ }
15
+ asset.AssetUploadError = AssetUploadError;
16
+ function buildScopeBase(scope) {
17
+ if (scope.type === 'collection') {
18
+ return `/public/collection/${encodeURIComponent(scope.collectionId)}`;
19
+ }
20
+ if (scope.type === 'product') {
21
+ return `/public/collection/${encodeURIComponent(scope.collectionId)}/product/${encodeURIComponent(scope.productId)}`;
22
+ }
23
+ // proof
24
+ return `/public/collection/${encodeURIComponent(scope.collectionId)}/product/${encodeURIComponent(scope.productId)}/proof/${encodeURIComponent(scope.proofId)}`;
25
+ }
26
+ /**
27
+ * Upload an asset file
28
+ * @returns The uploaded asset with its public URL
29
+ * @throws AssetUploadError if upload fails
30
+ */
31
+ async function upload(options) {
32
+ const base = buildScopeBase(options.scope);
33
+ let path = `${base}/asset`;
34
+ if (options.appId) {
35
+ const qp = new URLSearchParams({ appId: options.appId });
36
+ path += `?${qp.toString()}`;
37
+ }
38
+ const formData = new FormData();
39
+ formData.append("file", options.file);
40
+ if (options.name)
41
+ formData.append("name", options.name);
42
+ if (options.metadata)
43
+ formData.append("metadata", JSON.stringify(options.metadata));
44
+ // If progress callback provided, use XHR for progress events (browser-only)
45
+ if (options.onProgress && typeof window !== "undefined") {
46
+ const url = (typeof window !== "undefined" && window.SMARTLINKS_API_BASEURL)
47
+ ? window.SMARTLINKS_API_BASEURL + path
48
+ : path;
49
+ const headers = getApiHeaders ? getApiHeaders() : {};
50
+ return new Promise((resolve, reject) => {
51
+ const xhr = new XMLHttpRequest();
52
+ xhr.open("POST", url);
53
+ for (const [key, value] of Object.entries(headers))
54
+ xhr.setRequestHeader(key, value);
55
+ xhr.upload.onprogress = (event) => {
56
+ if (options.onProgress && event.lengthComputable) {
57
+ const percent = Math.round((event.loaded / event.total) * 100);
58
+ options.onProgress(percent);
59
+ }
60
+ };
61
+ xhr.onload = () => {
62
+ const status = xhr.status;
63
+ const text = xhr.responseText;
64
+ if (status >= 200 && status < 300) {
65
+ try {
66
+ resolve(JSON.parse(text));
67
+ }
68
+ catch (e) {
69
+ reject(new AssetUploadError("Failed to parse server response", 'UNKNOWN'));
70
+ }
71
+ }
72
+ else {
73
+ try {
74
+ const errBody = JSON.parse(text);
75
+ const code = mapStatusToUploadErrorCode(status, errBody === null || errBody === void 0 ? void 0 : errBody.code);
76
+ reject(new AssetUploadError((errBody === null || errBody === void 0 ? void 0 : errBody.message) || `Upload failed (${status})`, code, errBody));
77
+ }
78
+ catch (_a) {
79
+ const code = mapStatusToUploadErrorCode(status);
80
+ reject(new AssetUploadError(`Asset upload failed with status ${status}`, code));
81
+ }
82
+ }
83
+ };
84
+ xhr.onerror = () => reject(new AssetUploadError("Network error during asset upload", 'NETWORK_ERROR'));
85
+ xhr.send(formData);
86
+ });
87
+ }
88
+ // Otherwise use fetch helper
89
+ try {
90
+ return await post(path, formData);
91
+ }
92
+ catch (e) {
93
+ // Map generic Error to AssetUploadError
94
+ const msg = (e === null || e === void 0 ? void 0 : e.message) || 'Upload failed';
95
+ throw new AssetUploadError(msg, 'UNKNOWN');
96
+ }
97
+ }
98
+ asset.upload = upload;
99
+ function mapStatusToUploadErrorCode(status, serverCode) {
100
+ if (status === 401 || status === 403)
101
+ return 'UNAUTHORIZED';
102
+ if (status === 413)
103
+ return 'FILE_TOO_LARGE';
104
+ if (status === 415)
105
+ return 'INVALID_TYPE';
106
+ if (status === 429)
107
+ return 'QUOTA_EXCEEDED';
108
+ if (status === 0)
109
+ return 'NETWORK_ERROR';
110
+ return 'UNKNOWN';
111
+ }
4
112
  // Collection-level
5
113
  async function getForCollection(collectionId, assetId) {
6
114
  const path = `/public/collection/${encodeURIComponent(collectionId)}/asset/${encodeURIComponent(assetId)}`;
@@ -39,6 +147,7 @@ export var asset;
39
147
  asset.listForProof = listForProof;
40
148
  /**
41
149
  * Uploads an asset file to a proof, with optional extraData as JSON.
150
+ * @deprecated Use `asset.upload(options)` instead.
42
151
  * Supports progress reporting via onProgress callback (browser only).
43
152
  * @param collectionId - The collection ID
44
153
  * @param productId - The product ID
@@ -49,52 +158,60 @@ export var asset;
49
158
  * @returns Promise resolving to an AssetResponse object
50
159
  */
51
160
  async function uploadAsset(collectionId, productId, proofId, file, extraData, onProgress) {
52
- const path = `/public/collection/${encodeURIComponent(collectionId)}/product/${encodeURIComponent(productId)}/proof/${encodeURIComponent(proofId)}/asset`;
53
- const url = (typeof window !== "undefined" && window.SMARTLINKS_API_BASEURL)
54
- ? window.SMARTLINKS_API_BASEURL + path
55
- : path; // fallback for SSR or Node
56
- const formData = new FormData();
57
- formData.append("file", file);
58
- if (extraData) {
59
- formData.append("extraData", JSON.stringify(extraData));
60
- }
61
- // Use getApiHeaders from http module
62
- const headers = getApiHeaders ? getApiHeaders() : {};
63
- return new Promise((resolve, reject) => {
64
- const xhr = new XMLHttpRequest();
65
- xhr.open("POST", url);
66
- // Set headers for API key and bearer token if available
67
- for (const [key, value] of Object.entries(headers)) {
68
- xhr.setRequestHeader(key, value);
69
- }
70
- xhr.upload.onprogress = (event) => {
71
- if (onProgress && event.lengthComputable) {
72
- const percent = Math.round((event.loaded / event.total) * 100);
73
- onProgress(percent);
74
- }
75
- };
76
- xhr.onload = () => {
77
- if (xhr.status >= 200 && xhr.status < 300) {
78
- try {
79
- resolve(JSON.parse(xhr.responseText));
80
- }
81
- catch (e) {
82
- reject(new Error("Failed to parse server response"));
83
- }
84
- }
85
- else {
86
- try {
87
- const errBody = JSON.parse(xhr.responseText);
88
- reject(new Error(`Error ${errBody.code}: ${errBody.message}`));
89
- }
90
- catch (_a) {
91
- reject(new Error(`Asset upload failed with status ${xhr.status}`));
92
- }
93
- }
94
- };
95
- xhr.onerror = () => reject(new Error("Network error during asset upload"));
96
- xhr.send(formData);
161
+ // Route through new upload API for backward compatibility
162
+ const res = await upload({
163
+ file,
164
+ name: file === null || file === void 0 ? void 0 : file.name,
165
+ metadata: extraData,
166
+ onProgress,
167
+ scope: { type: 'proof', collectionId, productId, proofId },
97
168
  });
169
+ return res;
98
170
  }
99
171
  asset.uploadAsset = uploadAsset;
172
+ /**
173
+ * List assets for a given scope
174
+ */
175
+ async function list(options) {
176
+ const base = buildScopeBase(options.scope);
177
+ const params = new URLSearchParams();
178
+ if (options.appId)
179
+ params.set('appId', options.appId);
180
+ if (options.mimeTypePrefix)
181
+ params.set('mimeTypePrefix', options.mimeTypePrefix);
182
+ if (typeof options.limit === 'number')
183
+ params.set('limit', String(options.limit));
184
+ if (typeof options.offset === 'number')
185
+ params.set('offset', String(options.offset));
186
+ const path = `${base}/asset${params.toString() ? `?${params}` : ''}`;
187
+ return request(path);
188
+ }
189
+ asset.list = list;
190
+ /**
191
+ * Get an asset by id within a scope (public)
192
+ */
193
+ async function get(options) {
194
+ const base = buildScopeBase(options.scope);
195
+ const path = `${base}/asset/${encodeURIComponent(options.assetId)}`;
196
+ return request(path);
197
+ }
198
+ asset.get = get;
199
+ /**
200
+ * Remove an asset by id within a scope (admin)
201
+ */
202
+ async function remove(options) {
203
+ const scope = options.scope;
204
+ let path;
205
+ if (scope.type === 'collection') {
206
+ path = `/admin/collection/${encodeURIComponent(scope.collectionId)}/asset/${encodeURIComponent(options.assetId)}`;
207
+ }
208
+ else if (scope.type === 'product') {
209
+ path = `/admin/collection/${encodeURIComponent(scope.collectionId)}/product/${encodeURIComponent(scope.productId)}/asset/${encodeURIComponent(options.assetId)}`;
210
+ }
211
+ else {
212
+ path = `/admin/collection/${encodeURIComponent(scope.collectionId)}/product/${encodeURIComponent(scope.productId)}/proof/${encodeURIComponent(scope.proofId)}/asset/${encodeURIComponent(options.assetId)}`;
213
+ }
214
+ return del(path);
215
+ }
216
+ asset.remove = remove;
100
217
  })(asset || (asset = {}));
@@ -1,4 +1,4 @@
1
- import { ContactResponse, ContactCreateRequest, ContactUpdateRequest, ContactListResponse, PublicContactUpsertRequest, PublicContactUpsertResponse, UserSearchResponse } from "../types";
1
+ import { ContactResponse, ContactCreateRequest, ContactUpdateRequest, ContactListResponse, PublicContactUpsertRequest, PublicContactUpsertResponse, UserSearchResponse, ContactPatch, PublicGetMyContactResponse, PublicUpdateMyContactResponse } from "../types";
2
2
  export declare namespace contact {
3
3
  function create(collectionId: string, data: ContactCreateRequest): Promise<ContactResponse>;
4
4
  function list(collectionId: string, params?: {
@@ -17,6 +17,8 @@ export declare namespace contact {
17
17
  }): Promise<ContactResponse>;
18
18
  function upsert(collectionId: string, data: ContactCreateRequest): Promise<ContactResponse>;
19
19
  function publicUpsert(collectionId: string, data: PublicContactUpsertRequest): Promise<PublicContactUpsertResponse>;
20
+ function publicGetMine(collectionId: string): Promise<PublicGetMyContactResponse>;
21
+ function publicUpdateMine(collectionId: string, data: ContactPatch): Promise<PublicUpdateMyContactResponse>;
20
22
  function erase(collectionId: string, contactId: string, body?: any): Promise<ContactResponse>;
21
23
  function getUser(collectionId: string, userId: string): Promise<UserSearchResponse>;
22
24
  }
@@ -59,6 +59,18 @@ export var contact;
59
59
  return post(path, data);
60
60
  }
61
61
  contact.publicUpsert = publicUpsert;
62
+ // Public: Get "my" contact (requires auth bearer token)
63
+ async function publicGetMine(collectionId) {
64
+ const path = `/public/collection/${encodeURIComponent(collectionId)}/contact/me`;
65
+ return request(path);
66
+ }
67
+ contact.publicGetMine = publicGetMine;
68
+ // Public: Update "my" contact (requires auth bearer token)
69
+ async function publicUpdateMine(collectionId, data) {
70
+ const path = `/public/collection/${encodeURIComponent(collectionId)}/contact/me`;
71
+ return patch(path, data);
72
+ }
73
+ contact.publicUpdateMine = publicUpdateMine;
62
74
  async function erase(collectionId, contactId, body) {
63
75
  const path = `/admin/collection/${encodeURIComponent(collectionId)}/contacts/${encodeURIComponent(contactId)}/erase`;
64
76
  return post(path, body || {});
@@ -1,8 +1,142 @@
1
+ /**
2
+ * Response from any asset upload or retrieval operation
3
+ */
1
4
  /**
2
5
  * Represents an Asset object.
6
+ *
7
+ * Example server response shape:
8
+ * @example
9
+ * {
10
+ * "name": "Screenshot 2025-09-15 at 15.21.14",
11
+ * "assetType": "Image",
12
+ * "type": "png",
13
+ * "collectionId": "myCollection",
14
+ * "url": "https://cdn.smartlinks.app/s25-09-15%20at14537.png",
15
+ * "createdAt": "2005-10-10T23:15:03",
16
+ * "hash": "fb98140a6b41ee69b824f29cc8b6795444246f871e4ab2379528b34a4d16284e",
17
+ * "thumbnails": {
18
+ * "x100": "https://cdn.smartlinks.app/sit2F..._100x100.png",
19
+ * "x200": "https://cdn.smartlinks.app/sit2F..._200x200.png",
20
+ * "x512": "https://cdn.smartlinks.app/sit2F..._512x512.png"
21
+ * },
22
+ * "id": "7k1cGErrlmQ94J8yDlVj",
23
+ * "site": "ChaseAtlantic",
24
+ * "cleanName": "Screenshot 2025-09-15 at 15.21"
25
+ * }
3
26
  */
4
- export interface AssetResponse {
27
+ export interface Asset {
28
+ /** Unique identifier for the asset */
5
29
  id: string;
6
- name: string;
30
+ /** The public URL to access the asset */
7
31
  url: string;
32
+ /** Original filename */
33
+ name: string;
34
+ /** MIME type (e.g., 'image/jpeg', 'video/mp4') */
35
+ mimeType?: string;
36
+ /** File size in bytes */
37
+ size?: number;
38
+ /** When the asset was uploaded */
39
+ createdAt?: string;
40
+ /** Any custom metadata attached during upload */
41
+ metadata?: Record<string, any>;
42
+ /** Optional: broader classification like 'Image' or 'Video' */
43
+ assetType?: string;
44
+ /** Optional: file extension/type shorthand (e.g., 'png') */
45
+ type?: string;
46
+ /** Optional: owning collection identifier */
47
+ collectionId?: string;
48
+ /** Optional: content hash */
49
+ hash?: string;
50
+ /** Optional: CDN thumbnail URLs */
51
+ thumbnails?: {
52
+ x100?: string;
53
+ x200?: string;
54
+ x512?: string;
55
+ [key: string]: string | undefined;
56
+ };
57
+ /** Optional: site identifier alias */
58
+ site?: string;
59
+ /** Optional: prettified name */
60
+ cleanName?: string;
61
+ }
62
+ export type AssetResponse = Asset;
63
+ export interface UploadAssetOptions {
64
+ /** The file to upload (from input[type="file"] or drag-drop) */
65
+ file: File;
66
+ /** Where to attach the asset */
67
+ scope: {
68
+ type: 'collection';
69
+ collectionId: string;
70
+ } | {
71
+ type: 'product';
72
+ collectionId: string;
73
+ productId: string;
74
+ } | {
75
+ type: 'proof';
76
+ collectionId: string;
77
+ productId: string;
78
+ proofId: string;
79
+ };
80
+ /** Optional: Custom filename (defaults to file.name) */
81
+ name?: string;
82
+ /** Optional: Custom metadata to store with the asset */
83
+ metadata?: Record<string, any>;
84
+ /** Optional: Progress callback (0-100) */
85
+ onProgress?: (percent: number) => void;
86
+ /** Optional: App ID for scoping to a specific microapp */
87
+ appId?: string;
88
+ }
89
+ export interface ListAssetsOptions {
90
+ scope: {
91
+ type: 'collection';
92
+ collectionId: string;
93
+ } | {
94
+ type: 'product';
95
+ collectionId: string;
96
+ productId: string;
97
+ } | {
98
+ type: 'proof';
99
+ collectionId: string;
100
+ productId: string;
101
+ proofId: string;
102
+ };
103
+ /** Filter by app ID */
104
+ appId?: string;
105
+ /** Filter by MIME type prefix (e.g., 'image/', 'video/') */
106
+ mimeTypePrefix?: string;
107
+ /** Pagination */
108
+ limit?: number;
109
+ offset?: number;
110
+ }
111
+ export interface GetAssetOptions {
112
+ assetId: string;
113
+ scope: {
114
+ type: 'collection';
115
+ collectionId: string;
116
+ } | {
117
+ type: 'product';
118
+ collectionId: string;
119
+ productId: string;
120
+ } | {
121
+ type: 'proof';
122
+ collectionId: string;
123
+ productId: string;
124
+ proofId: string;
125
+ };
126
+ }
127
+ export interface RemoveAssetOptions {
128
+ assetId: string;
129
+ scope: {
130
+ type: 'collection';
131
+ collectionId: string;
132
+ } | {
133
+ type: 'product';
134
+ collectionId: string;
135
+ productId: string;
136
+ } | {
137
+ type: 'proof';
138
+ collectionId: string;
139
+ productId: string;
140
+ proofId: string;
141
+ };
8
142
  }
@@ -50,3 +50,28 @@ export interface UserSearchResponse {
50
50
  contact: ContactResponse | null;
51
51
  existsAsContact: boolean;
52
52
  }
53
+ export interface ContactPublic {
54
+ contactId: string;
55
+ firstName?: string | null;
56
+ lastName?: string | null;
57
+ displayName?: string | null;
58
+ company?: string | null;
59
+ avatarUrl?: string | null;
60
+ locale?: string | null;
61
+ timezone?: string | null;
62
+ email?: string | null;
63
+ phone?: string | null;
64
+ externalIds?: Record<string, any>;
65
+ customFields?: ContactCustomFields;
66
+ }
67
+ export type ContactPatch = Partial<Pick<Contact, "firstName" | "lastName" | "displayName" | "company" | "avatarUrl" | "locale" | "timezone" | "email" | "phone" | "externalIds">> & {
68
+ customFields?: ContactCustomFields;
69
+ };
70
+ export interface PublicGetMyContactResponse {
71
+ ok: boolean;
72
+ contact: ContactPublic | null;
73
+ }
74
+ export interface PublicUpdateMyContactResponse {
75
+ ok: boolean;
76
+ contact: ContactPublic;
77
+ }
@@ -3,7 +3,7 @@ export interface TemplateBase {
3
3
  collectionId: string;
4
4
  name: string;
5
5
  description?: string;
6
- type: string;
6
+ type: 'pdf' | 'email' | 'multichannel' | 'label';
7
7
  resizeMode?: string;
8
8
  pdf?: {
9
9
  base: {
@@ -11,6 +11,26 @@ export interface TemplateBase {
11
11
  };
12
12
  orientation: 'portrait' | 'landscape';
13
13
  };
14
+ channels?: {
15
+ email?: {
16
+ subject: string;
17
+ body: string;
18
+ };
19
+ sms?: {
20
+ body: string;
21
+ };
22
+ push: {
23
+ title: string;
24
+ body: string;
25
+ url?: string;
26
+ iconUrl?: string;
27
+ };
28
+ wallet?: {
29
+ header: string;
30
+ body: string;
31
+ imageUri?: string;
32
+ };
33
+ };
14
34
  subject?: string;
15
35
  body?: string;
16
36
  css?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proveanything/smartlinks",
3
- "version": "1.1.22",
3
+ "version": "1.1.24",
4
4
  "description": "Official JavaScript/TypeScript SDK for the Smartlinks API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",