@proveanything/smartlinks 1.13.0 → 1.13.2

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/README.md CHANGED
@@ -368,7 +368,7 @@ await asset.remove({
368
368
  "site": "acme-demo",
369
369
  "productId": null,
370
370
  "proofId": null,
371
- "app": null,
371
+ "appId": null,
372
372
  "name": "product-hero-shot",
373
373
  "cleanName": "product-hero-shot",
374
374
  "assetType": "Image",
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 1.13.0 | Generated: 2026-05-06T20:31:38.856Z
3
+ Version: 1.13.2 | Generated: 2026-05-08T09:09:55.295Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -1439,6 +1439,16 @@ interface DeepLinkEntry {
1439
1439
  * Do NOT include platform context params (collectionId, appId, productId, etc.) —
1440
1440
  * those are injected by the platform automatically.
1441
1441
  params?: Record<string, string>;
1442
+ * When `true`, this entry is also available as a dynamic data context for widgets
1443
+ * (in addition to being a navigable page / container route).
1444
+ *
1445
+ * Entries with `widget: true` appear in the widget config picker so an admin can
1446
+ * select this dataset to drive how the widget renders. The widget receives `params`
1447
+ * and decides its own presentation — no separate rendering contract is required.
1448
+ *
1449
+ * Omit (or `false`) for entries that are only meaningful as full-page navigation
1450
+ * (e.g. multi-step forms, settings pages, checkout flows).
1451
+ widget?: true;
1442
1452
  }
1443
1453
  ```
1444
1454
 
@@ -2291,7 +2301,7 @@ interface Asset {
2291
2301
  site: string
2292
2302
  productId: string | null
2293
2303
  proofId: string | null
2294
- app: string | null
2304
+ appId: string | null
2295
2305
  url: string
2296
2306
  * CDN URL of the WebP thumbnail (max 512px longest edge, no crop).
2297
2307
  * Always .webp — null until thumbnail generation has run.
@@ -2427,7 +2437,7 @@ interface UpdateAssetOptions {
2427
2437
  collectionId: string
2428
2438
  assetId: string
2429
2439
  name?: string
2430
- app?: string
2440
+ appId?: string
2431
2441
  labels?: string[]
2432
2442
  metadata?: Record<string, any>
2433
2443
  thumbnail?: string
@@ -14,7 +14,7 @@ interface Asset {
14
14
  site: string // alias for collectionId (compat)
15
15
  productId: string | null // set when scoped to a product
16
16
  proofId: string | null // set when scoped to a proof (ledger entry)
17
- app: string | null // app that owns this asset, e.g. 'homepage'
17
+ appId: string | null // app that owns this asset, e.g. 'homepage'
18
18
 
19
19
  // File
20
20
  url: string // CDN URL of the original file
@@ -21,6 +21,7 @@ This doc covers both sides of the contract: **suppliers** declare their navigabl
21
21
  - [Portal Navigation Menu](#portal-navigation-menu)
22
22
  - [AI Orchestration](#ai-orchestration)
23
23
  - [Cross-App Navigation](#cross-app-navigation)
24
+ - [Widget Config Picker — Dynamic Data Context](#widget-config-picker--dynamic-data-context)
24
25
  - [Link Picker — Admin Configuration](#link-picker--admin-configuration)
25
26
  - [Rendering Links at Runtime](#rendering-links-at-runtime)
26
27
  - [TypeScript Types](#typescript-types)
@@ -191,6 +192,18 @@ interface DeepLinkEntry {
191
192
  * are injected automatically — do NOT include them here.
192
193
  */
193
194
  params?: Record<string, string>;
195
+
196
+ /**
197
+ * When `true`, this entry is also available as a dynamic data context for widgets.
198
+ *
199
+ * Entries with `widget: true` appear in the widget config picker so an admin can
200
+ * select this dataset to drive how the widget renders. The widget receives `params`
201
+ * and decides its own presentation — no additional contract is required.
202
+ *
203
+ * Omit for entries that are only meaningful as full-page navigation
204
+ * (e.g. multi-step forms, settings pages, checkout flows).
205
+ */
206
+ widget?: true;
194
207
  }
195
208
  ```
196
209
 
@@ -199,9 +212,12 @@ interface DeepLinkEntry {
199
212
  | `title` | ✅ | Displayed in menus and offered to AI agents. Should be concise and human-readable. |
200
213
  | `path` | ❌ | Hash route within the app. Defaults to `/` if omitted. |
201
214
  | `params` | ❌ | App-specific query params only. Platform params are injected automatically. |
215
+ | `widget` | ❌ | Set to `true` to make this entry selectable in the widget config picker as a dynamic data context. |
202
216
 
203
217
  > **Tip:** Different entries can share the same `path` if they differ by `params` — for example, two entries pointing at `/settings` with different `tab` params.
204
218
 
219
+ > **Container vs widget:** All entries are navigable via a container (full-page render). `widget: true` additionally opts the entry into the widget picker — use it for datasets that make sense as a compact card, e.g. a specific gallery view or a named product showcase. Don't set it on management/settings pages.
220
+
205
221
  ---
206
222
 
207
223
  ## Quick Start
@@ -500,6 +516,58 @@ if (entry) {
500
516
 
501
517
  ---
502
518
 
519
+ ### Widget Config Picker — Dynamic Data Context
520
+
521
+ When a widget's admin settings include a "which view/dataset to show" picker, use the `widget: true` entries from `appConfig.linkable` as the source. Filter to entries with `widget: true` across all installed apps (or just the widget's own app) and let the admin select one. Persist only the `params` — the title is ephemeral display.
522
+
523
+ ```typescript
524
+ // Fetch linkable entries for a specific app and filter to widget-eligible ones
525
+ const config = await SL.appConfiguration.getConfig({ collectionId, appId: 'media-gallery' });
526
+ const widgetViews = (config?.linkable ?? []).filter(e => e.widget === true);
527
+
528
+ // widgetViews might be:
529
+ // [
530
+ // { title: "Gallery: Summer 2026", params: { viewId: "sum26" }, widget: true },
531
+ // { title: "Gallery: Archive", params: { viewId: "archive" }, widget: true },
532
+ // ]
533
+ ```
534
+
535
+ ```tsx
536
+ // Widget admin settings — view picker
537
+ <select
538
+ value={JSON.stringify(settings.viewParams ?? {})}
539
+ onChange={e => saveSettings({ ...settings, viewParams: JSON.parse(e.target.value) })}
540
+ >
541
+ <option value="{}">— Default view —</option>
542
+ {widgetViews.map(entry => (
543
+ <option key={entry.title} value={JSON.stringify(entry.params)}>
544
+ {entry.title}
545
+ </option>
546
+ ))}
547
+ </select>
548
+ ```
549
+
550
+ The widget then reads `settings.viewParams` at render time and uses it to fetch or filter its data. The widget owns all rendering decisions — `params` is just a key.
551
+
552
+ **Supply side** — when the media gallery creates or renames a gallery view, it syncs `appConfig.linkable` as usual, marking card-appropriate views with `widget: true`:
553
+
554
+ ```typescript
555
+ const linkable = galleryViews.map(view => ({
556
+ title: view.name,
557
+ params: { viewId: view.id },
558
+ widget: view.isCardReady ? true : undefined, // only opt in views that make sense as cards
559
+ }));
560
+
561
+ await SL.appConfiguration.setConfig({
562
+ collectionId, appId: 'media-gallery', admin: true,
563
+ config: { ...current, linkable },
564
+ });
565
+ ```
566
+
567
+ > **Rule of thumb:** set `widget: true` on dataset entries (gallery views, product showcases, named feeds). Leave it off on management/utility pages (settings, upload config, multi-step forms).
568
+
569
+ ---
570
+
503
571
  ### Link Picker — Admin Configuration
504
572
 
505
573
  When an admin needs to configure any outbound link — to another installed app, a specific page within an app, or an external URL — **never use a bare text input**. Use `<LinkPicker />` from `@proveanything/smartlinks-utils-ui`. It handles all three `LinkTarget` kinds and produces a single `LinkTarget` value to persist.
@@ -656,6 +724,12 @@ export interface DeepLinkEntry {
656
724
  * Do NOT include platform context params (collectionId, appId, etc.).
657
725
  */
658
726
  params?: Record<string, string>;
727
+ /**
728
+ * When `true`, this entry is also available as a dynamic data context for widgets
729
+ * (in addition to being a navigable page / container route).
730
+ * Omit for entries that are only meaningful as full-page navigation.
731
+ */
732
+ widget?: true;
659
733
  }
660
734
 
661
735
  /** Convenience alias for an array of DeepLinkEntry */
package/dist/openapi.yaml CHANGED
@@ -15058,6 +15058,9 @@ components:
15058
15058
  type: object
15059
15059
  additionalProperties:
15060
15060
  type: string
15061
+ widget:
15062
+ type: object
15063
+ additionalProperties: true
15061
15064
  required:
15062
15065
  - title
15063
15066
  ExecutorContext:
@@ -16539,7 +16542,7 @@ components:
16539
16542
  type: string
16540
16543
  proofId:
16541
16544
  type: string
16542
- app:
16545
+ appId:
16543
16546
  type: string
16544
16547
  url:
16545
16548
  type: string
@@ -16618,7 +16621,7 @@ components:
16618
16621
  - site
16619
16622
  - productId
16620
16623
  - proofId
16621
- - app
16624
+ - appId
16622
16625
  - url
16623
16626
  - thumbnail
16624
16627
  - name
@@ -16769,7 +16772,7 @@ components:
16769
16772
  type: string
16770
16773
  name:
16771
16774
  type: string
16772
- app:
16775
+ appId:
16773
16776
  type: string
16774
16777
  labels:
16775
16778
  type: array
@@ -96,6 +96,18 @@ export interface DeepLinkEntry {
96
96
  * those are injected by the platform automatically.
97
97
  */
98
98
  params?: Record<string, string>;
99
+ /**
100
+ * When `true`, this entry is also available as a dynamic data context for widgets
101
+ * (in addition to being a navigable page / container route).
102
+ *
103
+ * Entries with `widget: true` appear in the widget config picker so an admin can
104
+ * select this dataset to drive how the widget renders. The widget receives `params`
105
+ * and decides its own presentation — no separate rendering contract is required.
106
+ *
107
+ * Omit (or `false`) for entries that are only meaningful as full-page navigation
108
+ * (e.g. multi-step forms, settings pages, checkout flows).
109
+ */
110
+ widget?: true;
99
111
  }
100
112
  /**
101
113
  * Context object passed to every executor factory function.
@@ -38,7 +38,7 @@ export interface Asset {
38
38
  /** Set when scoped to a proof (ledger entry) */
39
39
  proofId: string | null;
40
40
  /** App that owns this asset, e.g. 'homepage' */
41
- app: string | null;
41
+ appId: string | null;
42
42
  /** CDN URL of the original file */
43
43
  url: string;
44
44
  /**
@@ -230,7 +230,7 @@ export interface UpdateAssetOptions {
230
230
  collectionId: string;
231
231
  assetId: string;
232
232
  name?: string;
233
- app?: string;
233
+ appId?: string;
234
234
  labels?: string[];
235
235
  metadata?: Record<string, any>;
236
236
  /** Manually override the thumbnail URL */
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 1.13.0 | Generated: 2026-05-06T20:31:38.856Z
3
+ Version: 1.13.2 | Generated: 2026-05-08T09:09:55.295Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -1439,6 +1439,16 @@ interface DeepLinkEntry {
1439
1439
  * Do NOT include platform context params (collectionId, appId, productId, etc.) —
1440
1440
  * those are injected by the platform automatically.
1441
1441
  params?: Record<string, string>;
1442
+ * When `true`, this entry is also available as a dynamic data context for widgets
1443
+ * (in addition to being a navigable page / container route).
1444
+ *
1445
+ * Entries with `widget: true` appear in the widget config picker so an admin can
1446
+ * select this dataset to drive how the widget renders. The widget receives `params`
1447
+ * and decides its own presentation — no separate rendering contract is required.
1448
+ *
1449
+ * Omit (or `false`) for entries that are only meaningful as full-page navigation
1450
+ * (e.g. multi-step forms, settings pages, checkout flows).
1451
+ widget?: true;
1442
1452
  }
1443
1453
  ```
1444
1454
 
@@ -2291,7 +2301,7 @@ interface Asset {
2291
2301
  site: string
2292
2302
  productId: string | null
2293
2303
  proofId: string | null
2294
- app: string | null
2304
+ appId: string | null
2295
2305
  url: string
2296
2306
  * CDN URL of the WebP thumbnail (max 512px longest edge, no crop).
2297
2307
  * Always .webp — null until thumbnail generation has run.
@@ -2427,7 +2437,7 @@ interface UpdateAssetOptions {
2427
2437
  collectionId: string
2428
2438
  assetId: string
2429
2439
  name?: string
2430
- app?: string
2440
+ appId?: string
2431
2441
  labels?: string[]
2432
2442
  metadata?: Record<string, any>
2433
2443
  thumbnail?: string
package/docs/assets.md CHANGED
@@ -14,7 +14,7 @@ interface Asset {
14
14
  site: string // alias for collectionId (compat)
15
15
  productId: string | null // set when scoped to a product
16
16
  proofId: string | null // set when scoped to a proof (ledger entry)
17
- app: string | null // app that owns this asset, e.g. 'homepage'
17
+ appId: string | null // app that owns this asset, e.g. 'homepage'
18
18
 
19
19
  // File
20
20
  url: string // CDN URL of the original file
@@ -21,6 +21,7 @@ This doc covers both sides of the contract: **suppliers** declare their navigabl
21
21
  - [Portal Navigation Menu](#portal-navigation-menu)
22
22
  - [AI Orchestration](#ai-orchestration)
23
23
  - [Cross-App Navigation](#cross-app-navigation)
24
+ - [Widget Config Picker — Dynamic Data Context](#widget-config-picker--dynamic-data-context)
24
25
  - [Link Picker — Admin Configuration](#link-picker--admin-configuration)
25
26
  - [Rendering Links at Runtime](#rendering-links-at-runtime)
26
27
  - [TypeScript Types](#typescript-types)
@@ -191,6 +192,18 @@ interface DeepLinkEntry {
191
192
  * are injected automatically — do NOT include them here.
192
193
  */
193
194
  params?: Record<string, string>;
195
+
196
+ /**
197
+ * When `true`, this entry is also available as a dynamic data context for widgets.
198
+ *
199
+ * Entries with `widget: true` appear in the widget config picker so an admin can
200
+ * select this dataset to drive how the widget renders. The widget receives `params`
201
+ * and decides its own presentation — no additional contract is required.
202
+ *
203
+ * Omit for entries that are only meaningful as full-page navigation
204
+ * (e.g. multi-step forms, settings pages, checkout flows).
205
+ */
206
+ widget?: true;
194
207
  }
195
208
  ```
196
209
 
@@ -199,9 +212,12 @@ interface DeepLinkEntry {
199
212
  | `title` | ✅ | Displayed in menus and offered to AI agents. Should be concise and human-readable. |
200
213
  | `path` | ❌ | Hash route within the app. Defaults to `/` if omitted. |
201
214
  | `params` | ❌ | App-specific query params only. Platform params are injected automatically. |
215
+ | `widget` | ❌ | Set to `true` to make this entry selectable in the widget config picker as a dynamic data context. |
202
216
 
203
217
  > **Tip:** Different entries can share the same `path` if they differ by `params` — for example, two entries pointing at `/settings` with different `tab` params.
204
218
 
219
+ > **Container vs widget:** All entries are navigable via a container (full-page render). `widget: true` additionally opts the entry into the widget picker — use it for datasets that make sense as a compact card, e.g. a specific gallery view or a named product showcase. Don't set it on management/settings pages.
220
+
205
221
  ---
206
222
 
207
223
  ## Quick Start
@@ -500,6 +516,58 @@ if (entry) {
500
516
 
501
517
  ---
502
518
 
519
+ ### Widget Config Picker — Dynamic Data Context
520
+
521
+ When a widget's admin settings include a "which view/dataset to show" picker, use the `widget: true` entries from `appConfig.linkable` as the source. Filter to entries with `widget: true` across all installed apps (or just the widget's own app) and let the admin select one. Persist only the `params` — the title is ephemeral display.
522
+
523
+ ```typescript
524
+ // Fetch linkable entries for a specific app and filter to widget-eligible ones
525
+ const config = await SL.appConfiguration.getConfig({ collectionId, appId: 'media-gallery' });
526
+ const widgetViews = (config?.linkable ?? []).filter(e => e.widget === true);
527
+
528
+ // widgetViews might be:
529
+ // [
530
+ // { title: "Gallery: Summer 2026", params: { viewId: "sum26" }, widget: true },
531
+ // { title: "Gallery: Archive", params: { viewId: "archive" }, widget: true },
532
+ // ]
533
+ ```
534
+
535
+ ```tsx
536
+ // Widget admin settings — view picker
537
+ <select
538
+ value={JSON.stringify(settings.viewParams ?? {})}
539
+ onChange={e => saveSettings({ ...settings, viewParams: JSON.parse(e.target.value) })}
540
+ >
541
+ <option value="{}">— Default view —</option>
542
+ {widgetViews.map(entry => (
543
+ <option key={entry.title} value={JSON.stringify(entry.params)}>
544
+ {entry.title}
545
+ </option>
546
+ ))}
547
+ </select>
548
+ ```
549
+
550
+ The widget then reads `settings.viewParams` at render time and uses it to fetch or filter its data. The widget owns all rendering decisions — `params` is just a key.
551
+
552
+ **Supply side** — when the media gallery creates or renames a gallery view, it syncs `appConfig.linkable` as usual, marking card-appropriate views with `widget: true`:
553
+
554
+ ```typescript
555
+ const linkable = galleryViews.map(view => ({
556
+ title: view.name,
557
+ params: { viewId: view.id },
558
+ widget: view.isCardReady ? true : undefined, // only opt in views that make sense as cards
559
+ }));
560
+
561
+ await SL.appConfiguration.setConfig({
562
+ collectionId, appId: 'media-gallery', admin: true,
563
+ config: { ...current, linkable },
564
+ });
565
+ ```
566
+
567
+ > **Rule of thumb:** set `widget: true` on dataset entries (gallery views, product showcases, named feeds). Leave it off on management/utility pages (settings, upload config, multi-step forms).
568
+
569
+ ---
570
+
503
571
  ### Link Picker — Admin Configuration
504
572
 
505
573
  When an admin needs to configure any outbound link — to another installed app, a specific page within an app, or an external URL — **never use a bare text input**. Use `<LinkPicker />` from `@proveanything/smartlinks-utils-ui`. It handles all three `LinkTarget` kinds and produces a single `LinkTarget` value to persist.
@@ -656,6 +724,12 @@ export interface DeepLinkEntry {
656
724
  * Do NOT include platform context params (collectionId, appId, etc.).
657
725
  */
658
726
  params?: Record<string, string>;
727
+ /**
728
+ * When `true`, this entry is also available as a dynamic data context for widgets
729
+ * (in addition to being a navigable page / container route).
730
+ * Omit for entries that are only meaningful as full-page navigation.
731
+ */
732
+ widget?: true;
659
733
  }
660
734
 
661
735
  /** Convenience alias for an array of DeepLinkEntry */
package/openapi.yaml CHANGED
@@ -15058,6 +15058,9 @@ components:
15058
15058
  type: object
15059
15059
  additionalProperties:
15060
15060
  type: string
15061
+ widget:
15062
+ type: object
15063
+ additionalProperties: true
15061
15064
  required:
15062
15065
  - title
15063
15066
  ExecutorContext:
@@ -16539,7 +16542,7 @@ components:
16539
16542
  type: string
16540
16543
  proofId:
16541
16544
  type: string
16542
- app:
16545
+ appId:
16543
16546
  type: string
16544
16547
  url:
16545
16548
  type: string
@@ -16618,7 +16621,7 @@ components:
16618
16621
  - site
16619
16622
  - productId
16620
16623
  - proofId
16621
- - app
16624
+ - appId
16622
16625
  - url
16623
16626
  - thumbnail
16624
16627
  - name
@@ -16769,7 +16772,7 @@ components:
16769
16772
  type: string
16770
16773
  name:
16771
16774
  type: string
16772
- app:
16775
+ appId:
16773
16776
  type: string
16774
16777
  labels:
16775
16778
  type: array
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proveanything/smartlinks",
3
- "version": "1.13.0",
3
+ "version": "1.13.2",
4
4
  "description": "Official JavaScript/TypeScript SDK for the Smartlinks API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",