@proveanything/smartlinks 1.4.7 → 1.5.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.
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 1.4.7 | Generated: 2026-02-21T14:49:14.374Z
3
+ Version: 1.5.0 | Generated: 2026-02-23T22:41:17.422Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -33,7 +33,6 @@ The Smartlinks SDK is organized into the following namespaces:
33
33
  - **batch** - Group products into batches; manage serial number ranges and lookups.
34
34
  - **crate** - Organize products in containers/crates for logistics and grouping.
35
35
  - **form** - Build and manage dynamic forms used by apps and workflows.
36
- - **appRecord** - Store and retrieve application-level records tied to a collection.
37
36
  - **appConfiguration** - Read/write app configuration and scoped data (collection/product/proof).
38
37
 
39
38
  — Identity & Access —
@@ -63,6 +62,7 @@ The Smartlinks SDK is organized into the following namespaces:
63
62
  - **serialNumber** - Assign, lookup, and manage serial numbers across scopes.
64
63
 
65
64
  — Other —
65
+ - **appObjects** - Functions for appObjects operations
66
66
  - **async** - Functions for async operations
67
67
  - **attestation** - Functions for attestation operations
68
68
  - **jobs** - Functions for jobs operations
@@ -120,8 +120,9 @@ Returns true if the SDK currently has any auth credential set (bearer token or A
120
120
  persistence?: 'none' | 'indexeddb'
121
121
  persistenceTtlMs?: number
122
122
  serveStaleOnOffline?: boolean
123
+ clearOnPageLoad?: boolean
123
124
  }) → `void`
124
- Configure the SDK's built-in in-memory GET cache. The cache is transparent — it sits inside the HTTP layer and requires no changes to your existing API calls. All GET requests benefit automatically. Per-resource rules (collections/products → 1 h, proofs → 30 s, etc.) override this value. in-memory only (`'none'`, default). Ignored in Node.js. fallback, from the original fetch time (default: 7 days). `SmartlinksOfflineError` with stale data instead of propagating the network error. ```ts // Enable IndexedDB persistence for offline support configureSdkCache({ persistence: 'indexeddb' }) // Disable cache entirely in test environments configureSdkCache({ enabled: false }) ```
125
+ Configure the SDK's built-in in-memory GET cache. The cache is transparent — it sits inside the HTTP layer and requires no changes to your existing API calls. All GET requests benefit automatically. Per-resource rules (collections/products → 1 h, proofs → 30 s, etc.) override this value. in-memory only (`'none'`, default). Ignored in Node.js. fallback, from the original fetch time (default: 7 days). `SmartlinksOfflineError` with stale data instead of propagating the network error. caches on page load/refresh. IndexedDB persists for offline. ```ts // Enable IndexedDB persistence for offline support configureSdkCache({ persistence: 'indexeddb' }) // Disable cache entirely in test environments configureSdkCache({ enabled: false }) // Keep caches across page refreshes (not recommended for production) configureSdkCache({ clearOnPageLoad: false }) ```
125
126
 
126
127
  **invalidateCache**(urlPattern?: string) → `void`
127
128
  Manually invalidate entries in the SDK's GET cache. *contains* this string is removed. Omit (or pass `undefined`) to wipe the entire cache. ```ts invalidateCache() // clear everything invalidateCache('/collection/abc123') // one specific collection invalidateCache('/product/') // all product responses ```
@@ -986,6 +987,330 @@ interface GetCollectionWidgetsOptions {
986
987
  }
