@proveanything/smartlinks 1.0.60 → 1.0.62

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/API_SUMMARY.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 1.0.60 | Generated: 2025-12-10T13:55:07.921Z
3
+ Version: 1.0.62 | Generated: 2025-12-17T18:11:04.911Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -19,6 +19,7 @@ The Smartlinks SDK is organized into the following namespaces:
19
19
  - **claimSet** - Claim creation, management, and verification
20
20
  - **collection** - Collection CRUD operations and management
21
21
  - **comms** - Functions for comms operations
22
+ - **contact** - Functions for contact operations
22
23
  - **crate** - Container/crate management for organizing products
23
24
  - **form** - Dynamic form creation and submission
24
25
  - **nfc** - Functions for nfc operations
@@ -65,6 +66,11 @@ Internal helper that performs a POST request to `${baseURL}${path}`, injecting h
65
66
  extraHeaders?: Record<string, string>) → `Promise<T>`
66
67
  Internal helper that performs a PUT request to `${baseURL}${path}`, injecting headers for apiKey or bearerToken if present. If body is FormData, Content-Type is not set. Returns the parsed JSON as T, or throws an Error.
67
68
 
69
+ **patch**(path: string,
70
+ body: any,
71
+ extraHeaders?: Record<string, string>) → `Promise<T>`
72
+ Internal helper that performs a PATCH request to `${baseURL}${path}`, injecting headers for apiKey or bearerToken if present. If body is FormData, Content-Type is not set. Returns the parsed JSON as T, or throws an Error.
73
+
68
74
  **requestWithOptions**(path: string,
69
75
  options: RequestInit) → `Promise<T>`
70
76
  Internal helper that performs a request to `${baseURL}${path}` with custom options, injecting headers for apiKey or bearerToken if present. Returns the parsed JSON as T, or throws an Error.
