@proveanything/smartlinks 1.3.33 → 1.3.35

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.
@@ -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';
@@ -20,6 +20,24 @@ export declare namespace product {
20
20
  /**
21
21
  * Create a new product for a collection (admin only).
22
22
  * The `data` payload follows the same shape as ProductResponse minus `id` and `collectionId`.
23
+ *
24
+ * **Hero Image Auto-Fetch:**
25
+ * You can pass `heroImage` as either:
26
+ * - A full asset object: `{ url: '...', thumbnails: {...} }`
27
+ * - A string URL: The system automatically fetches and stores the image
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * // Using a URL - auto-fetched and stored
32
+ * const product = await product.create(collectionId, {
33
+ * name: 'Wine Bottle',
34
+ * description: 'Premium red wine',
35
+ * heroImage: 'https://example.com/wine.jpg', // Auto-fetched!
36
+ * tags: {},
37
+ * data: {}
38
+ * });
39
+ * ```
40
+ *
23
41
  * @param collectionId – Identifier of the parent collection
24
42
  * @param data – Product creation data (see ProductCreateRequest)
25
43
  * @returns Promise resolving to a ProductResponse object
@@ -29,6 +47,20 @@ export declare namespace product {
29
47
  /**
30
48
  * Update a product for a collection (admin only).
31
49
  * The `data` payload is a partial of ProductResponse minus `id` and `collectionId`.
50
+ *
51
+ * **Hero Image Auto-Fetch:**
52
+ * You can pass `heroImage` as either:
53
+ * - A full asset object: `{ url: '...', thumbnails: {...} }`
54
+ * - A string URL: The system automatically fetches and stores the image
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * // Update with new URL - auto-fetched and stored
59
+ * const product = await product.update(collectionId, productId, {
60
+ * heroImage: 'https://example.com/new-wine.jpg' // Auto-fetched!
61
+ * });
62
+ * ```
63
+ *
32
64
  * @param collectionId – Identifier of the parent collection
33
65
  * @param productId – Identifier of the product
34
66
  * @param data – Product update data (see ProductUpdateRequest)
@@ -32,6 +32,24 @@ export var product;
32
32
  /**
33
33
  * Create a new product for a collection (admin only).
34
34
  * The `data` payload follows the same shape as ProductResponse minus `id` and `collectionId`.
35
+ *
36
+ * **Hero Image Auto-Fetch:**
37
+ * You can pass `heroImage` as either:
38
+ * - A full asset object: `{ url: '...', thumbnails: {...} }`
39
+ * - A string URL: The system automatically fetches and stores the image
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * // Using a URL - auto-fetched and stored
44
+ * const product = await product.create(collectionId, {
45
+ * name: 'Wine Bottle',
46
+ * description: 'Premium red wine',
47
+ * heroImage: 'https://example.com/wine.jpg', // Auto-fetched!
48
+ * tags: {},
49
+ * data: {}
50
+ * });
51
+ * ```
52
+ *
35
53
  * @param collectionId – Identifier of the parent collection
36
54
  * @param data – Product creation data (see ProductCreateRequest)
37
55
  * @returns Promise resolving to a ProductResponse object
@@ -45,6 +63,20 @@ export var product;
45
63
  /**
46
64
  * Update a product for a collection (admin only).
47
65
  * The `data` payload is a partial of ProductResponse minus `id` and `collectionId`.
66
+ *
67
+ * **Hero Image Auto-Fetch:**
68
+ * You can pass `heroImage` as either:
69
+ * - A full asset object: `{ url: '...', thumbnails: {...} }`
70
+ * - A string URL: The system automatically fetches and stores the image
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * // Update with new URL - auto-fetched and stored
75
+ * const product = await product.update(collectionId, productId, {
76
+ * heroImage: 'https://example.com/new-wine.jpg' // Auto-fetched!
77
+ * });
78
+ * ```
79
+ *
48
80
  * @param collectionId – Identifier of the parent collection
49
81
  * @param productId – Identifier of the product
50
82
  * @param data – Product update data (see ProductUpdateRequest)
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 1.3.33 | Generated: 2026-02-15T09:39:22.347Z
3
+ Version: 1.3.35 | Generated: 2026-02-16T09:53:23.211Z
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 {
@@ -3344,6 +3363,10 @@ interface Product {
3344
3363
  description: string
3345
3364
  gtin?: string
3346
3365
  type?: string
3366
+ * Hero image asset object.
3367
+ * When creating/updating, you can pass either:
3368
+ * - A full asset object with url and thumbnails
3369
+ * - A string URL - the system will automatically fetch and store the image
3347
3370
  heroImage: {
3348
3371
  url: string
3349
3372
  thumbnails: {
@@ -3363,9 +3386,9 @@ interface Product {
3363
3386
 
3364
3387
  **ProductResponse** = `Product`
3365
3388
 
3366
- **ProductCreateRequest** = `Omit<Product, 'id' | 'collectionId'>`
3389
+ **ProductCreateRequest** = `Omit<Product, 'id' | 'collectionId'> & {`
3367
3390
 
3368
- **ProductUpdateRequest** = `Partial<Omit<Product, 'id' | 'collectionId'>>`
3391
+ **ProductUpdateRequest** = `Partial<Omit<Product, 'id' | 'collectionId'>> & {`
3369
3392
 
3370
3393
  ### proof
3371
3394
 
@@ -3935,38 +3958,51 @@ Post a chat message to the AI (admin or public)
3935
3958
  options?: GetCollectionWidgetsOptions) → `Promise<CollectionWidgetsResponse>`
3936
3959
  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 }); ```
3937
3960
 
3961
+ ### appRecord
3962
+
3963
+ **get**(collectionId: string, appId: string) → `Promise<any>`
3964
+
3965
+ **create**(collectionId: string, appId: string, data: any) → `Promise<any>`
3966
+
3967
+ **update**(collectionId: string, appId: string, data: any) → `Promise<any>`
3968
+
3969
+ **remove**(collectionId: string, appId: string) → `Promise<void>`
3970
+
3938
3971
  ### asset
3939
3972
 
3940
3973
  **upload**(options: UploadAssetOptions) → `Promise<Asset>`
3941
3974
  Upload an asset file
3942
3975
 
3976
+ **uploadFromUrl**(options: UploadFromUrlOptions) → `Promise<Asset>`
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' } }); ```
3978
+
3943
3979
  **getForCollection**(collectionId: string,
3944
3980
  assetId: string) → `Promise<AssetResponse>`
3945
- Upload an asset file
3981
+ 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' } }); ```
3946
3982
 
3947
3983
  **listForCollection**(collectionId: string) → `Promise<AssetResponse[]>`
3948
- Upload an asset file
3984
+ 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' } }); ```
3949
3985
 
3950
3986
  **getForProduct**(collectionId: string,
3951
3987
  productId: string,
3952
3988
  assetId: 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
  **listForProduct**(collectionId: string,
3956
3992
  productId: string) → `Promise<AssetResponse[]>`
3957
- Upload an asset file
3993
+ 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' } }); ```
3958
3994
 
3959
3995
  **getForProof**(collectionId: string,
3960
3996
  productId: string,
3961
3997
  proofId: string,
3962
3998
  assetId: string) → `Promise<AssetResponse>`
3963
- Upload an asset file
3999
+ 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' } }); ```
3964
4000
 
3965
4001
  **listForProof**(collectionId: string,
3966
4002
  productId: string,
3967
4003
  proofId: string,
3968
4004
  appId?: string) → `Promise<AssetResponse[]>`
3969
- Upload an asset file
4005
+ 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' } }); ```
3970
4006
 
3971
4007
  **uploadAsset**(collectionId: string,
3972
4008
  productId: string,
@@ -4746,12 +4782,12 @@ List all Product Items for a Collection.
4746
4782
 
4747
4783
  **create**(collectionId: string,
4748
4784
  data: ProductCreateRequest) → `Promise<ProductResponse>`
4749
- Create a new product for a collection (admin only). The `data` payload follows the same shape as ProductResponse minus `id` and `collectionId`.
4785
+ Create a new product for a collection (admin only). The `data` payload follows the same shape as ProductResponse minus `id` and `collectionId`. **Hero Image Auto-Fetch:** You can pass `heroImage` as either: - A full asset object: `{ url: '...', thumbnails: {...} }` - A string URL: The system automatically fetches and stores the image ```typescript // Using a URL - auto-fetched and stored const product = await product.create(collectionId, { name: 'Wine Bottle', description: 'Premium red wine', heroImage: 'https://example.com/wine.jpg', // Auto-fetched! tags: {}, data: {} }); ```
4750
4786
 
4751
4787
  **update**(collectionId: string,
4752
4788
  productId: string,
4753
4789
  data: ProductUpdateRequest) → `Promise<ProductResponse>`
4754
- Update a product for a collection (admin only). The `data` payload is a partial of ProductResponse minus `id` and `collectionId`.
4790
+ Update a product for a collection (admin only). The `data` payload is a partial of ProductResponse minus `id` and `collectionId`. **Hero Image Auto-Fetch:** You can pass `heroImage` as either: - A full asset object: `{ url: '...', thumbnails: {...} }` - A string URL: The system automatically fetches and stores the image ```typescript // Update with new URL - auto-fetched and stored const product = await product.update(collectionId, productId, { heroImage: 'https://example.com/new-wine.jpg' // Auto-fetched! }); ```
4755
4791
 
4756
4792
  **remove**(collectionId: string,
4757
4793
  productId: string) → `Promise<void>`
@@ -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';
@@ -14,7 +14,12 @@ export interface Product {
14
14
  gtin?: string;
15
15
  /** An optional product type from the standard smartlinks types */
16
16
  type?: string;
17
- /** Hero image asset object */
17
+ /**
18
+ * Hero image asset object.
19
+ * When creating/updating, you can pass either:
20
+ * - A full asset object with url and thumbnails
21
+ * - A string URL - the system will automatically fetch and store the image
22
+ */
18
23
  heroImage: {
19
24
  /** URL to the asset */
20
25
  url: string;
@@ -35,5 +40,9 @@ export interface Product {
35
40
  };
36
41
  }
37
42
  export type ProductResponse = Product;
38
- export type ProductCreateRequest = Omit<Product, 'id' | 'collectionId'>;
39
- export type ProductUpdateRequest = Partial<Omit<Product, 'id' | 'collectionId'>>;
43
+ export type ProductCreateRequest = Omit<Product, 'id' | 'collectionId'> & {
44
+ heroImage?: Product['heroImage'] | string;
45
+ };
46
+ export type ProductUpdateRequest = Partial<Omit<Product, 'id' | 'collectionId'>> & {
47
+ heroImage?: Product['heroImage'] | string;
48
+ };
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 1.3.33 | Generated: 2026-02-15T09:39:22.347Z
3
+ Version: 1.3.35 | Generated: 2026-02-16T09:53:23.211Z
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 {
@@ -3344,6 +3363,10 @@ interface Product {
3344
3363
  description: string
3345
3364
  gtin?: string
3346
3365
  type?: string
3366
+ * Hero image asset object.
3367
+ * When creating/updating, you can pass either:
3368
+ * - A full asset object with url and thumbnails
3369
+ * - A string URL - the system will automatically fetch and store the image
3347
3370
  heroImage: {
3348
3371
  url: string
3349
3372
  thumbnails: {
@@ -3363,9 +3386,9 @@ interface Product {
3363
3386
 
3364
3387
  **ProductResponse** = `Product`
3365
3388
 
3366
- **ProductCreateRequest** = `Omit<Product, 'id' | 'collectionId'>`
3389
+ **ProductCreateRequest** = `Omit<Product, 'id' | 'collectionId'> & {`
3367
3390
 
3368
- **ProductUpdateRequest** = `Partial<Omit<Product, 'id' | 'collectionId'>>`
3391
+ **ProductUpdateRequest** = `Partial<Omit<Product, 'id' | 'collectionId'>> & {`
3369
3392
 
3370
3393
  ### proof
3371
3394
 
@@ -3935,38 +3958,51 @@ Post a chat message to the AI (admin or public)
3935
3958
  options?: GetCollectionWidgetsOptions) → `Promise<CollectionWidgetsResponse>`
3936
3959
  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 }); ```
3937
3960
 
3961
+ ### appRecord
3962
+
3963
+ **get**(collectionId: string, appId: string) → `Promise<any>`
3964
+
3965
+ **create**(collectionId: string, appId: string, data: any) → `Promise<any>`
3966
+
3967
+ **update**(collectionId: string, appId: string, data: any) → `Promise<any>`
3968
+
3969
+ **remove**(collectionId: string, appId: string) → `Promise<void>`
3970
+
3938
3971
  ### asset
3939
3972
 
3940
3973
  **upload**(options: UploadAssetOptions) → `Promise<Asset>`
3941
3974
  Upload an asset file
3942
3975
 
3976
+ **uploadFromUrl**(options: UploadFromUrlOptions) → `Promise<Asset>`
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' } }); ```
3978
+
3943
3979
  **getForCollection**(collectionId: string,
3944
3980
  assetId: string) → `Promise<AssetResponse>`
3945
- Upload an asset file
3981
+ 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' } }); ```
3946
3982
 
3947
3983
  **listForCollection**(collectionId: string) → `Promise<AssetResponse[]>`
3948
- Upload an asset file
3984
+ 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' } }); ```
3949
3985
 
3950
3986
  **getForProduct**(collectionId: string,
3951
3987
  productId: string,
3952
3988
  assetId: 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
  **listForProduct**(collectionId: string,
3956
3992
  productId: string) → `Promise<AssetResponse[]>`
3957
- Upload an asset file
3993
+ 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' } }); ```
3958
3994
 
3959
3995
  **getForProof**(collectionId: string,
3960
3996
  productId: string,
3961
3997
  proofId: string,
3962
3998
  assetId: string) → `Promise<AssetResponse>`
3963
- Upload an asset file
3999
+ 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' } }); ```
3964
4000
 
3965
4001
  **listForProof**(collectionId: string,
3966
4002
  productId: string,
3967
4003
  proofId: string,
3968
4004
  appId?: string) → `Promise<AssetResponse[]>`
3969
- Upload an asset file
4005
+ 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' } }); ```
3970
4006
 
3971
4007
  **uploadAsset**(collectionId: string,
3972
4008
  productId: string,
@@ -4746,12 +4782,12 @@ List all Product Items for a Collection.
4746
4782
 
4747
4783
  **create**(collectionId: string,
4748
4784
  data: ProductCreateRequest) → `Promise<ProductResponse>`
4749
- Create a new product for a collection (admin only). The `data` payload follows the same shape as ProductResponse minus `id` and `collectionId`.
4785
+ Create a new product for a collection (admin only). The `data` payload follows the same shape as ProductResponse minus `id` and `collectionId`. **Hero Image Auto-Fetch:** You can pass `heroImage` as either: - A full asset object: `{ url: '...', thumbnails: {...} }` - A string URL: The system automatically fetches and stores the image ```typescript // Using a URL - auto-fetched and stored const product = await product.create(collectionId, { name: 'Wine Bottle', description: 'Premium red wine', heroImage: 'https://example.com/wine.jpg', // Auto-fetched! tags: {}, data: {} }); ```
4750
4786
 
4751
4787
  **update**(collectionId: string,
4752
4788
  productId: string,
4753
4789
  data: ProductUpdateRequest) → `Promise<ProductResponse>`
4754
- Update a product for a collection (admin only). The `data` payload is a partial of ProductResponse minus `id` and `collectionId`.
4790
+ Update a product for a collection (admin only). The `data` payload is a partial of ProductResponse minus `id` and `collectionId`. **Hero Image Auto-Fetch:** You can pass `heroImage` as either: - A full asset object: `{ url: '...', thumbnails: {...} }` - A string URL: The system automatically fetches and stores the image ```typescript // Update with new URL - auto-fetched and stored const product = await product.update(collectionId, productId, { heroImage: 'https://example.com/new-wine.jpg' // Auto-fetched! }); ```
4755
4791
 
4756
4792
  **remove**(collectionId: string,
4757
4793
  productId: string) → `Promise<void>`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proveanything/smartlinks",
3
- "version": "1.3.33",
3
+ "version": "1.3.35",
4
4
  "description": "Official JavaScript/TypeScript SDK for the Smartlinks API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",