@proveanything/smartlinks 1.3.32 → 1.3.34

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,3 +1,4 @@
1
+ import { CollectionWidgetsResponse, GetCollectionWidgetsOptions } from "../types/appManifest";
1
2
  export type AppConfigOptions = {
2
3
  appId: string;
3
4
  collectionId?: string;
@@ -19,4 +20,41 @@ export declare namespace appConfiguration {
19
20
  function getDataItem(opts: AppConfigOptions): Promise<any>;
20
21
  function setDataItem(opts: AppConfigOptions): Promise<any>;
21
22
  function deleteDataItem(opts: AppConfigOptions): Promise<void>;
23
+ /**
24
+ * Fetches ALL widget data (manifests + bundle files) for a collection in one call.
25
+ * Returns everything needed to render widgets with zero additional requests.
26
+ *
27
+ * This solves N+1 query problems by fetching manifests, JavaScript bundles,
28
+ * and CSS files in parallel on the server.
29
+ *
30
+ * @param collectionId - The collection ID
31
+ * @param options - Optional settings (force: bypass cache)
32
+ * @returns Promise resolving to collection widgets with manifests and bundle files
33
+ * @throws ErrorResponse if the request fails
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * // Fetch all widget data for a collection
38
+ * const { apps } = await Api.AppConfiguration.getWidgets(collectionId);
39
+ * // Returns: [{ appId, manifestUrl, manifest, bundleSource, bundleCss }, ...]
40
+ *
41
+ * // Convert bundle source to dynamic imports
42
+ * for (const app of apps) {
43
+ * const blob = new Blob([app.bundleSource], { type: 'application/javascript' });
44
+ * const blobUrl = URL.createObjectURL(blob);
45
+ * const widgetModule = await import(blobUrl);
46
+ *
47
+ * // Inject CSS if present
48
+ * if (app.bundleCss) {
49
+ * const styleTag = document.createElement('style');
50
+ * styleTag.textContent = app.bundleCss;
51
+ * document.head.appendChild(styleTag);
52
+ * }
53
+ * }
54
+ *
55
+ * // Force refresh all widgets
56
+ * const { apps } = await Api.AppConfiguration.getWidgets(collectionId, { force: true });
57
+ * ```
58
+ */
59
+ function getWidgets(collectionId: string, options?: GetCollectionWidgetsOptions): Promise<CollectionWidgetsResponse>;
22
60
  }
@@ -88,4 +88,48 @@ export var appConfiguration;
88
88
  return del(path);
89
89
  }
90
90
  appConfiguration.deleteDataItem = deleteDataItem;
91
+ /**
92
+ * Fetches ALL widget data (manifests + bundle files) for a collection in one call.
93
+ * Returns everything needed to render widgets with zero additional requests.
94
+ *
95
+ * This solves N+1 query problems by fetching manifests, JavaScript bundles,
96
+ * and CSS files in parallel on the server.
97
+ *
98
+ * @param collectionId - The collection ID
99
+ * @param options - Optional settings (force: bypass cache)
100
+ * @returns Promise resolving to collection widgets with manifests and bundle files
101
+ * @throws ErrorResponse if the request fails
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * // Fetch all widget data for a collection
106
+ * const { apps } = await Api.AppConfiguration.getWidgets(collectionId);
107
+ * // Returns: [{ appId, manifestUrl, manifest, bundleSource, bundleCss }, ...]
108
+ *
109
+ * // Convert bundle source to dynamic imports
110
+ * for (const app of apps) {
111
+ * const blob = new Blob([app.bundleSource], { type: 'application/javascript' });
112
+ * const blobUrl = URL.createObjectURL(blob);
113
+ * const widgetModule = await import(blobUrl);
114
+ *
115
+ * // Inject CSS if present
116
+ * if (app.bundleCss) {
117
+ * const styleTag = document.createElement('style');
118
+ * styleTag.textContent = app.bundleCss;
119
+ * document.head.appendChild(styleTag);
120
+ * }
121
+ * }
122
+ *
123
+ * // Force refresh all widgets
124
+ * const { apps } = await Api.AppConfiguration.getWidgets(collectionId, { force: true });
125
+ * ```
126
+ */
127
+ async function getWidgets(collectionId, options) {
128
+ let path = `/public/collection/${encodeURIComponent(collectionId)}/app/widgets`;
129
+ if (options === null || options === void 0 ? void 0 : options.force) {
130
+ path += '?force=true';
131
+ }
132
+ return request(path);
133
+ }
134
+ appConfiguration.getWidgets = getWidgets;
91
135
  })(appConfiguration || (appConfiguration = {}));