@@ -108,29 +114,29 @@ interface AssetResponse {
108
114
  **AttestationResponse** (interface)
109
115
  ```typescript
110
116
  interface AttestationResponse {
111
- id: string // Attestation id
112
- createdAt: string // Creation timestamp
113
- updatedAt: string // Last updated timestamp
114
- public: Record<string, any> // Public attestation data
115
- private: Record<string, any> // Private attestation data
116
- proof: Record<string, any> // Associated proof reference/data
117
+ id: string
118
+ createdAt: string
119
+ updatedAt: string
120
+ public: Record<string, any>
121
+ private: Record<string, any>
122
+ proof: Record<string, any>
117
123
  }
118
124
  ```
119
125
 
120
126
  **AttestationCreateRequest** (interface)
121
127
  ```typescript
122
128
  interface AttestationCreateRequest {
123
- public: Record<string, any> // Public attestation payload
124
- private: Record<string, any> // Private attestation payload
125
- proof: Record<string, any> // Proof linkage or payload
129
+ public: Record<string, any>
130
+ private: Record<string, any>
131
+ proof: Record<string, any>
126
132
  }
127
133
  ```
128
134
 
129
135
  **AttestationUpdateRequest** (interface)
130
136
  ```typescript
131
137
  interface AttestationUpdateRequest {
132
- type?: string // Update operation/type
133
- data?: Record<string, any> // Partial attestation data
138
+ type?: string
139
+ data?: Record<string, any>
134
140
  }
135
141
  ```
136
142
 
@@ -138,14 +144,21 @@ interface AttestationUpdateRequest {
138
144
 
139
145
  **UserAccountRegistrationRequest** (type)
140
146
  ```typescript
141
- type UserAccountRegistrationRequest = {
142
- name: string // User's display name
143
- email?: string // Optional user email
144
- phone?: string // Optional user phone number
145
- password?: string // Optional password for email login
146
- sendAccountConfirmation?: boolean // Send confirmation email after registration
147
- collectionId?: string, // Optional collection context for registration
148
- tokenType?: 'bearer' | 'firebase' // Desired token type returned
147
+ type UserAccountRegistrationRequest = {
148
+ /** User's display name */
149
+ name: string
150
+ /** Optional user email */
151
+ email?: string
152
+ /** Optional user phone number */
153
+ phone?: string
154
+ /** Optional password for email login */
155
+ password?: string
156
+ /** Send confirmation email after registration */
157
+ sendAccountConfirmation?: boolean
158
+ /** Optional collection context for registration */
159
+ collectionId?: string,
160
+ /** Desired token type returned */
161
+ tokenType?: 'bearer' | 'firebase'
149
162
  }
150
163
  ```
151
164
 
@@ -320,30 +333,30 @@ interface AuthKitConfig {
320
333
  **ClaimCodeRef** (interface)
321
334
  ```typescript
322
335
  interface ClaimCodeRef {
323
- codeId: string // Identifier of the code (e.g., tag or QR code)
324
- claimId: string // Identifier of the claim within the claim set
336
+ codeId: string
337
+ claimId: string
325
338
  }
326
339
  ```
327
340
 
328
341
  **UpdateClaimDataRequest** (interface)
329
342
  ```typescript
330
343
  interface UpdateClaimDataRequest {
331
- data: Record<string, any> // Arbitrary key/value pairs for the claim data update
332
- codes: ClaimCodeRef[] // Array of code+claim references affected by this update
344
+ data: Record<string, any>
345
+ codes: ClaimCodeRef[]
333
346
  }
334
347
  ```
335
348
 
336
349
  **AssignClaimsRequest** (interface)
337
350
  ```typescript
338
351
  interface AssignClaimsRequest {
339
- id: string // The claim set ID (required)
340
- collectionId: string // The collection ID (required)
341
- productId: string // The product ID (required)
342
- batchId?: string // Optional batch identifier
343
- start?: number // Optional start index for bulk assignment
344
- end?: number // Optional end index for bulk assignment
345
- codeId?: string // Optional single code identifier for single assignment
346
- data?: Record<string, any> // Optional key/value pairs to set on the claim
352
+ id: string
353
+ collectionId: string
354
+ productId: string
355
+ batchId?: string
356
+ start?: number
357
+ end?: number
358
+ codeId?: string
359
+ data?: Record<string, any>
347
360
  }
348
361
  ```
349
362
 
@@ -352,35 +365,35 @@ interface AssignClaimsRequest {
352
365
  **CollectionResponse** (interface)
353
366
  ```typescript
354
367
  interface CollectionResponse {
355
- id: string // Unique identifier for the collection
356
- title: string // Human-readable title of the collection
357
- description: string // Description of collection
368
+ id: string
369
+ title: string
370
+ description: string
358
371
  headerImage?: {
359
- url: string // URL to the asset
360
- thumbnails: { // Thumbnail URLs in different sizes
372
+ url: string
373
+ thumbnails: {
361
374
  x100: string
362
375
  x200: string
363
376
  x512: string
364
377
  }
365
378
  }
366
379
  logoImage?: {
367
- url: string // URL to the asset
368
- thumbnails: { // Thumbnail URLs in different sizes
380
+ url: string
381
+ thumbnails: {
369
382
  x100: string
370
383
  x200: string
371
384
  x512: string
372
385
  }
373
386
  }
374
387
  loaderImage?: {
375
- overwriteName: string // Override name for the file
376
- name: string // Name of the asset
377
- type: string // File type/extension
378
- url: string // URL to the asset
388
+ overwriteName: string
389
+ name: string
390
+ type: string
391
+ url: string
379
392
  }
380
393
  languages?: {
381
- code: string // Language code (e.g., "fr", "it", "es")
382
- lang: string // Human-readable language name (e.g., "French", "Italian")
383
- supported: boolean // Whether this language is supported
394
+ code: string
395
+ lang: string
396
+ supported: boolean
384
397
  }[],
385
398
  roles: {
386
399
  [userId: string]: string
@@ -397,25 +410,25 @@ interface CollectionResponse {
397
410
  **NotificationSubjectTarget** (interface)
398
411
  ```typescript
399
412
  interface NotificationSubjectTarget {
400
- type: 'product' | 'collection' | 'user' | 'batch' | 'proof' // Type of target entity
401
- id: string // ID of the target entity
413
+ type: 'product' | 'collection' | 'user' | 'batch' | 'proof'
414
+ id: string
402
415
  }
403
416
  ```
404
417
 
405
418
  **PushNotificationTemplate** (interface)
406
419
  ```typescript
407
420
  interface PushNotificationTemplate {
408
- title: string // Notification title
409
- body: string // Notification body text
410
- icon?: string // Optional icon URL for the notification
421
+ title: string
422
+ body: string
423
+ icon?: string
411
424
  }
412
425
  ```
413
426
 
414
427
  **EmailNotificationTemplate** (interface)
415
428
  ```typescript
416
429
  interface EmailNotificationTemplate {
417
- subject: string // Email subject line
418
- body: string // Email body content (plain text or HTML)
430
+ subject: string
431
+ body: string
419
432
  }
420
433
  ```
421
434
 
@@ -423,9 +436,9 @@ interface EmailNotificationTemplate {
423
436
  ```typescript
424
437
  interface WalletUpdateTemplate {
425
438
  textModulesData?: Array<{
426
- id: string // Module ID
427
- header: string // Module header text
428
- body: string // Module body text
439
+ id: string
440
+ header: string
441
+ body: string
429
442
  }>
430
443
  }
431
444
  ```
@@ -433,42 +446,42 @@ interface WalletUpdateTemplate {
433
446
  **NotificationTemplate** (interface)
434
447
  ```typescript
435
448
  interface NotificationTemplate {
436
- push?: PushNotificationTemplate // Push notification content
437
- email?: EmailNotificationTemplate // Email notification content
438
- walletUpdate?: WalletUpdateTemplate // Wallet pass update content
449
+ push?: PushNotificationTemplate
450
+ email?: EmailNotificationTemplate
451
+ walletUpdate?: WalletUpdateTemplate
439
452
  }
440
453
  ```
441
454
 
442
455
  **SendNotificationRequest** (interface)
443
456
  ```typescript
444
457
  interface SendNotificationRequest {
445
- subjectTargets: NotificationSubjectTarget[] // Target subjects that should receive the notification
446
- severity: 'low' | 'normal' | 'important' | 'critical' // Severity level of the notification
447
- mode: 'preferred' | 'all' // Delivery channel mode preference
448
- channels : ("push" | "email" | "wallet")[] // Specific channels to use for delivery
449
- template: NotificationTemplate // Notification content templates for different delivery methods
458
+ subjectTargets: NotificationSubjectTarget[]
459
+ severity: 'low' | 'normal' | 'important' | 'critical'
460
+ mode: 'preferred' | 'all'
461
+ channels : ("push" | "email" | "wallet")[]
462
+ template: NotificationTemplate
450
463
  }
451
464
  ```
452
465
 
453
466
  **SendNotificationResponse** (interface)
454
467
  ```typescript
455
468
  interface SendNotificationResponse {
456
- ok: boolean // Whether the request was accepted
457
- notificationId: string // Unique ID for this notification
458
- counts: { // Basic counts for contacts and attempts
469
+ ok: boolean
470
+ notificationId: string
471
+ counts: {
459
472
  contacts: number
460
473
  attempts: number
461
474
  }
462
- status: { // Detailed status for the notification
475
+ status: {
463
476
  notification: {
464
- notificationId: string // The notification ID (repeated for convenience)
465
- state: 'queued' | 'sent' | 'failed' | 'confirmed' | string // Current processing state
466
- subjectTargets: NotificationSubjectTarget[] // Targets this notification refers to
467
- severity: 'low' | 'normal' | 'important' | 'critical' | string // Severity of this notification
468
- channelsOverride: Record<string, any> // Optional channel overrides used when sending
469
- template: NotificationTemplate // The effective template used
477
+ notificationId: string
478
+ state: 'queued' | 'sent' | 'failed' | 'confirmed' | string
479
+ subjectTargets: NotificationSubjectTarget[]
480
+ severity: 'low' | 'normal' | 'important' | 'critical' | string
481
+ channelsOverride: Record<string, any>
482
+ template: NotificationTemplate
470
483
  }
471
- totals: { // Totals across all contacts
484
+ totals: {
472
485
  queued: number
473
486
  sent: number
474
487
  failed: number
@@ -478,6 +491,66 @@ interface SendNotificationResponse {
478
491
  }
479
492
  ```
480
493
 
494
+ ### contact
495
+
496
+ **ContactResponse** (interface)
497
+ ```typescript
498
+ interface ContactResponse {
499
+ contactId: string
500
+ orgId: string
501
+ firstName: string | null
502
+ lastName: string | null
503
+ displayName: string | null
504
+ company: string | null
505
+ email: string | null
506
+ phone: string | null
507
+ emails?: string[]
508
+ phones?: string[]
509
+ customFields: ContactCustomFields
510
+ createdAt: string
511
+ updatedAt: string
512
+ deletedAt: string | null
513
+ erasedAt: string | null
514
+ }
515
+ ```
516
+
517
+ **ContactCreateRequest** (interface)
518
+ ```typescript
519
+ interface ContactCreateRequest {
520
+ firstName?: string | null
521
+ lastName?: string | null
522
+ displayName?: string | null
523
+ company?: string | null
524
+ email?: string | null
525
+ phone?: string | null
526
+ customFields?: ContactCustomFields
527
+ }
528
+ ```
529
+
530
+ **ContactUpdateRequest** (interface)
531
+ ```typescript
532
+ interface ContactUpdateRequest {
533
+ firstName?: string | null
534
+ lastName?: string | null
535
+ displayName?: string | null
536
+ company?: string | null
537
+ email?: string | null
538
+ phone?: string | null
539
+ customFields?: ContactCustomFields
540
+ }
541
+ ```
542
+
543
+ **ContactListResponse** (interface)
544
+ ```typescript
545
+ interface ContactListResponse {
546
+ items: ContactResponse[]
547
+ limit: number
548
+ offset: number
549
+ }
550
+ ```
551
+
552
+ **ContactCustomFields** = `Record<string, any>`
553
+
481
554
  ### error
482
555
 
483
556
  **ErrorResponse** (interface)
@@ -552,15 +625,15 @@ interface NfcClaimTagRequest {
552
625
  **ProductResponse** (interface)
553
626
  ```typescript
554
627
  interface ProductResponse {
555
- id: string // Unique identifier for the product
556
- name: string // Name of the product
557
- collectionId: string // Unique identifier for the product's collection
558
- description: string // Detailed description of the product
559
- gtin?: string // A product GTIN (Global Trade Item Number)
560
- type?: string // An optional product type from the standard smartlinks types
628
+ id: string
629
+ name: string
630
+ collectionId: string
631
+ description: string
632
+ gtin?: string
633
+ type?: string
561
634
  heroImage: {
562
- url: string // URL to the asset
563
- thumbnails: { // Thumbnail URLs in different sizes
635
+ url: string
636
+ thumbnails: {
564
637
  x100: string
565
638
  x200: string
566
639
  x512: string
@@ -584,15 +657,15 @@ interface ProductResponse {
584
657
  **ProofResponse** (interface)
585
658
  ```typescript
586
659
  interface ProofResponse {
587
- collectionId: string // Unique identifier for the collection
588
- createdAt: string // Creation timestamp
589
- id: string // Unique identifier for the proof
590
- productId: string // Unique identifier for the product
591
- tokenId: string // Unique identifier for the token
592
- userId: string // Unique identifier for the user
593
- claimable: boolean // Is this proof available to be claimed
594
- transient: boolean // Is this proof transient
595
- values: Record<string, any> // Arbitrary key-value pairs for proof values
660
+ collectionId: string
661
+ createdAt: string
662
+ id: string
663
+ productId: string
664
+ tokenId: string
665
+ userId: string
666
+ claimable?: boolean
667
+ transient?: boolean
668
+ values: Record<string, any>
596
669
  }
597
670
  ```
598
671
 
@@ -1082,6 +1155,31 @@ Assign a value to a serial number for a collection (admin only).
1082
1155
  request: SendNotificationRequest) → `Promise<SendNotificationResponse>`
1083
1156
  Send a notification to specified targets within a collection. Supports multiple delivery methods including push notifications, email, and wallet pass updates. The notification will be delivered based on user preferences and the specified delivery mode. ```typescript const result = await comms.sendNotification('my-collection', { subjectTargets: [{ type: 'product', id: 'prod_123' }], severity: 'important', mode: 'preferred', template: { push: { title: 'Update available', body: 'We\'ve shipped an important update.', icon: 'https://cdn.example.com/brand/logo-128.png' }, email: { subject: 'Important update for your product', body: 'There\'s an important update. Open your pass or profile to learn more.' }, walletUpdate: { textModulesData: [ { id: 'notice', header: 'Update', body: 'Open your wallet pass for details.' } ] } } }) if (result.ok) { console.log('Notification queued:', result.notificationId) console.log('Totals:', result.status.totals) } ```
1084
1157
 
1158
+ ### contact
1159
+
1160
+ **create**(collectionId: string, data: ContactCreateRequest) → `Promise<ContactResponse>`
1161
+
1162
+ **list**(collectionId: string,
1163
+ params?: { limit?: number; offset?: number; includeDeleted?: boolean }) → `Promise<ContactListResponse>`
1164
+
1165
+ **get**(collectionId: string,
1166
+ contactId: string,
1167
+ params?: { includeDeleted?: boolean }) → `Promise<ContactResponse>`
1168
+
1169
+ **update**(collectionId: string,
1170
+ contactId: string,
1171
+ data: ContactUpdateRequest) → `Promise<ContactResponse>`
1172
+
1173
+ **remove**(collectionId: string, contactId: string) → `Promise<void>`
1174
+
1175
+ **lookup**(collectionId: string,
1176
+ params: { email?: string; phone?: string }) → `Promise<ContactResponse>`
1177
+
1178
+ **upsert**(collectionId: string,
1179
+ data: ContactCreateRequest) → `Promise<ContactResponse>`
1180
+
1181
+ **erase**(collectionId: string, contactId: string, body?: any) → `Promise<ContactResponse>`
1182
+
1085
1183
  ### crate
1086
1184
 
1087
1185
  **get**(collectionId: string, crateId: string) → `Promise<any>`
@@ -0,0 +1,20 @@
1
+ import { ContactResponse, ContactCreateRequest, ContactUpdateRequest, ContactListResponse } from "../types/contact";
2
+ export declare namespace contact {
3
+ function create(collectionId: string, data: ContactCreateRequest): Promise<ContactResponse>;
4
+ function list(collectionId: string, params?: {
5
+ limit?: number;
6
+ offset?: number;
7
+ includeDeleted?: boolean;
8
+ }): Promise<ContactListResponse>;
9
+ function get(collectionId: string, contactId: string, params?: {
10
+ includeDeleted?: boolean;
11
+ }): Promise<ContactResponse>;
12
+ function update(collectionId: string, contactId: string, data: ContactUpdateRequest): Promise<ContactResponse>;
13
+ function remove(collectionId: string, contactId: string): Promise<void>;
14
+ function lookup(collectionId: string, params: {
15
+ email?: string;
16
+ phone?: string;
17
+ }): Promise<ContactResponse>;
18
+ function upsert(collectionId: string, data: ContactCreateRequest): Promise<ContactResponse>;
19
+ function erase(collectionId: string, contactId: string, body?: any): Promise<ContactResponse>;
20
+ }
@@ -0,0 +1,61 @@
1
+ import { request, post, del, patch } from "../http";
2
+ export var contact;
3
+ (function (contact) {
4
+ async function create(collectionId, data) {
5
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/crm/contacts`;
6
+ return post(path, data);
7
+ }
8
+ contact.create = create;
9
+ async function list(collectionId, params) {
10
+ const query = new URLSearchParams();
11
+ if ((params === null || params === void 0 ? void 0 : params.limit) !== undefined)
12
+ query.set("limit", String(params.limit));
13
+ if ((params === null || params === void 0 ? void 0 : params.offset) !== undefined)
14
+ query.set("offset", String(params.offset));
15
+ if ((params === null || params === void 0 ? void 0 : params.includeDeleted) !== undefined)
16
+ query.set("includeDeleted", String(params.includeDeleted));
17
+ const qs = query.toString();
18
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/crm/contacts${qs ? `?${qs}` : ""}`;
19
+ return request(path);
20
+ }
21
+ contact.list = list;
22
+ async function get(collectionId, contactId, params) {
23
+ const query = new URLSearchParams();
24
+ if ((params === null || params === void 0 ? void 0 : params.includeDeleted) !== undefined)
25
+ query.set("includeDeleted", String(params.includeDeleted));
26
+ const qs = query.toString();
27
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/crm/contacts/${encodeURIComponent(contactId)}${qs ? `?${qs}` : ""}`;
28
+ return request(path);
29
+ }
30
+ contact.get = get;
31
+ async function update(collectionId, contactId, data) {
32
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/crm/contacts/${encodeURIComponent(contactId)}`;
33
+ return patch(path, data);
34
+ }
35
+ contact.update = update;
36
+ async function remove(collectionId, contactId) {
37
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/crm/contacts/${encodeURIComponent(contactId)}`;
38
+ return del(path);
39
+ }
40
+ contact.remove = remove;
41
+ async function lookup(collectionId, params) {
42
+ const query = new URLSearchParams();
43
+ if (params.email)
44
+ query.set("email", params.email);
45
+ if (params.phone)
46
+ query.set("phone", params.phone);
47
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/crm/contacts/lookup?${query.toString()}`;
48
+ return request(path);
49
+ }
50
+ contact.lookup = lookup;
51
+ async function upsert(collectionId, data) {
52
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/crm/contacts:upsert`;
53
+ return post(path, data);
54
+ }
55
+ contact.upsert = upsert;
56
+ async function erase(collectionId, contactId, body) {
57
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/crm/contacts/${encodeURIComponent(contactId)}/erase`;
58
+ return post(path, body || {});
59
+ }
60
+ contact.erase = erase;
61
+ })(contact || (contact = {}));
package/dist/http.d.ts CHANGED
@@ -43,6 +43,13 @@ export declare function post<T>(path: string, body: any, extraHeaders?: Record<s
43
43
  * Returns the parsed JSON as T, or throws an Error.
44
44
  */
45
45
  export declare function put<T>(path: string, body: any, extraHeaders?: Record<string, string>): Promise<T>;
46
+ /**
47
+ * Internal helper that performs a PATCH request to `${baseURL}${path}`,
48
+ * injecting headers for apiKey or bearerToken if present.
49
+ * If body is FormData, Content-Type is not set.
50
+ * Returns the parsed JSON as T, or throws an Error.
51
+ */
52
+ export declare function patch<T>(path: string, body: any, extraHeaders?: Record<string, string>): Promise<T>;
46
53
  /**
47
54
  * Internal helper that performs a request to `${baseURL}${path}` with custom options,
48
55
  * injecting headers for apiKey or bearerToken if present.
package/dist/http.js CHANGED
@@ -68,7 +68,7 @@ function safeBodyPreview(body) {
68
68
  * @property {string} [options.bearerToken] - (Optional) Bearer token for AUTHORIZATION header
69
69
  * @property {boolean} [options.proxyMode] - (Optional) Tells the API that it is running in an iframe via parent proxy
70
70
  */
71
- import { enableAutoIframeResize, isIframe } from './iframe';
71
+ import { iframe } from './iframe';
72
72
  export function initializeApi(options) {
73
73
  // Normalize baseURL by removing trailing slashes.
74
74
  baseURL = options.baseURL.replace(/\/+$/g, "");
@@ -83,8 +83,8 @@ export function initializeApi(options) {
83
83
  : inferredNgrok;
84
84
  extraHeadersGlobal = options.extraHeaders ? Object.assign({}, options.extraHeaders) : {};
85
85
  // Auto-enable iframe resize unless explicitly disabled
86
- if (isIframe() && options.iframeAutoResize !== false) {
87
- enableAutoIframeResize();
86
+ if (iframe.isIframe() && options.iframeAutoResize !== false) {
87
+ iframe.enableAutoIframeResize();
88
88
  }
89
89
  logger = options.logger;
90
90
  logDebug('[smartlinks] initializeApi', {
@@ -93,7 +93,7 @@ export function initializeApi(options) {
93
93
  inferredNgrok,
94
94
  ngrokSkipBrowserWarning,
95
95
  extraHeaders: Object.keys(extraHeadersGlobal),
96
- iframeAutoResizeEnabled: isIframe() && options.iframeAutoResize !== false,
96
+ iframeAutoResizeEnabled: iframe.isIframe() && options.iframeAutoResize !== false,
97
97
  });
98
98
  }
99
99
  /** Enable/disable automatic "ngrok-skip-browser-warning" header. */
@@ -292,6 +292,53 @@ export async function put(path, body, extraHeaders) {
292
292
  }
293
293
  return (await response.json());
294
294
  }
295
+ /**
296
+ * Internal helper that performs a PATCH request to `${baseURL}${path}`,
297
+ * injecting headers for apiKey or bearerToken if present.
298
+ * If body is FormData, Content-Type is not set.
299
+ * Returns the parsed JSON as T, or throws an Error.
300
+ */
301
+ export async function patch(path, body, extraHeaders) {
302
+ if (proxyMode) {
303
+ logDebug('[smartlinks] PATCH via proxy', { path, body: safeBodyPreview(body) });
304
+ return proxyRequest("PATCH", path, body, extraHeaders);
305
+ }
306
+ if (!baseURL) {
307
+ throw new Error("HTTP client is not initialized. Call initializeApi(...) first.");
308
+ }
309
+ const url = `${baseURL}${path}`;
310
+ const headers = extraHeaders ? Object.assign({}, extraHeaders) : {};
311
+ if (apiKey)
312
+ headers["X-API-Key"] = apiKey;
313
+ if (bearerToken)
314
+ headers["AUTHORIZATION"] = `Bearer ${bearerToken}`;
315
+ if (ngrokSkipBrowserWarning)
316
+ headers["ngrok-skip-browser-warning"] = "true";
317
+ for (const [k, v] of Object.entries(extraHeadersGlobal))
318
+ if (!(k in headers))
319
+ headers[k] = v;
320
+ // Only set Content-Type for non-FormData bodies
321
+ if (!(body instanceof FormData)) {
322
+ headers["Content-Type"] = "application/json";
323
+ }
324
+ logDebug('[smartlinks] PATCH fetch', { url, headers: redactHeaders(headers), body: safeBodyPreview(body) });
325
+ const response = await fetch(url, {
326
+ method: "PATCH",
327
+ headers,
328
+ body: body instanceof FormData ? body : JSON.stringify(body),
329
+ });
330
+ logDebug('[smartlinks] PATCH response', { url, status: response.status, ok: response.ok });
331
+ if (!response.ok) {
332
+ try {
333
+ const errBody = (await response.json());
334
+ throw new Error(`Error ${errBody.code}: ${errBody.message}`);
335
+ }
336
+ catch (_a) {
337
+ throw new Error(`Request to ${url} failed with status ${response.status}`);
338
+ }
339
+ }
340
+ return (await response.json());
341
+ }
295
342
  /**
296
343
  * Internal helper that performs a request to `${baseURL}${path}` with custom options,
297
344
  * injecting headers for apiKey or bearerToken if present.
package/dist/iframe.d.ts CHANGED
@@ -1,25 +1,27 @@
1
- interface IframeResizeOptions {
2
- /** Minimum ms between height postMessages (default 100). */
3
- intervalMs?: number;
4
- /** Post even if height unchanged (default false). */
5
- alwaysSend?: boolean;
6
- /** Additional payload properties to include with each resize message. */
7
- extra?: Record<string, any>;
8
- /** Custom message type name (default 'smartlinks:resize'). */
9
- messageType?: string;
1
+ export declare namespace iframe {
2
+ interface IframeResizeOptions {
3
+ /** Minimum ms between height postMessages (default 100). */
4
+ intervalMs?: number;
5
+ /** Post even if height unchanged (default false). */
6
+ alwaysSend?: boolean;
7
+ /** Additional payload properties to include with each resize message. */
8
+ extra?: Record<string, any>;
9
+ /** Custom message type name (default 'smartlinks:resize'). */
10
+ messageType?: string;
11
+ }
12
+ /** Redirect parent window to a URL (if in iframe). */
13
+ export function redirectParent(url: string): void;
14
+ /** Request parent to adjust iframe height to current content height. */
15
+ export function sendHeight(height?: number, extra?: Record<string, any>): void;
16
+ /** Enable automatic height reporting to parent iframe. */
17
+ export function enableAutoIframeResize(options?: IframeResizeOptions): void;
18
+ /** Disable automatic height reporting. */
19
+ export function disableAutoIframeResize(): void;
20
+ /** Send a custom message to parent (browser-only). */
21
+ export function sendParentCustom(type: string, payload: Record<string, any>): void;
22
+ /** Returns true if running inside an iframe (browser). */
23
+ export function isIframe(): boolean;
24
+ /** Returns true if ResizeObserver is supported in current environment. */
25
+ export function supportsResizeObserver(): boolean;
26
+ export {};
10
27
  }
11
- /** Redirect parent window to a URL (if in iframe). */
12
- export declare function redirectParent(url: string): void;
13
- /** Request parent to adjust iframe height to current content height. */
14
- export declare function sendHeight(height?: number, extra?: Record<string, any>): void;
15
- /** Enable automatic height reporting to parent iframe. */
16
- export declare function enableAutoIframeResize(options?: IframeResizeOptions): void;
17
- /** Disable automatic height reporting. */
18
- export declare function disableAutoIframeResize(): void;
19
- /** Send a custom message to parent (browser-only). */
20
- export declare function sendParentCustom(type: string, payload: Record<string, any>): void;
21
- /** Returns true if running inside an iframe (browser). */
22
- export declare function isIframe(): boolean;
23
- /** Returns true if ResizeObserver is supported in current environment. */
24
- export declare function supportsResizeObserver(): boolean;
25
- export {};
package/dist/iframe.js CHANGED
@@ -2,122 +2,132 @@
2
2
  // Utilities to communicate with parent window when running inside an iframe.
3
3
  // These helpers are optional and safe in non-browser / Node environments.
4
4
  // They build on the existing proxyMode infrastructure but can also be used standalone.
5
- let autoResizeTimer;
6
- let lastHeight = 0;
7
- let resizeOptions;
8
- let resizeObserver;
9
- let mutationObserver;
10
- function isBrowser() {
11
- return typeof window !== 'undefined' && typeof document !== 'undefined';
12
- }
13
- function inIframe() {
14
- return isBrowser() && window.parent && window.parent !== window;
15
- }
16
- function postParentMessage(type, payload) {
17
- if (!inIframe())
18
- return;
19
- try {
20
- window.parent.postMessage({ _smartlinksIframeMessage: true, type, payload }, '*');
5
+ export var iframe;
6
+ (function (iframe) {
7
+ let autoResizeTimer;
8
+ let lastHeight = 0;
9
+ let resizeOptions;
10
+ let resizeObserver;
11
+ let mutationObserver;
12
+ function isBrowser() {
13
+ return typeof window !== 'undefined' && typeof document !== 'undefined';
21
14
  }
22
- catch (_a) {
23
- // swallow errors silently
15
+ function inIframe() {
16
+ return isBrowser() && window.parent && window.parent !== window;
24
17
  }
25
- }
26
- /** Redirect parent window to a URL (if in iframe). */
27
- export function redirectParent(url) {
28
- postParentMessage('smartlinks:redirect', { url });
29
- }
30
- /** Request parent to adjust iframe height to current content height. */
31
- export function sendHeight(height, extra) {
32
- if (!inIframe())
33
- return;
34
- const h = height !== null && height !== void 0 ? height : document.documentElement.scrollHeight;
35
- postParentMessage((resizeOptions === null || resizeOptions === void 0 ? void 0 : resizeOptions.messageType) || 'smartlinks:resize', Object.assign(Object.assign({ height: h }, resizeOptions === null || resizeOptions === void 0 ? void 0 : resizeOptions.extra), extra));
36
- }
37
- function measureHeight() {
38
- if (!isBrowser())
39
- return 0;
40
- const doc = document.documentElement;
41
- // Use max of several properties for robustness
42
- return Math.max(doc.scrollHeight, doc.offsetHeight, doc.clientHeight, document.body ? document.body.scrollHeight : 0, document.body ? document.body.offsetHeight : 0);
43
- }
44
- function scheduleManualPolling() {
45
- var _a;
46
- if (!isBrowser())
47
- return;
48
- clearInterval(autoResizeTimer);
49
- const interval = (_a = resizeOptions === null || resizeOptions === void 0 ? void 0 : resizeOptions.intervalMs) !== null && _a !== void 0 ? _a : 100;
50
- autoResizeTimer = window.setInterval(() => {
51
- const h = measureHeight();
52
- if ((resizeOptions === null || resizeOptions === void 0 ? void 0 : resizeOptions.alwaysSend) || h !== lastHeight) {
53
- lastHeight = h;
54
- sendHeight(h);
18
+ function postParentMessage(type, payload) {
19
+ if (!inIframe())
20
+ return;
21
+ try {
22
+ window.parent.postMessage({ _smartlinksIframeMessage: true, type, payload }, '*');
55
23
  }
56
- }, interval);
57
- }
58
- function setupObservers() {
59
- if (!isBrowser())
60
- return;
61
- // Prefer ResizeObserver for layout changes
62
- if (typeof ResizeObserver !== 'undefined') {
63
- resizeObserver = new ResizeObserver(() => {
64
- const h = measureHeight();
65
- if ((resizeOptions === null || resizeOptions === void 0 ? void 0 : resizeOptions.alwaysSend) || h !== lastHeight) {
66
- lastHeight = h;
67
- sendHeight(h);
68
- }
69
- });
70
- resizeObserver.observe(document.body);
24
+ catch (_a) {
25
+ // swallow errors silently
26
+ }
27
+ }
28
+ /** Redirect parent window to a URL (if in iframe). */
29
+ function redirectParent(url) {
30
+ postParentMessage('smartlinks:redirect', { url });
31
+ }
32
+ iframe.redirectParent = redirectParent;
33
+ /** Request parent to adjust iframe height to current content height. */
34
+ function sendHeight(height, extra) {
35
+ if (!inIframe())
36
+ return;
37
+ const h = height !== null && height !== void 0 ? height : document.documentElement.scrollHeight;
38
+ postParentMessage((resizeOptions === null || resizeOptions === void 0 ? void 0 : resizeOptions.messageType) || 'smartlinks:resize', Object.assign(Object.assign({ height: h }, resizeOptions === null || resizeOptions === void 0 ? void 0 : resizeOptions.extra), extra));
71
39
  }
72
- else {
73
- // Fallback: MutationObserver for DOM changes
74
- mutationObserver = new MutationObserver(() => {
40
+ iframe.sendHeight = sendHeight;
41
+ function measureHeight() {
42
+ if (!isBrowser())
43
+ return 0;
44
+ const doc = document.documentElement;
45
+ // Use max of several properties for robustness
46
+ return Math.max(doc.scrollHeight, doc.offsetHeight, doc.clientHeight, document.body ? document.body.scrollHeight : 0, document.body ? document.body.offsetHeight : 0);
47
+ }
48
+ function scheduleManualPolling() {
49
+ var _a;
50
+ if (!isBrowser())
51
+ return;
52
+ clearInterval(autoResizeTimer);
53
+ const interval = (_a = resizeOptions === null || resizeOptions === void 0 ? void 0 : resizeOptions.intervalMs) !== null && _a !== void 0 ? _a : 100;
54
+ autoResizeTimer = window.setInterval(() => {
75
55
  const h = measureHeight();
76
56
  if ((resizeOptions === null || resizeOptions === void 0 ? void 0 : resizeOptions.alwaysSend) || h !== lastHeight) {
77
57
  lastHeight = h;
78
58
  sendHeight(h);
79
59
  }
80
- });
81
- mutationObserver.observe(document.body, { childList: true, subtree: true, attributes: true });
82
- // Manual polling as additional safeguard
83
- scheduleManualPolling();
60
+ }, interval);
84
61
  }
85
- }
86
- /** Enable automatic height reporting to parent iframe. */
87
- export function enableAutoIframeResize(options) {
88
- if (!inIframe())
89
- return;
90
- resizeOptions = options || {};
91
- lastHeight = measureHeight();
92
- sendHeight(lastHeight);
93
- setupObservers();
94
- if (!resizeObserver) {
95
- // If no ResizeObserver, MutationObserver is active and we also poll
96
- scheduleManualPolling();
62
+ function setupObservers() {
63
+ if (!isBrowser())
64
+ return;
65
+ // Prefer ResizeObserver for layout changes
66
+ if (typeof ResizeObserver !== 'undefined') {
67
+ resizeObserver = new ResizeObserver(() => {
68
+ const h = measureHeight();
69
+ if ((resizeOptions === null || resizeOptions === void 0 ? void 0 : resizeOptions.alwaysSend) || h !== lastHeight) {
70
+ lastHeight = h;
71
+ sendHeight(h);
72
+ }
73
+ });
74
+ resizeObserver.observe(document.body);
75
+ }
76
+ else {
77
+ // Fallback: MutationObserver for DOM changes
78
+ mutationObserver = new MutationObserver(() => {
79
+ const h = measureHeight();
80
+ if ((resizeOptions === null || resizeOptions === void 0 ? void 0 : resizeOptions.alwaysSend) || h !== lastHeight) {
81
+ lastHeight = h;
82
+ sendHeight(h);
83
+ }
84
+ });
85
+ mutationObserver.observe(document.body, { childList: true, subtree: true, attributes: true });
86
+ // Manual polling as additional safeguard
87
+ scheduleManualPolling();
88
+ }
97
89
  }
98
- }
99
- /** Disable automatic height reporting. */
100
- export function disableAutoIframeResize() {
101
- if (resizeObserver)
102
- resizeObserver.disconnect();
103
- if (mutationObserver)
104
- mutationObserver.disconnect();
105
- if (isBrowser())
106
- clearInterval(autoResizeTimer);
107
- resizeObserver = undefined;
108
- mutationObserver = undefined;
109
- autoResizeTimer = undefined;
110
- resizeOptions = undefined;
111
- }
112
- /** Send a custom message to parent (browser-only). */
113
- export function sendParentCustom(type, payload) {
114
- postParentMessage(type, payload);
115
- }
116
- /** Returns true if running inside an iframe (browser). */
117
- export function isIframe() {
118
- return inIframe();
119
- }
120
- /** Returns true if ResizeObserver is supported in current environment. */
121
- export function supportsResizeObserver() {
122
- return typeof ResizeObserver !== 'undefined';
123
- }
90
+ /** Enable automatic height reporting to parent iframe. */
91
+ function enableAutoIframeResize(options) {
92
+ if (!inIframe())
93
+ return;
94
+ resizeOptions = options || {};
95
+ lastHeight = measureHeight();
96
+ sendHeight(lastHeight);
97
+ setupObservers();
98
+ if (!resizeObserver) {
99
+ // If no ResizeObserver, MutationObserver is active and we also poll
100
+ scheduleManualPolling();
101
+ }
102
+ }
103
+ iframe.enableAutoIframeResize = enableAutoIframeResize;
104
+ /** Disable automatic height reporting. */
105
+ function disableAutoIframeResize() {
106
+ if (resizeObserver)
107
+ resizeObserver.disconnect();
108
+ if (mutationObserver)
109
+ mutationObserver.disconnect();
110
+ if (isBrowser())
111
+ clearInterval(autoResizeTimer);
112
+ resizeObserver = undefined;
113
+ mutationObserver = undefined;
114
+ autoResizeTimer = undefined;
115
+ resizeOptions = undefined;
116
+ }
117
+ iframe.disableAutoIframeResize = disableAutoIframeResize;
118
+ /** Send a custom message to parent (browser-only). */
119
+ function sendParentCustom(type, payload) {
120
+ postParentMessage(type, payload);
121
+ }
122
+ iframe.sendParentCustom = sendParentCustom;
123
+ /** Returns true if running inside an iframe (browser). */
124
+ function isIframe() {
125
+ return inIframe();
126
+ }
127
+ iframe.isIframe = isIframe;
128
+ /** Returns true if ResizeObserver is supported in current environment. */
129
+ function supportsResizeObserver() {
130
+ return typeof ResizeObserver !== 'undefined';
131
+ }
132
+ iframe.supportsResizeObserver = supportsResizeObserver;
133
+ })(iframe || (iframe = {}));
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { initializeApi, request, sendCustomProxyMessage } from "./http";
2
2
  export * from "./api";
3
3
  export * from "./types";
4
+ export { iframe } from "./iframe";
4
5
  export type { LoginResponse, VerifyTokenResponse, AccountInfoResponse, } from "./api/auth";
5
6
  export type { UserAccountRegistrationRequest, } from "./types/auth";
6
7
  export type { SendNotificationRequest, SendNotificationResponse, NotificationSubjectTarget, NotificationTemplate, PushNotificationTemplate, EmailNotificationTemplate, WalletUpdateTemplate, } from "./types/comms";
package/dist/index.js CHANGED
@@ -3,3 +3,5 @@
3
3
  export { initializeApi, request, sendCustomProxyMessage } from "./http";
4
4
  export * from "./api";
5
5
  export * from "./types";
6
+ // Iframe namespace
7
+ export { iframe } from "./iframe";
@@ -1,17 +1,28 @@
1
1
  export interface AttestationResponse {
2
+ /** Attestation id */
2
3
  id: string;
4
+ /** Creation timestamp */
3
5
  createdAt: string;
6
+ /** Last updated timestamp */
4
7
  updatedAt: string;
8
+ /** Public attestation data */
5
9
  public: Record<string, any>;
10
+ /** Private attestation data */
6
11
  private: Record<string, any>;
12
+ /** Associated proof reference/data */
7
13
  proof: Record<string, any>;
8
14
  }
9
15
  export interface AttestationCreateRequest {
16
+ /** Public attestation payload */
10
17
  public: Record<string, any>;
18
+ /** Private attestation payload */
11
19
  private: Record<string, any>;
20
+ /** Proof linkage or payload */
12
21
  proof: Record<string, any>;
13
22
  }
14
23
  export interface AttestationUpdateRequest {
24
+ /** Update operation/type */
15
25
  type?: string;
26
+ /** Partial attestation data */
16
27
  data?: Record<string, any>;
17
28
  }
@@ -1,9 +1,16 @@
1
1
  export type UserAccountRegistrationRequest = {
2
+ /** User's display name */
2
3
  name: string;
4
+ /** Optional user email */
3
5
  email?: string;
6
+ /** Optional user phone number */
4
7
  phone?: string;
8
+ /** Optional password for email login */
5
9
  password?: string;
10
+ /** Send confirmation email after registration */
6
11
  sendAccountConfirmation?: boolean;
12
+ /** Optional collection context for registration */
7
13
  collectionId?: string;
14
+ /** Desired token type returned */
8
15
  tokenType?: 'bearer' | 'firebase';
9
16
  };
@@ -1,18 +1,40 @@
1
+ /**
2
+ * Reference to a specific claim attached to a code/tag.
3
+ */
1
4
  export interface ClaimCodeRef {
5
+ /** Identifier of the code (e.g., tag or QR code) */
2
6
  codeId: string;
7
+ /** Identifier of the claim within the claim set */
3
8
  claimId: string;
4
9
  }
10
+ /**
11
+ * Request body for updating claim data on a claim set.
12
+ * Contains arbitrary key/value pairs and a list of code+claim references to update.
13
+ */
5
14
  export interface UpdateClaimDataRequest {
15
+ /** Arbitrary key/value pairs for the claim data update */
6
16
  data: Record<string, any>;
17
+ /** Array of code+claim references affected by this update */
7
18
  codes: ClaimCodeRef[];
8
19
  }
20
+ /**
21
+ * Request body for assigning claims to codes or ranges within a collection.
22
+ */
9
23
  export interface AssignClaimsRequest {
24
+ /** The claim set ID (required) */
10
25
  id: string;
26
+ /** The collection ID (required) */
11
27
  collectionId: string;
28
+ /** The product ID (required) */
12
29
  productId: string;
30
+ /** Optional batch identifier */
13
31
  batchId?: string;
32
+ /** Optional start index for bulk assignment */
14
33
  start?: number;
34
+ /** Optional end index for bulk assignment */
15
35
  end?: number;
36
+ /** Optional single code identifier for single assignment */
16
37
  codeId?: string;
38
+ /** Optional key/value pairs to set on the claim */
17
39
  data?: Record<string, any>;
18
40
  }
@@ -2,12 +2,17 @@
2
2
  * Represents a Collection object.
3
3
  */
4
4
  export interface CollectionResponse {
5
+ /** Unique identifier for the collection */
5
6
  id: string;
7
+ /** Human-readable title of the collection */
6
8
  title: string;
9
+ /** Description of collection */
7
10
  description: string;
8
11
  /** URL to the collection's larger header/hero image */
9
12
  headerImage?: {
13
+ /** URL to the asset */
10
14
  url: string;
15
+ /** Thumbnail URLs in different sizes */
11
16
  thumbnails: {
12
17
  x100: string;
13
18
  x200: string;
@@ -16,7 +21,9 @@ export interface CollectionResponse {
16
21
  };
17
22
  /** URL to the collection's logo image */
18
23
  logoImage?: {
24
+ /** URL to the asset */
19
25
  url: string;
26
+ /** Thumbnail URLs in different sizes */
20
27
  thumbnails: {
21
28
  x100: string;
22
29
  x200: string;
@@ -25,15 +32,22 @@ export interface CollectionResponse {
25
32
  };
26
33
  /** Collection's loader image */
27
34
  loaderImage?: {
35
+ /** Override name for the file */
28
36
  overwriteName: string;
37
+ /** Name of the asset */
29
38
  name: string;
39
+ /** File type/extension */
30
40
  type: string;
41
+ /** URL to the asset */
31
42
  url: string;
32
43
  };
33
44
  /** Array of supported languages */
34
45
  languages?: {
46
+ /** Language code (e.g., "fr", "it", "es") */
35
47
  code: string;
48
+ /** Human-readable language name (e.g., "French", "Italian") */
36
49
  lang: string;
50
+ /** Whether this language is supported */
37
51
  supported: boolean;
38
52
  }[];
39
53
  /** User roles mapping with user IDs as keys and role names as values */
@@ -2,22 +2,29 @@
2
2
  * Target subject for notifications (product, collection, etc.)
3
3
  */
4
4
  export interface NotificationSubjectTarget {
5
+ /** Type of target entity */
5
6
  type: 'product' | 'collection' | 'user' | 'batch' | 'proof';
7
+ /** ID of the target entity */
6
8
  id: string;
7
9
  }
8
10
  /**
9
11
  * Push notification template content
10
12
  */
11
13
  export interface PushNotificationTemplate {
14
+ /** Notification title */
12
15
  title: string;
16
+ /** Notification body text */
13
17
  body: string;
18
+ /** Optional icon URL for the notification */
14
19
  icon?: string;
15
20
  }
16
21
  /**
17
22
  * Email notification template content
18
23
  */
19
24
  export interface EmailNotificationTemplate {
25
+ /** Email subject line */
20
26
  subject: string;
27
+ /** Email body content (plain text or HTML) */
21
28
  body: string;
22
29
  }
23
30
  /**
@@ -25,8 +32,11 @@ export interface EmailNotificationTemplate {
25
32
  */
26
33
  export interface WalletUpdateTemplate {
27
34
  textModulesData?: Array<{
35
+ /** Module ID */
28
36
  id: string;
37
+ /** Module header text */
29
38
  header: string;
39
+ /** Module body text */
30
40
  body: string;
31
41
  }>;
32
42
  }
@@ -34,39 +44,58 @@ export interface WalletUpdateTemplate {
34
44
  * Notification template containing different delivery methods
35
45
  */
36
46
  export interface NotificationTemplate {
47
+ /** Push notification content */
37
48
  push?: PushNotificationTemplate;
49
+ /** Email notification content */
38
50
  email?: EmailNotificationTemplate;
51
+ /** Wallet pass update content */
39
52
  walletUpdate?: WalletUpdateTemplate;
40
53
  }
41
54
  /**
42
55
  * Request payload for sending notifications
43
56
  */
44
57
  export interface SendNotificationRequest {
58
+ /** Target subjects that should receive the notification */
45
59
  subjectTargets: NotificationSubjectTarget[];
60
+ /** Severity level of the notification */
46
61
  severity: 'low' | 'normal' | 'important' | 'critical';
62
+ /** Delivery channel mode preference */
47
63
  mode: 'preferred' | 'all';
64
+ /** Specific channels to use for delivery */
48
65
  channels: ("push" | "email" | "wallet")[];
66
+ /** Notification content templates for different delivery methods */
49
67
  template: NotificationTemplate;
50
68
  }
51
69
  /**
52
70
  * Response from sending notifications
53
71
  */
54
72
  export interface SendNotificationResponse {
73
+ /** Whether the request was accepted */
55
74
  ok: boolean;
75
+ /** Unique ID for this notification */
56
76
  notificationId: string;
77
+ /** Basic counts for contacts and attempts */
57
78
  counts: {
58
79
  contacts: number;
59
80
  attempts: number;
60
81
  };
82
+ /** Detailed status for the notification */
61
83
  status: {
62
84
  notification: {
85
+ /** The notification ID (repeated for convenience) */
63
86
  notificationId: string;
87
+ /** Current processing state */
64
88
  state: 'queued' | 'sent' | 'failed' | 'confirmed' | string;
89
+ /** Targets this notification refers to */
65
90
  subjectTargets: NotificationSubjectTarget[];
91
+ /** Severity of this notification */
66
92
  severity: 'low' | 'normal' | 'important' | 'critical' | string;
93
+ /** Optional channel overrides used when sending */
67
94
  channelsOverride: Record<string, any>;
95
+ /** The effective template used */
68
96
  template: NotificationTemplate;
69
97
  };
98
+ /** Totals across all contacts */
70
99
  totals: {
71
100
  queued: number;
72
101
  sent: number;
@@ -0,0 +1,41 @@
1
+ export type ContactCustomFields = Record<string, any>;
2
+ export interface ContactResponse {
3
+ contactId: string;
4
+ orgId: string;
5
+ firstName: string | null;
6
+ lastName: string | null;
7
+ displayName: string | null;
8
+ company: string | null;
9
+ email: string | null;
10
+ phone: string | null;
11
+ emails?: string[];
12
+ phones?: string[];
13
+ customFields: ContactCustomFields;
14
+ createdAt: string;
15
+ updatedAt: string;
16
+ deletedAt: string | null;
17
+ erasedAt: string | null;
18
+ }
19
+ export interface ContactCreateRequest {
20
+ firstName?: string | null;
21
+ lastName?: string | null;
22
+ displayName?: string | null;
23
+ company?: string | null;
24
+ email?: string | null;
25
+ phone?: string | null;
26
+ customFields?: ContactCustomFields;
27
+ }
28
+ export interface ContactUpdateRequest {
29
+ firstName?: string | null;
30
+ lastName?: string | null;
31
+ displayName?: string | null;
32
+ company?: string | null;
33
+ email?: string | null;
34
+ phone?: string | null;
35
+ customFields?: ContactCustomFields;
36
+ }
37
+ export interface ContactListResponse {
38
+ items: ContactResponse[];
39
+ limit: number;
40
+ offset: number;
41
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -10,3 +10,4 @@ export * from "./claimSet";
10
10
  export * from "./auth";
11
11
  export * from "./comms";
12
12
  export * from "./nfc";
13
+ export * from "./contact";
@@ -12,3 +12,4 @@ export * from "./claimSet";
12
12
  export * from "./auth";
13
13
  export * from "./comms";
14
14
  export * from "./nfc";
15
+ export * from "./contact";
@@ -2,15 +2,23 @@
2
2
  * Represents a Product Item object.
3
3
  */
4
4
  export interface ProductResponse {
5
+ /** Unique identifier for the product */
5
6
  id: string;
7
+ /** Name of the product */
6
8
  name: string;
9
+ /** Unique identifier for the product's collection */
7
10
  collectionId: string;
11
+ /** Detailed description of the product */
8
12
  description: string;
13
+ /** A product GTIN (Global Trade Item Number) */
9
14
  gtin?: string;
15
+ /** An optional product type from the standard smartlinks types */
10
16
  type?: string;
11
17
  /** Hero image asset object */
12
18
  heroImage: {
19
+ /** URL to the asset */
13
20
  url: string;
21
+ /** Thumbnail URLs in different sizes */
14
22
  thumbnails: {
15
23
  x100: string;
16
24
  x200: string;
@@ -2,13 +2,22 @@
2
2
  * Represents a Proof object.
3
3
  */
4
4
  export interface ProofResponse {
5
+ /** Unique identifier for the collection */
5
6
  collectionId: string;
7
+ /** Creation timestamp */
6
8
  createdAt: string;
9
+ /** Unique identifier for the proof */
7
10
  id: string;
11
+ /** Unique identifier for the product */
8
12
  productId: string;
13
+ /** Unique identifier for the token */
9
14
  tokenId: string;
15
+ /** Unique identifier for the user */
10
16
  userId: string;
11
- claimable: boolean;
12
- transient: boolean;
17
+ /** Is this proof available to be claimed */
18
+ claimable?: boolean;
19
+ /** Is this proof transient */
20
+ transient?: boolean;
21
+ /** Arbitrary key-value pairs for proof values */
13
22
  values: Record<string, any>;
14
23
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proveanything/smartlinks",
3
- "version": "1.0.60",
3
+ "version": "1.0.62",
4
4
  "description": "Official JavaScript/TypeScript SDK for the Smartlinks API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",