@proveanything/smartlinks 1.5.0 → 1.5.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.
@@ -106,14 +106,14 @@ Each object has a `visibility` field that controls who can access it on **public
106
106
 
107
107
  ```typescript
108
108
  // Public discussion thread
109
- await threads.create(collectionId, appId, {
109
+ await app.threads.create(collectionId, appId, {
110
110
  visibility: 'public',
111
111
  title: 'How do I clean this product?',
112
112
  body: { text: 'Looking for cleaning instructions...' }
113
113
  });
114
114
 
115
115
  // Private support case
116
- await cases.create(collectionId, appId, {
116
+ await app.cases.create(collectionId, appId, {
117
117
  visibility: 'owner', // Only this contact can see it
118
118
  category: 'warranty',
119
119
  data: { issue: 'Defective unit' },
@@ -121,7 +121,7 @@ await cases.create(collectionId, appId, {
121
121
  });
122
122
 
123
123
  // Admin-only internal record
124
- await records.create(collectionId, appId, {
124
+ await app.records.create(collectionId, appId, {
125
125
  visibility: 'admin', // Never appears on public endpoints
126
126
  recordType: 'audit_log',
127
127
  admin: { action: 'manual_refund', amount: 50.00 }
@@ -155,10 +155,10 @@ await records.create(collectionId, appId, {
155
155
  ### Example: Warranty Claims
156
156
 
157
157
  ```typescript
158
- import { cases } from '@proveanything/smartlinks';
158
+ import { app } from '@proveanything/smartlinks';
159
159
 
160
160
  // Customer submits a warranty claim (public endpoint)
