@proveanything/smartlinks 1.12.0 → 1.13.0
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 +28 -13
- package/dist/api/asset.d.ts +60 -1
- package/dist/api/asset.js +245 -2
- package/dist/docs/API_SUMMARY.md +219 -61
- package/dist/docs/assets.md +310 -0
- package/dist/docs/liquid-templates.md +1 -3
- package/dist/docs/overview.md +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/openapi.yaml +615 -115
- package/dist/types/asset.d.ts +159 -46
- package/dist/types/collection.d.ts +5 -22
- package/dist/types/product.d.ts +31 -30
- package/docs/API_SUMMARY.md +219 -61
- package/docs/assets.md +310 -0
- package/docs/liquid-templates.md +1 -3
- package/docs/overview.md +1 -0
- package/openapi.yaml +615 -115
- package/package.json +1 -1
package/dist/docs/API_SUMMARY.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Smartlinks API Summary
|
|
2
2
|
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.13.0 | Generated: 2026-05-06T20:31:38.856Z
|
|
4
4
|
|
|
5
5
|
This is a concise summary of all available API functions and types.
|
|
6
6
|
|
|
@@ -9,26 +9,41 @@ This is a concise summary of all available API functions and types.
|
|
|
9
9
|
For detailed guides on specific features:
|
|
10
10
|
|
|
11
11
|
- **[SmartLinks Microapp Overview](overview.md)** - Platform architecture, data model, auth patterns, storage, anti-patterns, and quick-reference for all SDK docs
|
|
12
|
+
- **[Assets](assets.md)** - Asset object, AssetRef, upload, replace, soft-delete, restore, bulk-delete, and public token-based uploads
|
|
12
13
|
- **[AI & Chat Completions](ai.md)** - Chat completions, RAG (document-grounded Q&A), voice integration, streaming, tool calling, podcast generation
|
|
13
14
|
- **[Translations](translations.md)** - Runtime translation lookup, browser-side IndexedDB caching, and admin translation management
|
|
14
15
|
- **[Widgets](widgets.md)** - Embeddable React components for parent applications
|
|
15
|
-
- **[
|
|
16
|
+
- **[Building React Components](building-react-components.md)** - Foundational guide to building React widgets and containers for SmartLinks
|
|
17
|
+
- **[Containers](containers.md)** - Building full-app embeddable containers (lazy-loaded)
|
|
18
|
+
- **[Mobile Admin Container](mobile-admin-container.md)** - Building mobile-optimised operator/admin containers as a separate bundle
|
|
19
|
+
- **[Container Tracking](container-tracking.md)** - Hierarchical physical/logical container groupings with item membership
|
|
16
20
|
- **[Scanner Containers](scanner-container.md)** - Building scanner microapps for the SmartLinks Scanner Android host (RFID, NFC, QR, key events)
|
|
17
21
|
- **[Multi-Page App Architecture](mpa.md)** - Vite MPA build pipeline: public/admin entry points, widget/container/executor bundles, content-hashed CDN assets
|
|
18
22
|
- **[App Configuration Files](app-manifest.md)** - `app.manifest.json` and `app.admin.json` reference — bundles, components, setup questions, import schemas, tunable fields, and metrics
|
|
19
23
|
- **[Executor Model](executor.md)** - Programmatic JS bundles for AI-driven setup, server-side SEO metadata generation, and LLM content for AI crawlers
|
|
20
24
|
- **[Realtime](realtime.md)** - Real-time data updates and WebSocket connections
|
|
21
25
|
- **[iframe Responder](iframe-responder.md)** - iframe integration and cross-origin communication
|
|
26
|
+
- **[iframe Streaming Parent Changes](iframe-streaming-parent-changes.md)** - Parent-side changes required to support AI streaming in iframe proxy mode
|
|
22
27
|
- **[Utilities](utils.md)** - Helper functions for building portal paths, URLs, and common tasks
|
|
28
|
+
- **[UI Utils](ui-utils.md)** - Reusable, themeable admin UI React component library for microapps
|
|
29
|
+
- **[Caching](caching.md)** - Multi-tier caching strategy (in-memory, SessionStorage, IndexedDB) used by the SDK
|
|
30
|
+
- **[Native Facade](native-facade.md)** - Contract layer for accessing device capabilities (share, NFC, haptics) across host shells
|
|
23
31
|
- **[i18n](i18n.md)** - Internationalization and localization
|
|
24
32
|
- **[Liquid Templates](liquid-templates.md)** - Dynamic templating for content generation
|
|
25
33
|
- **[Theme System](theme.system.md)** - Theme configuration and customization
|
|
26
34
|
- **[Theme Defaults](theme-defaults.md)** - Default theme values and presets
|
|
27
35
|
- **[Proof Claiming Methods](proof-claiming-methods.md)** - All methods for claiming/registering product ownership (NFC tags, serial numbers, auto-generated claims)
|
|
36
|
+
- **[Product Facets SDK](PRODUCT_FACETS_SDK.md)** - Admin and public product facet endpoints and TypeScript interfaces
|
|
37
|
+
- **[Attestations](attestations.md)** - Append-only fact log with cryptographic chain integrity, time-series analytics, and public/owner/admin visibility
|
|
38
|
+
- **[Auth Kit](auth-kit.md)** - End-user authentication flows (email/password, magic link, OTP, OAuth) for microapps
|
|
28
39
|
- **[App Data Storage](app-data-storage.md)** - User-specific and collection-scoped app data storage
|
|
40
|
+
- **[Forms](forms.md)** - Platform-managed form definitions, submissions, and schema-driven React form UI
|
|
29
41
|
- **[App Objects: Cases, Threads & Records](app-objects.md)** - Generic app-scoped building blocks for support cases, discussions, bookings, registrations, and more
|
|
42
|
+
- **[App Records Pattern](app-records-pattern.md)** - Canonical pattern for storing per-product, per-facet, or rule-targeted app data
|
|
30
43
|
- **[Communications](comms.md)** - Transactional sends, multi-channel broadcasts, consent management, push registration, and analytics
|
|
31
44
|
- **[Interactions & Event Tracking](interactions.md)** - Log user events, count outcomes, query history, and define interaction types with permissions
|
|
45
|
+
- **[Analytics](analytics.md)** - Web analytics, link-click tracking, QR/tag scan telemetry, and event reporting
|
|
46
|
+
- **[Analytics Metadata Conventions](analytics-metadata-conventions.md)** - Standard recommended keys and conventions for analytics metadata fields
|
|
32
47
|
- **[Loyalty: Points, Members & Earning Rules](loyalty.md)** - Loyalty schemes, automatic point earning via interaction rules, member balances, transaction history, and manual adjustments
|
|
33
48
|
- **[Deep Link Discovery](deep-link-discovery.md)** - Registering and discovering navigable app states for portal menus and AI orchestration
|
|
34
49
|
- **[AI-Native App Manifests](manifests.md)** - How AI workflows discover, configure, and import apps via structured manifests and prose guides
|
|
@@ -2245,28 +2260,71 @@ interface PublicCreateBranch {
|
|
|
2245
2260
|
|
|
2246
2261
|
### asset
|
|
2247
2262
|
|
|
2263
|
+
**AssetRef** (interface)
|
|
2264
|
+
```typescript
|
|
2265
|
+
interface AssetRef {
|
|
2266
|
+
id: string
|
|
2267
|
+
url: string
|
|
2268
|
+
thumbnail: string | null
|
|
2269
|
+
}
|
|
2270
|
+
```
|
|
2271
|
+
|
|
2272
|
+
**AssetVersion** (interface)
|
|
2273
|
+
```typescript
|
|
2274
|
+
interface AssetVersion {
|
|
2275
|
+
url: string
|
|
2276
|
+
mimeType: string | null
|
|
2277
|
+
fileType: string | null
|
|
2278
|
+
size: number | null
|
|
2279
|
+
hash: string | null
|
|
2280
|
+
thumbnail: string | null
|
|
2281
|
+
replacedAt: string
|
|
2282
|
+
replacedBy: string | null
|
|
2283
|
+
}
|
|
2284
|
+
```
|
|
2285
|
+
|
|
2248
2286
|
**Asset** (interface)
|
|
2249
2287
|
```typescript
|
|
2250
2288
|
interface Asset {
|
|
2251
2289
|
id: string
|
|
2290
|
+
collectionId: string
|
|
2291
|
+
site: string
|
|
2292
|
+
productId: string | null
|
|
2293
|
+
proofId: string | null
|
|
2294
|
+
app: string | null
|
|
2252
2295
|
url: string
|
|
2296
|
+
* CDN URL of the WebP thumbnail (max 512px longest edge, no crop).
|
|
2297
|
+
* Always .webp — null until thumbnail generation has run.
|
|
2298
|
+
thumbnail: string | null
|
|
2253
2299
|
name: string
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2300
|
+
cleanName: string | null
|
|
2301
|
+
assetType: 'Image' | 'Video' | 'Audio' | 'Document'
|
|
2302
|
+
fileType: string | null
|
|
2303
|
+
type: string | null
|
|
2304
|
+
mimeType: string | null
|
|
2305
|
+
contentType: string | null
|
|
2306
|
+
size: number | null
|
|
2307
|
+
width: number | null
|
|
2308
|
+
height: number | null
|
|
2309
|
+
hash: string | null
|
|
2310
|
+
labels: string[]
|
|
2311
|
+
metadata: Record<string, any>
|
|
2312
|
+
versions: AssetVersion[]
|
|
2313
|
+
uploadedBy: string | null
|
|
2314
|
+
uploaderContactId: string | null
|
|
2315
|
+
uploadTokenId: string | null
|
|
2316
|
+
uploaderIp: string | null
|
|
2317
|
+
status: 'active' | 'pending_review' | 'deleted'
|
|
2318
|
+
createdAt: string
|
|
2319
|
+
updatedAt: string
|
|
2320
|
+
deletedAt: string | null
|
|
2321
|
+
* @deprecated Use `thumbnail` instead. Legacy multi-size thumbnail map.
|
|
2262
2322
|
thumbnails?: {
|
|
2263
2323
|
x100?: string
|
|
2264
2324
|
x200?: string
|
|
2265
2325
|
x512?: string
|
|
2266
2326
|
[key: string]: string | undefined
|
|
2267
2327
|
}
|
|
2268
|
-
site?: string
|
|
2269
|
-
cleanName?: string
|
|
2270
2328
|
}
|
|
2271
2329
|
```
|
|
2272
2330
|
|
|
@@ -2337,6 +2395,117 @@ interface RemoveAssetOptions {
|
|
|
2337
2395
|
}
|
|
2338
2396
|
```
|
|
2339
2397
|
|
|
2398
|
+
**AdminListAssetsOptions** (interface)
|
|
2399
|
+
```typescript
|
|
2400
|
+
interface AdminListAssetsOptions {
|
|
2401
|
+
collectionId: string
|
|
2402
|
+
productId?: string
|
|
2403
|
+
proofId?: string
|
|
2404
|
+
appId?: string
|
|
2405
|
+
assetType?: 'Image' | 'Video' | 'Audio' | 'Document'
|
|
2406
|
+
labels?: string
|
|
2407
|
+
sort?: 'createdAt' | 'name' | 'size' | 'assetType'
|
|
2408
|
+
order?: 'asc' | 'desc'
|
|
2409
|
+
limit?: number
|
|
2410
|
+
offset?: number
|
|
2411
|
+
}
|
|
2412
|
+
```
|
|
2413
|
+
|
|
2414
|
+
**AdminListAssetsResponse** (interface)
|
|
2415
|
+
```typescript
|
|
2416
|
+
interface AdminListAssetsResponse {
|
|
2417
|
+
data: Asset[]
|
|
2418
|
+
total: number
|
|
2419
|
+
limit: number
|
|
2420
|
+
offset: number
|
|
2421
|
+
}
|
|
2422
|
+
```
|
|
2423
|
+
|
|
2424
|
+
**UpdateAssetOptions** (interface)
|
|
2425
|
+
```typescript
|
|
2426
|
+
interface UpdateAssetOptions {
|
|
2427
|
+
collectionId: string
|
|
2428
|
+
assetId: string
|
|
2429
|
+
name?: string
|
|
2430
|
+
app?: string
|
|
2431
|
+
labels?: string[]
|
|
2432
|
+
metadata?: Record<string, any>
|
|
2433
|
+
thumbnail?: string
|
|
2434
|
+
}
|
|
2435
|
+
```
|
|
2436
|
+
|
|
2437
|
+
**ReplaceAssetFileOptions** (interface)
|
|
2438
|
+
```typescript
|
|
2439
|
+
interface ReplaceAssetFileOptions {
|
|
2440
|
+
collectionId: string
|
|
2441
|
+
assetId: string
|
|
2442
|
+
file: File
|
|
2443
|
+
onProgress?: (percent: number) => void
|
|
2444
|
+
}
|
|
2445
|
+
```
|
|
2446
|
+
|
|
2447
|
+
**DeleteAssetOptions** (interface)
|
|
2448
|
+
```typescript
|
|
2449
|
+
interface DeleteAssetOptions {
|
|
2450
|
+
collectionId: string
|
|
2451
|
+
assetId: string
|
|
2452
|
+
graceDays?: number
|
|
2453
|
+
}
|
|
2454
|
+
```
|
|
2455
|
+
|
|
2456
|
+
**BulkDeleteAssetsOptions** (interface)
|
|
2457
|
+
```typescript
|
|
2458
|
+
interface BulkDeleteAssetsOptions {
|
|
2459
|
+
collectionId: string
|
|
2460
|
+
assetIds: string[]
|
|
2461
|
+
graceDays?: number
|
|
2462
|
+
}
|
|
2463
|
+
```
|
|
2464
|
+
|
|
2465
|
+
**RequestUploadTokenOptions** (interface)
|
|
2466
|
+
```typescript
|
|
2467
|
+
interface RequestUploadTokenOptions {
|
|
2468
|
+
collectionId: string
|
|
2469
|
+
appId: string
|
|
2470
|
+
contactId?: string
|
|
2471
|
+
productId?: string
|
|
2472
|
+
proofId?: string
|
|
2473
|
+
}
|
|
2474
|
+
```
|
|
2475
|
+
|
|
2476
|
+
**UploadTokenPolicy** (interface)
|
|
2477
|
+
```typescript
|
|
2478
|
+
interface UploadTokenPolicy {
|
|
2479
|
+
requireLevel: 'anonymous' | 'contact' | 'owner'
|
|
2480
|
+
allowedMimeTypes: string[]
|
|
2481
|
+
maxFileSizeBytes: number
|
|
2482
|
+
reviewRequired: boolean
|
|
2483
|
+
productId: string | null
|
|
2484
|
+
proofId: string | null
|
|
2485
|
+
}
|
|
2486
|
+
```
|
|
2487
|
+
|
|
2488
|
+
**UploadTokenResponse** (interface)
|
|
2489
|
+
```typescript
|
|
2490
|
+
interface UploadTokenResponse {
|
|
2491
|
+
tokenId: string
|
|
2492
|
+
expiresAt: string
|
|
2493
|
+
policy: UploadTokenPolicy
|
|
2494
|
+
}
|
|
2495
|
+
```
|
|
2496
|
+
|
|
2497
|
+
**PublicTokenUploadOptions** (interface)
|
|
2498
|
+
```typescript
|
|
2499
|
+
interface PublicTokenUploadOptions {
|
|
2500
|
+
collectionId: string
|
|
2501
|
+
tokenId: string
|
|
2502
|
+
file: File
|
|
2503
|
+
name?: string
|
|
2504
|
+
metadata?: Record<string, any>
|
|
2505
|
+
onProgress?: (percent: number) => void
|
|
2506
|
+
}
|
|
2507
|
+
```
|
|
2508
|
+
|
|
2340
2509
|
**AssetResponse** = `Asset`
|
|
2341
2510
|
|
|
2342
2511
|
### attestation
|
|
@@ -3190,22 +3359,8 @@ interface Collection {
|
|
|
3190
3359
|
id: string
|
|
3191
3360
|
title: string
|
|
3192
3361
|
description: string
|
|
3193
|
-
headerImage?:
|
|
3194
|
-
|
|
3195
|
-
thumbnails: {
|
|
3196
|
-
x100: string
|
|
3197
|
-
x200: string
|
|
3198
|
-
x512: string
|
|
3199
|
-
}
|
|
3200
|
-
}
|
|
3201
|
-
logoImage?: {
|
|
3202
|
-
url: string
|
|
3203
|
-
thumbnails: {
|
|
3204
|
-
x100: string
|
|
3205
|
-
x200: string
|
|
3206
|
-
x512: string
|
|
3207
|
-
}
|
|
3208
|
-
}
|
|
3362
|
+
headerImage?: AssetRef | null
|
|
3363
|
+
logoImage?: AssetRef | null
|
|
3209
3364
|
loaderImage?: {
|
|
3210
3365
|
overwriteName: string
|
|
3211
3366
|
name: string
|
|
@@ -6276,37 +6431,6 @@ interface ProductKey {
|
|
|
6276
6431
|
}
|
|
6277
6432
|
```
|
|
6278
6433
|
|
|
6279
|
-
**ProductImageThumbnails** (interface)
|
|
6280
|
-
```typescript
|
|
6281
|
-
interface ProductImageThumbnails {
|
|
6282
|
-
x100?: string
|
|
6283
|
-
x200?: string
|
|
6284
|
-
x512?: string
|
|
6285
|
-
}
|
|
6286
|
-
```
|
|
6287
|
-
|
|
6288
|
-
**ProductImage** (interface)
|
|
6289
|
-
```typescript
|
|
6290
|
-
interface ProductImage {
|
|
6291
|
-
id?: string
|
|
6292
|
-
collectionId?: string
|
|
6293
|
-
productId?: string
|
|
6294
|
-
site?: string
|
|
6295
|
-
name?: string
|
|
6296
|
-
cleanName?: string
|
|
6297
|
-
assetType?: string
|
|
6298
|
-
type?: string
|
|
6299
|
-
url?: string
|
|
6300
|
-
thumbnails?: ProductImageThumbnails
|
|
6301
|
-
contentType?: string
|
|
6302
|
-
size?: string | number
|
|
6303
|
-
hash?: string
|
|
6304
|
-
createdAt?: ISODateString | null
|
|
6305
|
-
updatedAt?: ISODateString | null
|
|
6306
|
-
deletedAt?: ISODateString | null
|
|
6307
|
-
}
|
|
6308
|
-
```
|
|
6309
|
-
|
|
6310
6434
|
**ProductImageUrlInput** (interface)
|
|
6311
6435
|
```typescript
|
|
6312
6436
|
interface ProductImageUrlInput {
|
|
@@ -6378,14 +6502,21 @@ interface ProductWriteInput {
|
|
|
6378
6502
|
name: string
|
|
6379
6503
|
description?: string | null
|
|
6380
6504
|
gtin?: string | null
|
|
6381
|
-
ownGtin?:
|
|
6505
|
+
ownGtin?: string | null
|
|
6382
6506
|
additionalGtins?: AdditionalGtin[]
|
|
6383
6507
|
sku?: string | null
|
|
6508
|
+
schemaType?: string | null
|
|
6384
6509
|
label?: string | null
|
|
6385
6510
|
status?: string | null
|
|
6386
6511
|
sortOrder?: number | null
|
|
6387
|
-
|
|
6512
|
+
* Pass the existing `AssetRef` unchanged to keep the current image,
|
|
6513
|
+
* or a URL string / `{ url }` object to import a new file.
|
|
6514
|
+
heroImage?: AssetRef | ProductImageUrlInput | string | null
|
|
6515
|
+
* Pass existing `AssetRef` entries unchanged; replace entries with a URL string
|
|
6516
|
+
* or `{ url }` object to import new files.
|
|
6517
|
+
additionalImages?: Array<AssetRef | ProductImageUrlInput | string>
|
|
6388
6518
|
facets?: ProductFacetMap
|
|
6519
|
+
tags?: Record<string, boolean>
|
|
6389
6520
|
data?: Record<string, JsonValue>
|
|
6390
6521
|
admin?: Record<string, JsonValue>
|
|
6391
6522
|
extra?: Record<string, JsonValue>
|
|
@@ -7634,6 +7765,33 @@ Get an asset by id within a scope (public)
|
|
|
7634
7765
|
**remove**(options: RemoveAssetOptions) → `Promise<void>`
|
|
7635
7766
|
Remove an asset by id within a scope (admin)
|
|
7636
7767
|
|
|
7768
|
+
**listAdmin**(options: AdminListAssetsOptions) → `Promise<AdminListAssetsResponse>`
|
|
7769
|
+
List assets for a collection with full filtering options.
|
|
7770
|
+
|
|
7771
|
+
**getAdmin**(collectionId: string, assetId: string) → `Promise<Asset>`
|
|
7772
|
+
Get a single asset by ID (admin).
|
|
7773
|
+
|
|
7774
|
+
**updateAdmin**(options: UpdateAssetOptions) → `Promise<Asset>`
|
|
7775
|
+
Update asset metadata (admin). Use `replaceFile` to swap the file.
|
|
7776
|
+
|
|
7777
|
+
**replaceFile**(options: ReplaceAssetFileOptions) → `Promise<Asset>`
|
|
7778
|
+
Replace the file of an existing asset. The previous file URL is snapshotted into `versions[]` on the asset.
|
|
7779
|
+
|
|
7780
|
+
**deleteAdmin**(options: DeleteAssetOptions) → `Promise<`
|
|
7781
|
+
Soft-delete an asset. Schedules CDN purge after `graceDays` (default 30). Recoverable via `restoreAdmin` until purge runs.
|
|
7782
|
+
|
|
7783
|
+
**restoreAdmin**(collectionId: string, assetId: string) → `Promise<Asset>`
|
|
7784
|
+
Restore a soft-deleted asset (clears `deletedAt`).
|
|
7785
|
+
|
|
7786
|
+
**bulkDelete**(options: BulkDeleteAssetsOptions) → `Promise<`
|
|
7787
|
+
Soft-delete multiple assets in one request.
|
|
7788
|
+
|
|
7789
|
+
**requestUploadToken**(options: RequestUploadTokenOptions) → `Promise<UploadTokenResponse>`
|
|
7790
|
+
Request a single-use upload token for a public (unauthenticated) upload. The token encodes the upload policy (allowed types, max size, review requirement). ```typescript const { tokenId, policy } = await asset.requestUploadToken({ collectionId: 'my-collection', appId: 'user-gallery', contactId: contact.id, }) const uploaded = await asset.publicUploadWithToken({ collectionId: 'my-collection', tokenId, file: selectedFile, }) ```
|
|
7791
|
+
|
|
7792
|
+
**publicUploadWithToken**(options: PublicTokenUploadOptions) → `Promise<Asset>`
|
|
7793
|
+
Upload a file using a single-use upload token (no admin auth required). Assets are created with `status: 'pending_review'` when the token policy has `reviewRequired: true`.
|
|
7794
|
+
|
|
7637
7795
|
### async
|
|
7638
7796
|
|
|
7639
7797
|
**enqueueAsyncJob**(collectionId: string,
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
# Assets
|
|
2
|
+
|
|
3
|
+
Reference for asset types, endpoints, and public (token-based) uploads.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Asset object
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
interface Asset {
|
|
11
|
+
// Identity
|
|
12
|
+
id: string // Postgres UUID — stable permanent identifier
|
|
13
|
+
collectionId: string // owning collection
|
|
14
|
+
site: string // alias for collectionId (compat)
|
|
15
|
+
productId: string | null // set when scoped to a product
|
|
16
|
+
proofId: string | null // set when scoped to a proof (ledger entry)
|
|
17
|
+
app: string | null // app that owns this asset, e.g. 'homepage'
|
|
18
|
+
|
|
19
|
+
// File
|
|
20
|
+
url: string // CDN URL of the original file
|
|
21
|
+
thumbnail: string | null // CDN URL of WebP thumbnail (max 512px longest edge, no crop)
|
|
22
|
+
// Always .webp — null until thumbnail generation has run
|
|
23
|
+
name: string // original filename
|
|
24
|
+
cleanName: string | null // filename without extension
|
|
25
|
+
assetType: 'Image' | 'Video' | 'Audio' | 'Document'
|
|
26
|
+
fileType: string | null // file extension, e.g. 'jpg'
|
|
27
|
+
type: string | null // alias for fileType (compat)
|
|
28
|
+
mimeType: string | null // e.g. 'image/jpeg'
|
|
29
|
+
contentType: string | null // alias for mimeType (compat)
|
|
30
|
+
size: number | null // bytes
|
|
31
|
+
width: number | null // pixels (images only)
|
|
32
|
+
height: number | null // pixels (images only)
|
|
33
|
+
hash: string | null // SHA-256 of file content
|
|
34
|
+
|
|
35
|
+
// Organisation
|
|
36
|
+
labels: string[] // arbitrary string labels for filtering
|
|
37
|
+
metadata: Record<string, any>
|
|
38
|
+
versions: AssetVersion[] // previous file versions (populated by replace)
|
|
39
|
+
|
|
40
|
+
// Upload provenance
|
|
41
|
+
uploadedBy: string | null // Firebase UID of admin uploader
|
|
42
|
+
uploaderContactId: string | null // contact ID for public/token uploads
|
|
43
|
+
uploadTokenId: string | null // upload token used (public uploads)
|
|
44
|
+
uploaderIp: string | null
|
|
45
|
+
|
|
46
|
+
// Lifecycle
|
|
47
|
+
status: 'active' | 'pending_review' | 'deleted'
|
|
48
|
+
createdAt: string // ISO 8601
|
|
49
|
+
updatedAt: string
|
|
50
|
+
deletedAt: string | null
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
interface AssetVersion {
|
|
54
|
+
url: string
|
|
55
|
+
mimeType: string | null
|
|
56
|
+
fileType: string | null
|
|
57
|
+
size: number | null
|
|
58
|
+
hash: string | null
|
|
59
|
+
thumbnail: string | null
|
|
60
|
+
replacedAt: string
|
|
61
|
+
replacedBy: string | null
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Thumbnail spec
|
|
66
|
+
|
|
67
|
+
- Format: WebP, quality 82
|
|
68
|
+
- Max 512px on the longest edge — never upscales
|
|
69
|
+
- Fit: `inside` (letterbox, no crop)
|
|
70
|
+
- SVGs are skipped — `thumbnail` stays null
|
|
71
|
+
- URL always ends in `_thumb.webp`
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## AssetRef — slim embedded shape
|
|
76
|
+
|
|
77
|
+
When an asset is referenced inside a product or collection document (e.g. `heroImage`), only three fields are stored to keep documents lean:
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
interface AssetRef {
|
|
81
|
+
id: string // Postgres UUID — use to fetch the full Asset if needed
|
|
82
|
+
url: string // CDN URL of the original file
|
|
83
|
+
thumbnail: string | null // WebP thumbnail URL, or null if not yet generated
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Render the thumbnail wherever a compact preview is needed; fall back to `url` if null:
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
function getHeroImageUrl(product: Product): string | null {
|
|
91
|
+
const ref = product.heroImage
|
|
92
|
+
if (!ref) return null
|
|
93
|
+
return ref.thumbnail ?? ref.url
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Admin endpoints
|
|
100
|
+
|
|
101
|
+
All admin endpoints require authentication. Base path: `/api/admin/collection/:collectionId`
|
|
102
|
+
|
|
103
|
+
### List assets
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
GET /assets
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
| Parameter | Type | Description |
|
|
110
|
+
|-------------|--------|-------------|
|
|
111
|
+
| `productId` | string | Filter to a specific product |
|
|
112
|
+
| `proofId` | string | Filter to a specific proof |
|
|
113
|
+
| `appId` | string | Filter by owning app |
|
|
114
|
+
| `assetType` | string | `Image`, `Video`, `Audio`, `Document` |
|
|
115
|
+
| `labels` | string | Comma-separated label filter (any match) |
|
|
116
|
+
| `sort` | string | `createdAt` (default), `name`, `size`, `assetType` |
|
|
117
|
+
| `order` | string | `desc` (default), `asc` |
|
|
118
|
+
| `limit` | number | Max results (default 50, max 200) |
|
|
119
|
+
| `offset` | number | Pagination offset |
|
|
120
|
+
|
|
121
|
+
**Response:**
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
{ data: Asset[], total: number, limit: number, offset: number }
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**SDK:**
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
const { data, total } = await Api.asset.listAdmin({
|
|
131
|
+
collectionId: 'my-collection',
|
|
132
|
+
assetType: 'Image',
|
|
133
|
+
labels: 'hero,banner',
|
|
134
|
+
limit: 20,
|
|
135
|
+
})
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
### Get asset
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
GET /assets/:assetId
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Returns `Asset` or `404`.
|
|
147
|
+
|
|
148
|
+
**SDK:** `Api.asset.getAdmin(collectionId, assetId)`
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
### Upload asset
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
POST /assets
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Use the existing `Api.asset.upload()` method (file) or `Api.asset.uploadFromUrl()` (URL import).
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
### Update asset metadata
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
PUT /assets/:assetId
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Updates metadata only. Use `/replace` to swap the file.
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
await Api.asset.updateAdmin({
|
|
172
|
+
collectionId: 'my-collection',
|
|
173
|
+
assetId: 'abc123',
|
|
174
|
+
name: 'New display name',
|
|
175
|
+
labels: ['hero', 'featured'],
|
|
176
|
+
metadata: { altText: 'A product photo' },
|
|
177
|
+
})
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
### Replace file
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
POST /assets/:assetId/replace
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Replaces the file; the previous URL is snapshotted into `versions[]`.
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
await Api.asset.replaceFile({
|
|
192
|
+
collectionId: 'my-collection',
|
|
193
|
+
assetId: 'abc123',
|
|
194
|
+
file: newFile,
|
|
195
|
+
onProgress: (pct) => console.log(pct),
|
|
196
|
+
})
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
### Delete asset (soft)
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
DELETE /assets/:assetId?graceDays=30
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Sets `deletedAt` and schedules CDN purge after `graceDays` (default 30). Recoverable until purge.
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
await Api.asset.deleteAdmin({ collectionId: 'my-collection', assetId: 'abc123', graceDays: 7 })
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
### Restore asset
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
POST /assets/:assetId/restore
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Clears `deletedAt`. Asset becomes active again.
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
await Api.asset.restoreAdmin('my-collection', 'abc123')
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
### Bulk delete
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
POST /assets/bulk-delete
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
await Api.asset.bulkDelete({
|
|
237
|
+
collectionId: 'my-collection',
|
|
238
|
+
assetIds: ['abc123', 'def456'],
|
|
239
|
+
graceDays: 14,
|
|
240
|
+
})
|
|
241
|
+
// Returns { deleted: 2 }
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Public (token-based) uploads
|
|
247
|
+
|
|
248
|
+
For anonymous or contact-initiated uploads from the portal — no admin auth required.
|
|
249
|
+
|
|
250
|
+
### 1. Request an upload token
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
const { tokenId, expiresAt, policy } = await Api.asset.requestUploadToken({
|
|
254
|
+
collectionId: 'my-collection',
|
|
255
|
+
appId: 'user-gallery',
|
|
256
|
+
contactId: contact.id, // required when policy requireLevel = 'contact'
|
|
257
|
+
})
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
The `policy` describes what the token allows:
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
interface UploadTokenPolicy {
|
|
264
|
+
requireLevel: 'anonymous' | 'contact' | 'owner'
|
|
265
|
+
allowedMimeTypes: string[]
|
|
266
|
+
maxFileSizeBytes: number
|
|
267
|
+
reviewRequired: boolean // when true, asset is created as 'pending_review'
|
|
268
|
+
productId: string | null
|
|
269
|
+
proofId: string | null
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Tokens are **single-use**, TTL 900 s.
|
|
274
|
+
|
|
275
|
+
### 2. Upload with token
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
const asset = await Api.asset.publicUploadWithToken({
|
|
279
|
+
collectionId: 'my-collection',
|
|
280
|
+
tokenId,
|
|
281
|
+
file: selectedFile,
|
|
282
|
+
onProgress: (pct) => setProgress(pct),
|
|
283
|
+
})
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Assets are created with `status: 'pending_review'` when `reviewRequired: true`. An admin must review and set `status` to `'active'` before the asset appears publicly.
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Writing image fields on products and collections
|
|
291
|
+
|
|
292
|
+
`heroImage`, `additionalImages` (products), `logoImage`, and `headerImage` (collections) all use the slim `AssetRef` shape when read.
|
|
293
|
+
|
|
294
|
+
When writing:
|
|
295
|
+
|
|
296
|
+
- **Pass the `AssetRef` back unchanged** to keep the current image (server detects the UUID and skips re-processing).
|
|
297
|
+
- **Pass a URL string or `{ url }`** to import a new file — the server fetches/registers it and returns the resulting `AssetRef`.
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
// Keep existing image
|
|
301
|
+
await Api.products.update(collectionId, productId, {
|
|
302
|
+
name: 'New name',
|
|
303
|
+
heroImage: product.heroImage, // AssetRef — not re-processed
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
// Import a new image
|
|
307
|
+
await Api.products.update(collectionId, productId, {
|
|
308
|
+
heroImage: 'https://example.com/new-image.jpg',
|
|
309
|
+
})
|
|
310
|
+
```
|
|
@@ -95,9 +95,7 @@ A **Product** represents a type or definition of a physical or digital item. Pro
|
|
|
95
95
|
| `product.gtin` | string | Global Trade Item Number |
|
|
96
96
|
| `product.type` | string | Product type from standard types |
|
|
97
97
|
| `product.heroImage.url` | string | Primary product image URL |
|
|
98
|
-
| `product.heroImage.
|
|
99
|
-
| `product.heroImage.thumbnails.x200` | string | 200px thumbnail |
|
|
100
|
-
| `product.heroImage.thumbnails.x512` | string | 512px thumbnail |
|
|
98
|
+
| `product.heroImage.thumbnail` | string | WebP thumbnail URL (max 512px longest edge), or null if not yet generated |
|
|
101
99
|
| `product.tags` | object | Tag map with boolean values |
|
|
102
100
|
| `product.data` | object | Flexible key-value data map |
|
|
103
101
|
| `product.admin` | object | Admin-only configuration |
|
package/dist/docs/overview.md
CHANGED
|
@@ -48,6 +48,7 @@ The SmartLinks SDK (`@proveanything/smartlinks`) includes comprehensive document
|
|
|
48
48
|
| Topic | File | When to Use |
|
|
49
49
|
|-------|------|-------------|
|
|
50
50
|
| **API Reference** | `docs/API_SUMMARY.md` | Complete SDK function reference, types, error handling |
|
|
51
|
+
| **Assets** | `docs/assets.md` | Asset object, AssetRef, upload, replace, soft-delete, restore, bulk-delete, public token-based uploads |
|
|
51
52
|
| **Building React Components** | `docs/building-react-components.md` | **READ THIS FIRST** — Dual-mode rendering, router rules, useAppContext pattern |
|
|
52
53
|
| **Multi-Page Architecture** | `docs/mpa.md` | Build pipeline, entry points, multi-page setup, content hashing |
|
|
53
54
|
| **AI & Chat** | `docs/ai.md` | Chat completions, RAG, streaming, tool calling, voice, podcasts, TTS |
|