@explorins/pers-sdk 2.1.21 → 2.1.24

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.
Files changed (122) hide show
  1. package/dist/business/api/business-api.d.ts +6 -9
  2. package/dist/business/api/business-api.d.ts.map +1 -1
  3. package/dist/business/index.d.ts +1 -0
  4. package/dist/business/index.d.ts.map +1 -1
  5. package/dist/business/services/business-service.d.ts +8 -5
  6. package/dist/business/services/business-service.d.ts.map +1 -1
  7. package/dist/business.cjs +1 -1
  8. package/dist/business.js +1 -1
  9. package/dist/campaign/api/campaign-api.d.ts +21 -14
  10. package/dist/campaign/api/campaign-api.d.ts.map +1 -1
  11. package/dist/campaign/index.d.ts +2 -1
  12. package/dist/campaign/index.d.ts.map +1 -1
  13. package/dist/campaign/models/index.d.ts +16 -6
  14. package/dist/campaign/models/index.d.ts.map +1 -1
  15. package/dist/campaign/services/campaign-service.d.ts +16 -23
  16. package/dist/campaign/services/campaign-service.d.ts.map +1 -1
  17. package/dist/campaign.cjs +36 -16
  18. package/dist/campaign.cjs.map +1 -1
  19. package/dist/campaign.js +36 -16
  20. package/dist/campaign.js.map +1 -1
  21. package/dist/chunks/{business-membership-service-BfHzIQlc.cjs → business-membership-service-DXLG5fP9.cjs} +17 -2
  22. package/dist/chunks/business-membership-service-DXLG5fP9.cjs.map +1 -0
  23. package/dist/chunks/{business-membership-service-CFa-TI39.js → business-membership-service-IyY5CkL0.js} +17 -2
  24. package/dist/chunks/business-membership-service-IyY5CkL0.js.map +1 -0
  25. package/dist/chunks/{index-DgTEdUgC.js → index-8y63MFOX.js} +28 -16
  26. package/dist/chunks/index-8y63MFOX.js.map +1 -0
  27. package/dist/chunks/{index-CGaKfZNU.cjs → index-CVuttuU8.cjs} +27 -14
  28. package/dist/chunks/{index-CGaKfZNU.cjs.map → index-CVuttuU8.cjs.map} +1 -1
  29. package/dist/chunks/{pers-sdk-DHohtBN8.cjs → pers-sdk-DXCcAgUS.cjs} +385 -96
  30. package/dist/chunks/pers-sdk-DXCcAgUS.cjs.map +1 -0
  31. package/dist/chunks/{pers-sdk-BTLsI3bU.js → pers-sdk-DkCRHY5i.js} +385 -96
  32. package/dist/chunks/pers-sdk-DkCRHY5i.js.map +1 -0
  33. package/dist/chunks/{redemption-service-OY_JjwCL.cjs → redemption-service-5Mu78Sne.cjs} +60 -8
  34. package/dist/chunks/redemption-service-5Mu78Sne.cjs.map +1 -0
  35. package/dist/chunks/{redemption-service-CoyjUi8C.js → redemption-service-CoODony4.js} +60 -8
  36. package/dist/chunks/redemption-service-CoODony4.js.map +1 -0
  37. package/dist/chunks/{tenant-manager-B4FygDMF.cjs → tenant-manager-D3toTiB9.cjs} +21 -3
  38. package/dist/chunks/{tenant-manager-B4FygDMF.cjs.map → tenant-manager-D3toTiB9.cjs.map} +1 -1
  39. package/dist/chunks/{tenant-manager-DkWkZfCF.js → tenant-manager-D8-eD2CZ.js} +21 -3
  40. package/dist/chunks/{tenant-manager-DkWkZfCF.js.map → tenant-manager-D8-eD2CZ.js.map} +1 -1
  41. package/dist/chunks/{tenant-service-Ch-V3mj-.cjs → tenant-service-8vZWmTLV.cjs} +16 -1
  42. package/dist/chunks/tenant-service-8vZWmTLV.cjs.map +1 -0
  43. package/dist/chunks/{tenant-service-BnTAZCxS.js → tenant-service-DlhdZAs9.js} +16 -1
  44. package/dist/chunks/tenant-service-DlhdZAs9.js.map +1 -0
  45. package/dist/chunks/{web3-chain-service-DcLiy3m2.cjs → web3-chain-service-CSxlvjMg.cjs} +2 -2
  46. package/dist/chunks/{web3-chain-service-DcLiy3m2.cjs.map → web3-chain-service-CSxlvjMg.cjs.map} +1 -1
  47. package/dist/chunks/{web3-chain-service-nGntR60S.js → web3-chain-service-DRoykR1u.js} +2 -2
  48. package/dist/chunks/{web3-chain-service-nGntR60S.js.map → web3-chain-service-DRoykR1u.js.map} +1 -1
  49. package/dist/chunks/{web3-manager-DRkj7s5C.js → web3-manager-DZXBaBh0.js} +4 -4
  50. package/dist/chunks/{web3-manager-DRkj7s5C.js.map → web3-manager-DZXBaBh0.js.map} +1 -1
  51. package/dist/chunks/{web3-manager-msPdWhlR.cjs → web3-manager-ojRB6_ty.cjs} +4 -4
  52. package/dist/chunks/{web3-manager-msPdWhlR.cjs.map → web3-manager-ojRB6_ty.cjs.map} +1 -1
  53. package/dist/core/auth/api/auth-api.d.ts +37 -2
  54. package/dist/core/auth/api/auth-api.d.ts.map +1 -1
  55. package/dist/core/auth/services/auth-service.d.ts +24 -3
  56. package/dist/core/auth/services/auth-service.d.ts.map +1 -1
  57. package/dist/core/errors/index.d.ts +26 -13
  58. package/dist/core/errors/index.d.ts.map +1 -1
  59. package/dist/core/events/event-emitter.d.ts +13 -1
  60. package/dist/core/events/event-emitter.d.ts.map +1 -1
  61. package/dist/core/events/event-types.d.ts +11 -0
  62. package/dist/core/events/event-types.d.ts.map +1 -1
  63. package/dist/core/pers-config.d.ts +13 -0
  64. package/dist/core/pers-config.d.ts.map +1 -1
  65. package/dist/core.cjs +7 -6
  66. package/dist/core.cjs.map +1 -1
  67. package/dist/core.js +6 -6
  68. package/dist/index.cjs +7 -6
  69. package/dist/index.cjs.map +1 -1
  70. package/dist/index.d.ts +2 -2
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +6 -6
  73. package/dist/managers/auth-manager.d.ts +61 -3
  74. package/dist/managers/auth-manager.d.ts.map +1 -1
  75. package/dist/managers/business-manager.d.ts +4 -4
  76. package/dist/managers/business-manager.d.ts.map +1 -1
  77. package/dist/managers/campaign-manager.d.ts +49 -49
  78. package/dist/managers/campaign-manager.d.ts.map +1 -1
  79. package/dist/managers/events-manager.d.ts.map +1 -1
  80. package/dist/managers/index.d.ts +1 -0
  81. package/dist/managers/index.d.ts.map +1 -1
  82. package/dist/managers/redemption-manager.d.ts +25 -3
  83. package/dist/managers/redemption-manager.d.ts.map +1 -1
  84. package/dist/managers/tenant-manager.d.ts +16 -0
  85. package/dist/managers/tenant-manager.d.ts.map +1 -1
  86. package/dist/node.cjs +6 -6
  87. package/dist/node.js +6 -6
  88. package/dist/package.json +2 -2
  89. package/dist/pers-sdk.d.ts +12 -6
  90. package/dist/pers-sdk.d.ts.map +1 -1
  91. package/dist/redemption/api/redemption-api.d.ts +30 -11
  92. package/dist/redemption/api/redemption-api.d.ts.map +1 -1
  93. package/dist/redemption/index.d.ts +2 -1
  94. package/dist/redemption/index.d.ts.map +1 -1
  95. package/dist/redemption/models/index.d.ts +17 -3
  96. package/dist/redemption/models/index.d.ts.map +1 -1
  97. package/dist/redemption/services/redemption-service.d.ts +18 -14
  98. package/dist/redemption/services/redemption-service.d.ts.map +1 -1
  99. package/dist/redemption.cjs +1 -1
  100. package/dist/redemption.js +1 -1
  101. package/dist/tenant/api/tenant-api.d.ts +7 -0
  102. package/dist/tenant/api/tenant-api.d.ts.map +1 -1
  103. package/dist/tenant/services/tenant-service.d.ts +4 -0
  104. package/dist/tenant/services/tenant-service.d.ts.map +1 -1
  105. package/dist/tenant.cjs +1 -1
  106. package/dist/tenant.js +1 -1
  107. package/dist/web3-chain.cjs +2 -2
  108. package/dist/web3-chain.js +2 -2
  109. package/dist/web3-manager.cjs +5 -5
  110. package/dist/web3-manager.js +5 -5
  111. package/dist/web3.cjs +5 -5
  112. package/dist/web3.js +5 -5
  113. package/package.json +2 -2
  114. package/dist/chunks/business-membership-service-BfHzIQlc.cjs.map +0 -1
  115. package/dist/chunks/business-membership-service-CFa-TI39.js.map +0 -1
  116. package/dist/chunks/index-DgTEdUgC.js.map +0 -1
  117. package/dist/chunks/pers-sdk-BTLsI3bU.js.map +0 -1
  118. package/dist/chunks/pers-sdk-DHohtBN8.cjs.map +0 -1
  119. package/dist/chunks/redemption-service-CoyjUi8C.js.map +0 -1
  120. package/dist/chunks/redemption-service-OY_JjwCL.cjs.map +0 -1
  121. package/dist/chunks/tenant-service-BnTAZCxS.js.map +0 -1
  122. package/dist/chunks/tenant-service-Ch-V3mj-.cjs.map +0 -1