987
988
  ```
988
989
 
990
+ ### appObjects
991
+
992
+ **AggregateRequest** (interface)
993
+ ```typescript
994
+ interface AggregateRequest {
995
+ filters?: {
996
+ status?: string
997
+ category?: string // cases only
998
+ record_type?: string // records only
999
+ product_id?: string
1000
+ created_at?: { gte?: string; lte?: string }
1001
+ closed_at?: '__notnull__' | { gte?: string; lte?: string } // cases only
1002
+ expires_at?: { lte?: string } // records only
1003
+ }
1004
+ groupBy?: string[] // see per-resource allowed values
1005
+ metrics?: string[] // see per-resource allowed values below
1006
+ timeSeriesField?: string // e.g. 'created_at'
1007
+ timeSeriesInterval?: 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year'
1008
+ }
1009
+ ```
1010
+
1011
+ **AggregateResponse** (interface)
1012
+ ```typescript
1013
+ interface AggregateResponse {
1014
+ groups?: ({ count: number } & Record<string, unknown>)[]
1015
+ timeSeries?: ({ bucket: string; count: number } & Record<string, unknown>)[]
1016
+ count?: number
1017
+ avg_close_time_seconds?: number
1018
+ p50_close_time_seconds?: number
1019
+ p95_close_time_seconds?: number
1020
+ total_replies?: number
1021
+ avg_replies?: number
1022
+ }
1023
+ ```
1024
+
1025
+ **ListQueryParams** (interface)
1026
+ ```typescript
1027
+ interface ListQueryParams {
1028
+ limit?: number // default 50, max 500
1029
+ offset?: number // default 0
1030
+ sort?: string // field:asc or field:desc
1031
+ includeDeleted?: boolean // admin only
1032
+ status?: string // exact or in:a,b,c
1033
+ productId?: string
1034
+ createdAt?: string // gte:2024-01-01, lte:2024-12-31, or ISO date string
1035
+ updatedAt?: string // same format
1036
+ }
1037
+ ```
1038
+
1039
+ **AppCase** (interface)
1040
+ ```typescript
1041
+ interface AppCase {
1042
+ id: string
1043
+ orgId: string
1044
+ collectionId: string
1045
+ appId: string
1046
+ visibility: Visibility
1047
+ ref: string | null
1048
+ status: string // 'open' | 'resolved' | 'closed' | custom
1049
+ priority: number | null
1050
+ category: string | null
1051
+ assignedTo: string | null // admin zone / admin callers only
1052
+ productId: string | null
1053
+ proofId: string | null
1054
+ contactId: string | null
1055
+ createdAt: string // ISO 8601
1056
+ updatedAt: string
1057
+ closedAt: string | null
1058
+ deletedAt: string | null // admin callers only
1059
+ data: Record<string, unknown> // visible to all roles
1060
+ owner: Record<string, unknown> // visible to owner + admin
1061
+ admin: Record<string, unknown> // visible to admin only
1062
+ }
1063
+ ```
1064
+
1065
+ **CreateCaseInput** (interface)
1066
+ ```typescript
1067
+ interface CreateCaseInput {
1068
+ visibility?: Visibility // default 'owner'
1069
+ ref?: string
1070
+ status?: string // default 'open'
1071
+ priority?: number
1072
+ category?: string
1073
+ assignedTo?: string // admin only
1074
+ productId?: string
1075
+ proofId?: string
1076
+ contactId?: string
1077
+ data?: Record<string, unknown>
1078
+ owner?: Record<string, unknown>
1079
+ admin?: Record<string, unknown> // admin only
1080
+ }
1081
+ ```
1082
+
1083
+ **UpdateCaseInput** (interface)
1084
+ ```typescript
1085
+ interface UpdateCaseInput {
1086
+ data?: Record<string, unknown>
1087
+ owner?: Record<string, unknown>
1088
+ admin?: Record<string, unknown>
1089
+ status?: string
1090
+ priority?: number
1091
+ category?: string
1092
+ assignedTo?: string
1093
+ ref?: string
1094
+ }
1095
+ ```
1096
+
1097
+ **AppendHistoryInput** (interface)
1098
+ ```typescript
1099
+ interface AppendHistoryInput {
1100
+ entry?: Record<string, unknown> // free-form entry object; 'at' is auto-set
1101
+ historyTarget?: 'owner' | 'admin' // which zone receives the entry (default 'admin')
1102
+ status?: string // optionally update status atomically
1103
+ priority?: number
1104
+ assignedTo?: string
1105
+ }
1106
+ ```
1107
+
1108
+ **CaseSummaryRequest** (interface)
1109
+ ```typescript
1110
+ interface CaseSummaryRequest {
1111
+ period?: { from: string; to: string } // ISO 8601 date range
1112
+ }
1113
+ ```
1114
+
1115
+ **CaseSummaryResponse** (interface)
1116
+ ```typescript
1117
+ interface CaseSummaryResponse {
1118
+ total: number
1119
+ byStatus: Record<string, number>
1120
+ byPriority: Record<string, number>
1121
+ trend: { week: string; count: number }[]
1122
+ }
1123
+ ```
1124
+
1125
+ **ReplyEntry** (interface)
1126
+ ```typescript
1127
+ interface ReplyEntry {
1128
+ at: string // ISO 8601, auto-set
1129
+ authorId?: string
1130
+ authorType?: string
1131
+ [key: string]: unknown
1132
+ }
1133
+ ```
1134
+
1135
+ **AppThread** (interface)
1136
+ ```typescript
1137
+ interface AppThread {
1138
+ id: string
1139
+ orgId: string
1140
+ collectionId: string
1141
+ appId: string
1142
+ visibility: Visibility
1143
+ slug: string | null
1144
+ title: string | null
1145
+ status: string // 'open' | 'closed' | custom
1146
+ authorId: string | null
1147
+ authorType: string // default 'user'
1148
+ productId: string | null
1149
+ proofId: string | null
1150
+ contactId: string | null
1151
+ parentType: string | null
1152
+ parentId: string | null
1153
+ replyCount: number
1154
+ lastReplyAt: string | null
1155
+ createdAt: string
1156
+ updatedAt: string
1157
+ deletedAt: string | null // admin only
1158
+ body: Record<string, unknown>
1159
+ replies: ReplyEntry[]
1160
+ tags: string[]
1161
+ data: Record<string, unknown>
1162
+ owner: Record<string, unknown>
1163
+ admin: Record<string, unknown> // admin only
1164
+ }
1165
+ ```
1166
+
1167
+ **CreateThreadInput** (interface)
1168
+ ```typescript
1169
+ interface CreateThreadInput {
1170
+ visibility?: Visibility // default 'owner'
1171
+ slug?: string
1172
+ title?: string
1173
+ status?: string // default 'open'
1174
+ authorId?: string
1175
+ authorType?: string
1176
+ productId?: string
1177
+ proofId?: string
1178
+ contactId?: string
1179
+ parentType?: string
1180
+ parentId?: string
1181
+ body?: Record<string, unknown>
1182
+ tags?: string[]
1183
+ data?: Record<string, unknown>
1184
+ owner?: Record<string, unknown>
1185
+ admin?: Record<string, unknown> // admin only
1186
+ }
1187
+ ```
1188
+
1189
+ **UpdateThreadInput** (interface)
1190
+ ```typescript
1191
+ interface UpdateThreadInput {
1192
+ body?: Record<string, unknown>
1193
+ tags?: string[]
1194
+ data?: Record<string, unknown>
1195
+ owner?: Record<string, unknown>
1196
+ admin?: Record<string, unknown>
1197
+ title?: string
1198
+ slug?: string
1199
+ status?: string
1200
+ visibility?: Visibility
1201
+ }
1202
+ ```
1203
+
1204
+ **ReplyInput** (interface)
1205
+ ```typescript
1206
+ interface ReplyInput {
1207
+ authorId?: string
1208
+ authorType?: string
1209
+ [key: string]: unknown // any extra fields stored on the reply object
1210
+ }
1211
+ ```
1212
+
1213
+ **AppRecord** (interface)
1214
+ ```typescript
1215
+ interface AppRecord {
1216
+ id: string
1217
+ orgId: string
1218
+ collectionId: string
1219
+ appId: string
1220
+ visibility: Visibility
1221
+ recordType: string
1222
+ ref: string | null
1223
+ status: string // default 'active'
1224
+ productId: string | null
1225
+ proofId: string | null
1226
+ contactId: string | null
1227
+ authorId: string | null
1228
+ authorType: string
1229
+ parentType: string | null
1230
+ parentId: string | null
1231
+ createdAt: string
1232
+ updatedAt: string
1233
+ startsAt: string | null
1234
+ expiresAt: string | null
1235
+ deletedAt: string | null // admin only
1236
+ data: Record<string, unknown>
1237
+ owner: Record<string, unknown>
1238
+ admin: Record<string, unknown> // admin only
1239
+ }
1240
+ ```
1241
+
1242
+ **CreateRecordInput** (interface)
1243
+ ```typescript
1244
+ interface CreateRecordInput {
1245
+ recordType: string
1246
+ visibility?: Visibility // default 'owner'
1247
+ ref?: string
1248
+ status?: string // default 'active'
1249
+ productId?: string
1250
+ proofId?: string
1251
+ contactId?: string
1252
+ authorId?: string
1253
+ authorType?: string
1254
+ parentType?: string
1255
+ parentId?: string
1256
+ startsAt?: string // ISO 8601
1257
+ expiresAt?: string
1258
+ data?: Record<string, unknown>
1259
+ owner?: Record<string, unknown>
1260
+ admin?: Record<string, unknown> // admin only
1261
+ }
1262
+ ```
1263
+
1264
+ **UpdateRecordInput** (interface)
1265
+ ```typescript
1266
+ interface UpdateRecordInput {
1267
+ data?: Record<string, unknown>
1268
+ owner?: Record<string, unknown>
1269
+ admin?: Record<string, unknown>
1270
+ status?: string
1271
+ visibility?: Visibility
1272
+ ref?: string
1273
+ recordType?: string
1274
+ startsAt?: string
1275
+ expiresAt?: string
1276
+ }
1277
+ ```
1278
+
1279
+ **RelatedResponse** (interface)
1280
+ ```typescript
1281
+ interface RelatedResponse {
1282
+ threads: AppThread[]
1283
+ records: AppRecord[]
1284
+ }
1285
+ ```
1286
+
1287
+ **PublicCreatePolicy** (interface)
1288
+ ```typescript
1289
+ interface PublicCreatePolicy {
1290
+ cases?: PublicCreateRule
1291
+ threads?: PublicCreateRule
1292
+ records?: PublicCreateRule
1293
+ }
1294
+ ```
1295
+
1296
+ **PublicCreateRule** (interface)
1297
+ ```typescript
1298
+ interface PublicCreateRule {
1299
+ allow: {
1300
+ anonymous?: boolean
1301
+ authenticated?: boolean
1302
+ }
1303
+ enforce?: {
1304
+ anonymous?: Partial<CreateCaseInput | CreateThreadInput | CreateRecordInput>
1305
+ authenticated?: Partial<CreateCaseInput | CreateThreadInput | CreateRecordInput>
1306
+ }
1307
+ }
1308
+ ```
1309
+
1310
+ **Visibility** = `'public' | 'owner' | 'admin'`
1311
+
1312
+ **CallerRole** = `'admin' | 'owner' | 'public'`
1313
+
989
1314
  ### asset
990
1315
 
991
1316
  **Asset** (interface)
@@ -4071,16 +4396,6 @@ Delete a data item by ID within a scope. Requires admin authentication. ```types
4071
4396
  options?: GetCollectionWidgetsOptions) → `Promise<CollectionWidgetsResponse>`