161
- const claim = await cases.create(collectionId, appId, {
161
+ const claim = await app.cases.create(collectionId, appId, {
162
162
  visibility: 'owner',
163
163
  category: 'warranty',
164
164
  status: 'open',
@@ -178,7 +178,7 @@ const claim = await cases.create(collectionId, appId, {
178
178
  });
179
179
 
180
180
  // Admin reviews and assigns (admin endpoint)
181
- await cases.update(collectionId, appId, claim.id, {
181
+ await app.cases.update(collectionId, appId, claim.id, {
182
182
  assignedTo: 'user_jane_support',
183
183
  priority: 3, // escalate
184
184
  admin: {
@@ -187,7 +187,7 @@ await cases.update(collectionId, appId, claim.id, {
187
187
  }, true); // admin = true
188
188
 
189
189
  // Admin appends to history
190
- await cases.appendHistory(collectionId, appId, claim.id, {
190
+ await app.cases.appendHistory(collectionId, appId, claim.id, {
191
191
  entry: {
192
192
  action: 'approved_replacement',
193
193
  agent: 'Jane',
@@ -198,7 +198,7 @@ await cases.appendHistory(collectionId, appId, claim.id, {
198
198
  });
199
199
 
200
200
  // Get case summary stats (admin)
201
- const summary = await cases.summary(collectionId, appId, {
201
+ const summary = await app.cases.summary(collectionId, appId, {
202
202
  period: { from: '2026-01-01', to: '2026-02-28' }
203
203
  });
204
204
  // Returns: { total: 142, byStatus: { open: 12, resolved: 130 }, ... }
@@ -209,21 +209,21 @@ const summary = await cases.summary(collectionId, appId, {
209
209
  Build a live support dashboard showing open cases by priority:
210
210
 
211
211
  ```typescript
212
- const openCases = await cases.list(collectionId, appId, {
212
+ const openCases = await app.cases.list(collectionId, appId, {
213
213
  status: 'open',
214
214
  sort: 'priority:desc',
215
215
  limit: 50
216
216
  }, true);
217
217
 
218
218
  // Aggregate by category
219
- const stats = await cases.aggregate(collectionId, appId, {
219
+ const stats = await app.cases.aggregate(collectionId, appId, {
220
220
  filters: { status: 'open' },
221
221
  groupBy: ['category', 'priority'],
222
222
  metrics: ['count']
223
223
  }, true);
224
224
 
225
225
  // Time series: cases created per week
226
- const trend = await cases.aggregate(collectionId, appId, {
226
+ const trend = await app.cases.aggregate(collectionId, appId, {
227
227
  timeSeriesField: 'created_at',
228
228
  timeSeriesInterval: 'week',
229
229
  metrics: ['count']
@@ -257,10 +257,10 @@ const trend = await cases.aggregate(collectionId, appId, {
257
257
  ### Example: Product Q&A
258
258
 
259
259
  ```typescript
260
- import { threads } from '@proveanything/smartlinks';
260
+ import { app } from '@proveanything/smartlinks';
261
261
 
262
262
  // Customer asks a question (public endpoint)
263
- const question = await threads.create(collectionId, appId, {
263
+ const question = await app.threads.create(collectionId, appId, {
264
264
  visibility: 'public',
265
265
  slug: 'how-to-clean-leather',
266
266
  title: 'How do I clean leather without damaging it?',
@@ -275,14 +275,14 @@ const question = await threads.create(collectionId, appId, {
275
275
  });
276
276
 
277
277
  // Another customer replies
278
- await threads.reply(collectionId, appId, question.id, {
278
+ await app.threads.reply(collectionId, appId, question.id, {
279
279
  authorId: otherUser.contactId,
280
280
  authorType: 'customer',
281
281
  text: 'I use a mild soap and water solution. Works great!'
282
282
  });
283
283
 
284
284
  // Admin (brand expert) replies
285
- await threads.reply(collectionId, appId, question.id, {
285
+ await app.threads.reply(collectionId, appId, question.id, {
286
286
  authorId: 'user_expert_sarah',
287
287
  authorType: 'brand_expert',
288
288
  text: 'Our official leather care kit is perfect for this. Avoid harsh chemicals.',
@@ -290,7 +290,7 @@ await threads.reply(collectionId, appId, question.id, {
290
290
  }, true); // admin endpoint
291
291
 
292
292
  // Admin marks as resolved
293
- await threads.update(collectionId, appId, question.id, {
293
+ await app.threads.update(collectionId, appId, question.id, {
294
294
  status: 'resolved'
295
295
  }, true);
296
296
  ```
@@ -301,19 +301,19 @@ List recent discussions with reply counts:
301
301
 
302
302
  ```typescript
303
303
  // Get active threads
304
- const activeThreads = await threads.list(collectionId, appId, {
304
+ const activeThreads = await app.threads.list(collectionId, appId, {
305
305
  status: 'open',
306
306
  sort: 'lastReplyAt:desc',
307
307
  limit: 20
308
308
  });
309
309
 
310
310
  // Filter by tag
311
- const cleaningThreads = await threads.list(collectionId, appId, {
311
+ const cleaningThreads = await app.threads.list(collectionId, appId, {
312
312
  tag: 'cleaning'
313
313
  });
314
314
 
315
315
  // Aggregate: most active discussion topics
316
- const topicStats = await threads.aggregate(collectionId, appId, {
316
+ const topicStats = await app.threads.aggregate(collectionId, appId, {
317
317
  groupBy: ['status'],
318
318
  metrics: ['count', 'reply_count']
319
319
  });
@@ -325,7 +325,7 @@ Attach comments to a specific product:
325
325
 
326
326
  ```typescript
327
327
  // Create a comment thread for a product
328
- await threads.create(collectionId, appId, {
328
+ await app.threads.create(collectionId, appId, {
329
329
  visibility: 'public',
330
330
  parentType: 'product',
331
331
  parentId: product.id,
@@ -335,7 +335,7 @@ await threads.create(collectionId, appId, {
335
335
  });
336
336
 
337
337
  // List all comments for a product
338
- const productComments = await threads.list(collectionId, appId, {
338
+ const productComments = await app.threads.list(collectionId, appId, {
339
339
  parentType: 'product',
340
340
  parentId: product.id,
341
341
  sort: 'createdAt:desc'
@@ -371,10 +371,10 @@ const productComments = await threads.list(collectionId, appId, {
371
371
  ### Example: Product Registration
372
372
 
373
373
  ```typescript
374
- import { records } from '@proveanything/smartlinks';
374
+ import { app } from '@proveanything/smartlinks';
375
375
 
376
376
  // Customer registers a product
377
- const registration = await records.create(collectionId, appId, {
377
+ const registration = await app.records.create(collectionId, appId, {
378
378
  recordType: 'product_registration',
379
379
  visibility: 'owner',
380
380
  status: 'active',
@@ -398,14 +398,14 @@ const registration = await records.create(collectionId, appId, {
398
398
  });
399
399
 
400
400
  // List active registrations for a customer
401
- const activeRegistrations = await records.list(collectionId, appId, {
401
+ const activeRegistrations = await app.records.list(collectionId, appId, {
402
402
  contactId: user.contactId,
403
403
  recordType: 'product_registration',
404
404
  status: 'active'
405
405
  });
406
406
 
407
407
  // Find expiring registrations (admin)
408
- const expiringSoon = await records.list(collectionId, appId, {
408
+ const expiringSoon = await app.records.list(collectionId, appId, {
409
409
  recordType: 'product_registration',
410
410
  expiresAt: `lte:${new Date(Date.now() + 30*24*60*60*1000).toISOString()}` // next 30 days
411
411
  }, true);
@@ -415,7 +415,7 @@ const expiringSoon = await records.list(collectionId, appId, {
415
415
 
416
416
  ```typescript
417
417
  // Customer books a service appointment
418
- const booking = await records.create(collectionId, appId, {
418
+ const booking = await app.records.create(collectionId, appId, {
419
419
  recordType: 'service_appointment',
420
420
  visibility: 'owner',
421
421
  contactId: user.contactId,
@@ -434,7 +434,7 @@ const booking = await records.create(collectionId, appId, {
434
434
  });
435
435
 
436
436
  // Admin assigns technician
437
- await records.update(collectionId, appId, booking.id, {
437
+ await app.records.update(collectionId, appId, booking.id, {
438
438
  data: {
439
439
  serviceType: 'installation',
440
440
  location: 'Customer site',
@@ -448,7 +448,7 @@ await records.update(collectionId, appId, booking.id, {
448
448
 
449
449
  // List today's appointments
450
450
  const today = new Date().toISOString().split('T')[0];
451
- const todaysAppointments = await records.list(collectionId, appId, {
451
+ const todaysAppointments = await app.records.list(collectionId, appId, {
452
452
  recordType: 'service_appointment',
453
453
  startsAt: `gte:${today}T00:00:00Z`,
454
454
  sort: 'startsAt:asc'
@@ -459,7 +459,7 @@ const todaysAppointments = await records.list(collectionId, appId, {
459
459
 
460
460
  ```typescript
461
461
  // Log product usage (could be triggered by IoT device)
462
- await records.create(collectionId, appId, {
462
+ await app.records.create(collectionId, appId, {
463
463
  recordType: 'usage_log',
464
464
  visibility: 'admin',
465
465
  productId: product.id,
@@ -473,7 +473,7 @@ await records.create(collectionId, appId, {
473
473
  }, true);
474
474
 
475
475
  // Aggregate usage metrics
476
- const usageStats = await records.aggregate(collectionId, appId, {
476
+ const usageStats = await app.records.aggregate(collectionId, appId, {
477
477
  filters: {
478
478
  record_type: 'usage_log',
479
479
  created_at: {
@@ -608,7 +608,7 @@ interface AggregateRequest {
608
608
 
609
609
  ```typescript
610
610
  // Average resolution time by category
611
- const metrics = await cases.aggregate(collectionId, appId, {
611
+ const metrics = await app.cases.aggregate(collectionId, appId, {
612
612
  filters: {
613
613
  closed_at: '__notnull__'
614
614
  },
@@ -635,7 +635,7 @@ const metrics = await cases.aggregate(collectionId, appId, {
635
635
 
636
636
  ```typescript
637
637
  // Most active discussion authors
638
- const authorStats = await threads.aggregate(collectionId, appId, {
638
+ const authorStats = await app.threads.aggregate(collectionId, appId, {
639
639
  groupBy: ['author_type'],
640
640
  metrics: ['count', 'reply_count']
641
641
  });
@@ -651,7 +651,7 @@ const authorStats = await threads.aggregate(collectionId, appId, {
651
651
 
652
652
  ```typescript
653
653
  // Bookings by status
654
- const bookingStats = await records.aggregate(collectionId, appId, {
654
+ const bookingStats = await app.records.aggregate(collectionId, appId, {
655
655
  filters: {
656
656
  record_type: 'service_appointment'
657
657
  },
@@ -666,7 +666,7 @@ Generate time-based charts:
666
666
 
667
667
  ```typescript
668
668
  // Cases created per week
669
- const casesTrend = await cases.aggregate(collectionId, appId, {
669
+ const casesTrend = await app.cases.aggregate(collectionId, appId, {
670
670
  timeSeriesField: 'created_at',
671
671
  timeSeriesInterval: 'week',
672
672
  metrics: ['count']
@@ -692,7 +692,7 @@ Cases have a built-in `related()` endpoint to fetch associated threads and recor
692
692
 
693
693
  ```typescript
694
694
  // Get all related content for a case
695
- const related = await cases.related(collectionId, appId, caseId);
695
+ const related = await app.cases.related(collectionId, appId, caseId);
696
696
  // Returns: { threads: [...], records: [...] }
697
697
  ```
698
698
 
@@ -700,14 +700,14 @@ For threads and records, use parent linking:
700
700
 
701
701
  ```typescript
702
702
  // Create a thread about a case
703
- await threads.create(collectionId, appId, {
703
+ await app.threads.create(collectionId, appId, {
704
704
  parentType: 'case',
705
705
  parentId: caseId,
706
706
  body: { text: 'Follow-up discussion about this case' }
707
707
  });
708
708
 
709
709
  // List all threads for a case
710
- const caseThreads = await threads.list(collectionId, appId, {
710
+ const caseThreads = await app.threads.list(collectionId, appId, {
711
711
  parentType: 'case',
712
712
  parentId: caseId
713
713
  });
@@ -719,13 +719,13 @@ Use `parentType` and `parentId` to build hierarchies:
719
719
 
720
720
  ```typescript
721
721
  // Parent record: subscription
722
- const subscription = await records.create(collectionId, appId, {
722
+ const subscription = await app.records.create(collectionId, appId, {
723
723
  recordType: 'subscription',
724
724
  data: { plan: 'premium', billingCycle: 'monthly' }
725
725
  });
726
726
 
727
727
  // Child records: invoices
728
- await records.create(collectionId, appId, {
728
+ await app.records.create(collectionId, appId, {
729
729
  recordType: 'invoice',
730
730
  parentType: 'subscription',
731
731
  parentId: subscription.id,
@@ -733,7 +733,7 @@ await records.create(collectionId, appId, {
733
733
  });
734
734
 
735
735
  // List all invoices for a subscription
736
- const invoices = await records.list(collectionId, appId, {
736
+ const invoices = await app.records.list(collectionId, appId, {
737
737
  recordType: 'invoice',
738
738
  parentType: 'subscription',
739
739
  parentId: subscription.id
@@ -746,7 +746,7 @@ Use admin-only records to log changes:
746
746
 
747
747
  ```typescript
748
748
  async function auditLog(action: string, details: any) {
749
- await records.create(collectionId, appId, {
749
+ await app.records.create(collectionId, appId, {
750
750
  recordType: 'audit_log',
751
751
  visibility: 'admin',
752
752
  authorId: currentUser.id,
@@ -772,10 +772,10 @@ await auditLog('case_reassigned', {
772
772
  Combine with the realtime API to notify users of changes:
773
773
 
774
774
  ```typescript
775
- import { realtime } from '@proveanything/smartlinks';
775
+ import { app, realtime } from '@proveanything/smartlinks';
776
776
 
777
777
  // When a case is updated
778
- await cases.update(collectionId, appId, caseId, { status: 'resolved' }, true);
778
+ await app.cases.update(collectionId, appId, caseId, { status: 'resolved' }, true);
779
779
 
780
780
  // Notify the contact
781
781
  await realtime.publish(collectionId, `contact:${contactId}`, {
@@ -832,10 +832,10 @@ While statuses are free-form strings, consider standard conventions:
832
832
  Here's a full workflow combining all three object types:
833
833
 
834
834
  ```typescript
835
- import { cases, threads, records } from '@proveanything/smartlinks';
835
+ import { app } from '@proveanything/smartlinks';
836
836
 
837
837
  // 1. Customer submits a warranty claim (case)
838
- const claim = await cases.create(collectionId, appId, {
838
+ const claim = await app.cases.create(collectionId, appId, {
839
839
  visibility: 'owner',
840
840
  category: 'warranty',
841
841
  status: 'open',
@@ -848,7 +848,7 @@ const claim = await cases.create(collectionId, appId, {
848
848
  });
849
849
 
850
850
  // 2. Customer starts a discussion about the claim (thread)
851
- const discussion = await threads.create(collectionId, appId, {
851
+ const discussion = await app.threads.create(collectionId, appId, {
852
852
  visibility: 'owner',
853
853
  parentType: 'case',
854
854
  parentId: claim.id,
@@ -857,14 +857,14 @@ const discussion = await threads.create(collectionId, appId, {
857
857
  });
858
858
 
859
859
  // 3. Admin replies to the discussion
860
- await threads.reply(collectionId, appId, discussion.id, {
860
+ await app.threads.reply(collectionId, appId, discussion.id, {
861
861
  authorId: 'admin_sarah',
862
862
  authorType: 'support_agent',
863
863
  text: 'We'll ship a replacement within 2 business days'
864
864
  }, true);
865
865
 
866
866
  // 4. Admin approves and creates a shipping record
867
- const shipment = await records.create(collectionId, appId, {
867
+ const shipment = await app.records.create(collectionId, appId, {
868
868
  recordType: 'shipment',
869
869
  parentType: 'case',
870
870
  parentId: claim.id,
@@ -883,7 +883,7 @@ const shipment = await records.create(collectionId, appId, {
883
883
  }, true);
884
884
 
885
885
  // 5. Admin updates case with history
886
- await cases.appendHistory(collectionId, appId, claim.id, {
886
+ await app.cases.appendHistory(collectionId, appId, claim.id, {
887
887
  entry: {
888
888
  action: 'replacement_shipped',
889
889
  tracking: 'UPS-123456789'
@@ -893,13 +893,13 @@ await cases.appendHistory(collectionId, appId, claim.id, {
893
893
  });
894
894
 
895
895
  // 6. Customer receives item, admin closes case
896
- await cases.update(collectionId, appId, claim.id, {
896
+ await app.cases.update(collectionId, appId, claim.id, {
897
897
  status: 'resolved',
898
898
  admin: { resolvedBy: 'admin_sarah', satisfactionScore: 5 }
899
899
  }, true);
900
900
 
901
901
  // 7. Generate analytics
902
- const monthlyReport = await cases.summary(collectionId, appId, {
902
+ const monthlyReport = await app.cases.summary(collectionId, appId, {
903
903
  period: { from: '2026-02-01', to: '2026-02-28' }
904
904
  });
905
905
  ```
@@ -912,19 +912,19 @@ Import types and functions:
912
912
 
913
913
  ```typescript
914
914
  import {
915
- cases, threads, records,
915
+ app,
916
916
  AppCase, AppThread, AppRecord,
917
917
  CreateCaseInput, CreateThreadInput, CreateRecordInput,
918
918
  PaginatedResponse, AggregateResponse
919
919
  } from '@proveanything/smartlinks';
920
920
 
921
921
  // Fully typed
922
- const newCase: AppCase = await cases.create(collectionId, appId, {
922
+ const newCase: AppCase = await app.cases.create(collectionId, appId, {
923
923
  category: 'support',
924
924
  data: { issue: 'Login problem' }
925
925
  });
926
926
 
927
- const threadList: PaginatedResponse<AppThread> = await threads.list(
927
+ const threadList: PaginatedResponse<AppThread> = await app.threads.list(
928
928
  collectionId,
929
929
  appId,
930
930
  { limit: 50, sort: 'createdAt:desc' }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proveanything/smartlinks",
3
- "version": "1.5.0",
3
+ "version": "1.5.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",