@@ -1,16 +1,16 @@
1
1
  'use strict';
2
2
 
3
3
  var persShared = require('@explorins/pers-shared');
4
- var index = require('./index-CGaKfZNU.cjs');
4
+ var index = require('./index-CVuttuU8.cjs');
5
5
  var user = require('../user.cjs');
6
6
  var userStatus = require('../user-status.cjs');
7
7
  var tokenService = require('./token-service-C1xe11OX.cjs');
8
- var businessMembershipService = require('./business-membership-service-BfHzIQlc.cjs');
8
+ var businessMembershipService = require('./business-membership-service-DXLG5fP9.cjs');
9
9
  var campaign = require('../campaign.cjs');
10
- var redemptionService = require('./redemption-service-OY_JjwCL.cjs');
10
+ var redemptionService = require('./redemption-service-5Mu78Sne.cjs');
11
11
  var transactionRequest_builder = require('./transaction-request.builder-D8pIzjYD.cjs');
12
12
  var paymentService = require('./payment-service-Bkw7ZXev.cjs');
13
- var tenantManager = require('./tenant-manager-B4FygDMF.cjs');
13
+ var tenantManager = require('./tenant-manager-D3toTiB9.cjs');
14
14
  var paginationUtils = require('./pagination-utils-B2jRHMSO.cjs');
15
15
  var analyticsService = require('./analytics-service-CF9AsMQH.cjs');
16
16
  var donation = require('../donation.cjs');
@@ -32,7 +32,8 @@ const DEFAULT_PERS_CONFIG = {
32
32
  retries: 3,
33
33
  tokenRefreshMargin: 60, // Refresh tokens 60 seconds before expiry
34
34
  backgroundRefreshThreshold: 30, // Use background refresh if >30s remaining
35
- captureWalletEvents: true // Auto-connect to wallet events after auth
35
+ captureWalletEvents: true, // Auto-connect to wallet events after auth
36
+ autoRestoreSession: true // Auto-restore session from stored tokens on init
36
37
  };