4072
4397
  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 }); ```
4073
4398
 
4074
- ### appRecord
4075
-
4076
- **get**(collectionId: string, appId: string) → `Promise<any>`
4077
-
4078
- **create**(collectionId: string, appId: string, data: any) → `Promise<any>`
4079
-
4080
- **update**(collectionId: string, appId: string, data: any) → `Promise<any>`
4081
-
4082
- **remove**(collectionId: string, appId: string) → `Promise<void>`
4083
-
4084
4399
  ### asset
4085
4400
 
4086
4401
  **upload**(options: UploadAssetOptions) → `Promise<Asset>`
@@ -4389,6 +4704,61 @@ Get all tags/codes assigned to a specific batch. Shows which claim set codes hav
4389
4704
  **appendBulk**(collectionId: string,
4390
4705
  body: BroadcastAppendBulkBody) → `Promise<AppendBulkResult>`
4391
4706
 
4707
+ ### cases
4708
+
4709
+ **create**(collectionId: string,
4710
+ appId: string,
4711
+ input: CreateCaseInput,
4712
+ admin: boolean = false) → `Promise<AppCase>`
4713
+ Create a new case POST /cases
4714
+
4715
+ **list**(collectionId: string,
4716
+ appId: string,
4717
+ params?: CaseListQueryParams,
4718
+ admin: boolean = false) → `Promise<PaginatedResponse<AppCase>>`
4719
+ List cases with optional query parameters GET /cases
4720
+
4721
+ **get**(collectionId: string,
4722
+ appId: string,
4723
+ caseId: string,
4724
+ admin: boolean = false) → `Promise<AppCase>`
4725
+ Get a single case by ID GET /cases/:caseId
4726
+
4727
+ **update**(collectionId: string,
4728
+ appId: string,
4729
+ caseId: string,
4730
+ input: UpdateCaseInput,
4731
+ admin: boolean = false) → `Promise<AppCase>`
4732
+ Update a case PATCH /cases/:caseId Admin can update any field, public (owner) can only update data and owner zones
4733
+
4734
+ **remove**(collectionId: string,
4735
+ appId: string,
4736
+ caseId: string,
4737
+ admin: boolean = false) → `Promise<`
4738
+ Soft delete a case DELETE /cases/:caseId
4739
+
4740
+ **aggregate**(collectionId: string,
4741
+ appId: string,
4742
+ request: AggregateRequest,
4743
+ admin: boolean = false) → `Promise<AggregateResponse>`
4744
+ Get aggregate statistics for cases POST /cases/aggregate
4745
+
4746
+ **summary**(collectionId: string,
4747
+ appId: string,
4748
+ request?: CaseSummaryRequest) → `Promise<CaseSummaryResponse>`
4749
+ Get case summary (admin only) POST /cases/summary
4750
+
4751
+ **appendHistory**(collectionId: string,
4752
+ appId: string,
4753
+ caseId: string,
4754
+ input: AppendHistoryInput) → `Promise<AppCase>`
4755
+ Append an entry to case history (admin only) POST /cases/:caseId/history
4756
+
4757
+ **related**(collectionId: string,
4758
+ appId: string,
4759
+ caseId: string) → `Promise<RelatedResponse>`
4760
+ Get related threads and records for a case (admin only) GET /cases/:caseId/related
4761
+
4392
4762
  ### claimSet
4393
4763
 
4394
4764
  **getAllForCollection**(collectionId: string) → `Promise<any[]>`
@@ -4988,6 +5358,45 @@ Get an Ably token for public (user-scoped) real-time communication. This endpoin
4988
5358
  **getAdminToken**() → `Promise<AblyTokenRequest>`
4989
5359
  Get an Ably token for admin real-time communication. This endpoint returns an Ably TokenRequest that can be used to initialize an Ably client with admin permissions to receive system notifications and alerts. Admin users get subscribe-only (read-only) access to the interaction:{userId} channel pattern. Requires admin authentication (Bearer token). ```ts const tokenRequest = await realtime.getAdminToken() // Use with Ably const ably = new Ably.Realtime.Promise({ authCallback: async (data, callback) => { callback(null, tokenRequest) } }) // Subscribe to admin interaction channel const userId = 'my-user-id' const channel = ably.channels.get(`interaction:${userId}`) await channel.subscribe((message) => { console.log('Admin notification:', message.data) }) ```
