@proveanything/smartlinks 1.3.27 → 1.3.29
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/dist/api/appConfiguration.d.ts +27 -0
- package/dist/api/appConfiguration.js +33 -0
- package/dist/docs/API_SUMMARY.md +87 -1
- package/dist/docs/utils.md +52 -28
- package/dist/types/appManifest.d.ts +80 -0
- package/dist/types/appManifest.js +2 -0
- package/dist/types/collection.d.ts +2 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/utils/paths.d.ts +19 -6
- package/dist/utils/paths.js +25 -11
- package/docs/API_SUMMARY.md +87 -1
- package/docs/utils.md +52 -28
- package/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AppManifest } from "../types/appManifest";
|
|
1
2
|
export type AppConfigOptions = {
|
|
2
3
|
appId: string;
|
|
3
4
|
collectionId?: string;
|
|
@@ -19,4 +20,30 @@ 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 an app's manifest file through the proxy API.
|
|
25
|
+
* The manifest is cached on the server for 5 minutes.
|
|
26
|
+
*
|
|
27
|
+
* @param manifestUrl - The full URL to the manifest file (e.g., 'https://smartlinks.app/apps/my-app/v1.0.0/app.manifest.json')
|
|
28
|
+
* @param force - If true, bypasses cache and fetches fresh manifest
|
|
29
|
+
* @returns Promise resolving to the manifest object, or empty object if not found
|
|
30
|
+
* @throws ErrorResponse if the request fails
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* // Use with appsConfig
|
|
35
|
+
* const appsConfig = await Api.Collection.Public.getAppsConfig(collectionId);
|
|
36
|
+
* const app = appsConfig.apps[0];
|
|
37
|
+
* if (app.manifestUrl) {
|
|
38
|
+
* const manifest = await Api.AppConfiguration.getManifest(app.manifestUrl);
|
|
39
|
+
* if (manifest.widgets) {
|
|
40
|
+
* console.log('Available widgets:', manifest.widgets);
|
|
41
|
+
* }
|
|
42
|
+
* }
|
|
43
|
+
*
|
|
44
|
+
* // Force refresh
|
|
45
|
+
* const freshManifest = await Api.AppConfiguration.getManifest(app.manifestUrl, true);
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
function getManifest(manifestUrl: string, force?: boolean): Promise<AppManifest>;
|
|
22
49
|
}
|
|
@@ -88,4 +88,37 @@ export var appConfiguration;
|
|
|
88
88
|
return del(path);
|
|
89
89
|
}
|
|
90
90
|
appConfiguration.deleteDataItem = deleteDataItem;
|
|
91
|
+
/**
|
|
92
|
+
* Fetches an app's manifest file through the proxy API.
|
|
93
|
+
* The manifest is cached on the server for 5 minutes.
|
|
94
|
+
*
|
|
95
|
+
* @param manifestUrl - The full URL to the manifest file (e.g., 'https://smartlinks.app/apps/my-app/v1.0.0/app.manifest.json')
|
|
96
|
+
* @param force - If true, bypasses cache and fetches fresh manifest
|
|
97
|
+
* @returns Promise resolving to the manifest object, or empty object if not found
|
|
98
|
+
* @throws ErrorResponse if the request fails
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* // Use with appsConfig
|
|
103
|
+
* const appsConfig = await Api.Collection.Public.getAppsConfig(collectionId);
|
|
104
|
+
* const app = appsConfig.apps[0];
|
|
105
|
+
* if (app.manifestUrl) {
|
|
106
|
+
* const manifest = await Api.AppConfiguration.getManifest(app.manifestUrl);
|
|
107
|
+
* if (manifest.widgets) {
|
|
108
|
+
* console.log('Available widgets:', manifest.widgets);
|
|
109
|
+
* }
|
|
110
|
+
* }
|
|
111
|
+
*
|
|
112
|
+
* // Force refresh
|
|
113
|
+
* const freshManifest = await Api.AppConfiguration.getManifest(app.manifestUrl, true);
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
async function getManifest(manifestUrl, force) {
|
|
117
|
+
let path = `/public/app/manifest?url=${encodeURIComponent(manifestUrl)}`;
|
|
118
|
+
if (force) {
|
|
119
|
+
path += '&force=true';
|
|
120
|
+
}
|
|
121
|
+
return request(path);
|
|
122
|
+
}
|
|
123
|
+
appConfiguration.getManifest = getManifest;
|
|
91
124
|
})(appConfiguration || (appConfiguration = {}));
|
package/dist/docs/API_SUMMARY.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Smartlinks API Summary
|
|
2
2
|
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.29 | Generated: 2026-02-14T14:15:49.096Z
|
|
4
4
|
|
|
5
5
|
This is a concise summary of all available API functions and types.
|
|
6
6
|
|
|
@@ -791,6 +791,88 @@ interface AppConfigurationResponse {
|
|
|
791
791
|
}
|
|
792
792
|
```
|
|
793
793
|
|
|
794
|
+
### appManifest
|
|
795
|
+
|
|
796
|
+
**AppManifest** (interface)
|
|
797
|
+
```typescript
|
|
798
|
+
interface AppManifest {
|
|
799
|
+
$schema?: string;
|
|
800
|
+
meta?: {
|
|
801
|
+
name: string;
|
|
802
|
+
description?: string;
|
|
803
|
+
version: string;
|
|
804
|
+
platformRevision?: string;
|
|
805
|
+
appId: string;
|
|
806
|
+
};
|
|
807
|
+
widgets?: Array<{
|
|
808
|
+
name: string;
|
|
809
|
+
description?: string;
|
|
810
|
+
sizes?: string[];
|
|
811
|
+
props?: {
|
|
812
|
+
required?: string[];
|
|
813
|
+
optional?: string[];
|
|
814
|
+
};
|
|
815
|
+
}>;
|
|
816
|
+
setup?: {
|
|
817
|
+
description?: string;
|
|
818
|
+
questions?: Array<{
|
|
819
|
+
id: string;
|
|
820
|
+
prompt: string;
|
|
821
|
+
type: string;
|
|
822
|
+
default?: any;
|
|
823
|
+
required?: boolean;
|
|
824
|
+
}>;
|
|
825
|
+
configSchema?: Record<string, any>;
|
|
826
|
+
saveWith?: {
|
|
827
|
+
method: string;
|
|
828
|
+
scope: string;
|
|
829
|
+
admin?: boolean;
|
|
830
|
+
};
|
|
831
|
+
contentHints?: Record<string, {
|
|
832
|
+
aiGenerate?: boolean;
|
|
833
|
+
prompt?: string;
|
|
834
|
+
}>;
|
|
835
|
+
};
|
|
836
|
+
import?: {
|
|
837
|
+
description?: string;
|
|
838
|
+
scope?: string;
|
|
839
|
+
fields?: Array<{
|
|
840
|
+
name: string;
|
|
841
|
+
type: string;
|
|
842
|
+
required?: boolean;
|
|
843
|
+
default?: any;
|
|
844
|
+
description?: string;
|
|
845
|
+
}>;
|
|
846
|
+
csvExample?: string;
|
|
847
|
+
saveWith?: {
|
|
848
|
+
method: string;
|
|
849
|
+
scope: string;
|
|
850
|
+
admin?: boolean;
|
|
851
|
+
note?: string;
|
|
852
|
+
};
|
|
853
|
+
};
|
|
854
|
+
tunable?: {
|
|
855
|
+
description?: string;
|
|
856
|
+
fields?: Array<{
|
|
857
|
+
name: string;
|
|
858
|
+
description?: string;
|
|
859
|
+
type: string;
|
|
860
|
+
}>;
|
|
861
|
+
};
|
|
862
|
+
metrics?: {
|
|
863
|
+
interactions?: Array<{
|
|
864
|
+
id: string;
|
|
865
|
+
description?: string;
|
|
866
|
+
}>;
|
|
867
|
+
kpis?: Array<{
|
|
868
|
+
name: string;
|
|
869
|
+
compute?: string;
|
|
870
|
+
}>;
|
|
871
|
+
};
|
|
872
|
+
[key: string]: any; // Allow additional custom fields
|
|
873
|
+
}
|
|
874
|
+
```
|
|
875
|
+
|
|
794
876
|
### asset
|
|
795
877
|
|
|
796
878
|
**Asset** (interface)
|
|
@@ -1394,6 +1476,7 @@ interface AppConfig {
|
|
|
1394
1476
|
ownersOnly?: boolean
|
|
1395
1477
|
hidden?: boolean
|
|
1396
1478
|
publicIframeUrl?: string
|
|
1479
|
+
manifestUrl?: string
|
|
1397
1480
|
supportsDeepLinks?: boolean;
|
|
1398
1481
|
usage: {
|
|
1399
1482
|
collection: boolean; // use at the collecton level
|
|
@@ -3824,6 +3907,9 @@ Post a chat message to the AI (admin or public)
|
|
|
3824
3907
|
|
|
3825
3908
|
**deleteDataItem**(opts: AppConfigOptions) → `Promise<void>`
|
|
3826
3909
|
|
|
3910
|
+
**getManifest**(manifestUrl: string, force?: boolean) → `Promise<AppManifest>`
|
|
3911
|
+
Fetches an app's manifest file through the proxy API. The manifest is cached on the server for 5 minutes. ```typescript // Use with appsConfig const appsConfig = await Api.Collection.Public.getAppsConfig(collectionId); const app = appsConfig.apps[0]; if (app.manifestUrl) { const manifest = await Api.AppConfiguration.getManifest(app.manifestUrl); if (manifest.widgets) { console.log('Available widgets:', manifest.widgets); } } // Force refresh const freshManifest = await Api.AppConfiguration.getManifest(app.manifestUrl, true); ```
|
|
3912
|
+
|
|
3827
3913
|
### appRecord
|
|
3828
3914
|
|
|
3829
3915
|
**get**(collectionId: string, appId: string) → `Promise<any>`
|
package/dist/docs/utils.md
CHANGED
|
@@ -12,40 +12,46 @@ import { utils } from '@proveanything/smartlinks'
|
|
|
12
12
|
|
|
13
13
|
## Path Builder Utility
|
|
14
14
|
|
|
15
|
-
Pass in objects (collection, product, batch, etc.) and the function extracts what it needs
|
|
15
|
+
Builds full portal URLs by default. Pass in objects (collection, product, batch, etc.) and the function extracts what it needs. Uses `collection.portalUrl` as the domain, or defaults to `https://zt.smartlinks.io`.
|
|
16
16
|
|
|
17
17
|
### Basic Usage
|
|
18
18
|
|
|
19
|
-
Pass objects where you have them, or just IDs for simpler cases:
|
|
20
|
-
|
|
21
19
|
```typescript
|
|
22
|
-
import { utils } from '@
|
|
20
|
+
import { utils } from '@proveanything/smartlinks'
|
|
23
21
|
|
|
24
|
-
//
|
|
25
|
-
const
|
|
26
|
-
collection: myCollection,
|
|
22
|
+
// Returns full URL by default (uses collection.portalUrl)
|
|
23
|
+
const url = utils.buildPortalPath({
|
|
24
|
+
collection: myCollection, // uses collection.portalUrl or default domain
|
|
27
25
|
product: myProduct // ownGtin is read from product, not overridden
|
|
28
26
|
})
|
|
29
27
|
// Returns: https://portal.smartlinks.io/c/abc123/prod123
|
|
30
28
|
|
|
29
|
+
// Return just the path (no domain)
|
|
30
|
+
const path = utils.buildPortalPath({
|
|
31
|
+
collection: { shortId: 'abc123' },
|
|
32
|
+
productId: 'prod1',
|
|
33
|
+
pathOnly: true // Set to true for path only
|
|
34
|
+
})
|
|
35
|
+
// Returns: /c/abc123/prod1
|
|
36
|
+
|
|
31
37
|
// Or just IDs if you don't have full objects
|
|
32
|
-
const
|
|
38
|
+
const url2 = utils.buildPortalPath({
|
|
33
39
|
collection: { shortId: 'abc123' },
|
|
34
40
|
productId: 'prod1'
|
|
35
41
|
})
|
|
36
|
-
// Returns: /c/abc123/prod1
|
|
42
|
+
// Returns: https://zt.smartlinks.io/c/abc123/prod1 (default domain)
|
|
37
43
|
```
|
|
38
44
|
|
|
39
45
|
## Path Builder Function
|
|
40
46
|
|
|
41
47
|
### `buildPortalPath(params)`
|
|
42
48
|
|
|
43
|
-
Builds a portal
|
|
49
|
+
Builds a full portal URL based on the provided parameters. Returns full URL by default using `collection.portalUrl` or `https://zt.smartlinks.io`.
|
|
44
50
|
|
|
45
51
|
**Parameters:**
|
|
46
52
|
|
|
47
53
|
- `collection` (required) - Collection object or `{ shortId: string, portalUrl?: string }`
|
|
48
|
-
Extracts: `shortId` and optional `portalUrl` for base
|
|
54
|
+
Extracts: `shortId` and optional `portalUrl` for base domain
|
|
49
55
|
|
|
50
56
|
- `product` (optional) - Full product object
|
|
51
57
|
Extracts: `id`, `gtin`, and `ownGtin` (ownGtin is a critical product setting - read only, never overridden)
|
|
@@ -69,6 +75,9 @@ Builds a portal path/URL based on the provided parameters.
|
|
|
69
75
|
|
|
70
76
|
- `queryParams` (optional) - Additional query parameters object
|
|
71
77
|
|
|
78
|
+
- `pathOnly` (optional, default: `false`) - Return only the path without domain
|
|
79
|
+
Set to `true` to get `/c/abc/prod` instead of `https://domain.com/c/abc/prod`
|
|
80
|
+
|
|
72
81
|
**Path Formats:**
|
|
73
82
|
|
|
74
83
|
- Basic product: `/c/{shortId}/{productId}`
|
|
@@ -80,16 +89,23 @@ Builds a portal path/URL based on the provided parameters.
|
|
|
80
89
|
|
|
81
90
|
## Examples
|
|
82
91
|
|
|
83
|
-
###
|
|
92
|
+
### Full URL (Default Behavior)
|
|
84
93
|
|
|
85
94
|
```typescript
|
|
86
|
-
//
|
|
95
|
+
// Returns full URL using collection.portalUrl
|
|
87
96
|
utils.buildPortalPath({
|
|
88
|
-
collection: myCollection, //
|
|
89
|
-
product: myProduct
|
|
97
|
+
collection: myCollection, // uses collection.portalUrl
|
|
98
|
+
product: myProduct
|
|
90
99
|
})
|
|
91
100
|
// Returns: https://portal.smartlinks.io/c/abc123/prod123
|
|
92
101
|
|
|
102
|
+
// Without portalUrl, uses default domain
|
|
103
|
+
utils.buildPortalPath({
|
|
104
|
+
collection: { shortId: 'abc123' },
|
|
105
|
+
productId: 'prod1'
|
|
106
|
+
})
|
|
107
|
+
// Returns: https://zt.smartlinks.io/c/abc123/prod1
|
|
108
|
+
|
|
93
109
|
// With proof object
|
|
94
110
|
utils.buildPortalPath({
|
|
95
111
|
collection: myCollection,
|
|
@@ -99,6 +115,27 @@ utils.buildPortalPath({
|
|
|
99
115
|
// Returns: https://portal.smartlinks.io/c/abc123/prod123/proof789
|
|
100
116
|
```
|
|
101
117
|
|
|
118
|
+
### Path Only (No Domain)
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
// Set pathOnly: true to get just the path
|
|
122
|
+
utils.buildPortalPath({
|
|
123
|
+
collection: myCollection,
|
|
124
|
+
product: myProduct,
|
|
125
|
+
pathOnly: true
|
|
126
|
+
})
|
|
127
|
+
// Returns: /c/abc123/prod123
|
|
128
|
+
|
|
129
|
+
// Useful when you need to build your own full URL
|
|
130
|
+
const path = utils.buildPortalPath({
|
|
131
|
+
collection: { shortId: 'abc123' },
|
|
132
|
+
productId: 'prod1',
|
|
133
|
+
pathOnly: true
|
|
134
|
+
})
|
|
135
|
+
const customUrl = `https://mycustomdomain.com${path}`
|
|
136
|
+
// Result: https://mycustomdomain.com/c/abc123/prod1
|
|
137
|
+
```
|
|
138
|
+
|
|
102
139
|
### GTIN Paths
|
|
103
140
|
|
|
104
141
|
```typescript
|
|
@@ -172,19 +209,6 @@ utils.buildPortalPath({
|
|
|
172
209
|
// Returns: https://portal.smartlinks.io/c/abc123/prod123?utm_source=email&utm_campaign=launch&lang=fr
|
|
173
210
|
```
|
|
174
211
|
|
|
175
|
-
### Just IDs (No Full Objects)
|
|
176
|
-
|
|
177
|
-
```typescript
|
|
178
|
-
// Minimal - just IDs
|
|
179
|
-
utils.buildPortalPath({
|
|
180
|
-
collection: { shortId: 'abc123' },
|
|
181
|
-
productId: 'prod1',
|
|
182
|
-
batchId: 'batch1',
|
|
183
|
-
variant: 'var1'
|
|
184
|
-
})
|
|
185
|
-
// Returns: /c/abc123/prod1
|
|
186
|
-
```
|
|
187
|
-
|
|
188
212
|
## Use Cases
|
|
189
213
|
|
|
190
214
|
### QR Code Generation
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SmartLinks App Manifest structure
|
|
3
|
+
* Defines the configuration, widgets, setup, import, and metrics for a microapp
|
|
4
|
+
*/
|
|
5
|
+
export interface AppManifest {
|
|
6
|
+
$schema?: string;
|
|
7
|
+
meta?: {
|
|
8
|
+
name: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
version: string;
|
|
11
|
+
platformRevision?: string;
|
|
12
|
+
appId: string;
|
|
13
|
+
};
|
|
14
|
+
widgets?: Array<{
|
|
15
|
+
name: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
sizes?: string[];
|
|
18
|
+
props?: {
|
|
19
|
+
required?: string[];
|
|
20
|
+
optional?: string[];
|
|
21
|
+
};
|
|
22
|
+
}>;
|
|
23
|
+
setup?: {
|
|
24
|
+
description?: string;
|
|
25
|
+
questions?: Array<{
|
|
26
|
+
id: string;
|
|
27
|
+
prompt: string;
|
|
28
|
+
type: string;
|
|
29
|
+
default?: any;
|
|
30
|
+
required?: boolean;
|
|
31
|
+
}>;
|
|
32
|
+
configSchema?: Record<string, any>;
|
|
33
|
+
saveWith?: {
|
|
34
|
+
method: string;
|
|
35
|
+
scope: string;
|
|
36
|
+
admin?: boolean;
|
|
37
|
+
};
|
|
38
|
+
contentHints?: Record<string, {
|
|
39
|
+
aiGenerate?: boolean;
|
|
40
|
+
prompt?: string;
|
|
41
|
+
}>;
|
|
42
|
+
};
|
|
43
|
+
import?: {
|
|
44
|
+
description?: string;
|
|
45
|
+
scope?: string;
|
|
46
|
+
fields?: Array<{
|
|
47
|
+
name: string;
|
|
48
|
+
type: string;
|
|
49
|
+
required?: boolean;
|
|
50
|
+
default?: any;
|
|
51
|
+
description?: string;
|
|
52
|
+
}>;
|
|
53
|
+
csvExample?: string;
|
|
54
|
+
saveWith?: {
|
|
55
|
+
method: string;
|
|
56
|
+
scope: string;
|
|
57
|
+
admin?: boolean;
|
|
58
|
+
note?: string;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
tunable?: {
|
|
62
|
+
description?: string;
|
|
63
|
+
fields?: Array<{
|
|
64
|
+
name: string;
|
|
65
|
+
description?: string;
|
|
66
|
+
type: string;
|
|
67
|
+
}>;
|
|
68
|
+
};
|
|
69
|
+
metrics?: {
|
|
70
|
+
interactions?: Array<{
|
|
71
|
+
id: string;
|
|
72
|
+
description?: string;
|
|
73
|
+
}>;
|
|
74
|
+
kpis?: Array<{
|
|
75
|
+
name: string;
|
|
76
|
+
compute?: string;
|
|
77
|
+
}>;
|
|
78
|
+
};
|
|
79
|
+
[key: string]: any;
|
|
80
|
+
}
|
|
@@ -91,6 +91,8 @@ export interface AppConfig {
|
|
|
91
91
|
hidden?: boolean;
|
|
92
92
|
/** Universal iframe URL for external embedding */
|
|
93
93
|
publicIframeUrl?: string;
|
|
94
|
+
/** Where to get the app manifest for AI and widget definitions */
|
|
95
|
+
manifestUrl?: string;
|
|
94
96
|
/** supports multiple pages / deep links into the app */
|
|
95
97
|
supportsDeepLinks?: boolean;
|
|
96
98
|
/** App component configuration */
|
package/dist/types/index.d.ts
CHANGED
package/dist/types/index.js
CHANGED
package/dist/utils/paths.d.ts
CHANGED
|
@@ -28,10 +28,15 @@ export interface PortalPathParams {
|
|
|
28
28
|
proof?: Proof | string;
|
|
29
29
|
/** Additional query parameters */
|
|
30
30
|
queryParams?: Record<string, string>;
|
|
31
|
+
/** Return only the path without domain (default: false, returns full URL) */
|
|
32
|
+
pathOnly?: boolean;
|
|
31
33
|
}
|
|
32
34
|
/**
|
|
33
35
|
* Builds a portal path/URL based on the provided parameters.
|
|
34
36
|
*
|
|
37
|
+
* Returns a full URL by default using collection.portalUrl or the default smartlinks domain.
|
|
38
|
+
* Set pathOnly: true to return just the path without the domain.
|
|
39
|
+
*
|
|
35
40
|
* Pass in objects where available (collection, product, batch, etc.) and the function
|
|
36
41
|
* will extract the needed properties. You can also pass just IDs if you don't have the full objects.
|
|
37
42
|
*
|
|
@@ -44,17 +49,25 @@ export interface PortalPathParams {
|
|
|
44
49
|
* - With variant: adds `/22/{variantId}`
|
|
45
50
|
*
|
|
46
51
|
* @param params - Path parameters
|
|
47
|
-
* @returns The built portal
|
|
52
|
+
* @returns The built portal URL (default) or path (if pathOnly: true)
|
|
48
53
|
*
|
|
49
54
|
* @example
|
|
50
55
|
* ```typescript
|
|
51
|
-
* //
|
|
56
|
+
* // Returns full URL by default
|
|
52
57
|
* buildPortalPath({
|
|
53
|
-
* collection: myCollection,
|
|
54
|
-
* product: myProduct
|
|
58
|
+
* collection: myCollection, // uses collection.portalUrl
|
|
59
|
+
* product: myProduct
|
|
55
60
|
* })
|
|
56
61
|
* // Returns: https://portal.smartlinks.io/c/abc123/prod1
|
|
57
62
|
*
|
|
63
|
+
* // Return just the path
|
|
64
|
+
* buildPortalPath({
|
|
65
|
+
* collection: myCollection,
|
|
66
|
+
* product: myProduct,
|
|
67
|
+
* pathOnly: true
|
|
68
|
+
* })
|
|
69
|
+
* // Returns: /c/abc123/prod1
|
|
70
|
+
*
|
|
58
71
|
* // GTIN path (ownGtin read from product)
|
|
59
72
|
* buildPortalPath({
|
|
60
73
|
* collection: myCollection,
|
|
@@ -68,7 +81,7 @@ export interface PortalPathParams {
|
|
|
68
81
|
* product: myProduct,
|
|
69
82
|
* batch: myBatch // extracts id and expiryDate
|
|
70
83
|
* })
|
|
71
|
-
* // Returns: /01/1234567890123/10/batch1?17=260630
|
|
84
|
+
* // Returns: https://portal.smartlinks.io/01/1234567890123/10/batch1?17=260630
|
|
72
85
|
*
|
|
73
86
|
* // Or just pass IDs
|
|
74
87
|
* buildPortalPath({
|
|
@@ -76,7 +89,7 @@ export interface PortalPathParams {
|
|
|
76
89
|
* productId: 'prod1',
|
|
77
90
|
* batchId: 'batch1' // just the ID, no expiry
|
|
78
91
|
* })
|
|
79
|
-
* // Returns: /c/abc123/prod1
|
|
92
|
+
* // Returns: https://smartlinks.app/c/abc123/prod1
|
|
80
93
|
* ```
|
|
81
94
|
*/
|
|
82
95
|
export declare function buildPortalPath(params: PortalPathParams): string;
|
package/dist/utils/paths.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Builds a portal path/URL based on the provided parameters.
|
|
3
3
|
*
|
|
4
|
+
* Returns a full URL by default using collection.portalUrl or the default smartlinks domain.
|
|
5
|
+
* Set pathOnly: true to return just the path without the domain.
|
|
6
|
+
*
|
|
4
7
|
* Pass in objects where available (collection, product, batch, etc.) and the function
|
|
5
8
|
* will extract the needed properties. You can also pass just IDs if you don't have the full objects.
|
|
6
9
|
*
|
|
@@ -13,17 +16,25 @@
|
|
|
13
16
|
* - With variant: adds `/22/{variantId}`
|
|
14
17
|
*
|
|
15
18
|
* @param params - Path parameters
|
|
16
|
-
* @returns The built portal
|
|
19
|
+
* @returns The built portal URL (default) or path (if pathOnly: true)
|
|
17
20
|
*
|
|
18
21
|
* @example
|
|
19
22
|
* ```typescript
|
|
20
|
-
* //
|
|
23
|
+
* // Returns full URL by default
|
|
21
24
|
* buildPortalPath({
|
|
22
|
-
* collection: myCollection,
|
|
23
|
-
* product: myProduct
|
|
25
|
+
* collection: myCollection, // uses collection.portalUrl
|
|
26
|
+
* product: myProduct
|
|
24
27
|
* })
|
|
25
28
|
* // Returns: https://portal.smartlinks.io/c/abc123/prod1
|
|
26
29
|
*
|
|
30
|
+
* // Return just the path
|
|
31
|
+
* buildPortalPath({
|
|
32
|
+
* collection: myCollection,
|
|
33
|
+
* product: myProduct,
|
|
34
|
+
* pathOnly: true
|
|
35
|
+
* })
|
|
36
|
+
* // Returns: /c/abc123/prod1
|
|
37
|
+
*
|
|
27
38
|
* // GTIN path (ownGtin read from product)
|
|
28
39
|
* buildPortalPath({
|
|
29
40
|
* collection: myCollection,
|
|
@@ -37,7 +48,7 @@
|
|
|
37
48
|
* product: myProduct,
|
|
38
49
|
* batch: myBatch // extracts id and expiryDate
|
|
39
50
|
* })
|
|
40
|
-
* // Returns: /01/1234567890123/10/batch1?17=260630
|
|
51
|
+
* // Returns: https://portal.smartlinks.io/01/1234567890123/10/batch1?17=260630
|
|
41
52
|
*
|
|
42
53
|
* // Or just pass IDs
|
|
43
54
|
* buildPortalPath({
|
|
@@ -45,11 +56,11 @@
|
|
|
45
56
|
* productId: 'prod1',
|
|
46
57
|
* batchId: 'batch1' // just the ID, no expiry
|
|
47
58
|
* })
|
|
48
|
-
* // Returns: /c/abc123/prod1
|
|
59
|
+
* // Returns: https://smartlinks.app/c/abc123/prod1
|
|
49
60
|
* ```
|
|
50
61
|
*/
|
|
51
62
|
export function buildPortalPath(params) {
|
|
52
|
-
const { collection, product, productId, batch, batchId, variant, proof, queryParams = {} } = params;
|
|
63
|
+
const { collection, product, productId, batch, batchId, variant, proof, queryParams = {}, pathOnly = false } = params;
|
|
53
64
|
// Extract values from collection
|
|
54
65
|
const shortId = collection.shortId;
|
|
55
66
|
const baseUrl = 'portalUrl' in collection ? collection.portalUrl : undefined;
|
|
@@ -138,11 +149,14 @@ export function buildPortalPath(params) {
|
|
|
138
149
|
// Build final URL
|
|
139
150
|
const queryString = searchParams.toString();
|
|
140
151
|
const fullPath = pathname + (queryString ? `?${queryString}` : '');
|
|
141
|
-
if
|
|
142
|
-
|
|
143
|
-
return
|
|
152
|
+
// Return path only if requested
|
|
153
|
+
if (pathOnly) {
|
|
154
|
+
return fullPath;
|
|
144
155
|
}
|
|
145
|
-
|
|
156
|
+
// Return full URL using collection.portalUrl or default domain
|
|
157
|
+
const domain = baseUrl || 'https://smartlinks.app';
|
|
158
|
+
const cleanDomain = domain.replace(/\/$/, '');
|
|
159
|
+
return cleanDomain + fullPath;
|
|
146
160
|
}
|
|
147
161
|
/**
|
|
148
162
|
* Formats an expiry date to YYMMDD format.
|
package/docs/API_SUMMARY.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Smartlinks API Summary
|
|
2
2
|
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.29 | Generated: 2026-02-14T14:15:49.096Z
|
|
4
4
|
|
|
5
5
|
This is a concise summary of all available API functions and types.
|
|
6
6
|
|
|
@@ -791,6 +791,88 @@ interface AppConfigurationResponse {
|
|
|
791
791
|
}
|
|
792
792
|
```
|
|
793
793
|
|
|
794
|
+
### appManifest
|
|
795
|
+
|
|
796
|
+
**AppManifest** (interface)
|
|
797
|
+
```typescript
|
|
798
|
+
interface AppManifest {
|
|
799
|
+
$schema?: string;
|
|
800
|
+
meta?: {
|
|
801
|
+
name: string;
|
|
802
|
+
description?: string;
|
|
803
|
+
version: string;
|
|
804
|
+
platformRevision?: string;
|
|
805
|
+
appId: string;
|
|
806
|
+
};
|
|
807
|
+
widgets?: Array<{
|
|
808
|
+
name: string;
|
|
809
|
+
description?: string;
|
|
810
|
+
sizes?: string[];
|
|
811
|
+
props?: {
|
|
812
|
+
required?: string[];
|
|
813
|
+
optional?: string[];
|
|
814
|
+
};
|
|
815
|
+
}>;
|
|
816
|
+
setup?: {
|
|
817
|
+
description?: string;
|
|
818
|
+
questions?: Array<{
|
|
819
|
+
id: string;
|
|
820
|
+
prompt: string;
|
|
821
|
+
type: string;
|
|
822
|
+
default?: any;
|
|
823
|
+
required?: boolean;
|
|
824
|
+
}>;
|
|
825
|
+
configSchema?: Record<string, any>;
|
|
826
|
+
saveWith?: {
|
|
827
|
+
method: string;
|
|
828
|
+
scope: string;
|
|
829
|
+
admin?: boolean;
|
|
830
|
+
};
|
|
831
|
+
contentHints?: Record<string, {
|
|
832
|
+
aiGenerate?: boolean;
|
|
833
|
+
prompt?: string;
|
|
834
|
+
}>;
|
|
835
|
+
};
|
|
836
|
+
import?: {
|
|
837
|
+
description?: string;
|
|
838
|
+
scope?: string;
|
|
839
|
+
fields?: Array<{
|
|
840
|
+
name: string;
|
|
841
|
+
type: string;
|
|
842
|
+
required?: boolean;
|
|
843
|
+
default?: any;
|
|
844
|
+
description?: string;
|
|
845
|
+
}>;
|
|
846
|
+
csvExample?: string;
|
|
847
|
+
saveWith?: {
|
|
848
|
+
method: string;
|
|
849
|
+
scope: string;
|
|
850
|
+
admin?: boolean;
|
|
851
|
+
note?: string;
|
|
852
|
+
};
|
|
853
|
+
};
|
|
854
|
+
tunable?: {
|
|
855
|
+
description?: string;
|
|
856
|
+
fields?: Array<{
|
|
857
|
+
name: string;
|
|
858
|
+
description?: string;
|
|
859
|
+
type: string;
|
|
860
|
+
}>;
|
|
861
|
+
};
|
|
862
|
+
metrics?: {
|
|
863
|
+
interactions?: Array<{
|
|
864
|
+
id: string;
|
|
865
|
+
description?: string;
|
|
866
|
+
}>;
|
|
867
|
+
kpis?: Array<{
|
|
868
|
+
name: string;
|
|
869
|
+
compute?: string;
|
|
870
|
+
}>;
|
|
871
|
+
};
|
|
872
|
+
[key: string]: any; // Allow additional custom fields
|
|
873
|
+
}
|
|
874
|
+
```
|
|
875
|
+
|
|
794
876
|
### asset
|
|
795
877
|
|
|
796
878
|
**Asset** (interface)
|
|
@@ -1394,6 +1476,7 @@ interface AppConfig {
|
|
|
1394
1476
|
ownersOnly?: boolean
|
|
1395
1477
|
hidden?: boolean
|
|
1396
1478
|
publicIframeUrl?: string
|
|
1479
|
+
manifestUrl?: string
|
|
1397
1480
|
supportsDeepLinks?: boolean;
|
|
1398
1481
|
usage: {
|
|
1399
1482
|
collection: boolean; // use at the collecton level
|
|
@@ -3824,6 +3907,9 @@ Post a chat message to the AI (admin or public)
|
|
|
3824
3907
|
|
|
3825
3908
|
**deleteDataItem**(opts: AppConfigOptions) → `Promise<void>`
|
|
3826
3909
|
|
|
3910
|
+
**getManifest**(manifestUrl: string, force?: boolean) → `Promise<AppManifest>`
|
|
3911
|
+
Fetches an app's manifest file through the proxy API. The manifest is cached on the server for 5 minutes. ```typescript // Use with appsConfig const appsConfig = await Api.Collection.Public.getAppsConfig(collectionId); const app = appsConfig.apps[0]; if (app.manifestUrl) { const manifest = await Api.AppConfiguration.getManifest(app.manifestUrl); if (manifest.widgets) { console.log('Available widgets:', manifest.widgets); } } // Force refresh const freshManifest = await Api.AppConfiguration.getManifest(app.manifestUrl, true); ```
|
|
3912
|
+
|
|
3827
3913
|
### appRecord
|
|
3828
3914
|
|
|
3829
3915
|
**get**(collectionId: string, appId: string) → `Promise<any>`
|
package/docs/utils.md
CHANGED
|
@@ -12,40 +12,46 @@ import { utils } from '@proveanything/smartlinks'
|
|
|
12
12
|
|
|
13
13
|
## Path Builder Utility
|
|
14
14
|
|
|
15
|
-
Pass in objects (collection, product, batch, etc.) and the function extracts what it needs
|
|
15
|
+
Builds full portal URLs by default. Pass in objects (collection, product, batch, etc.) and the function extracts what it needs. Uses `collection.portalUrl` as the domain, or defaults to `https://zt.smartlinks.io`.
|
|
16
16
|
|
|
17
17
|
### Basic Usage
|
|
18
18
|
|
|
19
|
-
Pass objects where you have them, or just IDs for simpler cases:
|
|
20
|
-
|
|
21
19
|
```typescript
|
|
22
|
-
import { utils } from '@
|
|
20
|
+
import { utils } from '@proveanything/smartlinks'
|
|
23
21
|
|
|
24
|
-
//
|
|
25
|
-
const
|
|
26
|
-
collection: myCollection,
|
|
22
|
+
// Returns full URL by default (uses collection.portalUrl)
|
|
23
|
+
const url = utils.buildPortalPath({
|
|
24
|
+
collection: myCollection, // uses collection.portalUrl or default domain
|
|
27
25
|
product: myProduct // ownGtin is read from product, not overridden
|
|
28
26
|
})
|
|
29
27
|
// Returns: https://portal.smartlinks.io/c/abc123/prod123
|
|
30
28
|
|
|
29
|
+
// Return just the path (no domain)
|
|
30
|
+
const path = utils.buildPortalPath({
|
|
31
|
+
collection: { shortId: 'abc123' },
|
|
32
|
+
productId: 'prod1',
|
|
33
|
+
pathOnly: true // Set to true for path only
|
|
34
|
+
})
|
|
35
|
+
// Returns: /c/abc123/prod1
|
|
36
|
+
|
|
31
37
|
// Or just IDs if you don't have full objects
|
|
32
|
-
const
|
|
38
|
+
const url2 = utils.buildPortalPath({
|
|
33
39
|
collection: { shortId: 'abc123' },
|
|
34
40
|
productId: 'prod1'
|
|
35
41
|
})
|
|
36
|
-
// Returns: /c/abc123/prod1
|
|
42
|
+
// Returns: https://zt.smartlinks.io/c/abc123/prod1 (default domain)
|
|
37
43
|
```
|
|
38
44
|
|
|
39
45
|
## Path Builder Function
|
|
40
46
|
|
|
41
47
|
### `buildPortalPath(params)`
|
|
42
48
|
|
|
43
|
-
Builds a portal
|
|
49
|
+
Builds a full portal URL based on the provided parameters. Returns full URL by default using `collection.portalUrl` or `https://zt.smartlinks.io`.
|
|
44
50
|
|
|
45
51
|
**Parameters:**
|
|
46
52
|
|
|
47
53
|
- `collection` (required) - Collection object or `{ shortId: string, portalUrl?: string }`
|
|
48
|
-
Extracts: `shortId` and optional `portalUrl` for base
|
|
54
|
+
Extracts: `shortId` and optional `portalUrl` for base domain
|
|
49
55
|
|
|
50
56
|
- `product` (optional) - Full product object
|
|
51
57
|
Extracts: `id`, `gtin`, and `ownGtin` (ownGtin is a critical product setting - read only, never overridden)
|
|
@@ -69,6 +75,9 @@ Builds a portal path/URL based on the provided parameters.
|
|
|
69
75
|
|
|
70
76
|
- `queryParams` (optional) - Additional query parameters object
|
|
71
77
|
|
|
78
|
+
- `pathOnly` (optional, default: `false`) - Return only the path without domain
|
|
79
|
+
Set to `true` to get `/c/abc/prod` instead of `https://domain.com/c/abc/prod`
|
|
80
|
+
|
|
72
81
|
**Path Formats:**
|
|
73
82
|
|
|
74
83
|
- Basic product: `/c/{shortId}/{productId}`
|
|
@@ -80,16 +89,23 @@ Builds a portal path/URL based on the provided parameters.
|
|
|
80
89
|
|
|
81
90
|
## Examples
|
|
82
91
|
|
|
83
|
-
###
|
|
92
|
+
### Full URL (Default Behavior)
|
|
84
93
|
|
|
85
94
|
```typescript
|
|
86
|
-
//
|
|
95
|
+
// Returns full URL using collection.portalUrl
|
|
87
96
|
utils.buildPortalPath({
|
|
88
|
-
collection: myCollection, //
|
|
89
|
-
product: myProduct
|
|
97
|
+
collection: myCollection, // uses collection.portalUrl
|
|
98
|
+
product: myProduct
|
|
90
99
|
})
|
|
91
100
|
// Returns: https://portal.smartlinks.io/c/abc123/prod123
|
|
92
101
|
|
|
102
|
+
// Without portalUrl, uses default domain
|
|
103
|
+
utils.buildPortalPath({
|
|
104
|
+
collection: { shortId: 'abc123' },
|
|
105
|
+
productId: 'prod1'
|
|
106
|
+
})
|
|
107
|
+
// Returns: https://zt.smartlinks.io/c/abc123/prod1
|
|
108
|
+
|
|
93
109
|
// With proof object
|
|
94
110
|
utils.buildPortalPath({
|
|
95
111
|
collection: myCollection,
|
|
@@ -99,6 +115,27 @@ utils.buildPortalPath({
|
|
|
99
115
|
// Returns: https://portal.smartlinks.io/c/abc123/prod123/proof789
|
|
100
116
|
```
|
|
101
117
|
|
|
118
|
+
### Path Only (No Domain)
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
// Set pathOnly: true to get just the path
|
|
122
|
+
utils.buildPortalPath({
|
|
123
|
+
collection: myCollection,
|
|
124
|
+
product: myProduct,
|
|
125
|
+
pathOnly: true
|
|
126
|
+
})
|
|
127
|
+
// Returns: /c/abc123/prod123
|
|
128
|
+
|
|
129
|
+
// Useful when you need to build your own full URL
|
|
130
|
+
const path = utils.buildPortalPath({
|
|
131
|
+
collection: { shortId: 'abc123' },
|
|
132
|
+
productId: 'prod1',
|
|
133
|
+
pathOnly: true
|
|
134
|
+
})
|
|
135
|
+
const customUrl = `https://mycustomdomain.com${path}`
|
|
136
|
+
// Result: https://mycustomdomain.com/c/abc123/prod1
|
|
137
|
+
```
|
|
138
|
+
|
|
102
139
|
### GTIN Paths
|
|
103
140
|
|
|
104
141
|
```typescript
|
|
@@ -172,19 +209,6 @@ utils.buildPortalPath({
|
|
|
172
209
|
// Returns: https://portal.smartlinks.io/c/abc123/prod123?utm_source=email&utm_campaign=launch&lang=fr
|
|
173
210
|
```
|
|
174
211
|
|
|
175
|
-
### Just IDs (No Full Objects)
|
|
176
|
-
|
|
177
|
-
```typescript
|
|
178
|
-
// Minimal - just IDs
|
|
179
|
-
utils.buildPortalPath({
|
|
180
|
-
collection: { shortId: 'abc123' },
|
|
181
|
-
productId: 'prod1',
|
|
182
|
-
batchId: 'batch1',
|
|
183
|
-
variant: 'var1'
|
|
184
|
-
})
|
|
185
|
-
// Returns: /c/abc123/prod1
|
|
186
|
-
```
|
|
187
|
-
|
|
188
212
|
## Use Cases
|
|
189
213
|
|
|
190
214
|
### QR Code Generation
|