37
38
  /**
38
39
  * Build the API root URL based on config
@@ -99,11 +100,28 @@ class AuthApi {
99
100
  }
100
101
  /**
101
102
  * Login tenant admin with JWT
103
+ *
104
+ * Authenticates an admin in a tenant context.
105
+ *
106
+ * @param jwt - Authentication token (Firebase JWT)
107
+ * @param options - Tenant authentication options (tenantId for multi-tenant admins)
108
+ * @returns Session response with tenant context
109
+ * @throws MultipleContextSelectionError when tenantId is required but not provided
110
+ *
111
+ * @example
112
+ * ```typescript
113
+ * // Single tenant - auto-selects
114
+ * const response = await authApi.loginTenantAdmin(jwt);
115
+ *
116
+ * // Multiple tenants - explicit selection
117
+ * const response = await authApi.loginTenantAdmin(jwt, { tenantId: 'tenant-123' });
118
+ * ```
102
119
  */
103
- async loginTenantAdmin(jwt) {
120
+ async loginTenantAdmin(jwt, options) {
104
121
  const body = {
105
122
  authToken: jwt,
106
- authType: persShared.AccountOwnerType.TENANT
123
+ authType: persShared.AccountOwnerType.TENANT,
124
+ context: options?.tenantId ? { tenantId: options.tenantId } : undefined
107
125
  };
108
126
  return this.apiClient.post(`${this.basePath}/token`, body, { bypassAuth: true });
109
127
  }
@@ -161,6 +179,30 @@ class AuthApi {
161
179
  async refreshAccessToken(refreshToken) {
162
180
  return this.apiClient.post(`${this.basePath}/refresh`, { refreshToken }, { bypassAuth: true, isRefreshRequest: true });
163
181
  }
182
+ // ==========================================
183
+ // IDENTITY VERIFICATION (for session restore)
184
+ // Note: These duplicate calls in domain APIs (user-api, business-api)
185
+ // but are kept here to avoid circular dependencies during initialization.
186
+ // If endpoints change, update both locations.
187
+ // ==========================================
188
+ /**
189
+ * Get current authenticated user
190
+ */
191
+ async getCurrentUser() {
192
+ return this.apiClient.get('/users/me');
193
+ }
194
+ /**
195
+ * Get current business context
196
+ */
197
+ async getCurrentBusiness() {
198
+ return this.apiClient.get('/businesses/me');
199
+ }
200
+ /**
201
+ * Get current admin context
202
+ */
203
+ async getCurrentAdmin() {
204
+ return this.apiClient.get('/admins/me');
205
+ }
164
206
  }
165
207
 
166
208
  /**
@@ -185,6 +227,12 @@ exports.AuthStatus = void 0;
185
227
  AuthStatus["SESSION_RESTORATION_FAILED"] = "session_restoration_failed";
186
228
  })(exports.AuthStatus || (exports.AuthStatus = {}));
187
229
 
230
+ /**
231
+ * Type guard to check if provider implements extended storage methods
232
+ */
233
+ function isExtendedProvider(provider) {
234
+ return 'setAuthType' in provider && typeof provider.setAuthType === 'function';
235
+ }
188
236
  /**
189
237
  * Platform-agnostic authentication service
190
238
  * Handles login, token refresh, and storage operations
@@ -196,6 +244,12 @@ class AuthService {
196
244
  this.activeRefreshPromise = null;
197
245
  this.currentAuthStatus = exports.AuthStatus.UNAUTHENTICATED;
198
246
  }
247
+ /**
248
+ * Get extended provider if available, null otherwise
249
+ */
250
+ get extendedProvider() {
251
+ return this.authProvider && isExtendedProvider(this.authProvider) ? this.authProvider : null;
252
+ }
199
253
  /**
200
254
  * Emit auth status change to the app
201
255
  */
@@ -203,9 +257,10 @@ class AuthService {
203
257
  if (this.currentAuthStatus === status)
204
258
  return; // No change
205
259
  this.currentAuthStatus = status;
206
- if (this.authProvider && typeof this.authProvider.onAuthStatusChange === 'function') {
260
+ const extended = this.extendedProvider;
261
+ if (extended?.onAuthStatusChange) {
207
262
  try {
208
- await this.authProvider.onAuthStatusChange(status);
263
+ await extended.onAuthStatusChange(status);
209
264
  }
210
265
  catch (error) {
211
266
  console.warn('[AuthService] Auth status change callback failed:', error);
@@ -217,9 +272,14 @@ class AuthService {
217
272
  // ==========================================
218
273
  /**
219
274
  * Login tenant admin with JWT
275
+ *
276
+ * @param jwt - Authentication token (Firebase JWT)
277
+ * @param options - Tenant authentication options (tenantId for multi-tenant admins)
278
+ * @returns Session response with tenant context
279
+ * @throws Error with code MULTIPLE_CONTEXT_SELECTION_REQUIRED when tenantId is required but not provided
220
280
  */
221
- async loginTenantAdmin(jwt) {
222
- const response = await this.authApi.loginTenantAdmin(jwt);
281
+ async loginTenantAdmin(jwt, options) {
282
+ const response = await this.authApi.loginTenantAdmin(jwt, options);
223
283
  if (this.authProvider && response.accessToken) {
224
284
  await this.storeTokens(response.accessToken, response.refreshToken, persShared.AccountOwnerType.TENANT, jwt);
225
285
  }
@@ -300,9 +360,13 @@ class AuthService {
300
360
  if (!tokenToUse) {
301
361
  throw new Error('No refresh token available for token refresh');
302
362
  }
363
+ // Get the current authType to preserve it after refresh
364
+ const extended = this.extendedProvider;
365
+ const currentAuthType = extended?.getAuthType ? await extended.getAuthType() ?? undefined : undefined;
303
366
  const response = await this.authApi.refreshAccessToken(tokenToUse);
304
367
  if (this.authProvider && response.accessToken) {
305
- await this.storeTokens(response.accessToken, response.refreshToken);
368
+ // Preserve the authType during refresh
369
+ await this.storeTokens(response.accessToken, response.refreshToken, currentAuthType);
306
370
  }
307
371
  return response;
308
372
  }
@@ -340,6 +404,27 @@ class AuthService {
340
404
  return !!token;
341
405
  }
342
406
  // ==========================================
407
+ // CONTEXT RETRIEVAL
408
+ // ==========================================
409
+ /**
410
+ * Get current authenticated user
411
+ */
412
+ async getCurrentUser() {
413
+ return this.authApi.getCurrentUser();
414
+ }
415
+ /**
416
+ * Get current business context
417
+ */
418
+ async getCurrentBusiness() {
419
+ return this.authApi.getCurrentBusiness();
420
+ }
421
+ /**
422
+ * Get current admin context
423
+ */
424
+ async getCurrentAdmin() {
425
+ return this.authApi.getCurrentAdmin();
426
+ }
427
+ // ==========================================
343
428
  // PRIVATE HELPERS
344
429
  // ==========================================
345
430
  /**
@@ -353,17 +438,18 @@ class AuthService {
353
438
  if (refreshToken) {
354
439
  await this.authProvider.setRefreshToken(refreshToken);
355
440
  }
356
- // Type-safe handling of extended token storage features
357
- const extendedProvider = this.authProvider;
358
- if (providerToken && extendedProvider.setProviderToken) {
359
- await extendedProvider.setProviderToken(providerToken);
360
- }
361
- if (authType && extendedProvider.setAuthType) {
362
- console.log('[AuthService] Storing auth type:', authType);
363
- await extendedProvider.setAuthType(authType);
441
+ // Handle optional extended storage methods
442
+ const extended = this.extendedProvider;
443
+ if (extended) {
444
+ if (providerToken && extended.setProviderToken) {
445
+ await extended.setProviderToken(providerToken);
446
+ }
447
+ if (authType && extended.setAuthType) {
448
+ await extended.setAuthType(authType);
449
+ }
364
450
  }
365
- else {
366
- console.warn('[AuthService] Auth type not stored - authType:', authType, 'has setAuthType:', !!extendedProvider.setAuthType);
451
+ else if (authType) {
452
+ console.warn('[AuthService] Auth type not stored - provider does not implement setAuthType');
367
453
  }
368
454
  // Emit authenticated status on successful token storage
369
455
  await this.emitAuthStatus(exports.AuthStatus.AUTHENTICATED);
@@ -1403,6 +1489,7 @@ function generateEventId() {
1403
1489
  *
1404
1490
  * All events flow through one subscription point.
1405
1491
  * Optional filtering at subscription level.
1492
+ * Supports replay of last auth event for late subscribers.
1406
1493
  *
1407
1494
  * @example Basic Usage
1408
1495
  * ```typescript
@@ -1426,6 +1513,13 @@ function generateEventId() {
1426
1513
  * showNotification(event.userMessage);
1427
1514
  * }, { excludeDomains: ['validation'] });
1428
1515
  *
1516
+ * // Subscribe with replay - get last auth event if missed
1517
+ * sdk.events.subscribe((event) => {
1518
+ * if (event.type === 'session_restored') {
1519
+ * setUser(event.details.user);
1520
+ * }
1521
+ * }, { domains: ['authentication'], replay: true });
1522
+ *
1429
1523
  * // Cleanup
1430
1524
  * unsubscribe();
1431
1525
  * ```
@@ -1433,6 +1527,8 @@ function generateEventId() {
1433
1527
  let emitterInstanceCounter = 0;
1434
1528
  class PersEventEmitter {
1435
1529
  constructor() {
1530
+ // Store last auth event for replay to late subscribers
1531
+ this.lastAuthEvent = null;
1436
1532
  this.handlers = new Set();
1437
1533
  this._instanceId = ++emitterInstanceCounter;
1438
1534
  }
@@ -1443,7 +1539,7 @@ class PersEventEmitter {
1443
1539
  * Subscribe to events
1444
1540
  *
1445
1541
  * @param handler - Callback for matching events
1446
- * @param filter - Optional filter by domain and/or level
1542
+ * @param filter - Optional filter by domain and/or level. Set `replay: true` to receive last auth event if missed.
1447
1543
  * @returns Unsubscribe function
1448
1544
  *
1449
1545
  * @example All events
@@ -1467,10 +1563,35 @@ class PersEventEmitter {
1467
1563
  * confetti();
1468
1564
  * }, { domains: ['transaction'], levels: ['success'] });
1469
1565
  * ```
1566
+ *
1567
+ * @example Auth events with replay (catches session_restored even if emitted before subscription)
1568
+ * ```typescript
1569
+ * sdk.events.subscribe((event) => {
1570
+ * if (event.type === 'session_restored') {
1571
+ * const { user } = event.details;
1572
+ * setUser(user);
1573
+ * }
1574
+ * }, { domains: ['authentication'], replay: true });
1575
+ * ```
1470
1576
  */
1471
1577
  subscribe(handler, filter) {
1472
1578
  const filteredHandler = { handler, filter };
1473
1579
  this.handlers.add(filteredHandler);
1580
+ // If replay is requested and we have a cached auth event, replay it immediately
1581
+ if (filter?.replay && this.lastAuthEvent) {
1582
+ // Check if event matches the filter
1583
+ if (!filter || this.matchesFilter(this.lastAuthEvent, filter)) {
1584
+ // Use queueMicrotask to ensure handler runs after subscribe returns
1585
+ queueMicrotask(() => {
1586
+ try {
1587
+ handler(this.lastAuthEvent);
1588
+ }
1589
+ catch (error) {
1590
+ console.error('[PersEventEmitter] Replay handler error:', error);
1591
+ }
1592
+ });
1593
+ }
1594
+ }
1474
1595
  return () => this.handlers.delete(filteredHandler);
1475
1596
  }
1476
1597
  /**
@@ -1495,6 +1616,7 @@ class PersEventEmitter {
1495
1616
  * Emit a success event
1496
1617
  *
1497
1618
  * Domain is restricted to business domains only (Domain type).
1619
+ * Auth events (login_success, session_restored) are cached for replay to late subscribers.
1498
1620
  *
1499
1621
  * @param event - Success event data (id and timestamp auto-generated)
1500
1622
  * @returns The complete event object
@@ -1515,6 +1637,15 @@ class PersEventEmitter {
1515
1637
  id: generateEventId(),
1516
1638
  timestamp: Date.now()
1517
1639
  };
1640
+ // Cache auth events for replay to late subscribers
1641
+ if (event.domain === 'authentication' &&
1642
+ (event.type === 'login_success' || event.type === 'session_restored')) {
1643
+ this.lastAuthEvent = fullEvent;
1644
+ }
1645
+ // Clear cached auth on logout
1646
+ if (event.domain === 'authentication' && event.type === 'logout_success') {
1647
+ this.lastAuthEvent = null;
1648
+ }
1518
1649
  this.notifyHandlers(fullEvent);
1519
1650
  return fullEvent;
1520
1651
  }
@@ -1542,6 +1673,10 @@ class PersEventEmitter {
1542
1673
  id: generateEventId(),
1543
1674
  timestamp: Date.now()
1544
1675
  };
1676
+ // Clear cached auth on auth failure (session invalid)
1677
+ if (event.domain === 'authentication' && event.type === 'session_restoration_failed') {
1678
+ this.lastAuthEvent = null;
1679
+ }
1545
1680
  this.notifyHandlers(fullEvent);
1546
1681
  return fullEvent;
1547
1682
  }
@@ -1665,7 +1800,8 @@ class AuthManager {
1665
1800
  this.events?.emitSuccess({
1666
1801
  domain: 'authentication',
1667
1802
  type: 'login_success',
1668
- userMessage: 'Successfully logged in'
1803
+ userMessage: 'Successfully logged in',
1804
+ details: { user: result.user }
1669
1805
  });
1670
1806
  return result;
1671
1807
  }
@@ -1713,7 +1849,66 @@ class AuthManager {
1713
1849
  */
1714
1850
  async loginAsBusiness(jwtToken, options) {
1715
1851
  const authService = this.apiClient.getAuthService();
1716
- return authService.loginBusiness(jwtToken, options);
1852
+ const result = await authService.loginBusiness(jwtToken, options);
1853
+ this.events?.emitSuccess({
1854
+ domain: 'authentication',
1855
+ type: 'login_success',
1856
+ userMessage: 'Successfully logged in as business',
1857
+ details: { user: result.user, business: result.business }
1858
+ });
1859
+ return result;
1860
+ }
1861
+ /**
1862
+ * Login as tenant admin with JWT token
1863
+ *
1864
+ * Authenticates an admin in a tenant context.
1865
+ *
1866
+ * **Auto-Selection Behavior:**
1867
+ * - If admin has access to a single tenant, it's auto-selected
1868
+ * - If admin has access to multiple tenants and no tenantId is provided,
1869
+ * throws `MULTIPLE_CONTEXT_SELECTION_REQUIRED` error with available options
1870
+ *
1871
+ * @param jwtToken - JWT token from auth provider (Firebase, etc.)
1872
+ * @param options - Tenant authentication options (tenantId for multi-tenant admins)
1873
+ * @returns Promise resolving to authentication response with tenant context
1874
+ * @throws Error with code `MULTIPLE_CONTEXT_SELECTION_REQUIRED` when tenantId is needed
1875
+ *
1876
+ * @example Single Tenant Access
1877
+ * ```typescript
1878
+ * // Auto-selects the admin's only tenant
1879
+ * const result = await sdk.auth.loginAsTenant(jwt);
1880
+ * console.log('Tenant:', result.admin?.tenantId);
1881
+ * ```
1882
+ *
1883
+ * @example Multiple Tenant Access
1884
+ * ```typescript
1885
+ * try {
1886
+ * const result = await sdk.auth.loginAsTenant(jwt);
1887
+ * } catch (error) {
1888
+ * if (error.code === 'MULTIPLE_CONTEXT_SELECTION_REQUIRED') {
1889
+ * // Show tenant selector UI
1890
+ * const selectedId = await showTenantSelector(error.details.availableOptions);
1891
+ * const result = await sdk.auth.loginAsTenant(jwt, { tenantId: selectedId });
1892
+ * }
1893
+ * }
1894
+ * ```
1895
+ *
1896
+ * @example Direct Tenant Selection
1897
+ * ```typescript
1898
+ * const result = await sdk.auth.loginAsTenant(jwt, { tenantId: 'tenant-123' });
1899
+ * console.log('Authenticated as admin for tenant:', result.admin?.tenantId);
1900
+ * ```
1901
+ */
1902
+ async loginAsTenant(jwtToken, options) {
1903
+ const authService = this.apiClient.getAuthService();
1904
+ const result = await authService.loginTenantAdmin(jwtToken, options);
1905
+ this.events?.emitSuccess({
1906
+ domain: 'authentication',
1907
+ type: 'login_success',
1908
+ userMessage: 'Successfully logged in as tenant admin',
1909
+ details: { admin: result.admin }
1910
+ });
1911
+ return result;
1717
1912
  }
1718
1913
  /**
1719
1914
  * Get current business context
@@ -1731,7 +1926,27 @@ class AuthManager {
1731
1926
  * ```
1732
1927
  */
1733
1928
  async getCurrentBusiness() {
1734
- return this.apiClient.get('/businesses/me');
1929
+ const authService = this.apiClient.getAuthService();
1930
+ return authService.getCurrentBusiness();
1931
+ }
1932
+ /**
1933
+ * Get current admin context
1934
+ *
1935
+ * Retrieves the current admin data if authenticated as tenant admin.
1936
+ * Requires prior tenant authentication via {@link loginAsTenant}.
1937
+ *
1938
+ * @returns Promise resolving to current admin data
1939
+ * @throws {PersApiError} When not authenticated as tenant admin
1940
+ *
1941
+ * @example
1942
+ * ```typescript
1943
+ * const admin = await sdk.auth.getCurrentAdmin();
1944
+ * console.log('Current admin:', admin.email);
1945
+ * ```
1946
+ */
1947
+ async getCurrentAdmin() {
1948
+ const authService = this.apiClient.getAuthService();
1949
+ return authService.getCurrentAdmin();
1735
1950
  }
1736
1951
  /**
1737
1952
  * Login with raw user data
@@ -1775,7 +1990,8 @@ class AuthManager {
1775
1990
  * ```
1776
1991
  */
1777
1992
  async getCurrentUser() {
1778
- return this.apiClient.get('/users/me');
1993
+ const authService = this.apiClient.getAuthService();
1994
+ return authService.getCurrentUser();
1779
1995
  }
1780
1996
  /**
1781
1997
  * Check if user is authenticated
@@ -3577,7 +3793,7 @@ class CampaignManager {
3577
3793
  * Returns campaigns with pagination metadata for efficient data loading.
3578
3794
  * Intelligent access: Public gets active only, Business gets own campaigns, Admin gets all.
3579
3795
  *
3580
- * @param options - Pagination and filter options (page, limit, sortBy, sortOrder, active, tag, search, businessId, include)
3796
+ * @param options - Pagination and filter options (page, limit, sortBy, sortOrder, active, tag, search, businessId, startDate, endDate, include)
3581
3797
  * @returns Promise resolving to paginated campaigns with metadata
3582
3798
  *
3583
3799
  * @example
@@ -3607,18 +3823,22 @@ class CampaignManager {
3607
3823
  * active: true
3608
3824
  * });
3609
3825
  *
3610
- * // Get active campaigns sorted by creation date
3611
- * const activeCampaigns = await sdk.campaigns.getCampaigns({
3612
- * active: true,
3613
- * sortBy: 'createdAt',
3614
- * sortOrder: 'DESC',
3615
- * page: 1,
3616
- * limit: 25
3826
+ * // Filter by date range
3827
+ * const dateFiltered = await sdk.campaigns.getCampaigns({
3828
+ * startDate: new Date('2026-05-01'),
3829
+ * endDate: new Date('2026-12-31'),
3830
+ * active: true
3617
3831
  * });
3618
3832
  *
3619
- * // Include related data (trigger sources and businesses)
3833
+ * // Get campaigns with claim count
3834
+ * const withCounts = await sdk.campaigns.getCampaigns({
3835
+ * include: ['claimCount']
3836
+ * });
3837
+ * withCounts.data.forEach(c => console.log(`${c.name}: ${c.claimCount} claims`));
3838
+ *
3839
+ * // Include related data (trigger sources, businesses, and claim count)
3620
3840
  * const campaignsWithRelations = await sdk.campaigns.getCampaigns({
3621
- * include: ['triggerSources', 'businesses']
3841
+ * include: ['triggerSources', 'businesses', 'claimCount']
3622
3842
  * });
3623
3843
  * ```
3624
3844
  */
@@ -4069,58 +4289,52 @@ class CampaignManager {
4069
4289
  async deleteCampaignBusinessEngagement(campaignId, engagementId) {
4070
4290
  return this.campaignService.deleteCampaignBusinessEngagement(campaignId, engagementId);
4071
4291
  }
4072
- /**
4073
- * Admin: Get all campaign claims
4074
- *
4075
- * Retrieves all campaign claims across the system for comprehensive reporting
4076
- * and analytics. This operation requires administrator privileges and provides
4077
- * system-wide visibility into campaign performance and user engagement.
4078
- *
4079
- * @returns Promise resolving to array of all campaign claims
4080
- * @throws {PersApiError} When not authenticated as administrator
4081
- *
4082
- * @example
4083
- * ```typescript
4084
- * // Admin operation - get campaign performance data
4085
- * const allClaims = await sdk.campaigns.getCampaignClaims();
4086
- *
4087
- * console.log(`Campaign Performance Report:`);
4088
- * console.log(`Total claims: ${allClaims.length}`);
4089
- *
4090
- * // Analyze claims by campaign
4091
- * const claimsByCampaign = allClaims.reduce((acc, claim) => {
4092
- * const campaignId = claim.campaignId;
4093
- * acc[campaignId] = (acc[campaignId] || 0) + 1;
4094
- * return acc;
4095
- * }, {});
4096
- *
4097
- * console.log('\nClaims by Campaign:');
4098
- * Object.entries(claimsByCampaign).forEach(([campaignId, count]) => {
4099
- * console.log(`${campaignId}: ${count} claims`);
4100
- * });
4101
- * ```
4102
- */
4103
4292
  /**
4104
4293
  * Admin: Get campaign claims with optional filters
4105
4294
  *
4106
- * Retrieves campaign claims with optional filtering by campaign, user, or business.
4295
+ * Retrieves campaign claims with optional filtering by campaign, user, business, or date range.
4107
4296
  * This operation requires administrator privileges and provides system-wide
4108
4297
  * visibility into campaign performance and user engagement.
4109
4298
  *
4110
4299
  * @param filters - Optional filters and pagination options
4300
+ * @param filters.campaignId - Filter by specific campaign ID
4301
+ * @param filters.userId - Filter by specific user ID
4302
+ * @param filters.businessId - Filter by specific business ID
4303
+ * @param filters.dateFrom - Filter claims from this date (inclusive)
4304
+ * @param filters.dateTo - Filter claims until this date (inclusive)
4305
+ * @param filters.page - Page number for pagination
4306
+ * @param filters.limit - Items per page
4307
+ * @param filters.sortBy - Field to sort by
4308
+ * @param filters.sortOrder - Sort direction ('asc' or 'desc')
4309
+ * @param include - Optional relations to include for enrichment
4111
4310
  * @returns Promise resolving to paginated campaign claims
4112
4311
  * @throws {PersApiError} When not authenticated as administrator
4113
4312
  *
4114
- * @example
4313
+ * @example Get All Claims
4314
+ * ```typescript
4315
+ * const { data: allClaims, pagination } = await sdk.campaigns.getCampaignClaims();
4316
+ * console.log(`Total: ${pagination.total}`);
4317
+ * ```
4318
+ *
4319
+ * @example Filter by User
4115
4320
  * ```typescript
4116
- * // Get all claims
4117
- * const allClaims = await sdk.campaigns.getCampaignClaims();
4321
+ * const { data: userClaims } = await sdk.campaigns.getCampaignClaims({ userId: 'user-123' });
4322
+ * ```
4118
4323
  *
4119
- * // Get claims for specific user
4120
- * const userClaims = await sdk.campaigns.getCampaignClaims({ userId: 'user-123' });
4324
+ * @example Filter by Date Range
4325
+ * ```typescript
4326
+ * // Get claims within a specific date range
4327
+ * const { data: monthClaims } = await sdk.campaigns.getCampaignClaims({
4328
+ * dateFrom: new Date('2024-01-01'),
4329
+ * dateTo: new Date('2024-01-31'),
4330
+ * limit: 100
4331
+ * });
4332
+ * console.log(`${monthClaims.length} claims in January 2024`);
4333
+ * ```
4121
4334
  *
4122
- * // Get claims for specific campaign with pagination
4123
- * const page1 = await sdk.campaigns.getCampaignClaims({
4335
+ * @example With Pagination and Campaign Filter
4336
+ * ```typescript
4337
+ * const { data: page1 } = await sdk.campaigns.getCampaignClaims({
4124
4338
  * campaignId: 'campaign-456',
4125
4339
  * page: 1,
4126
4340
  * limit: 50
@@ -4725,9 +4939,19 @@ class RedemptionManager {
4725
4939
  *
4726
4940
  * Retrieves all redemption redeems across the platform with filtering capabilities.
4727
4941
  * This is an admin-level operation that allows monitoring and analytics of redemption
4728
- * activity. Supports filtering by user, redemption offer, and enrichment of related entities.
4729
- *
4730
- * @param filters - Filter options (userId, redemptionId, pagination)
4942
+ * activity. Supports filtering by user, redemption offer, date range, and enrichment of related entities.
4943
+ *
4944
+ * @param filters - Filter options (userId, redemptionId, businessId, status, dateFrom, dateTo, pagination)
4945
+ * @param filters.userId - Filter by specific user ID
4946
+ * @param filters.redemptionId - Filter by specific redemption offer ID
4947
+ * @param filters.businessId - Filter by specific business ID
4948
+ * @param filters.status - Filter by redeem status
4949
+ * @param filters.dateFrom - Filter redeems from this date (inclusive)
4950
+ * @param filters.dateTo - Filter redeems until this date (inclusive)
4951
+ * @param filters.page - Page number for pagination
4952
+ * @param filters.limit - Items per page
4953
+ * @param filters.sortBy - Field to sort by
4954
+ * @param filters.sortOrder - Sort direction ('asc' or 'desc')
4731
4955
  * @param include - Optional relations to include for enrichment
4732
4956
  * @returns Promise resolving to paginated list of redemption redeems
4733
4957
  * @throws {PersApiError} When not authenticated as admin
@@ -4752,6 +4976,18 @@ class RedemptionManager {
4752
4976
  * console.log(`User has ${userRedeems.length} redemptions`);
4753
4977
  * ```
4754
4978
  *
4979
+ * @example Filter by Date Range
4980
+ * ```typescript
4981
+ * // Get redeems within a specific date range
4982
+ * const { data: recentRedeems } = await sdk.redemptions.getRedemptionRedeems({
4983
+ * dateFrom: new Date('2024-01-01'),
4984
+ * dateTo: new Date('2024-01-31'),
4985
+ * limit: 100
4986
+ * });
4987
+ *
4988
+ * console.log(`${recentRedeems.length} redeems in January 2024`);
4989
+ * ```
4990
+ *
4755
4991
  * @example With Enriched Data
4756
4992
  * ```typescript
4757
4993
  * const { data: redeems } = await sdk.redemptions.getRedemptionRedeems(
@@ -8688,7 +8924,8 @@ class WalletEventsManager {
8688
8924
  }
8689
8925
  // Save subscriptions for auto-resubscribe on reconnect
8690
8926
  this.lastSubscriptions.wallets = wallets;
8691
- return this.client.subscribeWallets(wallets);
8927
+ const result = await this.client.subscribeWallets(wallets);
8928
+ return result;
8692
8929
  }
8693
8930
  /**
8694
8931
  * Subscribe to chain events (Admin Dashboard)
@@ -8711,7 +8948,8 @@ class WalletEventsManager {
8711
8948
  }
8712
8949
  // Save subscriptions for auto-resubscribe on reconnect
8713
8950
  this.lastSubscriptions.chains = chains;
8714
- return this.client.subscribeChains(chains);
8951
+ const result = await this.client.subscribeChains(chains);
8952
+ return result;
8715
8953
  }
8716
8954
  /**
8717
8955
  * Unsubscribe from wallet events
@@ -9021,6 +9259,24 @@ class PersSDK {
9021
9259
  this.apiClient.setEvents(this._events);
9022
9260
  // Auto-connect to wallet events on successful login (if enabled)
9023
9261
  this.setupWalletEventsAutoConnect();
9262
+ // Auto-restore session from stored tokens (if enabled, default: true)
9263
+ this.setupAutoRestoreSession();
9264
+ }
9265
+ /**
9266
+ * Setup automatic session restoration from stored tokens
9267
+ * @internal
9268
+ */
9269
+ setupAutoRestoreSession() {
9270
+ const config = this.apiClient.getConfig();
9271
+ // Check if autoRestoreSession is enabled (default: true)
9272
+ if (config.autoRestoreSession === false) {
9273
+ return;
9274
+ }
9275
+ // Fire-and-forget: restore session asynchronously
9276
+ // Events will be emitted on success/failure
9277
+ this.restoreSession().catch(() => {
9278
+ // Error already emitted via session_restoration_failed event
9279
+ });
9024
9280
  }
9025
9281
  /**
9026
9282
  * Setup auto-connect for wallet events on authentication
@@ -9098,22 +9354,23 @@ class PersSDK {
9098
9354
  /**
9099
9355
  * Restore user session from stored tokens
9100
9356
  *
9101
- * Call this method after SDK initialization to restore the user's session
9102
- * if valid tokens exist. This is useful for maintaining login state across
9103
- * app restarts.
9357
+ * **Note:** This method is called automatically on SDK initialization when
9358
+ * `autoRestoreSession` is enabled (default: true). You only need to call this
9359
+ * manually if you disabled auto-restore or need to force a session refresh.
9360
+ *
9361
+ * Validates stored tokens and fetches user data to restore the session.
9362
+ * Emits `session_restored` event on success, `session_restoration_failed` on error.
9104
9363
  *
9105
9364
  * **Important:** Only works for USER and BUSINESS accounts. Admin/tenant
9106
9365
  * accounts don't support user data fetching, so this will return null for them
9107
9366
  * (though their tokens remain valid for API calls).
9108
9367
  *
9109
- * Emits auth domain success event when session is restored.
9110
- *
9111
9368
  * @returns Promise resolving to User data if session restored, null if no session or admin account
9112
9369
  * @throws {PersError} If token validation or user fetch fails
9113
9370
  *
9114
9371
  * @example
9115
9372
  * ```typescript
9116
- * // Call after initial render for better perceived performance
9373
+ * // Manual restore (only needed if autoRestoreSession: false)
9117
9374
  * const user = await sdk.restoreSession();
9118
9375
  * if (user) {
9119
9376
  * console.log('Welcome back,', user.name);
@@ -9127,25 +9384,57 @@ class PersSDK {
9127
9384
  }
9128
9385
  // Check auth type - only restore session for user and business accounts
9129
9386
  const authProvider = this.apiClient.getConfig().authProvider;
9130
- if (authProvider?.getAuthType) {
9131
- const authType = await authProvider.getAuthType();
9132
- if (authType === persShared.AccountOwnerType.TENANT) {
9133
- // Admin sessions don't support getCurrentUser(), skip restoration
9134
- // Tokens are valid and will be used for API calls
9387
+ const authType = authProvider?.getAuthType ? await authProvider.getAuthType() : persShared.AccountOwnerType.USER;
9388
+ if (authType === persShared.AccountOwnerType.TENANT) {
9389
+ // Ensure token is valid (refresh if expired) before fetching admin
9390
+ try {
9391
+ await this.auth.ensureValidToken();
9392
+ // Fetch current admin data
9393
+ const adminData = await this.auth.getCurrentAdmin();
9394
+ // Emit session restored for tenant admin
9395
+ this._events.emitSuccess({
9396
+ type: 'session_restored',
9397
+ domain: 'authentication',
9398
+ userMessage: 'Admin session restored successfully',
9399
+ details: { admin: adminData }
9400
+ });
9135
9401
  return null;
9136
9402
  }
9403
+ catch (error) {
9404
+ await this.auth.clearAuth();
9405
+ this._events.emitError({
9406
+ type: 'session_restoration_failed',
9407
+ domain: 'authentication',
9408
+ userMessage: 'Admin session restoration failed',
9409
+ code: 'SESSION_INVALID',
9410
+ details: { error }
9411
+ });
9412
+ throw error;
9413
+ }
9137
9414
  }
9138
9415
  try {
9139
9416
  // Ensure token is valid (refresh if expired) before fetching user
9140
9417
  await this.auth.ensureValidToken();
9141
- // Fetch user data to restore session
9418
+ // For BUSINESS auth, only fetch business context (no access to /users/me)
9419
+ if (authType === persShared.AccountOwnerType.BUSINESS) {
9420
+ const businessData = await this.auth.getCurrentBusiness();
9421
+ // Emit event with business data (no user data for business auth)
9422
+ this._events.emitSuccess({
9423
+ type: 'session_restored',
9424
+ domain: 'authentication',
9425
+ userMessage: 'Business session restored successfully',
9426
+ details: { business: businessData }
9427
+ });
9428
+ return null; // No user data for business auth
9429
+ }
9430
+ // For USER auth, fetch user data
9142
9431
  const userData = await this.auth.getCurrentUser();
9143
- // Emit event through proper event emitter
9432
+ // Emit event with user data
9144
9433
  this._events.emitSuccess({
9145
9434
  type: 'session_restored',
9146
9435
  domain: 'authentication',
9147
9436
  userMessage: 'Session restored successfully',
9148
- details: { userId: userData.id }
9437
+ details: { user: userData }
9149
9438
  });
9150
9439
  return userData;
9151
9440
  }
@@ -9694,4 +9983,4 @@ exports.buildWalletEventsWsUrl = buildWalletEventsWsUrl;
9694
9983
  exports.createPersEventsClient = createPersEventsClient;
9695
9984
  exports.createPersSDK = createPersSDK;
9696
9985
  exports.mergeWithDefaults = mergeWithDefaults;
9697
- //# sourceMappingURL=pers-sdk-DHohtBN8.cjs.map
9986
+ //# sourceMappingURL=pers-sdk-DXCcAgUS.cjs.map