4990
5360
 
5361
+ ### records
5362
+
5363
+ **create**(collectionId: string,
5364
+ appId: string,
5365
+ input: CreateRecordInput,
5366
+ admin: boolean = false) → `Promise<AppRecord>`
5367
+ Create a new record POST /records
5368
+
5369
+ **list**(collectionId: string,
5370
+ appId: string,
5371
+ params?: RecordListQueryParams,
5372
+ admin: boolean = false) → `Promise<PaginatedResponse<AppRecord>>`
5373
+ List records with optional query parameters GET /records
5374
+
5375
+ **get**(collectionId: string,
5376
+ appId: string,
5377
+ recordId: string,
5378
+ admin: boolean = false) → `Promise<AppRecord>`
5379
+ Get a single record by ID GET /records/:recordId
5380
+
5381
+ **update**(collectionId: string,
5382
+ appId: string,
5383
+ recordId: string,
5384
+ input: UpdateRecordInput,
5385
+ admin: boolean = false) → `Promise<AppRecord>`
5386
+ Update a record PATCH /records/:recordId Admin can update any field, public (owner) can only update data and owner
5387
+
5388
+ **remove**(collectionId: string,
5389
+ appId: string,
5390
+ recordId: string,
5391
+ admin: boolean = false) → `Promise<`
5392
+ Soft delete a record DELETE /records/:recordId
5393
+
5394
+ **aggregate**(collectionId: string,
5395
+ appId: string,
5396
+ request: AggregateRequest,
5397
+ admin: boolean = false) → `Promise<AggregateResponse>`
5398
+ Get aggregate statistics for records POST /records/aggregate
5399
+
4991
5400
  ### segments