@@ -4,25 +4,25 @@ export var appRecord;
4
4
  (function (appRecord) {
5
5
  // Get app record (admin only)
6
6
  async function get(collectionId, appId) {
7
- const path = `/api/v1/admin/collection/${encodeURIComponent(collectionId)}/app/${encodeURIComponent(appId)}`;
7
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/app/${encodeURIComponent(appId)}`;
8
8
  return request(path);
9
9
  }
10
10
  appRecord.get = get;
11
11
  // Create app record (admin only)
12
12
  async function create(collectionId, appId, data) {
13
- const path = `/api/v1/admin/collection/${encodeURIComponent(collectionId)}/app/${encodeURIComponent(appId)}`;
13
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/app/${encodeURIComponent(appId)}`;
14
14
  return post(path, data);
15
15
  }
16
16
  appRecord.create = create;
17
17
  // Update app record (admin only)
18
18
  async function update(collectionId, appId, data) {
19
- const path = `/api/v1/admin/collection/${encodeURIComponent(collectionId)}/app/${encodeURIComponent(appId)}`;
19
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/app/${encodeURIComponent(appId)}`;
20
20
  return put(path, data);
21
21
  }
22
22
  appRecord.update = update;
23
23
  // Delete app record (admin only)
24
24
  async function remove(collectionId, appId) {
25
- const path = `/api/v1/admin/collection/${encodeURIComponent(collectionId)}/app/${encodeURIComponent(appId)}`;
25
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/app/${encodeURIComponent(appId)}`;
26
26
  return del(path);
27
27
  }
28
28
  appRecord.remove = remove;
@@ -1,4 +1,4 @@
1
- import { Asset, AssetResponse, UploadAssetOptions, ListAssetsOptions, GetAssetOptions, RemoveAssetOptions } from "../types/asset";
1
+ import { Asset, AssetResponse, UploadAssetOptions, UploadFromUrlOptions, ListAssetsOptions, GetAssetOptions, RemoveAssetOptions } from "../types/asset";
2
2
  export declare namespace asset {
3
3
  /**
4
4
  * Error type for asset uploads
@@ -14,6 +14,34 @@ export declare namespace asset {
14
14
  * @throws AssetUploadError if upload fails
15
15
  */
16
16
  function upload(options: UploadAssetOptions): Promise<Asset>;
17
+ /**
18
+ * Upload an asset from a URL
19
+ * The server will fetch the file from the provided URL and store it permanently in your CDN.
20
+ * This solves CORS issues and ensures files are permanently stored.
21
+ *
22
+ * @param options - Upload options including URL and scope
23
+ * @returns The uploaded asset with its CDN URL
24
+ * @throws AssetUploadError if upload fails
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * // Upload AI-generated image
29
+ * const asset = await asset.uploadFromUrl({
30
+ * url: 'https://oaidalleapiprodscus.blob.core.windows.net/...',
31
+ * scope: { type: 'collection', collectionId: 'my-collection' },
32
+ * metadata: { name: 'AI Generated Image', app: 'gallery' }
33
+ * });
34
+ *
35
+ * // Upload stock photo
36
+ * const asset = await asset.uploadFromUrl({
37
+ * url: 'https://images.unsplash.com/photo-...',
38
+ * scope: { type: 'product', collectionId: 'my-collection', productId: 'wine-bottle' },
39
+ * folder: 'images',
40
+ * metadata: { name: 'Product Photo' }
41
+ * });
42
+ * ```
43
+ */
44
+ function uploadFromUrl(options: UploadFromUrlOptions): Promise<Asset>;
17
45
  function getForCollection(collectionId: string, assetId: string): Promise<AssetResponse>;
18
46
  function listForCollection(collectionId: string): Promise<AssetResponse[]>;
19
47
  function getForProduct(collectionId: string, productId: string, assetId: string): Promise<AssetResponse>;
package/dist/api/asset.js CHANGED
@@ -107,6 +107,58 @@ export var asset;
107
107
  }
108
108
  }
109
109
  asset.upload = upload;
110
+ /**
111
+ * Upload an asset from a URL
112
+ * The server will fetch the file from the provided URL and store it permanently in your CDN.
113
+ * This solves CORS issues and ensures files are permanently stored.
114
+ *
115
+ * @param options - Upload options including URL and scope
116
+ * @returns The uploaded asset with its CDN URL
117
+ * @throws AssetUploadError if upload fails
118
+ *
119
+ * @example
120
+ * ```typescript
121
+ * // Upload AI-generated image
122
+ * const asset = await asset.uploadFromUrl({
123
+ * url: 'https://oaidalleapiprodscus.blob.core.windows.net/...',
124
+ * scope: { type: 'collection', collectionId: 'my-collection' },
125
+ * metadata: { name: 'AI Generated Image', app: 'gallery' }
126
+ * });
127
+ *
128
+ * // Upload stock photo
129
+ * const asset = await asset.uploadFromUrl({
130
+ * url: 'https://images.unsplash.com/photo-...',
131
+ * scope: { type: 'product', collectionId: 'my-collection', productId: 'wine-bottle' },
132
+ * folder: 'images',
133
+ * metadata: { name: 'Product Photo' }
134
+ * });
135
+ * ```
136
+ */
137
+ async function uploadFromUrl(options) {
138
+ const base = buildScopeBase(options.scope, !!options.admin);
139
+ let path = `${base}/asset`;
140
+ if (options.appId) {
141
+ const qp = new URLSearchParams({ appId: options.appId });
142
+ path += `?${qp.toString()}`;
143
+ }
144
+ const body = {
145
+ url: options.url
146
+ };
147
+ if (options.folder) {
148
+ body.folder = options.folder;
149
+ }
150
+ if (options.metadata) {
151
+ body.extraData = options.metadata;
152
+ }
153
+ try {
154
+ return await post(path, body);
155
+ }
156
+ catch (e) {
157
+ const msg = (e === null || e === void 0 ? void 0 : e.message) || 'URL upload failed';
158
+ throw new AssetUploadError(msg, 'UNKNOWN');
159
+ }
160
+ }
161
+ asset.uploadFromUrl = uploadFromUrl;
110
162
  function mapStatusToUploadErrorCode(status, serverCode) {
111
163
  if (status === 401 || status === 403)
112
164
  return 'UNAUTHORIZED';
@@ -1,5 +1,4 @@
1
1
  import { CollectionResponse, CollectionCreateRequest, CollectionUpdateRequest, AppsConfigResponse } from "../types/collection";
2
- import { CollectionWidgetsResponse, GetCollectionWidgetsOptions } from "../types/appManifest";
3
2
  export declare namespace collection {
4
3
  /**
5
4
  * Retrieves a single Collection by its ID.
@@ -36,43 +35,6 @@ export declare namespace collection {
36
35
  * @throws ErrorResponse if the request fails
37
36
  */
38
37
  function getAppsConfig(collectionId: string): Promise<AppsConfigResponse>;
39
- /**
40
- * Fetches ALL widget data (manifests + bundle files) for a collection in one call.
41
- * Returns everything needed to render widgets with zero additional requests.
42
- *
43
- * This solves N+1 query problems by fetching manifests, JavaScript bundles,
44
- * and CSS files in parallel on the server.
45
- *
46
- * @param collectionId - The collection ID
47
- * @param options - Optional settings (force: bypass cache)
48
- * @returns Promise resolving to collection widgets with manifests and bundle files
49
- * @throws ErrorResponse if the request fails
50
- *
51
- * @example
52
- * ```typescript
53
- * // Fetch all widget data for a collection
54
- * const { apps } = await Api.Collection.getWidgets(collectionId);
55
- * // Returns: [{ appId, manifestUrl, manifest, bundleSource, bundleCss }, ...]
56
- *
57
- * // Convert bundle source to dynamic imports
58
- * for (const app of apps) {
59
- * const blob = new Blob([app.bundleSource], { type: 'application/javascript' });
60
- * const blobUrl = URL.createObjectURL(blob);
61
- * const widgetModule = await import(blobUrl);
62
- *
63
- * // Inject CSS if present
64
- * if (app.bundleCss) {
65
- * const styleTag = document.createElement('style');
66
- * styleTag.textContent = app.bundleCss;
67
- * document.head.appendChild(styleTag);
68
- * }
69
- * }
70
- *
71
- * // Force refresh all widgets
72
- * const { apps } = await Api.Collection.getWidgets(collectionId, { force: true });
73
- * ```
74
- */
75
- function getWidgets(collectionId: string, options?: GetCollectionWidgetsOptions): Promise<CollectionWidgetsResponse>;
76
38
  /**
77
39
  * Update a specific settings group for a collection (admin endpoint).
78
40
  * @param collectionId – Identifier of the collection
@@ -60,50 +60,6 @@ export var collection;
60
60
  return request(path);
61
61
  }
62
62
  collection.getAppsConfig = getAppsConfig;
63
- /**
64
- * Fetches ALL widget data (manifests + bundle files) for a collection in one call.
65
- * Returns everything needed to render widgets with zero additional requests.
66
- *
67
- * This solves N+1 query problems by fetching manifests, JavaScript bundles,
68
- * and CSS files in parallel on the server.
69
- *
70
- * @param collectionId - The collection ID
71
- * @param options - Optional settings (force: bypass cache)
72
- * @returns Promise resolving to collection widgets with manifests and bundle files
73
- * @throws ErrorResponse if the request fails
74
- *
75
- * @example
76
- * ```typescript
77
- * // Fetch all widget data for a collection
78
- * const { apps } = await Api.Collection.getWidgets(collectionId);
79
- * // Returns: [{ appId, manifestUrl, manifest, bundleSource, bundleCss }, ...]
80
- *
81
- * // Convert bundle source to dynamic imports
82
- * for (const app of apps) {
83
- * const blob = new Blob([app.bundleSource], { type: 'application/javascript' });
84
- * const blobUrl = URL.createObjectURL(blob);
85
- * const widgetModule = await import(blobUrl);
86
- *
87
- * // Inject CSS if present
88
- * if (app.bundleCss) {
89
- * const styleTag = document.createElement('style');
90
- * styleTag.textContent = app.bundleCss;
91
- * document.head.appendChild(styleTag);
92
- * }
93
- * }
94
- *
95
- * // Force refresh all widgets
96
- * const { apps } = await Api.Collection.getWidgets(collectionId, { force: true });
97
- * ```
98
- */
99
- async function getWidgets(collectionId, options) {
100
- let path = `/public/collection/${encodeURIComponent(collectionId)}/app/widgets`;
101
- if (options === null || options === void 0 ? void 0 : options.force) {
102
- path += '?force=true';
103
- }
104
- return request(path);
105
- }
106
- collection.getWidgets = getWidgets;
107
63
  /**
108
64
  * Update a specific settings group for a collection (admin endpoint).
109
65
  * @param collectionId – Identifier of the collection
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 1.3.32 | Generated: 2026-02-15T09:31:59.881Z
3
+ Version: 1.3.34 | Generated: 2026-02-16T09:46:01.466Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -29,6 +29,7 @@ The Smartlinks SDK is organized into the following namespaces:
29
29
  - **batch** - Group products into batches; manage serial number ranges and lookups.
30
30
  - **crate** - Organize products in containers/crates for logistics and grouping.
31
31
  - **form** - Build and manage dynamic forms used by apps and workflows.
32
+ - **appRecord** - Store and retrieve application-level records tied to a collection.
32
33
  - **appConfiguration** - Read/write app configuration and scoped data (collection/product/proof).
33
34
 
34
35
  — Identity & Access —
@@ -753,6 +754,9 @@ interface AIGenerateImageRequest {
753
754
  prompt: string
754
755
  provider?: string
755
756
  model?: string
757
+ * Requested image size.
758
+ * OpenAI supported values: '1024x1024', '1024x1792', '1792x1024'
759
+ * Other providers may support different sizes.
756
760
  size?: string
757
761
  [key: string]: any
758
762
  }
@@ -940,6 +944,21 @@ interface UploadAssetOptions {
940
944
  }
941
945
  ```
942
946
 
947
+ **UploadFromUrlOptions** (interface)
948
+ ```typescript
949
+ interface UploadFromUrlOptions {
950
+ url: string
951
+ scope:
952
+ | { type: 'collection'; collectionId: string }
953
+ | { type: 'product'; collectionId: string; productId: string }
954
+ | { type: 'proof'; collectionId: string; productId: string; proofId: string }
955
+ folder?: 'images' | 'videos' | 'documents'
956
+ metadata?: Record<string, any>
957
+ appId?: string
958
+ admin?: boolean
959
+ }
960
+ ```
961
+
943
962
  **ListAssetsOptions** (interface)
944
963
  ```typescript
945
964
  interface ListAssetsOptions {
@@ -3931,38 +3950,55 @@ Post a chat message to the AI (admin or public)
3931
3950
 
3932
3951
  **deleteDataItem**(opts: AppConfigOptions) → `Promise<void>`
3933
3952
 
3953
+ **getWidgets**(collectionId: string,
3954
+ options?: GetCollectionWidgetsOptions) → `Promise<CollectionWidgetsResponse>`
3955
+ Fetches ALL widget data (manifests + bundle files) for a collection in one call. Returns everything needed to render widgets with zero additional requests. This solves N+1 query problems by fetching manifests, JavaScript bundles, and CSS files in parallel on the server. ```typescript // Fetch all widget data for a collection const { apps } = await Api.AppConfiguration.getWidgets(collectionId); // Returns: [{ appId, manifestUrl, manifest, bundleSource, bundleCss }, ...] // Convert bundle source to dynamic imports for (const app of apps) { const blob = new Blob([app.bundleSource], { type: 'application/javascript' }); const blobUrl = URL.createObjectURL(blob); const widgetModule = await import(blobUrl); // Inject CSS if present if (app.bundleCss) { const styleTag = document.createElement('style'); styleTag.textContent = app.bundleCss; document.head.appendChild(styleTag); } } // Force refresh all widgets const { apps } = await Api.AppConfiguration.getWidgets(collectionId, { force: true }); ```
3956
+
3957
+ ### appRecord
3958
+
3959
+ **get**(collectionId: string, appId: string) → `Promise<any>`
3960
+
3961
+ **create**(collectionId: string, appId: string, data: any) → `Promise<any>`
3962
+
3963
+ **update**(collectionId: string, appId: string, data: any) → `Promise<any>`
3964
+
3965
+ **remove**(collectionId: string, appId: string) → `Promise<void>`
3966
+
3934
3967
  ### asset
3935
3968
 
3936
3969
  **upload**(options: UploadAssetOptions) → `Promise<Asset>`
3937
3970
  Upload an asset file
3938
3971
 
3972
+ **uploadFromUrl**(options: UploadFromUrlOptions) → `Promise<Asset>`
3973
+ Upload an asset from a URL The server will fetch the file from the provided URL and store it permanently in your CDN. This solves CORS issues and ensures files are permanently stored. ```typescript // Upload AI-generated image const asset = await asset.uploadFromUrl({ url: 'https://oaidalleapiprodscus.blob.core.windows.net/...', scope: { type: 'collection', collectionId: 'my-collection' }, metadata: { name: 'AI Generated Image', app: 'gallery' } }); // Upload stock photo const asset = await asset.uploadFromUrl({ url: 'https://images.unsplash.com/photo-...', scope: { type: 'product', collectionId: 'my-collection', productId: 'wine-bottle' }, folder: 'images', metadata: { name: 'Product Photo' } }); ```
3974
+
3939
3975
  **getForCollection**(collectionId: string,
3940
3976
  assetId: string) → `Promise<AssetResponse>`
3941
- Upload an asset file
3977
+ Upload an asset from a URL The server will fetch the file from the provided URL and store it permanently in your CDN. This solves CORS issues and ensures files are permanently stored. ```typescript // Upload AI-generated image const asset = await asset.uploadFromUrl({ url: 'https://oaidalleapiprodscus.blob.core.windows.net/...', scope: { type: 'collection', collectionId: 'my-collection' }, metadata: { name: 'AI Generated Image', app: 'gallery' } }); // Upload stock photo const asset = await asset.uploadFromUrl({ url: 'https://images.unsplash.com/photo-...', scope: { type: 'product', collectionId: 'my-collection', productId: 'wine-bottle' }, folder: 'images', metadata: { name: 'Product Photo' } }); ```
3942
3978
 
3943
3979
  **listForCollection**(collectionId: string) → `Promise<AssetResponse[]>`
3944
- Upload an asset file
3980
+ Upload an asset from a URL The server will fetch the file from the provided URL and store it permanently in your CDN. This solves CORS issues and ensures files are permanently stored. ```typescript // Upload AI-generated image const asset = await asset.uploadFromUrl({ url: 'https://oaidalleapiprodscus.blob.core.windows.net/...', scope: { type: 'collection', collectionId: 'my-collection' }, metadata: { name: 'AI Generated Image', app: 'gallery' } }); // Upload stock photo const asset = await asset.uploadFromUrl({ url: 'https://images.unsplash.com/photo-...', scope: { type: 'product', collectionId: 'my-collection', productId: 'wine-bottle' }, folder: 'images', metadata: { name: 'Product Photo' } }); ```
3945
3981
 
3946
3982
  **getForProduct**(collectionId: string,
3947
3983
  productId: string,
3948
3984
  assetId: string) → `Promise<AssetResponse>`
3949
- Upload an asset file
3985
+ Upload an asset from a URL The server will fetch the file from the provided URL and store it permanently in your CDN. This solves CORS issues and ensures files are permanently stored. ```typescript // Upload AI-generated image const asset = await asset.uploadFromUrl({ url: 'https://oaidalleapiprodscus.blob.core.windows.net/...', scope: { type: 'collection', collectionId: 'my-collection' }, metadata: { name: 'AI Generated Image', app: 'gallery' } }); // Upload stock photo const asset = await asset.uploadFromUrl({ url: 'https://images.unsplash.com/photo-...', scope: { type: 'product', collectionId: 'my-collection', productId: 'wine-bottle' }, folder: 'images', metadata: { name: 'Product Photo' } }); ```
3950
3986
 
3951
3987
  **listForProduct**(collectionId: string,
3952
3988
  productId: string) → `Promise<AssetResponse[]>`
3953
- Upload an asset file
3989
+ Upload an asset from a URL The server will fetch the file from the provided URL and store it permanently in your CDN. This solves CORS issues and ensures files are permanently stored. ```typescript // Upload AI-generated image const asset = await asset.uploadFromUrl({ url: 'https://oaidalleapiprodscus.blob.core.windows.net/...', scope: { type: 'collection', collectionId: 'my-collection' }, metadata: { name: 'AI Generated Image', app: 'gallery' } }); // Upload stock photo const asset = await asset.uploadFromUrl({ url: 'https://images.unsplash.com/photo-...', scope: { type: 'product', collectionId: 'my-collection', productId: 'wine-bottle' }, folder: 'images', metadata: { name: 'Product Photo' } }); ```
3954
3990
 
3955
3991
  **getForProof**(collectionId: string,
3956
3992
  productId: string,
3957
3993
  proofId: string,
3958
3994
  assetId: string) → `Promise<AssetResponse>`
3959
- Upload an asset file
3995
+ Upload an asset from a URL The server will fetch the file from the provided URL and store it permanently in your CDN. This solves CORS issues and ensures files are permanently stored. ```typescript // Upload AI-generated image const asset = await asset.uploadFromUrl({ url: 'https://oaidalleapiprodscus.blob.core.windows.net/...', scope: { type: 'collection', collectionId: 'my-collection' }, metadata: { name: 'AI Generated Image', app: 'gallery' } }); // Upload stock photo const asset = await asset.uploadFromUrl({ url: 'https://images.unsplash.com/photo-...', scope: { type: 'product', collectionId: 'my-collection', productId: 'wine-bottle' }, folder: 'images', metadata: { name: 'Product Photo' } }); ```
3960
3996
 
3961
3997
  **listForProof**(collectionId: string,
3962
3998
  productId: string,
3963
3999
  proofId: string,
3964
4000
  appId?: string) → `Promise<AssetResponse[]>`
3965
- Upload an asset file
4001
+ Upload an asset from a URL The server will fetch the file from the provided URL and store it permanently in your CDN. This solves CORS issues and ensures files are permanently stored. ```typescript // Upload AI-generated image const asset = await asset.uploadFromUrl({ url: 'https://oaidalleapiprodscus.blob.core.windows.net/...', scope: { type: 'collection', collectionId: 'my-collection' }, metadata: { name: 'AI Generated Image', app: 'gallery' } }); // Upload stock photo const asset = await asset.uploadFromUrl({ url: 'https://images.unsplash.com/photo-...', scope: { type: 'product', collectionId: 'my-collection', productId: 'wine-bottle' }, folder: 'images', metadata: { name: 'Product Photo' } }); ```
3966
4002
 
3967
4003
  **uploadAsset**(collectionId: string,
3968
4004
  productId: string,
@@ -4291,10 +4327,6 @@ Retrieve a specific settings group for a collection (public endpoint).
4291
4327
  **getAppsConfig**(collectionId: string) → `Promise<AppsConfigResponse>`
4292
4328
  Retrieve all configured app module definitions for a collection (public endpoint).
4293
4329
 
4294
- **getWidgets**(collectionId: string,
4295
- options?: GetCollectionWidgetsOptions) → `Promise<CollectionWidgetsResponse>`
4296
- Fetches ALL widget data (manifests + bundle files) for a collection in one call. Returns everything needed to render widgets with zero additional requests. This solves N+1 query problems by fetching manifests, JavaScript bundles, and CSS files in parallel on the server. ```typescript // Fetch all widget data for a collection const { apps } = await Api.Collection.getWidgets(collectionId); // Returns: [{ appId, manifestUrl, manifest, bundleSource, bundleCss }, ...] // Convert bundle source to dynamic imports for (const app of apps) { const blob = new Blob([app.bundleSource], { type: 'application/javascript' }); const blobUrl = URL.createObjectURL(blob); const widgetModule = await import(blobUrl); // Inject CSS if present if (app.bundleCss) { const styleTag = document.createElement('style'); styleTag.textContent = app.bundleCss; document.head.appendChild(styleTag); } } // Force refresh all widgets const { apps } = await Api.Collection.getWidgets(collectionId, { force: true }); ```
4297
-
4298
4330
  **updateSettings**(collectionId: string, settingGroup: string, settings: any) → `Promise<any>`
4299
4331
  Update a specific settings group for a collection (admin endpoint).
4300
4332
 
@@ -348,7 +348,11 @@ export interface AIGenerateImageRequest {
348
348
  provider?: string;
349
349
  /** Optional model name to use for image generation */
350
350
  model?: string;
351
- /** Requested image size, e.g. '1024x1024' */
351
+ /**
352
+ * Requested image size.
353
+ * OpenAI supported values: '1024x1024', '1024x1792', '1792x1024'
354
+ * Other providers may support different sizes.
355
+ */
352
356
  size?: string;
353
357
  /** Additional provider/model-specific options */
354
358
  [key: string]: any;
@@ -88,6 +88,36 @@ export interface UploadAssetOptions {
88
88
  /** Optional: Upload via admin route instead of public */
89
89
  admin?: boolean;
90
90
  }
91
+ /**
92
+ * Options for uploading an asset from a URL
93
+ * The server will fetch the file from the URL and store it in your CDN
94
+ */
95
+ export interface UploadFromUrlOptions {
96
+ /** The URL of the file to fetch and upload */
97
+ url: string;
98
+ /** Where to attach the asset */
99
+ scope: {
100
+ type: 'collection';
101
+ collectionId: string;
102
+ } | {
103
+ type: 'product';
104
+ collectionId: string;
105
+ productId: string;
106
+ } | {
107
+ type: 'proof';
108
+ collectionId: string;
109
+ productId: string;
110
+ proofId: string;
111
+ };
112
+ /** Optional: Storage folder ('images', 'videos', 'documents') */
113
+ folder?: 'images' | 'videos' | 'documents';
114
+ /** Optional: Custom metadata to store with the asset */
115
+ metadata?: Record<string, any>;
116
+ /** Optional: App ID for scoping to a specific microapp */
117
+ appId?: string;
118
+ /** Optional: Upload via admin route instead of public */
119
+ admin?: boolean;
120
+ }
91
121
  export interface ListAssetsOptions {
92
122
  scope: {
93
123
  type: 'collection';
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 1.3.32 | Generated: 2026-02-15T09:31:59.881Z
3
+ Version: 1.3.34 | Generated: 2026-02-16T09:46:01.466Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -29,6 +29,7 @@ The Smartlinks SDK is organized into the following namespaces:
29
29
  - **batch** - Group products into batches; manage serial number ranges and lookups.
30
30
  - **crate** - Organize products in containers/crates for logistics and grouping.
31
31
  - **form** - Build and manage dynamic forms used by apps and workflows.
32
+ - **appRecord** - Store and retrieve application-level records tied to a collection.
32
33
  - **appConfiguration** - Read/write app configuration and scoped data (collection/product/proof).
33
34
 
34
35
  — Identity & Access —
@@ -753,6 +754,9 @@ interface AIGenerateImageRequest {
753
754
  prompt: string
754
755
  provider?: string
755
756
  model?: string
757
+ * Requested image size.
758
+ * OpenAI supported values: '1024x1024', '1024x1792', '1792x1024'
759
+ * Other providers may support different sizes.
756
760
  size?: string
757
761
  [key: string]: any
758
762
  }
@@ -940,6 +944,21 @@ interface UploadAssetOptions {
940
944
  }
941
945
  ```
942
946
 
947
+ **UploadFromUrlOptions** (interface)
948
+ ```typescript
949
+ interface UploadFromUrlOptions {
950
+ url: string
951
+ scope:
952
+ | { type: 'collection'; collectionId: string }
953
+ | { type: 'product'; collectionId: string; productId: string }
954
+ | { type: 'proof'; collectionId: string; productId: string; proofId: string }
955
+ folder?: 'images' | 'videos' | 'documents'
956
+ metadata?: Record<string, any>
957
+ appId?: string
958
+ admin?: boolean
959
+ }
960
+ ```
961
+
943
962
  **ListAssetsOptions** (interface)
944
963
  ```typescript
945
964
  interface ListAssetsOptions {
@@ -3931,38 +3950,55 @@ Post a chat message to the AI (admin or public)
3931
3950
 
3932
3951
  **deleteDataItem**(opts: AppConfigOptions) → `Promise<void>`
3933
3952
 
3953
+ **getWidgets**(collectionId: string,
3954
+ options?: GetCollectionWidgetsOptions) → `Promise<CollectionWidgetsResponse>`
3955
+ Fetches ALL widget data (manifests + bundle files) for a collection in one call. Returns everything needed to render widgets with zero additional requests. This solves N+1 query problems by fetching manifests, JavaScript bundles, and CSS files in parallel on the server. ```typescript // Fetch all widget data for a collection const { apps } = await Api.AppConfiguration.getWidgets(collectionId); // Returns: [{ appId, manifestUrl, manifest, bundleSource, bundleCss }, ...] // Convert bundle source to dynamic imports for (const app of apps) { const blob = new Blob([app.bundleSource], { type: 'application/javascript' }); const blobUrl = URL.createObjectURL(blob); const widgetModule = await import(blobUrl); // Inject CSS if present if (app.bundleCss) { const styleTag = document.createElement('style'); styleTag.textContent = app.bundleCss; document.head.appendChild(styleTag); } } // Force refresh all widgets const { apps } = await Api.AppConfiguration.getWidgets(collectionId, { force: true }); ```
3956
+
3957
+ ### appRecord
3958
+
3959
+ **get**(collectionId: string, appId: string) → `Promise<any>`
3960
+
3961
+ **create**(collectionId: string, appId: string, data: any) → `Promise<any>`
3962
+
3963
+ **update**(collectionId: string, appId: string, data: any) → `Promise<any>`
3964
+
3965
+ **remove**(collectionId: string, appId: string) → `Promise<void>`
3966
+
3934
3967
  ### asset
3935
3968
 
3936
3969
  **upload**(options: UploadAssetOptions) → `Promise<Asset>`
3937
3970
  Upload an asset file
3938
3971
 
3972
+ **uploadFromUrl**(options: UploadFromUrlOptions) → `Promise<Asset>`
3973
+ Upload an asset from a URL The server will fetch the file from the provided URL and store it permanently in your CDN. This solves CORS issues and ensures files are permanently stored. ```typescript // Upload AI-generated image const asset = await asset.uploadFromUrl({ url: 'https://oaidalleapiprodscus.blob.core.windows.net/...', scope: { type: 'collection', collectionId: 'my-collection' }, metadata: { name: 'AI Generated Image', app: 'gallery' } }); // Upload stock photo const asset = await asset.uploadFromUrl({ url: 'https://images.unsplash.com/photo-...', scope: { type: 'product', collectionId: 'my-collection', productId: 'wine-bottle' }, folder: 'images', metadata: { name: 'Product Photo' } }); ```
3974
+
3939
3975
  **getForCollection**(collectionId: string,
3940
3976
  assetId: string) → `Promise<AssetResponse>`
3941
- Upload an asset file
3977
+ Upload an asset from a URL The server will fetch the file from the provided URL and store it permanently in your CDN. This solves CORS issues and ensures files are permanently stored. ```typescript // Upload AI-generated image const asset = await asset.uploadFromUrl({ url: 'https://oaidalleapiprodscus.blob.core.windows.net/...', scope: { type: 'collection', collectionId: 'my-collection' }, metadata: { name: 'AI Generated Image', app: 'gallery' } }); // Upload stock photo const asset = await asset.uploadFromUrl({ url: 'https://images.unsplash.com/photo-...', scope: { type: 'product', collectionId: 'my-collection', productId: 'wine-bottle' }, folder: 'images', metadata: { name: 'Product Photo' } }); ```
3942
3978
 
3943
3979
  **listForCollection**(collectionId: string) → `Promise<AssetResponse[]>`
3944
- Upload an asset file
3980
+ Upload an asset from a URL The server will fetch the file from the provided URL and store it permanently in your CDN. This solves CORS issues and ensures files are permanently stored. ```typescript // Upload AI-generated image const asset = await asset.uploadFromUrl({ url: 'https://oaidalleapiprodscus.blob.core.windows.net/...', scope: { type: 'collection', collectionId: 'my-collection' }, metadata: { name: 'AI Generated Image', app: 'gallery' } }); // Upload stock photo const asset = await asset.uploadFromUrl({ url: 'https://images.unsplash.com/photo-...', scope: { type: 'product', collectionId: 'my-collection', productId: 'wine-bottle' }, folder: 'images', metadata: { name: 'Product Photo' } }); ```
3945
3981
 
3946
3982
  **getForProduct**(collectionId: string,
3947
3983
  productId: string,
3948
3984
  assetId: string) → `Promise<AssetResponse>`
3949
- Upload an asset file
3985
+ Upload an asset from a URL The server will fetch the file from the provided URL and store it permanently in your CDN. This solves CORS issues and ensures files are permanently stored. ```typescript // Upload AI-generated image const asset = await asset.uploadFromUrl({ url: 'https://oaidalleapiprodscus.blob.core.windows.net/...', scope: { type: 'collection', collectionId: 'my-collection' }, metadata: { name: 'AI Generated Image', app: 'gallery' } }); // Upload stock photo const asset = await asset.uploadFromUrl({ url: 'https://images.unsplash.com/photo-...', scope: { type: 'product', collectionId: 'my-collection', productId: 'wine-bottle' }, folder: 'images', metadata: { name: 'Product Photo' } }); ```
3950
3986
 
3951
3987
  **listForProduct**(collectionId: string,
3952
3988
  productId: string) → `Promise<AssetResponse[]>`
3953
- Upload an asset file
3989
+ Upload an asset from a URL The server will fetch the file from the provided URL and store it permanently in your CDN. This solves CORS issues and ensures files are permanently stored. ```typescript // Upload AI-generated image const asset = await asset.uploadFromUrl({ url: 'https://oaidalleapiprodscus.blob.core.windows.net/...', scope: { type: 'collection', collectionId: 'my-collection' }, metadata: { name: 'AI Generated Image', app: 'gallery' } }); // Upload stock photo const asset = await asset.uploadFromUrl({ url: 'https://images.unsplash.com/photo-...', scope: { type: 'product', collectionId: 'my-collection', productId: 'wine-bottle' }, folder: 'images', metadata: { name: 'Product Photo' } }); ```
3954
3990
 
3955
3991
  **getForProof**(collectionId: string,
3956
3992
  productId: string,
3957
3993
  proofId: string,
3958
3994
  assetId: string) → `Promise<AssetResponse>`
3959
- Upload an asset file
3995
+ Upload an asset from a URL The server will fetch the file from the provided URL and store it permanently in your CDN. This solves CORS issues and ensures files are permanently stored. ```typescript // Upload AI-generated image const asset = await asset.uploadFromUrl({ url: 'https://oaidalleapiprodscus.blob.core.windows.net/...', scope: { type: 'collection', collectionId: 'my-collection' }, metadata: { name: 'AI Generated Image', app: 'gallery' } }); // Upload stock photo const asset = await asset.uploadFromUrl({ url: 'https://images.unsplash.com/photo-...', scope: { type: 'product', collectionId: 'my-collection', productId: 'wine-bottle' }, folder: 'images', metadata: { name: 'Product Photo' } }); ```
3960
3996
 
3961
3997
  **listForProof**(collectionId: string,
3962
3998
  productId: string,
3963
3999
  proofId: string,
3964
4000
  appId?: string) → `Promise<AssetResponse[]>`
3965
- Upload an asset file
4001
+ Upload an asset from a URL The server will fetch the file from the provided URL and store it permanently in your CDN. This solves CORS issues and ensures files are permanently stored. ```typescript // Upload AI-generated image const asset = await asset.uploadFromUrl({ url: 'https://oaidalleapiprodscus.blob.core.windows.net/...', scope: { type: 'collection', collectionId: 'my-collection' }, metadata: { name: 'AI Generated Image', app: 'gallery' } }); // Upload stock photo const asset = await asset.uploadFromUrl({ url: 'https://images.unsplash.com/photo-...', scope: { type: 'product', collectionId: 'my-collection', productId: 'wine-bottle' }, folder: 'images', metadata: { name: 'Product Photo' } }); ```
3966
4002
 
3967
4003
  **uploadAsset**(collectionId: string,
3968
4004
  productId: string,
@@ -4291,10 +4327,6 @@ Retrieve a specific settings group for a collection (public endpoint).
4291
4327
  **getAppsConfig**(collectionId: string) → `Promise<AppsConfigResponse>`
4292
4328
  Retrieve all configured app module definitions for a collection (public endpoint).
4293
4329
 
4294
- **getWidgets**(collectionId: string,
4295
- options?: GetCollectionWidgetsOptions) → `Promise<CollectionWidgetsResponse>`
4296
- Fetches ALL widget data (manifests + bundle files) for a collection in one call. Returns everything needed to render widgets with zero additional requests. This solves N+1 query problems by fetching manifests, JavaScript bundles, and CSS files in parallel on the server. ```typescript // Fetch all widget data for a collection const { apps } = await Api.Collection.getWidgets(collectionId); // Returns: [{ appId, manifestUrl, manifest, bundleSource, bundleCss }, ...] // Convert bundle source to dynamic imports for (const app of apps) { const blob = new Blob([app.bundleSource], { type: 'application/javascript' }); const blobUrl = URL.createObjectURL(blob); const widgetModule = await import(blobUrl); // Inject CSS if present if (app.bundleCss) { const styleTag = document.createElement('style'); styleTag.textContent = app.bundleCss; document.head.appendChild(styleTag); } } // Force refresh all widgets const { apps } = await Api.Collection.getWidgets(collectionId, { force: true }); ```
4297
-
4298
4330
  **updateSettings**(collectionId: string, settingGroup: string, settings: any) → `Promise<any>`
4299
4331
  Update a specific settings group for a collection (admin endpoint).
4300
4332
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proveanything/smartlinks",
3
- "version": "1.3.32",
3
+ "version": "1.3.34",
4
4
  "description": "Official JavaScript/TypeScript SDK for the Smartlinks API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",