4992
5401
 
4993
5402
  **create**(collectionId: string,
@@ -5096,6 +5505,52 @@ Backward-compat: Public batch lookup (GET) with collectionId parameter (ignored)
5096
5505
  **renderSource**(collectionId: string,
5097
5506
  body: TemplateRenderSourceRequest) → `Promise<TemplateRenderSourceResponse>`
5098
5507
 
5508
+ ### threads
5509
+
5510
+ **create**(collectionId: string,
5511
+ appId: string,
5512
+ input: CreateThreadInput,
5513
+ admin: boolean = false) → `Promise<AppThread>`
5514
+ Create a new thread POST /threads
5515
+
5516
+ **list**(collectionId: string,
5517
+ appId: string,
5518
+ params?: ThreadListQueryParams,
5519
+ admin: boolean = false) → `Promise<PaginatedResponse<AppThread>>`
5520
+ List threads with optional query parameters GET /threads
5521
+
5522
+ **get**(collectionId: string,
5523
+ appId: string,
5524
+ threadId: string,
5525
+ admin: boolean = false) → `Promise<AppThread>`
5526
+ Get a single thread by ID GET /threads/:threadId
5527
+
5528
+ **update**(collectionId: string,
5529
+ appId: string,
5530
+ threadId: string,
5531
+ input: UpdateThreadInput,
5532
+ admin: boolean = false) → `Promise<AppThread>`
5533
+ Update a thread PATCH /threads/:threadId Admin can update any field, public (owner) can only update body, tags, data, owner
5534
+
5535
+ **remove**(collectionId: string,
5536
+ appId: string,
5537
+ threadId: string,
5538
+ admin: boolean = false) → `Promise<`
5539
+ Soft delete a thread DELETE /threads/:threadId
5540
+
5541
+ **reply**(collectionId: string,
5542
+ appId: string,
5543
+ threadId: string,
5544
+ input: ReplyInput,
5545
+ admin: boolean = false) → `Promise<AppThread>`
5546
+ Add a reply to a thread POST /threads/:threadId/reply Atomically appends to replies array, increments replyCount, updates lastReplyAt
5547
+
5548
+ **aggregate**(collectionId: string,
5549
+ appId: string,
5550
+ request: AggregateRequest,
5551
+ admin: boolean = false) → `Promise<AggregateResponse>`
5552
+ Get aggregate statistics for threads POST /threads/aggregate
5553
+
5099
5554
  ### userAppData
5100
5555
 
5101
5556
  **getConfig**(appId: string) → `Promise<any>`