@explorins/pers-sdk 1.6.4 → 1.6.9

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 (212) hide show
  1. package/README.md +86 -342
  2. package/dist/analytics/index.d.ts +0 -16
  3. package/dist/analytics/index.d.ts.map +1 -1
  4. package/dist/analytics.cjs +5 -73
  5. package/dist/analytics.cjs.map +1 -1
  6. package/dist/analytics.js +1 -72
  7. package/dist/analytics.js.map +1 -1
  8. package/dist/business/index.d.ts +0 -24
  9. package/dist/business/index.d.ts.map +1 -1
  10. package/dist/business.cjs +5 -273
  11. package/dist/business.cjs.map +1 -1
  12. package/dist/business.js +1 -272
  13. package/dist/business.js.map +1 -1
  14. package/dist/campaign/api/campaign-api.d.ts +3 -3
  15. package/dist/campaign/api/campaign-api.d.ts.map +1 -1
  16. package/dist/campaign/index.d.ts +0 -34
  17. package/dist/campaign/index.d.ts.map +1 -1
  18. package/dist/campaign.cjs +5 -447
  19. package/dist/campaign.cjs.map +1 -1
  20. package/dist/campaign.js +1 -446
  21. package/dist/campaign.js.map +1 -1
  22. package/dist/chunks/analytics-service-CitlimKJ.cjs +49 -0
  23. package/dist/chunks/analytics-service-CitlimKJ.cjs.map +1 -0
  24. package/dist/chunks/analytics-service-CxyrOwel.js +46 -0
  25. package/dist/chunks/analytics-service-CxyrOwel.js.map +1 -0
  26. package/dist/chunks/{token-sdk-BW4kkJb3.js → base-token-service-BSXDwrcq.js} +138 -204
  27. package/dist/chunks/base-token-service-BSXDwrcq.js.map +1 -0
  28. package/dist/chunks/{token-sdk-CiAbOb6c.cjs → base-token-service-CYuqPPs0.cjs} +140 -207
  29. package/dist/chunks/base-token-service-CYuqPPs0.cjs.map +1 -0
  30. package/dist/chunks/business-service-Cq3-oksM.cjs +241 -0
  31. package/dist/chunks/business-service-Cq3-oksM.cjs.map +1 -0
  32. package/dist/chunks/business-service-DrC-TNGa.js +238 -0
  33. package/dist/chunks/business-service-DrC-TNGa.js.map +1 -0
  34. package/dist/chunks/campaign-service-CWK9I388.cjs +403 -0
  35. package/dist/chunks/campaign-service-CWK9I388.cjs.map +1 -0
  36. package/dist/chunks/campaign-service-Dd7gMjC9.js +400 -0
  37. package/dist/chunks/campaign-service-Dd7gMjC9.js.map +1 -0
  38. package/dist/chunks/donation-service-CyJS4DIZ.js +47 -0
  39. package/dist/chunks/donation-service-CyJS4DIZ.js.map +1 -0
  40. package/dist/chunks/donation-service-D-xFrONi.cjs +50 -0
  41. package/dist/chunks/donation-service-D-xFrONi.cjs.map +1 -0
  42. package/dist/chunks/{index-CJ9Jfa4A.js → explorer.utils-Ckll15ja.js} +108 -172
  43. package/dist/chunks/explorer.utils-Ckll15ja.js.map +1 -0
  44. package/dist/chunks/{index-CzEluQmf.cjs → explorer.utils-GpskbLl1.cjs} +106 -174
  45. package/dist/chunks/explorer.utils-GpskbLl1.cjs.map +1 -0
  46. package/dist/chunks/index-BtDNXaFq.js +13 -0
  47. package/dist/chunks/index-BtDNXaFq.js.map +1 -0
  48. package/dist/chunks/index-CMk3Aqkk.cjs +15 -0
  49. package/dist/chunks/index-CMk3Aqkk.cjs.map +1 -0
  50. package/dist/chunks/payment-service-B4qx0qiE.cjs +220 -0
  51. package/dist/chunks/payment-service-B4qx0qiE.cjs.map +1 -0
  52. package/dist/chunks/payment-service-DfCBFosx.js +217 -0
  53. package/dist/chunks/payment-service-DfCBFosx.js.map +1 -0
  54. package/dist/chunks/pers-sdk-Bd6BZHgt.js +5672 -0
  55. package/dist/chunks/pers-sdk-Bd6BZHgt.js.map +1 -0
  56. package/dist/chunks/pers-sdk-CmyPEhy7.cjs +5705 -0
  57. package/dist/chunks/pers-sdk-CmyPEhy7.cjs.map +1 -0
  58. package/dist/chunks/redemption-service-7qbeQxEM.cjs +330 -0
  59. package/dist/chunks/redemption-service-7qbeQxEM.cjs.map +1 -0
  60. package/dist/chunks/redemption-service-BT0J5Iy7.js +327 -0
  61. package/dist/chunks/redemption-service-BT0J5Iy7.js.map +1 -0
  62. package/dist/chunks/tenant-service-Ba7xrWED.cjs +171 -0
  63. package/dist/chunks/tenant-service-Ba7xrWED.cjs.map +1 -0
  64. package/dist/chunks/tenant-service-DELk412y.js +168 -0
  65. package/dist/chunks/tenant-service-DELk412y.js.map +1 -0
  66. package/dist/chunks/token-service-BWScn8Qa.cjs +208 -0
  67. package/dist/chunks/token-service-BWScn8Qa.cjs.map +1 -0
  68. package/dist/chunks/token-service-CpVwC5Eb.js +205 -0
  69. package/dist/chunks/token-service-CpVwC5Eb.js.map +1 -0
  70. package/dist/chunks/user-service-D1Rn4U8u.cjs +153 -0
  71. package/dist/chunks/user-service-D1Rn4U8u.cjs.map +1 -0
  72. package/dist/chunks/user-service-D6mTa_WZ.js +150 -0
  73. package/dist/chunks/user-service-D6mTa_WZ.js.map +1 -0
  74. package/dist/chunks/{index-BfOoX87y.cjs → web3-chain-service-D75TcHkh.cjs} +28 -53
  75. package/dist/chunks/web3-chain-service-D75TcHkh.cjs.map +1 -0
  76. package/dist/chunks/{index-CM21r58m.js → web3-chain-service-Dp5Z8p9I.js} +28 -51
  77. package/dist/chunks/web3-chain-service-Dp5Z8p9I.js.map +1 -0
  78. package/dist/core/auth/api/auth-api.d.ts +11 -14
  79. package/dist/core/auth/api/auth-api.d.ts.map +1 -1
  80. package/dist/core/auth/auth-provider.interface.d.ts +36 -68
  81. package/dist/core/auth/auth-provider.interface.d.ts.map +1 -1
  82. package/dist/core/auth/default-auth-provider.d.ts +13 -59
  83. package/dist/core/auth/default-auth-provider.d.ts.map +1 -1
  84. package/dist/core/auth/index.d.ts +8 -14
  85. package/dist/core/auth/index.d.ts.map +1 -1
  86. package/dist/core/auth/refresh-manager.d.ts +15 -0
  87. package/dist/core/auth/refresh-manager.d.ts.map +1 -0
  88. package/dist/core/auth/services/auth-service.d.ts +15 -21
  89. package/dist/core/auth/services/auth-service.d.ts.map +1 -1
  90. package/dist/core/auth/token-storage.d.ts +26 -48
  91. package/dist/core/auth/token-storage.d.ts.map +1 -1
  92. package/dist/core/environment.d.ts +2 -4
  93. package/dist/core/environment.d.ts.map +1 -1
  94. package/dist/core/errors/index.d.ts +1 -5
  95. package/dist/core/errors/index.d.ts.map +1 -1
  96. package/dist/core/index.d.ts +4 -3
  97. package/dist/core/index.d.ts.map +1 -1
  98. package/dist/core/pers-api-client.d.ts +14 -156
  99. package/dist/core/pers-api-client.d.ts.map +1 -1
  100. package/dist/core/pers-config.d.ts +13 -12
  101. package/dist/core/pers-config.d.ts.map +1 -1
  102. package/dist/core/utils/jwt.function.d.ts +9 -0
  103. package/dist/core/utils/jwt.function.d.ts.map +1 -1
  104. package/dist/core.cjs +22 -18
  105. package/dist/core.cjs.map +1 -1
  106. package/dist/core.js +13 -14
  107. package/dist/core.js.map +1 -1
  108. package/dist/donation/index.d.ts +0 -15
  109. package/dist/donation/index.d.ts.map +1 -1
  110. package/dist/donation.cjs +5 -75
  111. package/dist/donation.cjs.map +1 -1
  112. package/dist/donation.js +1 -74
  113. package/dist/donation.js.map +1 -1
  114. package/dist/index.cjs +50 -56
  115. package/dist/index.cjs.map +1 -1
  116. package/dist/index.js +15 -15
  117. package/dist/managers/analytics-manager.d.ts +290 -10
  118. package/dist/managers/analytics-manager.d.ts.map +1 -1
  119. package/dist/managers/auth-manager.d.ts +123 -23
  120. package/dist/managers/auth-manager.d.ts.map +1 -1
  121. package/dist/managers/business-manager.d.ts +273 -18
  122. package/dist/managers/business-manager.d.ts.map +1 -1
  123. package/dist/managers/campaign-manager.d.ts +585 -46
  124. package/dist/managers/campaign-manager.d.ts.map +1 -1
  125. package/dist/managers/donation-manager.d.ts +5 -5
  126. package/dist/managers/donation-manager.d.ts.map +1 -1
  127. package/dist/managers/file-manager.d.ts +430 -13
  128. package/dist/managers/file-manager.d.ts.map +1 -1
  129. package/dist/managers/purchase-manager.d.ts +340 -15
  130. package/dist/managers/purchase-manager.d.ts.map +1 -1
  131. package/dist/managers/redemption-manager.d.ts +450 -27
  132. package/dist/managers/redemption-manager.d.ts.map +1 -1
  133. package/dist/managers/tenant-manager.d.ts +5 -5
  134. package/dist/managers/tenant-manager.d.ts.map +1 -1
  135. package/dist/managers/token-manager.d.ts +245 -21
  136. package/dist/managers/token-manager.d.ts.map +1 -1
  137. package/dist/managers/transaction-manager.d.ts +447 -18
  138. package/dist/managers/transaction-manager.d.ts.map +1 -1
  139. package/dist/managers/user-manager.d.ts +216 -14
  140. package/dist/managers/user-manager.d.ts.map +1 -1
  141. package/dist/managers/web3-manager.d.ts +4 -4
  142. package/dist/managers/web3-manager.d.ts.map +1 -1
  143. package/dist/package.json +10 -4
  144. package/dist/payment/index.d.ts +0 -21
  145. package/dist/payment/index.d.ts.map +1 -1
  146. package/dist/payment.cjs +5 -255
  147. package/dist/payment.cjs.map +1 -1
  148. package/dist/payment.js +1 -254
  149. package/dist/payment.js.map +1 -1
  150. package/dist/pers-sdk.d.ts +141 -34
  151. package/dist/pers-sdk.d.ts.map +1 -1
  152. package/dist/redemption/index.d.ts +0 -25
  153. package/dist/redemption/index.d.ts.map +1 -1
  154. package/dist/redemption.cjs +5 -365
  155. package/dist/redemption.cjs.map +1 -1
  156. package/dist/redemption.js +1 -364
  157. package/dist/redemption.js.map +1 -1
  158. package/dist/tenant/index.d.ts +0 -22
  159. package/dist/tenant/index.d.ts.map +1 -1
  160. package/dist/tenant.cjs +5 -203
  161. package/dist/tenant.cjs.map +1 -1
  162. package/dist/tenant.js +1 -202
  163. package/dist/tenant.js.map +1 -1
  164. package/dist/token.cjs +6 -6
  165. package/dist/token.js +2 -2
  166. package/dist/transaction/index.d.ts +0 -22
  167. package/dist/transaction/index.d.ts.map +1 -1
  168. package/dist/transaction.cjs +0 -40
  169. package/dist/transaction.cjs.map +1 -1
  170. package/dist/transaction.js +1 -40
  171. package/dist/transaction.js.map +1 -1
  172. package/dist/user/index.d.ts +0 -25
  173. package/dist/user/index.d.ts.map +1 -1
  174. package/dist/user.cjs +5 -185
  175. package/dist/user.cjs.map +1 -1
  176. package/dist/user.js +1 -184
  177. package/dist/user.js.map +1 -1
  178. package/dist/web3/index.d.ts +0 -11
  179. package/dist/web3/index.d.ts.map +1 -1
  180. package/dist/web3-chain/index.d.ts +0 -9
  181. package/dist/web3-chain/index.d.ts.map +1 -1
  182. package/dist/web3-chain/services/getWeb3FCD.service.d.ts.map +1 -1
  183. package/dist/web3-chain.cjs +5 -6
  184. package/dist/web3-chain.cjs.map +1 -1
  185. package/dist/web3-chain.js +2 -2
  186. package/dist/web3.cjs +6 -10
  187. package/dist/web3.cjs.map +1 -1
  188. package/dist/web3.js +1 -4
  189. package/dist/web3.js.map +1 -1
  190. package/package.json +10 -4
  191. package/dist/chunks/base-token-service-D0KANDgM.js +0 -139
  192. package/dist/chunks/base-token-service-D0KANDgM.js.map +0 -1
  193. package/dist/chunks/base-token-service-zNfPjHRx.cjs +0 -141
  194. package/dist/chunks/base-token-service-zNfPjHRx.cjs.map +0 -1
  195. package/dist/chunks/index-BfOoX87y.cjs.map +0 -1
  196. package/dist/chunks/index-CJ9Jfa4A.js.map +0 -1
  197. package/dist/chunks/index-CM21r58m.js.map +0 -1
  198. package/dist/chunks/index-CzEluQmf.cjs.map +0 -1
  199. package/dist/chunks/pers-sdk-DbPwFKrf.cjs +0 -3378
  200. package/dist/chunks/pers-sdk-DbPwFKrf.cjs.map +0 -1
  201. package/dist/chunks/pers-sdk-Z6MKeFBX.js +0 -3353
  202. package/dist/chunks/pers-sdk-Z6MKeFBX.js.map +0 -1
  203. package/dist/chunks/token-sdk-BW4kkJb3.js.map +0 -1
  204. package/dist/chunks/token-sdk-CiAbOb6c.cjs.map +0 -1
  205. package/dist/core/auth/auth-constants.d.ts +0 -33
  206. package/dist/core/auth/auth-constants.d.ts.map +0 -1
  207. package/dist/core/auth/auth-errors.d.ts +0 -8
  208. package/dist/core/auth/auth-errors.d.ts.map +0 -1
  209. package/dist/core/auth/create-auth-provider.d.ts +0 -27
  210. package/dist/core/auth/create-auth-provider.d.ts.map +0 -1
  211. package/dist/core/auth/token-refresh.d.ts +0 -91
  212. package/dist/core/auth/token-refresh.d.ts.map +0 -1
@@ -1,3378 +0,0 @@
1
- 'use strict';
2
-
3
- var persShared = require('@explorins/pers-shared');
4
- var user = require('../user.cjs');
5
- var userStatus = require('../user-status.cjs');
6
- var tokenSdk = require('./token-sdk-CiAbOb6c.cjs');
7
- var business = require('../business.cjs');
8
- var campaign = require('../campaign.cjs');
9
- var redemption = require('../redemption.cjs');
10
- var transaction = require('../transaction.cjs');
11
- var payment = require('../payment.cjs');
12
- var tenant = require('../tenant.cjs');
13
- var analytics = require('../analytics.cjs');
14
- var donation = require('../donation.cjs');
15
- var web3 = require('./index-CzEluQmf.cjs');
16
- var web3Chain = require('./index-BfOoX87y.cjs');
17
-
18
- /**
19
- * PERS SDK Configuration interfaces and utilities
20
- *
21
- * Provides type-safe configuration options for the PERS SDK
22
- * with sensible defaults for production environments.
23
- */
24
- /**
25
- * Default configuration values
26
- */
27
- const DEFAULT_PERS_CONFIG = {
28
- environment: 'production',
29
- apiVersion: 'v2',
30
- timeout: 30000,
31
- retries: 3,
32
- tokenRefreshMargin: 60, // Refresh tokens 60 seconds before expiry
33
- backgroundRefreshThreshold: 30 // Use background refresh if >30s remaining
34
- };
35
- /**
36
- * Internal function to construct API root from environment
37
- * Now defaults to production and v2
38
- */
39
- function buildApiRoot(environment = 'production', version = 'v2') {
40
- const baseUrls = {
41
- development: 'https://explorins-loyalty.ngrok.io',
42
- staging: `https://dev.api.pers.ninja/${version}`,
43
- production: `https://api.pers.ninja/${version}`
44
- };
45
- return `${baseUrls[environment]}`;
46
- }
47
- /**
48
- * Merge user config with defaults
49
- */
50
- function mergeWithDefaults(config) {
51
- return {
52
- ...DEFAULT_PERS_CONFIG,
53
- ...config,
54
- environment: config.environment ?? DEFAULT_PERS_CONFIG.environment,
55
- apiVersion: config.apiVersion ?? DEFAULT_PERS_CONFIG.apiVersion,
56
- timeout: config.timeout ?? DEFAULT_PERS_CONFIG.timeout,
57
- retries: config.retries ?? DEFAULT_PERS_CONFIG.retries
58
- };
59
- }
60
-
61
- /**
62
- * Platform-Agnostic Auth Admin API Client
63
- *
64
- * Handles authentication and authorization admin operations using the PERS backend.
65
- * Uses @explorins/pers-shared DTOs for consistency with backend.
66
- *
67
- * Note: Special header handling (bypass-auth-interceptor) may need to be implemented
68
- * at the PersApiClient level or through a specialized auth client.
69
- */
70
- class AuthApi {
71
- constructor(apiClient) {
72
- this.apiClient = apiClient;
73
- this.basePath = '/auth';
74
- }
75
- // ==========================================
76
- // ADMIN AUTHENTICATION OPERATIONS
77
- // ==========================================
78
- /**
79
- * ADMIN: Login tenant admin with JWT
80
- * Note: JWT handling and auth bypass headers may need special implementation
81
- */
82
- async loginTenantAdmin(jwt) {
83
- const body = {
84
- authToken: jwt,
85
- authType: persShared.AccountOwnerType.TENANT
86
- };
87
- return this.apiClient.post(`${this.basePath}/token`, body, { bypassAuth: true });
88
- }
89
- /**
90
- * Login user with JWT - bypasses auth headers
91
- */
92
- async loginUser(jwt) {
93
- const body = {
94
- authToken: jwt,
95
- authType: persShared.AccountOwnerType.USER
96
- };
97
- return this.apiClient.post(`${this.basePath}/token`, body, { bypassAuth: true });
98
- }
99
- async loginUnAuthenticated(rawLoginData) {
100
- const body = {
101
- authToken: '',
102
- authType: persShared.AccountOwnerType.USER,
103
- rawLoginData
104
- };
105
- return this.apiClient.post(`${this.basePath}/token`, body, { bypassAuth: true });
106
- }
107
- /**
108
- * Refresh access token - bypasses auth headers to prevent circular dependency
109
- */
110
- async refreshAccessToken(refreshToken) {
111
- // Bypass auth headers for refresh calls to prevent circular dependency
112
- return this.apiClient.post(`${this.basePath}/refresh`, { refreshToken }, { bypassAuth: true });
113
- }
114
- }
115
-
116
- /**
117
- * Platform-Agnostic Auth Admin Service
118
- *
119
- * Contains auth admin business logic and operations that work across platforms.
120
- * No framework dependencies - pure TypeScript business logic.
121
- *
122
- * Focuses only on actual backend capabilities.
123
- */
124
- class AuthService {
125
- constructor(authApi, authProvider) {
126
- this.authApi = authApi;
127
- this.authProvider = authProvider;
128
- }
129
- // ==========================================
130
- // ADMIN AUTHENTICATION OPERATIONS
131
- // ==========================================
132
- /**
133
- * ADMIN: Login tenant admin with JWT
134
- * Automatically stores tokens if auth provider supports token storage
135
- */
136
- async loginTenantAdmin(jwt) {
137
- const response = await this.authApi.loginTenantAdmin(jwt);
138
- // Store tokens if auth provider supports it
139
- if (this.authProvider && response.accessToken) {
140
- await this.storeTokens(response.accessToken, response.refreshToken, 'admin', jwt);
141
- }
142
- return response;
143
- }
144
- /**
145
- * Automatically stores tokens if auth provider supports token storage
146
- */
147
- async loginUser(jwt) {
148
- const response = await this.authApi.loginUser(jwt);
149
- // Store tokens if auth provider supports it
150
- if (this.authProvider && response.accessToken) {
151
- await this.storeTokens(response.accessToken, response.refreshToken, 'user', jwt);
152
- }
153
- return response;
154
- }
155
- /**
156
- * Automatically stores tokens if auth provider supports token storage
157
- */
158
- async loginUserWithRawData(rawLoginData) {
159
- const loginData = {
160
- externalId: rawLoginData?.externalId,
161
- email: rawLoginData?.email,
162
- firstName: rawLoginData?.firstName,
163
- lastName: rawLoginData?.lastName,
164
- customData: rawLoginData?.customData
165
- };
166
- const response = await this.authApi.loginUnAuthenticated(loginData);
167
- // Store tokens if auth provider supports it
168
- if (this.authProvider && response.accessToken) {
169
- await this.storeTokens(response.accessToken, response.refreshToken, 'user');
170
- }
171
- return response;
172
- }
173
- /**
174
- * ADMIN: Refresh access token
175
- * Automatically stores new tokens if auth provider supports token storage
176
- */
177
- async refreshAccessToken(refreshToken) {
178
- // Use provided refresh token or get from auth provider
179
- const tokenToUse = refreshToken || (this.authProvider?.getRefreshToken ? await this.authProvider.getRefreshToken() : null);
180
- if (!tokenToUse) {
181
- throw new Error('No refresh token available for token refresh');
182
- }
183
- const response = await this.authApi.refreshAccessToken(tokenToUse);
184
- // Store new tokens if auth provider supports it
185
- if (this.authProvider && response.accessToken) {
186
- await this.storeTokens(response.accessToken, response.refreshToken);
187
- }
188
- return response;
189
- }
190
- /**
191
- * Automatic token refresh using stored refresh token
192
- * Convenience method for 401 error handling
193
- */
194
- async autoRefreshToken() {
195
- return this.refreshAccessToken(); // Uses stored refresh token
196
- }
197
- /**
198
- * Clear stored tokens if auth provider supports it
199
- */
200
- async clearTokens() {
201
- if (this.authProvider?.clearTokens) {
202
- await this.authProvider.clearTokens();
203
- }
204
- }
205
- /**
206
- * Check if we have valid tokens for authentication
207
- */
208
- hasValidAuth() {
209
- return this.authProvider?.hasValidToken?.() ?? false;
210
- }
211
- // ==========================================
212
- // PRIVATE HELPERS
213
- // ==========================================
214
- /**
215
- * Store tokens using auth provider if it supports token storage
216
- */
217
- async storeTokens(accessToken, refreshToken, authType, providerToken) {
218
- if (!this.authProvider)
219
- return;
220
- try {
221
- // Store access token
222
- if (this.authProvider.setAccessToken) {
223
- await this.authProvider.setAccessToken(accessToken);
224
- }
225
- // Store refresh token if provided and supported
226
- if (refreshToken && this.authProvider.setRefreshToken) {
227
- await this.authProvider.setRefreshToken(refreshToken);
228
- }
229
- // Store provider token if provided and provider supports it
230
- if (providerToken && 'setProviderToken' in this.authProvider &&
231
- typeof this.authProvider.setProviderToken === 'function') {
232
- await this.authProvider.setProviderToken(providerToken);
233
- }
234
- // Store auth type if provided and provider supports it
235
- if (authType && 'setAuthType' in this.authProvider &&
236
- typeof this.authProvider.setAuthType === 'function') {
237
- await this.authProvider.setAuthType(authType);
238
- }
239
- }
240
- catch (error) {
241
- // Don't throw - token storage failure shouldn't break authentication
242
- }
243
- }
244
- }
245
-
246
- /**
247
- * Authentication-related constants for type safety
248
- */
249
- /**
250
- * Storage keys for authentication tokens
251
- */
252
- const AUTH_STORAGE_KEYS = {
253
- ACCESS_TOKEN: 'pers_access_token',
254
- REFRESH_TOKEN: 'pers_refresh_token',
255
- PROVIDER_TOKEN: 'pers_provider_token', // Generic external JWT (Firebase, Auth0, etc.)
256
- AUTH_TYPE: 'pers_auth_type',
257
- };
258
- /**
259
- * Generate prefixed storage keys for different auth types
260
- */
261
- function createStorageKey(baseKey, authType = 'user') {
262
- if (baseKey === AUTH_STORAGE_KEYS.ACCESS_TOKEN) {
263
- return `pers_access_token_${authType}`;
264
- }
265
- if (baseKey === AUTH_STORAGE_KEYS.REFRESH_TOKEN) {
266
- return `pers_refresh_token_${authType}`;
267
- }
268
- return baseKey;
269
- }
270
- /**
271
- * Authentication method types
272
- */
273
- const AUTH_METHODS = {
274
- GET: 'GET',
275
- POST: 'POST',
276
- PUT: 'PUT',
277
- DELETE: 'DELETE',
278
- };
279
-
280
- /**
281
- * Token Storage Management
282
- *
283
- * Handles secure token storage with different strategies
284
- */
285
- /**
286
- * LocalStorage-based token storage
287
- */
288
- let LocalStorageTokenStorage$1 = class LocalStorageTokenStorage {
289
- async setToken(key, value) {
290
- if (typeof localStorage !== 'undefined') {
291
- localStorage.setItem(key, value);
292
- }
293
- }
294
- async getToken(key) {
295
- if (typeof localStorage !== 'undefined') {
296
- return localStorage.getItem(key);
297
- }
298
- return null;
299
- }
300
- async removeToken(key) {
301
- if (typeof localStorage !== 'undefined') {
302
- localStorage.removeItem(key);
303
- }
304
- }
305
- async clear() {
306
- if (typeof localStorage !== 'undefined') {
307
- Object.values(AUTH_STORAGE_KEYS).forEach(key => {
308
- localStorage.removeItem(key);
309
- });
310
- }
311
- }
312
- };
313
- /**
314
- * Token Manager - High-level token management
315
- */
316
- let TokenManager$1 = class TokenManager {
317
- constructor(storage = new LocalStorageTokenStorage$1()) {
318
- this.storage = storage;
319
- }
320
- async setAccessToken(token) {
321
- await this.storage.setToken(AUTH_STORAGE_KEYS.ACCESS_TOKEN, token);
322
- }
323
- async getAccessToken() {
324
- return this.storage.getToken(AUTH_STORAGE_KEYS.ACCESS_TOKEN);
325
- }
326
- async setRefreshToken(token) {
327
- await this.storage.setToken(AUTH_STORAGE_KEYS.REFRESH_TOKEN, token);
328
- }
329
- async getRefreshToken() {
330
- return this.storage.getToken(AUTH_STORAGE_KEYS.REFRESH_TOKEN);
331
- }
332
- async getProviderToken() {
333
- return await this.storage.getToken(AUTH_STORAGE_KEYS.PROVIDER_TOKEN);
334
- }
335
- async setTokenData(data) {
336
- if (data.accessToken) {
337
- await this.setAccessToken(data.accessToken);
338
- }
339
- if (data.refreshToken) {
340
- await this.setRefreshToken(data.refreshToken);
341
- }
342
- // Could store expiration time if needed
343
- }
344
- async getTokenData() {
345
- const accessToken = await this.getAccessToken();
346
- const refreshToken = await this.getRefreshToken();
347
- return {
348
- accessToken: accessToken || undefined,
349
- refreshToken: refreshToken || undefined
350
- };
351
- }
352
- async clearAllTokens() {
353
- await this.storage.clear();
354
- }
355
- async hasValidTokens() {
356
- const accessToken = await this.getAccessToken();
357
- return !!accessToken;
358
- }
359
- async hasRefreshToken() {
360
- const refreshToken = await this.getRefreshToken();
361
- return !!refreshToken;
362
- }
363
- async removeToken(key) {
364
- await this.storage.removeToken(key);
365
- }
366
- /**
367
- * Set auth type (user or admin)
368
- */
369
- async setAuthType(authType) {
370
- await this.storage.setToken(AUTH_STORAGE_KEYS.AUTH_TYPE, authType);
371
- }
372
- /**
373
- * Get stored auth type
374
- */
375
- async getAuthType() {
376
- const authType = await this.storage.getToken(AUTH_STORAGE_KEYS.AUTH_TYPE);
377
- return authType;
378
- }
379
- /**
380
- * Clear auth type from storage
381
- */
382
- async clearAuthType() {
383
- await this.storage.removeToken(AUTH_STORAGE_KEYS.AUTH_TYPE);
384
- }
385
- /**
386
- * Set provider token (generic external JWT)
387
- */
388
- async setProviderToken(token) {
389
- await this.storage.setToken(AUTH_STORAGE_KEYS.PROVIDER_TOKEN, token);
390
- }
391
- /**
392
- * Clear provider token
393
- */
394
- async clearProviderToken() {
395
- await this.storage.removeToken(AUTH_STORAGE_KEYS.PROVIDER_TOKEN);
396
- }
397
- };
398
-
399
- /**
400
- * PERS SDK Error Handling - Optimized for Performance
401
- *
402
- * Consolidated API and auth errors for fast SDK performance
403
- * Uses @explorins/pers-shared when available, fallback to SDK errors
404
- */
405
- // Fast type guards and utilities
406
- class ErrorUtils {
407
- /**
408
- * Fast token expiration detection
409
- */
410
- static isTokenExpired(error) {
411
- if (typeof error !== 'object' || error === null)
412
- return false;
413
- const err = error;
414
- const apiError = err?.error || err?.response?.data || err;
415
- const status = err?.status || err?.response?.status || err?.statusCode;
416
- return apiError?.code === 'TOKEN_EXPIRED' ||
417
- apiError?.errorCode === 'TOKEN_EXPIRED' ||
418
- (status === 401 && apiError?.message?.toLowerCase()?.includes('token'));
419
- }
420
- /**
421
- * Fast error message extraction
422
- */
423
- static getMessage(error) {
424
- if (typeof error !== 'object' || error === null)
425
- return 'Unknown error';
426
- const err = error;
427
- const apiError = err?.error || err?.response?.data || err;
428
- return apiError?.message || apiError?.detail || err?.message || 'Request failed';
429
- }
430
- /**
431
- * Fast status code extraction
432
- */
433
- static getStatus(error) {
434
- if (typeof error !== 'object' || error === null)
435
- return null;
436
- const err = error;
437
- return err?.status || err?.statusCode || err?.response?.status || null;
438
- }
439
- /**
440
- * Fast retryability check
441
- */
442
- static isRetryable(error) {
443
- if (typeof error !== 'object' || error === null)
444
- return false;
445
- const err = error;
446
- // Check explicit retryable property first (fastest)
447
- if (typeof err?.retryable === 'boolean')
448
- return err.retryable;
449
- // Fast status-based check
450
- const status = ErrorUtils.getStatus(error);
451
- return status === null || status >= 500 || status === 429;
452
- }
453
- /**
454
- * Check if error is from PERS API (uses @explorins/pers-shared format)
455
- */
456
- static isPersApiError(error) {
457
- return typeof error === 'object' && error !== null &&
458
- 'errorCode' in error && 'domain' in error && 'category' in error;
459
- }
460
- }
461
- // SDK-specific error classes for auth flows
462
- class TokenRefreshNeeded extends Error {
463
- constructor(refreshToken) {
464
- super('Token refresh needed');
465
- this.refreshToken = refreshToken;
466
- this.errorCode = 'TOKEN_REFRESH_NEEDED';
467
- this.domain = 'auth';
468
- this.category = 'SECURITY';
469
- this.retryable = true;
470
- this.name = 'TokenRefreshNeeded';
471
- }
472
- }
473
- class ProviderTokenRefreshNeeded extends Error {
474
- constructor(providerToken) {
475
- super('Provider token refresh needed');
476
- this.providerToken = providerToken;
477
- this.errorCode = 'PROVIDER_TOKEN_REFRESH_NEEDED';
478
- this.domain = 'auth';
479
- this.category = 'SECURITY';
480
- this.retryable = true;
481
- this.name = 'ProviderTokenRefreshNeeded';
482
- }
483
- }
484
- class LogoutRequired extends Error {
485
- constructor(message) {
486
- super(message);
487
- this.errorCode = 'LOGOUT_REQUIRED';
488
- this.domain = 'auth';
489
- this.category = 'SECURITY';
490
- this.retryable = false;
491
- this.name = 'LogoutRequired';
492
- }
493
- }
494
- class PersApiError extends Error {
495
- constructor(message, endpoint, method, status, retryable = false) {
496
- super(`API request failed: ${message}`);
497
- this.endpoint = endpoint;
498
- this.method = method;
499
- this.status = status;
500
- this.errorCode = 'PERS_API_ERROR';
501
- this.domain = 'api';
502
- this.category = 'TECHNICAL';
503
- this.name = 'PersApiError';
504
- this.retryable = retryable;
505
- }
506
- }
507
-
508
- /**
509
- * Token Refresh Management
510
- *
511
- * Handles the 6-step authentication process:
512
- * 1. Check for provider token → get complete token set from PERS if missing
513
- * 2. Store all tokens (access, refresh, provider)
514
- * 3. Use access token for requests
515
- * 4. Use refresh token if access expires → get new token set, keep provider
516
- * 5. Fall back to provider token if refresh fails → get fresh token set from PERS
517
- * 6. Clear all tokens if provider also fails
518
- */
519
- /**
520
- * Token Refresh Manager
521
- *
522
- * Implements the 6-step authentication process:
523
- * 1. Use provider token to retrieve complete token set from PERS if not present
524
- * 2. Store all 3 tokens (access, refresh, provider)
525
- * 3. Use access token for API requests
526
- * 4. Use refresh token if access expires → get new token set, preserve provider token
527
- * 5. Fall back to provider token if refresh fails → get fresh token set from PERS
528
- * 6. Clear all tokens if provider also fails → force logout
529
- */
530
- class TokenRefreshManager {
531
- constructor(tokenManager, refreshStrategy) {
532
- this.refreshAttempts = new Map();
533
- this.MAX_REFRESH_ATTEMPTS = 1;
534
- this.loginRequiredListeners = [];
535
- this.tokenManager = tokenManager;
536
- this.refreshStrategy = refreshStrategy;
537
- }
538
- /**
539
- * Add listener for login required events
540
- */
541
- onLoginRequired(listener) {
542
- this.loginRequiredListeners.push(listener);
543
- }
544
- /**
545
- * Remove listener for login required events
546
- */
547
- removeLoginRequiredListener(listener) {
548
- const index = this.loginRequiredListeners.indexOf(listener);
549
- if (index > -1) {
550
- this.loginRequiredListeners.splice(index, 1);
551
- }
552
- }
553
- /**
554
- * Emit login required event to all listeners
555
- */
556
- emitLoginRequired(reason) {
557
- const event = {
558
- reason,
559
- timestamp: new Date()
560
- };
561
- this.loginRequiredListeners.forEach(listener => {
562
- try {
563
- listener(event);
564
- }
565
- catch (error) {
566
- // Listener error - continuing with other listeners
567
- }
568
- });
569
- }
570
- /**
571
- * Handle token expiration - orchestrates the 6-step authentication process
572
- * 1. Check for provider token → get complete token set from PERS if missing
573
- * 2. Store all 3 tokens (access, refresh, provider)
574
- * 3. Use access token for requests
575
- * 4. Use refresh token if access expires → get new token set, keep provider
576
- * 5. Fall back to provider token if refresh fails → get fresh token set from PERS
577
- * 6. Clear all tokens if provider also fails
578
- */
579
- async handleTokenExpiration() {
580
- try {
581
- const accessToken = await this.tokenManager.getAccessToken();
582
- const refreshToken = await this.tokenManager.getRefreshToken();
583
- const providerToken = await this.tokenManager.getProviderToken();
584
- // If we have no PERS tokens but have a provider token, use it to get the complete set
585
- if (!accessToken && !refreshToken && providerToken) {
586
- await this.executeProviderTokenFlow(providerToken);
587
- return;
588
- }
589
- // Try refresh token if we have one
590
- if (refreshToken) {
591
- await this.executeRefreshTokenFlow(refreshToken);
592
- return;
593
- }
594
- // No refresh token, try provider token
595
- if (providerToken) {
596
- await this.executeProviderTokenFlow(providerToken);
597
- return;
598
- }
599
- // No tokens available, require login
600
- await this.executeAuthCleanup('No authentication tokens available');
601
- throw new LogoutRequired('No authentication tokens available');
602
- }
603
- catch (error) {
604
- if (error instanceof TokenRefreshNeeded || error instanceof ProviderTokenRefreshNeeded || error instanceof LogoutRequired) {
605
- throw error;
606
- }
607
- // Convert unexpected errors to login requirement
608
- await this.executeAuthCleanup('Authentication process failed unexpectedly');
609
- throw new LogoutRequired('Authentication process failed unexpectedly');
610
- }
611
- }
612
- /**
613
- * Execute refresh with refresh token (Step 4)
614
- * Use refresh token to get new access token, preserve provider token
615
- */
616
- async executeRefreshTokenFlow(refreshToken) {
617
- const attempts = this.refreshAttempts.get(refreshToken) || 0;
618
- if (attempts >= this.MAX_REFRESH_ATTEMPTS) {
619
- await this.fallbackToProviderToken();
620
- return;
621
- }
622
- try {
623
- this.refreshAttempts.set(refreshToken, attempts + 1);
624
- const result = await this.refreshStrategy.refreshWithRefreshToken(refreshToken);
625
- await this.storeTokenResult(result);
626
- this.refreshAttempts.delete(refreshToken);
627
- }
628
- catch (error) {
629
- await this.fallbackToProviderToken();
630
- }
631
- } /**
632
- * Execute refresh with provider token (Step 5)
633
- * Uses provider token to get a fresh token set from PERS backend
634
- */
635
- async executeProviderTokenFlow(providerToken) {
636
- try {
637
- const result = await this.refreshStrategy.refreshWithProviderToken(providerToken);
638
- await this.storeTokenResult(result);
639
- this.refreshAttempts.clear();
640
- }
641
- catch (error) {
642
- await this.executeAuthCleanup('Provider token authentication failed - all methods exhausted');
643
- throw new LogoutRequired('Provider token authentication failed - all methods exhausted');
644
- }
645
- }
646
- async storeTokenResult(result) {
647
- await this.tokenManager.setAccessToken(result.accessToken);
648
- if (result.refreshToken) {
649
- await this.tokenManager.setRefreshToken(result.refreshToken);
650
- }
651
- }
652
- async fallbackToProviderToken() {
653
- const providerToken = await this.tokenManager.getProviderToken();
654
- if (providerToken) {
655
- try {
656
- await this.executeProviderTokenFlow(providerToken);
657
- }
658
- catch (providerError) {
659
- await this.executeAuthCleanup('All authentication methods exhausted');
660
- throw new LogoutRequired('All authentication methods exhausted');
661
- }
662
- }
663
- else {
664
- await this.executeAuthCleanup('Refresh failed and no provider token available');
665
- throw new LogoutRequired('Refresh failed and no provider token available');
666
- }
667
- }
668
- async clearAuthTokens() {
669
- await this.tokenManager.removeToken(AUTH_STORAGE_KEYS.ACCESS_TOKEN);
670
- await this.tokenManager.removeToken(AUTH_STORAGE_KEYS.REFRESH_TOKEN);
671
- // Clear refresh attempts tracking
672
- this.refreshAttempts.clear();
673
- }
674
- /**
675
- * Execute authentication cleanup and notify login required (Step 6)
676
- */
677
- async executeAuthCleanup(reason = 'Authentication failed') {
678
- await this.tokenManager.clearAllTokens();
679
- this.refreshAttempts.clear();
680
- this.emitLoginRequired(reason);
681
- }
682
- /**
683
- * Check if an error should trigger token refresh (React Native compatible)
684
- */
685
- shouldRefreshToken(error) {
686
- return ErrorUtils.isTokenExpired(error);
687
- }
688
- }
689
-
690
- /**
691
- * DefaultAuthRefreshStrategy - Implements the actual refresh logic
692
- */
693
- class DefaultAuthRefreshStrategy {
694
- constructor(tokenManager, getProviderTokenFn, authApi) {
695
- this.tokenManager = tokenManager;
696
- this.getProviderTokenFn = getProviderTokenFn;
697
- this.authApi = authApi;
698
- }
699
- async refreshWithRefreshToken(refreshToken) {
700
- try {
701
- const result = await this.authApi.refreshAccessToken(refreshToken);
702
- if (!result.accessToken) {
703
- throw new Error('Invalid refresh response: missing accessToken');
704
- }
705
- return {
706
- accessToken: result.accessToken,
707
- refreshToken: result.refreshToken || refreshToken
708
- };
709
- }
710
- catch (error) {
711
- throw new Error(`Refresh token invalid or expired: ${error instanceof Error ? error.message : 'Unknown error'}`);
712
- }
713
- }
714
- async refreshWithProviderToken(providerToken) {
715
- try {
716
- const storedAuthType = await this.tokenManager.getAuthType();
717
- let result;
718
- if (storedAuthType === 'admin') {
719
- result = await this.authApi.loginTenantAdmin(providerToken);
720
- }
721
- else if (storedAuthType === 'user') {
722
- result = await this.authApi.loginUser(providerToken);
723
- }
724
- else {
725
- try {
726
- result = await this.authApi.loginUser(providerToken);
727
- await this.tokenManager.setAuthType('user');
728
- }
729
- catch (userLoginError) {
730
- result = await this.authApi.loginTenantAdmin(providerToken);
731
- await this.tokenManager.setAuthType('admin');
732
- }
733
- }
734
- if (!result.accessToken) {
735
- throw new Error('Invalid provider login response: missing accessToken');
736
- }
737
- return {
738
- accessToken: result.accessToken,
739
- refreshToken: result.refreshToken
740
- };
741
- }
742
- catch (error) {
743
- throw new Error(`Provider token login failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
744
- }
745
- }
746
- }
747
- /**
748
- * Default authentication provider with modular architecture
749
- *
750
- * Delegates token storage to TokenManager and refresh logic to TokenRefreshManager.
751
- * Perfect for platform-agnostic usage with reliable error handling.
752
- */
753
- class DefaultAuthProvider {
754
- constructor(projectKey, authApi) {
755
- this.projectKey = null;
756
- this.authApi = null;
757
- this.authType = 'admin';
758
- this.projectKey = projectKey || null;
759
- this.authApi = authApi || null;
760
- this.tokenManager = new TokenManager$1();
761
- const refreshStrategy = new DefaultAuthRefreshStrategy(this.tokenManager, () => Promise.resolve(this.getProviderToken()), this.authApi);
762
- this.tokenRefreshManager = new TokenRefreshManager(this.tokenManager, refreshStrategy);
763
- }
764
- async getToken() {
765
- return await this.tokenManager.getAccessToken();
766
- }
767
- async getProjectKey() {
768
- return this.projectKey;
769
- }
770
- /**
771
- * Centralized token refresh handler - delegates to TokenRefreshManager
772
- */
773
- async onTokenExpired() {
774
- await this.tokenRefreshManager.handleTokenExpiration();
775
- }
776
- /**
777
- * Check if an error indicates token expiration (React Native compatible)
778
- */
779
- isTokenExpiredError(error) {
780
- return ErrorUtils.isTokenExpired(error);
781
- }
782
- /**
783
- * Get Firebase or other provider token for fresh JWT request
784
- * Type-safe method that uses proper storage keys from AUTH_STORAGE_KEYS
785
- */
786
- getProviderToken() {
787
- if (typeof localStorage !== 'undefined') {
788
- return localStorage.getItem(AUTH_STORAGE_KEYS.PROVIDER_TOKEN);
789
- }
790
- return null;
791
- }
792
- async setAccessToken(token) {
793
- await this.tokenManager.setAccessToken(token);
794
- }
795
- async setRefreshToken(token) {
796
- await this.tokenManager.setRefreshToken(token);
797
- }
798
- async getRefreshToken() {
799
- return await this.tokenManager.getRefreshToken();
800
- }
801
- async setProviderToken(token) {
802
- await this.tokenManager.setProviderToken(token);
803
- }
804
- async clearProviderToken() {
805
- await this.tokenManager.clearProviderToken();
806
- }
807
- async clearTokens() {
808
- await this.tokenManager.clearAllTokens();
809
- }
810
- hasValidToken() {
811
- if (typeof localStorage !== 'undefined') {
812
- return !!localStorage.getItem(AUTH_STORAGE_KEYS.ACCESS_TOKEN);
813
- }
814
- return false;
815
- }
816
- hasRefreshToken() {
817
- if (typeof localStorage !== 'undefined') {
818
- return !!localStorage.getItem(AUTH_STORAGE_KEYS.REFRESH_TOKEN);
819
- }
820
- return false;
821
- }
822
- /**
823
- * Proactively check token expiry and refresh if needed BEFORE making requests
824
- * Uses smart refresh strategy based on time remaining:
825
- * - >backgroundThreshold seconds: Background refresh (non-blocking)
826
- * - <backgroundThreshold seconds: Immediate refresh (blocking)
827
- */
828
- async ensureValidToken(marginSeconds = 60, backgroundThreshold = 30) {
829
- try {
830
- const currentToken = await this.getToken();
831
- // If no token, nothing to check
832
- if (!currentToken) {
833
- return;
834
- }
835
- // Check if token is expired or will expire within margin
836
- if (await this.isTokenExpired(marginSeconds)) {
837
- // Determine refresh strategy based on time remaining
838
- const timeToExpiry = await this.getTokenTimeToExpiry(currentToken);
839
- if (timeToExpiry > backgroundThreshold) {
840
- // Token has enough time left - start background refresh (non-blocking)
841
- this.startBackgroundRefresh();
842
- }
843
- else {
844
- // Token expiring soon or expired - block and refresh immediately
845
- const shouldSkipRefresh = await this.isRefreshTokenExpired(marginSeconds);
846
- if (shouldSkipRefresh) {
847
- // Both tokens expired - use provider token directly
848
- await this.handleExpiredRefreshToken();
849
- }
850
- else {
851
- // Normal refresh with refresh token
852
- if (this.onTokenExpired) {
853
- await this.onTokenExpired();
854
- }
855
- }
856
- }
857
- }
858
- }
859
- catch (error) {
860
- // If token check/refresh fails, the error will be handled by the calling code
861
- throw error;
862
- }
863
- }
864
- /**
865
- * Check if current access token is expired
866
- */
867
- async isTokenExpired(marginSeconds = 60) {
868
- try {
869
- const currentToken = await this.getToken();
870
- if (!currentToken) {
871
- return true;
872
- }
873
- // Import isTokenExpired function here to avoid circular imports
874
- const { isTokenExpired } = await Promise.resolve().then(function () { return require('./index-BfOoX87y.cjs'); }).then(function (n) { return n.jwt_function; });
875
- return isTokenExpired(currentToken, marginSeconds);
876
- }
877
- catch (error) {
878
- return true;
879
- }
880
- }
881
- /**
882
- * Check if refresh token is expired
883
- */
884
- async isRefreshTokenExpired(marginSeconds = 60) {
885
- try {
886
- const refreshToken = await this.tokenManager.getRefreshToken();
887
- if (!refreshToken) {
888
- return true; // No refresh token
889
- }
890
- // Import isTokenExpired function here to avoid circular imports
891
- const { isTokenExpired } = await Promise.resolve().then(function () { return require('./index-BfOoX87y.cjs'); }).then(function (n) { return n.jwt_function; });
892
- return isTokenExpired(refreshToken, marginSeconds);
893
- }
894
- catch (error) {
895
- return true; // Assume expired if we can't check
896
- }
897
- }
898
- /**
899
- * Check if both access and refresh tokens are expired
900
- */
901
- async areAllTokensExpired(marginSeconds = 60) {
902
- const accessTokenExpired = await this.isTokenExpired(marginSeconds);
903
- const refreshTokenExpired = await this.isRefreshTokenExpired(marginSeconds);
904
- return accessTokenExpired && refreshTokenExpired;
905
- }
906
- /**
907
- * Get seconds until token expires
908
- */
909
- async getTokenTimeToExpiry(token) {
910
- try {
911
- const { isTokenExpired } = await Promise.resolve().then(function () { return require('./index-BfOoX87y.cjs'); }).then(function (n) { return n.jwt_function; });
912
- const { jwtDecode } = await import('jwt-decode');
913
- const decoded = jwtDecode(token);
914
- const currentTime = Math.floor(Date.now() / 1000);
915
- return Math.max(0, decoded.exp - currentTime);
916
- }
917
- catch (error) {
918
- return 0; // Assume expired if can't decode
919
- }
920
- }
921
- /**
922
- * Start refresh in background without blocking current request
923
- */
924
- startBackgroundRefresh() {
925
- // Use setTimeout to avoid blocking the current request
926
- setTimeout(async () => {
927
- try {
928
- if (this.onTokenExpired) {
929
- await this.onTokenExpired();
930
- }
931
- }
932
- catch (error) {
933
- // Background refresh failed - next request will trigger reactive refresh
934
- }
935
- }, 0);
936
- }
937
- /**
938
- * Handle case where refresh token is also expired - use provider token directly
939
- */
940
- async handleExpiredRefreshToken() {
941
- try {
942
- // Get provider token if available
943
- const providerToken = this.getProviderToken();
944
- if (!providerToken) {
945
- // No provider token available - let normal refresh handle the failure
946
- if (this.onTokenExpired) {
947
- await this.onTokenExpired();
948
- }
949
- return;
950
- }
951
- // Clear expired PERS tokens and use provider token to get fresh ones
952
- await this.clearTokens();
953
- // Trigger refresh which should now use provider token path
954
- if (this.onTokenExpired) {
955
- await this.onTokenExpired();
956
- }
957
- }
958
- catch (error) {
959
- // If provider token flow fails, let normal refresh handle it
960
- if (this.onTokenExpired) {
961
- await this.onTokenExpired();
962
- }
963
- }
964
- }
965
- }
966
-
967
- // packages/pers-sdk/src/core/pers-api-client.ts
968
- /**
969
- * PERS API Client - Core platform-agnostic client for PERS backend
970
- *
971
- * Provides authenticated HTTP client with automatic token management,
972
- * proactive refresh, and comprehensive error handling.
973
- *
974
- * Features:
975
- * - Automatic token refresh before expiry
976
- * - Background refresh for optimal performance
977
- * - Provider token fallback for seamless authentication
978
- * - Configurable retry and timeout settings
979
- * - Platform-agnostic design
980
- *
981
- * @example
982
- * ```typescript
983
- * const client = new PersApiClient(httpClient, {
984
- * environment: 'production',
985
- * apiProjectKey: 'your-project-key',
986
- * authProvider: createAuthProvider({
987
- * tokenProvider: () => getFirebaseToken()
988
- * })
989
- * });
990
- *
991
- * // Make authenticated requests
992
- * const data = await client.get('/users/me');
993
- * ```
994
- */
995
- class PersApiClient {
996
- /**
997
- * Creates a new PERS API Client instance
998
- *
999
- * @param httpClient - Platform-specific HTTP client implementation
1000
- * @param config - Configuration options for the API client
1001
- */
1002
- constructor(httpClient, config) {
1003
- this.httpClient = httpClient;
1004
- this.config = config;
1005
- // Merge user config with defaults (production + v2)
1006
- this.mergedConfig = mergeWithDefaults(config);
1007
- // Build API root from merged environment and version
1008
- this.apiRoot = buildApiRoot(this.mergedConfig.environment, this.mergedConfig.apiVersion);
1009
- // Initialize auth services for direct authentication
1010
- this.authApi = new AuthApi(this);
1011
- // Auto-create auth provider if none provided
1012
- if (!this.mergedConfig.authProvider) {
1013
- this.mergedConfig.authProvider = new DefaultAuthProvider(this.mergedConfig.apiProjectKey, this.authApi);
1014
- }
1015
- this.authService = new AuthService(this.authApi, this.mergedConfig.authProvider);
1016
- }
1017
- /**
1018
- * Ensures valid authentication token before making requests
1019
- *
1020
- * Implements intelligent refresh strategy:
1021
- * - Tokens with sufficient time remaining: Background refresh (non-blocking)
1022
- * - Tokens expiring soon or expired: Immediate refresh (blocking)
1023
- *
1024
- * @private
1025
- * @returns Promise that resolves when token validation is complete
1026
- */
1027
- async ensureValidToken() {
1028
- if (!this.mergedConfig.authProvider?.ensureValidToken) {
1029
- return; // Auth provider doesn't support proactive validation
1030
- }
1031
- try {
1032
- const refreshMargin = this.mergedConfig.tokenRefreshMargin || 60;
1033
- const backgroundThreshold = this.mergedConfig.backgroundRefreshThreshold || 30;
1034
- await this.mergedConfig.authProvider.ensureValidToken(refreshMargin, backgroundThreshold);
1035
- }
1036
- catch (error) {
1037
- // If token check/refresh fails, continue with request
1038
- // The reactive error handling will catch any auth issues
1039
- }
1040
- }
1041
- /**
1042
- * Get request headers including auth token and project key
1043
- */
1044
- async getHeaders() {
1045
- const headers = {
1046
- 'Content-Type': 'application/json',
1047
- };
1048
- // Add authentication token
1049
- if (this.mergedConfig.authProvider) {
1050
- const token = await this.mergedConfig.authProvider.getToken();
1051
- if (token) {
1052
- headers['Authorization'] = `Bearer ${token}`;
1053
- }
1054
- }
1055
- // Add project key
1056
- if (this.mergedConfig.authProvider) {
1057
- const projectKey = await this.mergedConfig.authProvider.getProjectKey();
1058
- if (projectKey) {
1059
- headers['x-project-key'] = projectKey;
1060
- }
1061
- }
1062
- else if (this.mergedConfig.apiProjectKey) {
1063
- // Fallback to config project key if no auth provider
1064
- headers['x-project-key'] = this.mergedConfig.apiProjectKey;
1065
- }
1066
- return headers;
1067
- }
1068
- /**
1069
- * Make a request with proper headers, auth, and error handling
1070
- */
1071
- async request(method, endpoint, body, options) {
1072
- const { retryCount = 0, responseType = 'json', bypassAuth = false } = options || {};
1073
- const url = `${this.apiRoot}${endpoint}`;
1074
- // Proactive token expiry check and refresh BEFORE making the request
1075
- if (!bypassAuth && this.mergedConfig.authProvider && retryCount === 0) {
1076
- await this.ensureValidToken();
1077
- }
1078
- const requestOptions = {
1079
- headers: bypassAuth ? await this.getHeadersWithoutAuth() : await this.getHeaders(),
1080
- timeout: this.mergedConfig.timeout,
1081
- responseType
1082
- };
1083
- // Log API request with auth info
1084
- // const hasAuth = !!this.mergedConfig.authProvider;
1085
- endpoint.includes('/export/csv');
1086
- try {
1087
- let result;
1088
- switch (method) {
1089
- case AUTH_METHODS.GET:
1090
- result = await this.httpClient.get(url, requestOptions);
1091
- break;
1092
- case AUTH_METHODS.POST:
1093
- result = await this.httpClient.post(url, body, requestOptions);
1094
- break;
1095
- case AUTH_METHODS.PUT:
1096
- result = await this.httpClient.put(url, body, requestOptions);
1097
- break;
1098
- case AUTH_METHODS.DELETE:
1099
- result = await this.httpClient.delete(url, requestOptions);
1100
- break;
1101
- default:
1102
- throw new Error(`Unsupported HTTP method: ${method}`);
1103
- }
1104
- return result;
1105
- }
1106
- catch (error) {
1107
- // Error handling - proactive token refresh should prevent most 401s
1108
- const status = ErrorUtils.getStatus(error);
1109
- const errorMessage = ErrorUtils.getMessage(error);
1110
- // Fallback: reactive token refresh only if proactive check missed something
1111
- if (retryCount === 0 && this.mergedConfig.authProvider && ErrorUtils.isTokenExpired(error)) {
1112
- try {
1113
- // Fallback token refresh delegation
1114
- const result = await this.handleTokenRefreshDelegation(method, endpoint, body, options);
1115
- if (result !== null) {
1116
- return result;
1117
- }
1118
- }
1119
- catch (refreshError) {
1120
- throw new PersApiError(`Auth failed: ${refreshError.message || refreshError}`, endpoint, method, 401);
1121
- }
1122
- }
1123
- throw new PersApiError(errorMessage, endpoint, method, status || undefined, ErrorUtils.isRetryable(error));
1124
- }
1125
- }
1126
- /**
1127
- * Delegate token refresh to auth provider and handle the results
1128
- */
1129
- async handleTokenRefreshDelegation(method, endpoint, body, options) {
1130
- try {
1131
- // Let auth provider handle the refresh process
1132
- const authProvider = this.mergedConfig.authProvider;
1133
- if (authProvider?.onTokenExpired) {
1134
- await authProvider.onTokenExpired();
1135
- }
1136
- // If we get here, tokens should be refreshed - retry the request
1137
- // Auth provider refresh succeeded, retrying...
1138
- return this.request(method, endpoint, body, { ...options, retryCount: 1 });
1139
- }
1140
- catch (refreshError) {
1141
- // Auth provider handled all refresh attempts and failed
1142
- // Re-throw the error for the caller to handle
1143
- throw refreshError;
1144
- }
1145
- }
1146
- /**
1147
- * Performs an authenticated GET request
1148
- *
1149
- * @template T - Expected response type
1150
- * @param endpoint - API endpoint path (without base URL)
1151
- * @param responseType - Expected response format
1152
- * @returns Promise resolving to typed response data
1153
- *
1154
- * @example
1155
- * ```typescript
1156
- * const user = await client.get<User>('/users/123');
1157
- * const csvData = await client.get('/export/data', 'blob');
1158
- * ```
1159
- */
1160
- async get(endpoint, responseType) {
1161
- return this.request(AUTH_METHODS.GET, endpoint, undefined, { responseType });
1162
- }
1163
- /**
1164
- * Performs an authenticated POST request
1165
- *
1166
- * @template T - Expected response type
1167
- * @param endpoint - API endpoint path (without base URL)
1168
- * @param body - Request payload data
1169
- * @param options - Request options including auth bypass
1170
- * @returns Promise resolving to typed response data
1171
- *
1172
- * @example
1173
- * ```typescript
1174
- * const user = await client.post<User>('/users', userData);
1175
- * const publicData = await client.post('/public/contact', formData, { bypassAuth: true });
1176
- * ```
1177
- */
1178
- async post(endpoint, body, options) {
1179
- return this.request(AUTH_METHODS.POST, endpoint, body, options);
1180
- }
1181
- /**
1182
- * Generic PUT request
1183
- */
1184
- async put(endpoint, body) {
1185
- return this.request(AUTH_METHODS.PUT, endpoint, body);
1186
- }
1187
- /**
1188
- * Generic DELETE request
1189
- */
1190
- async delete(endpoint) {
1191
- return this.request(AUTH_METHODS.DELETE, endpoint);
1192
- }
1193
- /**
1194
- * Get request headers WITHOUT auth token (for auth operations like refresh/login)
1195
- */
1196
- async getHeadersWithoutAuth() {
1197
- const headers = {
1198
- 'Content-Type': 'application/json',
1199
- };
1200
- // Add project key only (no auth token)
1201
- if (this.mergedConfig.authProvider) {
1202
- const projectKey = await this.mergedConfig.authProvider.getProjectKey();
1203
- if (projectKey) {
1204
- headers['x-project-key'] = projectKey;
1205
- }
1206
- }
1207
- else if (this.mergedConfig.apiProjectKey) {
1208
- headers['x-project-key'] = this.mergedConfig.apiProjectKey;
1209
- }
1210
- return headers;
1211
- }
1212
- // ==========================================
1213
- // AUTHENTICATION METHODS
1214
- // ==========================================
1215
- /**
1216
- * Authenticates an admin user using external JWT token
1217
- *
1218
- * Exchanges external provider token (Firebase, Auth0, etc.) for PERS access tokens.
1219
- * Automatically stores received tokens for subsequent requests.
1220
- *
1221
- * @param externalJwt - JWT token from external authentication provider
1222
- * @returns Promise resolving to session context with admin permissions
1223
- *
1224
- * @example
1225
- * ```typescript
1226
- * const firebaseToken = await getIdToken();
1227
- * const session = await client.loginAdmin(firebaseToken);
1228
- * console.log('Admin authenticated:', session.user.email);
1229
- * ```
1230
- */
1231
- async loginAdmin(externalJwt) {
1232
- return this.authService.loginTenantAdmin(externalJwt);
1233
- }
1234
- /**
1235
- * Authenticates a regular user using external JWT token
1236
- *
1237
- * Exchanges external provider token for PERS access tokens with user-level permissions.
1238
- * Automatically stores received tokens for subsequent requests.
1239
- *
1240
- * @param externalJwt - JWT token from external authentication provider
1241
- * @returns Promise resolving to session context with user permissions
1242
- *
1243
- * @example
1244
- * ```typescript
1245
- * const firebaseToken = await getIdToken();
1246
- * const session = await client.loginUser(firebaseToken);
1247
- * console.log('User authenticated:', session.user.email);
1248
- * ```
1249
- */
1250
- async loginUser(externalJwt) {
1251
- return this.authService.loginUser(externalJwt);
1252
- }
1253
- /**
1254
- * Authenticates a user using raw login data (no external JWT)
1255
- *
1256
- * Useful for custom authentication flows where user data is provided directly.
1257
- * Automatically stores received tokens for subsequent requests.
1258
- *
1259
- * @param rawLoginData - Object containing user login data (email, name, etc.)
1260
- * @return Promise resolving to session context with user permissions
1261
- */
1262
- async loginUserWithRawData(rawLoginData) {
1263
- return this.authService.loginUserWithRawData(rawLoginData);
1264
- }
1265
- /**
1266
- * Checks if current user has a valid authentication token
1267
- *
1268
- * Performs basic token availability check without network requests.
1269
- * For comprehensive validation including expiry, use isTokenExpired().
1270
- *
1271
- * @returns True if valid token exists, false otherwise
1272
- *
1273
- * @example
1274
- * ```typescript
1275
- * if (client.hasValidAuth()) {
1276
- * // User is authenticated, proceed with API calls
1277
- * const data = await client.get('/protected-data');
1278
- * } else {
1279
- * // Redirect to login
1280
- * redirectToLogin();
1281
- * }
1282
- * ```
1283
- */
1284
- hasValidAuth() {
1285
- return this.mergedConfig.authProvider?.hasValidToken?.() || false;
1286
- }
1287
- /**
1288
- * Checks if current access token is expired or expiring soon
1289
- *
1290
- * @param marginSeconds - Seconds before expiry to consider token as expired (default: 60)
1291
- * @returns Promise resolving to true if token is expired/expiring, false if valid
1292
- *
1293
- * @example
1294
- * ```typescript
1295
- * if (await client.isTokenExpired(120)) {
1296
- * console.log('Token expires within 2 minutes');
1297
- * // Optionally trigger manual refresh
1298
- * }
1299
- * ```
1300
- */
1301
- async isTokenExpired(marginSeconds = 60) {
1302
- if (!this.mergedConfig.authProvider?.isTokenExpired) {
1303
- return true; // No auth provider or doesn't support expiry checking
1304
- }
1305
- try {
1306
- return await this.mergedConfig.authProvider.isTokenExpired(marginSeconds);
1307
- }
1308
- catch (error) {
1309
- return true;
1310
- }
1311
- }
1312
- /**
1313
- * Checks if both access and refresh tokens are expired
1314
- *
1315
- * Useful for determining if full re-authentication is required.
1316
- *
1317
- * @param marginSeconds - Seconds before expiry to consider tokens as expired (default: 60)
1318
- * @returns Promise resolving to true if both tokens expired, false otherwise
1319
- *
1320
- * @example
1321
- * ```typescript
1322
- * if (await client.areAllTokensExpired()) {
1323
- * // Full re-authentication required
1324
- * await redirectToLogin();
1325
- * }
1326
- * ```
1327
- */
1328
- async areAllTokensExpired(marginSeconds = 60) {
1329
- if (!this.mergedConfig.authProvider?.areAllTokensExpired) {
1330
- // Fallback to checking access token only
1331
- return await this.isTokenExpired(marginSeconds);
1332
- }
1333
- return await this.mergedConfig.authProvider.areAllTokensExpired(marginSeconds);
1334
- }
1335
- /**
1336
- * Refresh access token using stored refresh token
1337
- *
1338
- * @param refreshToken - Optional refresh token, uses stored token if not provided
1339
- * @returns Promise resolving to new auth tokens
1340
- *
1341
- * @example
1342
- * ```typescript
1343
- * try {
1344
- * const tokens = await client.refreshTokens();
1345
- * console.log('Tokens refreshed successfully');
1346
- * } catch (error) {
1347
- * console.error('Token refresh failed:', error);
1348
- * }
1349
- * ```
1350
- */
1351
- async refreshTokens(refreshToken) {
1352
- return this.authService.refreshAccessToken(refreshToken);
1353
- }
1354
- /**
1355
- * Get current configuration (returns merged config)
1356
- */
1357
- getConfig() {
1358
- return this.mergedConfig;
1359
- }
1360
- /**
1361
- * Get original user configuration
1362
- */
1363
- getOriginalConfig() {
1364
- return this.config;
1365
- }
1366
- }
1367
-
1368
- /**
1369
- * Memory-based token storage (default)
1370
- */
1371
- class MemoryTokenStorage {
1372
- constructor() {
1373
- this.storage = new Map();
1374
- }
1375
- async setItem(key, value) {
1376
- this.storage.set(key, value);
1377
- }
1378
- async getItem(key) {
1379
- return this.storage.get(key) || null;
1380
- }
1381
- async removeItem(key) {
1382
- this.storage.delete(key);
1383
- }
1384
- }
1385
- /**
1386
- * localStorage-based token storage (browser only)
1387
- */
1388
- class LocalStorageTokenStorage {
1389
- async setItem(key, value) {
1390
- if (typeof localStorage !== 'undefined') {
1391
- localStorage.setItem(key, value);
1392
- }
1393
- else {
1394
- throw new Error('localStorage is not available in this environment');
1395
- }
1396
- }
1397
- async getItem(key) {
1398
- if (typeof localStorage !== 'undefined') {
1399
- return localStorage.getItem(key);
1400
- }
1401
- return null;
1402
- }
1403
- async removeItem(key) {
1404
- if (typeof localStorage !== 'undefined') {
1405
- localStorage.removeItem(key);
1406
- }
1407
- }
1408
- }
1409
- /**
1410
- * Creates a platform-agnostic AuthProvider from simple configuration
1411
- *
1412
- * This factory function is completely platform-agnostic and can be used
1413
- * across Angular, React, Vue, Node.js, or any other JavaScript environment.
1414
- *
1415
- * Features:
1416
- * - Token caching with refresh support
1417
- * - Automatic token refresh on expiration
1418
- * - Configurable token providers
1419
- * - Token storage (memory, localStorage, custom)
1420
- * - Platform-independent
1421
- *
1422
- * @param config - Simple auth configuration
1423
- * @returns AuthProvider implementation
1424
- */
1425
- function createAuthProvider(config) {
1426
- // Initialize token storage
1427
- let tokenStorage;
1428
- switch (config.tokenStorage) {
1429
- case 'localStorage':
1430
- tokenStorage = new LocalStorageTokenStorage();
1431
- break;
1432
- case 'custom':
1433
- if (!config.customTokenStorage) {
1434
- throw new Error('Custom token storage configuration is required when tokenStorage is "custom"');
1435
- }
1436
- tokenStorage = config.customTokenStorage;
1437
- break;
1438
- case 'memory':
1439
- default:
1440
- tokenStorage = new MemoryTokenStorage();
1441
- break;
1442
- }
1443
- // Token storage keys
1444
- const ACCESS_TOKEN_KEY = createStorageKey(AUTH_STORAGE_KEYS.ACCESS_TOKEN, config.authType || 'user');
1445
- const REFRESH_TOKEN_KEY = createStorageKey(AUTH_STORAGE_KEYS.REFRESH_TOKEN, config.authType || 'user');
1446
- // Store current token for refresh scenarios and caching
1447
- let currentToken = config.token || null;
1448
- let isRefreshing = false; // Prevent concurrent refresh attempts
1449
- let refreshPromise = null;
1450
- return {
1451
- authType: config.authType || 'user',
1452
- async getToken() {
1453
- // If currently refreshing, wait for it to complete
1454
- if (isRefreshing && refreshPromise) {
1455
- await refreshPromise;
1456
- return currentToken;
1457
- }
1458
- // Use cached current token (updated after refresh)
1459
- if (currentToken) {
1460
- return currentToken;
1461
- }
1462
- // Try to get token from storage
1463
- try {
1464
- const storedToken = await tokenStorage.getItem(ACCESS_TOKEN_KEY);
1465
- if (storedToken) {
1466
- currentToken = storedToken;
1467
- return storedToken;
1468
- }
1469
- }
1470
- catch (error) {
1471
- // Token retrieval failed - continuing without storage
1472
- }
1473
- // Custom token provider function (always fresh)
1474
- if (config.tokenProvider) {
1475
- const token = await config.tokenProvider();
1476
- currentToken = token; // Cache for future calls
1477
- return token;
1478
- }
1479
- // No token available
1480
- return null;
1481
- },
1482
- async getProjectKey() {
1483
- return config.projectKey || null;
1484
- },
1485
- // Token storage methods
1486
- async setAccessToken(token) {
1487
- currentToken = token;
1488
- try {
1489
- await tokenStorage.setItem(ACCESS_TOKEN_KEY, token);
1490
- }
1491
- catch (error) {
1492
- throw error;
1493
- }
1494
- },
1495
- async setRefreshToken(token) {
1496
- try {
1497
- await tokenStorage.setItem(REFRESH_TOKEN_KEY, token);
1498
- }
1499
- catch (error) {
1500
- throw error;
1501
- }
1502
- },
1503
- async getRefreshToken() {
1504
- try {
1505
- return await tokenStorage.getItem(REFRESH_TOKEN_KEY);
1506
- }
1507
- catch (error) {
1508
- return null;
1509
- }
1510
- },
1511
- async clearTokens() {
1512
- currentToken = null;
1513
- try {
1514
- await Promise.all([
1515
- tokenStorage.removeItem(ACCESS_TOKEN_KEY),
1516
- tokenStorage.removeItem(REFRESH_TOKEN_KEY)
1517
- ]);
1518
- }
1519
- catch (error) {
1520
- throw error;
1521
- }
1522
- },
1523
- async onTokenExpired() {
1524
- // Prevent concurrent refresh attempts
1525
- if (isRefreshing) {
1526
- if (refreshPromise) {
1527
- await refreshPromise;
1528
- }
1529
- return;
1530
- }
1531
- // No refresh logic provided
1532
- if (!config.onTokenExpired) {
1533
- currentToken = null;
1534
- try {
1535
- await tokenStorage.removeItem(ACCESS_TOKEN_KEY);
1536
- }
1537
- catch (error) {
1538
- // Token clearing failed - continuing
1539
- }
1540
- return;
1541
- }
1542
- // Start refresh process
1543
- isRefreshing = true;
1544
- refreshPromise = (async () => {
1545
- try {
1546
- // Execute refresh logic (should update token source)
1547
- await config.onTokenExpired();
1548
- // After refresh, get the new token
1549
- if (config.tokenProvider) {
1550
- const newToken = await config.tokenProvider();
1551
- if (newToken && newToken !== currentToken) {
1552
- currentToken = newToken;
1553
- // Store the new token
1554
- try {
1555
- await tokenStorage.setItem(ACCESS_TOKEN_KEY, newToken);
1556
- }
1557
- catch (error) {
1558
- // Token storage failed - token still valid in memory
1559
- }
1560
- // Notify about successful token refresh
1561
- if (config.onTokenRefreshed) {
1562
- config.onTokenRefreshed(newToken);
1563
- }
1564
- }
1565
- else {
1566
- currentToken = null;
1567
- try {
1568
- await tokenStorage.removeItem(ACCESS_TOKEN_KEY);
1569
- }
1570
- catch (error) {
1571
- // Token clearing failed - continuing
1572
- }
1573
- }
1574
- }
1575
- else {
1576
- // For static token configs, clear the token since we can't refresh
1577
- currentToken = null;
1578
- try {
1579
- await tokenStorage.removeItem(ACCESS_TOKEN_KEY);
1580
- }
1581
- catch (error) {
1582
- // Token clearing failed - continuing
1583
- }
1584
- }
1585
- }
1586
- catch (error) {
1587
- currentToken = null; // Clear token on refresh failure
1588
- try {
1589
- await tokenStorage.removeItem(ACCESS_TOKEN_KEY);
1590
- }
1591
- catch (storageError) {
1592
- // Token clearing failed - continuing
1593
- }
1594
- throw error; // Re-throw to let SDK handle the error
1595
- }
1596
- finally {
1597
- isRefreshing = false;
1598
- refreshPromise = null;
1599
- }
1600
- })();
1601
- await refreshPromise;
1602
- }
1603
- };
1604
- }
1605
- /**
1606
- * Platform-specific localStorage token provider for browsers
1607
- * This is a convenience function for browser environments
1608
- */
1609
- /* export function createBrowserTokenProvider(tokenKey: string = 'userJwt'): () => Promise<string | null> {
1610
- return async () => {
1611
- if (typeof localStorage !== 'undefined') {
1612
- return localStorage.getItem(tokenKey);
1613
- }
1614
- return null;
1615
- };
1616
- } */
1617
- /**
1618
- * Platform-specific environment variable token provider for Node.js
1619
- * This is a convenience function for Node.js environments
1620
- */
1621
- /* export function createNodeTokenProvider(envVar: string = 'JWT_TOKEN'): () => Promise<string | null> {
1622
- return async () => {
1623
- if (typeof process !== 'undefined' && process.env) {
1624
- return process.env[envVar] || null;
1625
- }
1626
- return null;
1627
- };
1628
- } */
1629
-
1630
- /**
1631
- * Authentication Manager - Clean, high-level interface for authentication operations
1632
- *
1633
- * Provides a simplified API for common authentication tasks while maintaining
1634
- * access to the underlying API client for advanced use cases.
1635
- */
1636
- class AuthManager {
1637
- constructor(apiClient) {
1638
- this.apiClient = apiClient;
1639
- }
1640
- /**
1641
- * Login with JWT token
1642
- *
1643
- * @param jwtToken - JWT token to authenticate with
1644
- * @param userType - Type of user ('user' | 'admin')
1645
- * @returns Promise resolving to authentication response
1646
- */
1647
- async loginWithToken(jwtToken, userType = 'user') {
1648
- return userType === 'admin'
1649
- ? this.apiClient.loginAdmin(jwtToken)
1650
- : this.apiClient.loginUser(jwtToken);
1651
- }
1652
- /**
1653
- * Login with raw user data
1654
- *
1655
- * @param rawUserData - Raw user data for authentication
1656
- * @returns Promise resolving to authentication response
1657
- */
1658
- async loginWithRawData(rawUserData) {
1659
- return this.apiClient.loginUserWithRawData(rawUserData);
1660
- }
1661
- /**
1662
- * Get current authenticated user
1663
- *
1664
- * @returns Promise resolving to current user data
1665
- */
1666
- async getCurrentUser() {
1667
- return this.apiClient.get('/users/me');
1668
- }
1669
- /**
1670
- * Refresh current user data
1671
- *
1672
- * @returns Promise resolving to updated user data
1673
- */
1674
- async refreshUserData() {
1675
- return this.getCurrentUser();
1676
- }
1677
- /**
1678
- * Check if user is authenticated
1679
- *
1680
- * @returns Promise resolving to boolean indicating authentication status
1681
- */
1682
- async isAuthenticated() {
1683
- try {
1684
- await this.getCurrentUser();
1685
- return true;
1686
- }
1687
- catch {
1688
- return false;
1689
- }
1690
- }
1691
- /**
1692
- * Refresh access token using stored refresh token
1693
- *
1694
- * @param refreshToken - Optional refresh token, uses stored token if not provided
1695
- * @returns Promise resolving to new auth tokens
1696
- */
1697
- async refreshTokens(refreshToken) {
1698
- return this.apiClient.refreshTokens(refreshToken);
1699
- }
1700
- /**
1701
- * Clear stored authentication tokens
1702
- *
1703
- * @returns Promise that resolves when tokens are cleared
1704
- */
1705
- async clearAuth() {
1706
- // Use auth provider to clear tokens if available
1707
- const authProvider = this.apiClient.getConfig().authProvider;
1708
- if (authProvider?.clearTokens) {
1709
- await authProvider.clearTokens();
1710
- }
1711
- }
1712
- /**
1713
- * Check if SDK has valid authentication
1714
- *
1715
- * @returns Boolean indicating if valid authentication exists
1716
- */
1717
- hasValidAuth() {
1718
- return this.apiClient.hasValidAuth();
1719
- }
1720
- /**
1721
- * Admin login with JWT token
1722
- *
1723
- * @param jwt - JWT token for admin authentication
1724
- * @returns Promise resolving to authentication context
1725
- */
1726
- async loginAdmin(jwt) {
1727
- return this.apiClient.loginAdmin(jwt);
1728
- }
1729
- /**
1730
- * User login with JWT token
1731
- *
1732
- * @param jwt - JWT token for user authentication
1733
- * @returns Promise resolving to authentication context
1734
- */
1735
- async loginUser(jwt) {
1736
- return this.apiClient.loginUser(jwt);
1737
- }
1738
- }
1739
-
1740
- /**
1741
- * User Manager - Clean, high-level interface for user operations
1742
- *
1743
- * Provides a simplified API for common user management tasks while maintaining
1744
- * access to the full user SDK for advanced use cases.
1745
- */
1746
- class UserManager {
1747
- constructor(apiClient) {
1748
- this.apiClient = apiClient;
1749
- this.userSDK = user.createUserSDK(apiClient);
1750
- }
1751
- /**
1752
- * Get current user profile
1753
- *
1754
- * @returns Promise resolving to current user data
1755
- */
1756
- async getCurrentUser() {
1757
- return this.userSDK.getRemoteUser();
1758
- }
1759
- /**
1760
- * Update current user profile
1761
- *
1762
- * @param userData - User data to update
1763
- * @returns Promise resolving to updated user data
1764
- */
1765
- async updateCurrentUser(userData) {
1766
- return this.userSDK.updateRemoteUser(userData);
1767
- }
1768
- /**
1769
- * Get user by unique identifier
1770
- *
1771
- * @param identifier - Unique identifier for the user
1772
- * @returns Promise resolving to user data
1773
- */
1774
- async getUserById(identifier) {
1775
- return this.userSDK.getUserByUniqueIdentifier(identifier);
1776
- }
1777
- /**
1778
- * Get all users public profiles with optional filtering
1779
- *
1780
- * @param filter - Optional filter criteria
1781
- * @returns Promise resolving to array of user public profiles
1782
- */
1783
- async getAllUsersPublic(filter) {
1784
- return this.userSDK.getAllUsersPublicProfiles(filter || null);
1785
- }
1786
- /**
1787
- * Admin: Get all users
1788
- *
1789
- * @returns Promise resolving to array of all users
1790
- */
1791
- async getAllUsers() {
1792
- return this.userSDK.getAllRemoteUsers();
1793
- }
1794
- /**
1795
- * Admin: Update user data
1796
- *
1797
- * @param userId - ID of user to update
1798
- * @param userData - User data to update
1799
- * @returns Promise resolving to updated user data
1800
- */
1801
- async updateUser(userId, userData) {
1802
- return this.userSDK.updateUserAsAdmin(userId, userData);
1803
- }
1804
- /**
1805
- * Admin: Toggle user active status
1806
- *
1807
- * @param user - User to toggle status for
1808
- * @returns Promise resolving to updated user data
1809
- */
1810
- async toggleUserStatus(user) {
1811
- return this.userSDK.toggleUserActiveStatusByUser(user);
1812
- }
1813
- /**
1814
- * Get the full user SDK for advanced operations
1815
- *
1816
- * @returns UserSDK instance
1817
- */
1818
- getUserSDK() {
1819
- return this.userSDK;
1820
- }
1821
- }
1822
-
1823
- /**
1824
- * User Status Manager - Clean, high-level interface for user status operations
1825
- *
1826
- * Provides a simplified API for common user status management tasks while maintaining
1827
- * access to the full user status SDK for advanced use cases.
1828
- */
1829
- class UserStatusManager {
1830
- constructor(apiClient) {
1831
- this.apiClient = apiClient;
1832
- this.userStatusSDK = userStatus.createUserStatusSDK(apiClient);
1833
- }
1834
- /**
1835
- * Get all user status types
1836
- *
1837
- * @returns Promise resolving to array of user status types
1838
- */
1839
- async getUserStatusTypes() {
1840
- return this.userStatusSDK.getRemoteUserStatusTypes();
1841
- }
1842
- /**
1843
- * Get earned user status for authenticated user
1844
- *
1845
- * @returns Promise resolving to array of earned user status
1846
- */
1847
- async getEarnedUserStatus() {
1848
- return this.userStatusSDK.getRemoteEarnedUserStatus();
1849
- }
1850
- /**
1851
- * Admin: Create new user status type
1852
- *
1853
- * @param userStatusType - User status type data
1854
- * @returns Promise resolving to created user status type
1855
- */
1856
- async createUserStatusType(userStatusType) {
1857
- return this.userStatusSDK.createUserStatusType(userStatusType);
1858
- }
1859
- /**
1860
- * Get the full user status SDK for advanced operations
1861
- *
1862
- * @returns UserStatusSDK instance
1863
- */
1864
- getUserStatusSDK() {
1865
- return this.userStatusSDK;
1866
- }
1867
- }
1868
-
1869
- /**
1870
- * Token Manager - Clean, high-level interface for token operations
1871
- *
1872
- * Provides a simplified API for common token management tasks while maintaining
1873
- * access to the full token SDK for advanced use cases.
1874
- */
1875
- class TokenManager {
1876
- constructor(apiClient) {
1877
- this.apiClient = apiClient;
1878
- this.tokenSDK = new tokenSdk.TokenSDK(apiClient);
1879
- }
1880
- /**
1881
- * Get all available tokens
1882
- *
1883
- * @returns Promise resolving to array of tokens
1884
- */
1885
- async getTokens() {
1886
- return this.tokenSDK.getTokens();
1887
- }
1888
- /**
1889
- * Get all token types
1890
- *
1891
- * @returns Promise resolving to token types
1892
- */
1893
- async getTokenTypes() {
1894
- return this.tokenSDK.getTokenTypes();
1895
- }
1896
- /**
1897
- * Get active credit token
1898
- *
1899
- * @returns Promise resolving to active credit token
1900
- */
1901
- async getActiveCreditToken() {
1902
- return this.tokenSDK.getActiveCreditToken();
1903
- }
1904
- /**
1905
- * Get reward tokens
1906
- *
1907
- * @returns Promise resolving to reward tokens
1908
- */
1909
- async getRewardTokens() {
1910
- return this.tokenSDK.getRewardTokens();
1911
- }
1912
- /**
1913
- * Get status tokens
1914
- *
1915
- * @returns Promise resolving to status tokens
1916
- */
1917
- async getStatusTokens() {
1918
- return this.tokenSDK.getStatusTokens();
1919
- }
1920
- /**
1921
- * Get token by contract address
1922
- *
1923
- * @param contractAddress - Contract address to search for
1924
- * @param contractTokenId - Optional contract token ID
1925
- * @returns Promise resolving to token
1926
- */
1927
- async getTokenByContract(contractAddress, contractTokenId) {
1928
- return this.tokenSDK.getTokenByContract(contractAddress, contractTokenId);
1929
- }
1930
- /**
1931
- * Admin: Create new token
1932
- *
1933
- * @param tokenData - Token creation data
1934
- * @returns Promise resolving to created token
1935
- */
1936
- async createToken(tokenData) {
1937
- return this.tokenSDK.createToken(tokenData);
1938
- }
1939
- /**
1940
- * Admin: Update token
1941
- *
1942
- * @param tokenId - Token ID to update
1943
- * @param tokenData - Token update data
1944
- * @returns Promise resolving to updated token
1945
- */
1946
- async updateToken(tokenId, tokenData) {
1947
- return this.tokenSDK.updateToken(tokenId, tokenData);
1948
- }
1949
- /**
1950
- * Admin: Toggle token active status
1951
- *
1952
- * @param tokenId - Token ID to toggle
1953
- * @returns Promise resolving to updated token
1954
- */
1955
- async toggleTokenActive(tokenId) {
1956
- return this.tokenSDK.toggleTokenActive(tokenId);
1957
- }
1958
- /**
1959
- * Get the full token SDK for advanced operations
1960
- *
1961
- * @returns TokenSDK instance
1962
- */
1963
- getTokenSDK() {
1964
- return this.tokenSDK;
1965
- }
1966
- }
1967
-
1968
- /**
1969
- * Business Manager - Clean, high-level interface for business operations
1970
- *
1971
- * Provides a simplified API for common business management tasks while maintaining
1972
- * access to the full business SDK for advanced use cases.
1973
- */
1974
- class BusinessManager {
1975
- constructor(apiClient) {
1976
- this.apiClient = apiClient;
1977
- this.businessSDK = business.createBusinessSDK(apiClient);
1978
- }
1979
- /**
1980
- * Get all active businesses
1981
- *
1982
- * @returns Promise resolving to array of active businesses
1983
- */
1984
- async getActiveBusinesses() {
1985
- return this.businessSDK.getActiveBusinesses();
1986
- }
1987
- /**
1988
- * Get business by ID
1989
- *
1990
- * @param businessId - Business ID to fetch
1991
- * @returns Promise resolving to business data
1992
- */
1993
- async getBusinessById(businessId) {
1994
- return this.businessSDK.getBusinessById(businessId);
1995
- }
1996
- /**
1997
- * Get business by account address
1998
- *
1999
- * @param accountAddress - Account address to search for
2000
- * @returns Promise resolving to business data
2001
- */
2002
- async getBusinessByAccount(accountAddress) {
2003
- return this.businessSDK.getBusinessByAccount(accountAddress);
2004
- }
2005
- /**
2006
- * Get all business types
2007
- *
2008
- * @returns Promise resolving to array of business types
2009
- */
2010
- async getBusinessTypes() {
2011
- return this.businessSDK.getBusinessTypes();
2012
- }
2013
- /**
2014
- * Get businesses by type
2015
- *
2016
- * @param typeId - Business type ID to filter by
2017
- * @returns Promise resolving to array of businesses
2018
- */
2019
- async getBusinessesByType(typeId) {
2020
- return this.businessSDK.getBusinessesByType(typeId);
2021
- }
2022
- /**
2023
- * Admin: Get all businesses (including inactive)
2024
- *
2025
- * @returns Promise resolving to array of all businesses
2026
- */
2027
- async getBusinesses() {
2028
- return this.businessSDK.getBusinesses();
2029
- }
2030
- /**
2031
- * Admin: Create new business
2032
- *
2033
- * @param displayName - Display name for the business
2034
- * @returns Promise resolving to created business data
2035
- */
2036
- async createBusiness(displayName) {
2037
- return this.businessSDK.createBusinessByDisplayName(displayName);
2038
- }
2039
- /**
2040
- * Admin: Update business
2041
- *
2042
- * @param businessId - ID of business to update
2043
- * @param businessData - Business data to update
2044
- * @returns Promise resolving to updated business data
2045
- */
2046
- async updateBusiness(businessId, businessData) {
2047
- return this.businessSDK.updateBusiness(businessId, businessData);
2048
- }
2049
- /**
2050
- * Admin: Toggle business active status
2051
- *
2052
- * @param businessId - ID of business to toggle
2053
- * @param toggleData - Toggle request data
2054
- * @returns Promise resolving to updated business data
2055
- */
2056
- async toggleBusinessStatus(businessId, toggleData) {
2057
- return this.businessSDK.toggleBusinessActive(businessId, toggleData);
2058
- }
2059
- /**
2060
- * Get the full business SDK for advanced operations
2061
- *
2062
- * @returns BusinessSDK instance
2063
- */
2064
- getBusinessSDK() {
2065
- return this.businessSDK;
2066
- }
2067
- }
2068
-
2069
- /**
2070
- * Campaign Manager - Clean, high-level interface for campaign operations
2071
- *
2072
- * Provides a simplified API for common campaign management tasks while maintaining
2073
- * access to the full campaign SDK for advanced use cases.
2074
- */
2075
- class CampaignManager {
2076
- constructor(apiClient) {
2077
- this.apiClient = apiClient;
2078
- this.campaignSDK = campaign.createCampaignSDK(apiClient);
2079
- }
2080
- /**
2081
- * Get all active campaigns
2082
- *
2083
- * @returns Promise resolving to array of active campaigns
2084
- */
2085
- async getActiveCampaigns() {
2086
- return this.campaignSDK.getActiveCampaigns();
2087
- }
2088
- /**
2089
- * Get campaign by ID
2090
- *
2091
- * @param campaignId - ID of the campaign
2092
- * @returns Promise resolving to campaign data
2093
- */
2094
- async getCampaignById(campaignId) {
2095
- return this.campaignSDK.getCampaignById(campaignId);
2096
- }
2097
- /**
2098
- * Claim a campaign reward
2099
- *
2100
- * @param claimRequest - Campaign claim data
2101
- * @returns Promise resolving to claim result
2102
- */
2103
- async claimCampaign(claimRequest) {
2104
- return this.campaignSDK.claimCampaign(claimRequest);
2105
- }
2106
- /**
2107
- * Get user's campaign claims
2108
- *
2109
- * @returns Promise resolving to array of user's claims
2110
- */
2111
- async getUserClaims() {
2112
- return this.campaignSDK.getClaimsForLoggedUser();
2113
- }
2114
- /**
2115
- * Admin: Get all campaigns
2116
- *
2117
- * @param active - Filter by active status
2118
- * @returns Promise resolving to array of campaigns
2119
- */
2120
- async getAllCampaigns(active) {
2121
- return this.campaignSDK.getCampaigns(active);
2122
- }
2123
- /**
2124
- * Admin: Create new campaign
2125
- *
2126
- * @param campaignData - Campaign data
2127
- * @returns Promise resolving to created campaign
2128
- */
2129
- async createCampaign(campaignData) {
2130
- return this.campaignSDK.createCampaign(campaignData);
2131
- }
2132
- /**
2133
- * Admin: Update campaign
2134
- *
2135
- * @param campaignId - ID of campaign to update
2136
- * @param campaignData - Updated campaign data
2137
- * @returns Promise resolving to updated campaign
2138
- */
2139
- async updateCampaign(campaignId, campaignData) {
2140
- return this.campaignSDK.updateCampaign(campaignId, campaignData);
2141
- }
2142
- /**
2143
- * Admin: Toggle campaign active status
2144
- *
2145
- * @param campaignId - ID of campaign to toggle
2146
- * @returns Promise resolving to updated campaign
2147
- */
2148
- async toggleCampaignStatus(campaignId) {
2149
- return this.campaignSDK.toggleCampaignActive(campaignId);
2150
- }
2151
- /**
2152
- * Admin: Toggle campaign testnet environment
2153
- *
2154
- * @param campaignId - ID of campaign to toggle
2155
- * @returns Promise resolving to updated campaign
2156
- */
2157
- async toggleCampaignTestnet(campaignId) {
2158
- return this.campaignSDK.toggleCampaignTestnet(campaignId);
2159
- }
2160
- /**
2161
- * Admin: Get campaign triggers
2162
- *
2163
- * @returns Promise resolving to array of campaign triggers
2164
- */
2165
- async getCampaignTriggers() {
2166
- return this.campaignSDK.getCampaignTriggers();
2167
- }
2168
- /**
2169
- * Admin: Set campaign trigger
2170
- *
2171
- * @param campaignId - ID of campaign
2172
- * @param triggerId - ID of trigger to set
2173
- * @returns Promise resolving to updated campaign
2174
- */
2175
- async setCampaignTrigger(campaignId, triggerId) {
2176
- return this.campaignSDK.setCampaignTrigger(campaignId, triggerId);
2177
- }
2178
- /**
2179
- * Admin: Create campaign token unit
2180
- *
2181
- * @param campaignId - ID of campaign
2182
- * @param tokenUnit - Token unit data
2183
- * @returns Promise resolving to updated campaign
2184
- */
2185
- async createCampaignTokenUnit(campaignId, tokenUnit) {
2186
- return this.campaignSDK.createCampaignTokenUnit(campaignId, tokenUnit);
2187
- }
2188
- /**
2189
- * Admin: Delete campaign token unit
2190
- *
2191
- * @param campaignId - ID of campaign
2192
- * @param tokenUnitId - ID of token unit to delete
2193
- * @returns Promise resolving to updated campaign
2194
- */
2195
- async deleteCampaignTokenUnit(campaignId, tokenUnitId) {
2196
- return this.campaignSDK.deleteCampaignTokenUnit(campaignId, tokenUnitId);
2197
- }
2198
- /**
2199
- * Admin: Add business engagement to campaign
2200
- *
2201
- * @param campaignId - ID of campaign
2202
- * @param engagement - Business engagement data
2203
- * @returns Promise resolving to updated campaign
2204
- */
2205
- async addBusinessEngagementToCampaign(campaignId, engagement) {
2206
- return this.campaignSDK.addBusinessEngagementToCampaign(campaignId, engagement);
2207
- }
2208
- /**
2209
- * Admin: Update campaign business engagement
2210
- *
2211
- * @param campaignId - ID of campaign
2212
- * @param engagementId - ID of engagement to update
2213
- * @param engagement - Updated engagement data
2214
- * @returns Promise resolving to updated campaign
2215
- */
2216
- async updateCampaignBusinessEngagement(campaignId, engagementId, engagement) {
2217
- return this.campaignSDK.updateCampaignBusinessEngagement(campaignId, engagementId, engagement);
2218
- }
2219
- /**
2220
- * Admin: Delete campaign business engagement
2221
- *
2222
- * @param campaignId - ID of campaign
2223
- * @param engagementId - ID of engagement to delete
2224
- * @returns Promise resolving to updated campaign
2225
- */
2226
- async deleteCampaignBusinessEngagement(campaignId, engagementId) {
2227
- return this.campaignSDK.deleteCampaignBusinessEngagement(campaignId, engagementId);
2228
- }
2229
- /**
2230
- * Admin: Get all campaign claims
2231
- *
2232
- * @returns Promise resolving to array of campaign claims
2233
- */
2234
- async getCampaignClaims() {
2235
- return this.campaignSDK.getCampaignClaims();
2236
- }
2237
- /**
2238
- * Admin: Get campaign claims by user ID
2239
- *
2240
- * @param userId - ID of user
2241
- * @returns Promise resolving to array of user's campaign claims
2242
- */
2243
- async getCampaignClaimsByUserId(userId) {
2244
- return this.campaignSDK.getCampaignClaimsByUserId(userId);
2245
- }
2246
- /**
2247
- * Admin: Get campaign claims by business ID
2248
- *
2249
- * @param businessId - ID of business
2250
- * @returns Promise resolving to array of business's campaign claims
2251
- */
2252
- async getCampaignClaimsByBusinessId(businessId) {
2253
- return this.campaignSDK.getCampaignClaimsByBusinessId(businessId);
2254
- }
2255
- /**
2256
- * Get the full campaign SDK for advanced operations
2257
- *
2258
- * @returns CampaignSDK instance
2259
- */
2260
- getCampaignSDK() {
2261
- return this.campaignSDK;
2262
- }
2263
- }
2264
-
2265
- /**
2266
- * Redemption Manager - Clean, high-level interface for redemption operations
2267
- *
2268
- * Provides a simplified API for common redemption management tasks while maintaining
2269
- * access to the full redemption SDK for advanced use cases.
2270
- */
2271
- class RedemptionManager {
2272
- constructor(apiClient) {
2273
- this.apiClient = apiClient;
2274
- this.redemptionSDK = redemption.createRedemptionSDK(apiClient);
2275
- }
2276
- /**
2277
- * Get all active redemption offers
2278
- *
2279
- * @returns Promise resolving to array of active redemptions
2280
- */
2281
- async getActiveRedemptions() {
2282
- return this.redemptionSDK.getActiveRedemptions();
2283
- }
2284
- /**
2285
- * Get available redemption types
2286
- *
2287
- * @returns Promise resolving to array of redemption types
2288
- */
2289
- async getRedemptionTypes() {
2290
- return this.redemptionSDK.getRedemptionTypes();
2291
- }
2292
- /**
2293
- * Redeem a redemption offer
2294
- *
2295
- * @param redemptionId - ID of the redemption to redeem
2296
- * @returns Promise resolving to redemption result
2297
- */
2298
- async redeemOffer(redemptionId) {
2299
- return this.redemptionSDK.redeemRedemption(redemptionId);
2300
- }
2301
- /**
2302
- * Get user's redemption history
2303
- *
2304
- * @returns Promise resolving to array of user's redemptions
2305
- */
2306
- async getUserRedemptions() {
2307
- return this.redemptionSDK.getUserRedeems();
2308
- }
2309
- /**
2310
- * Admin: Get all redemptions
2311
- *
2312
- * @param active - Filter by active status
2313
- * @returns Promise resolving to array of redemptions
2314
- */
2315
- async getAllRedemptions(active) {
2316
- return this.redemptionSDK.getRedemptionsAsAdmin(active);
2317
- }
2318
- /**
2319
- * Admin: Create new redemption offer
2320
- *
2321
- * @param redemptionData - Redemption data
2322
- * @returns Promise resolving to created redemption
2323
- */
2324
- async createRedemption(redemptionData) {
2325
- return this.redemptionSDK.createRedemption(redemptionData);
2326
- }
2327
- /**
2328
- * Admin: Update redemption
2329
- *
2330
- * @param redemptionId - ID of redemption to update
2331
- * @param redemptionData - Updated redemption data
2332
- * @returns Promise resolving to updated redemption
2333
- */
2334
- async updateRedemption(redemptionId, redemptionData) {
2335
- return this.redemptionSDK.updateRedemption(redemptionId, redemptionData);
2336
- }
2337
- /**
2338
- * Admin: Toggle redemption active status
2339
- *
2340
- * @param redemptionId - ID of redemption to toggle
2341
- * @returns Promise resolving to updated redemption
2342
- */
2343
- async toggleRedemptionStatus(redemptionId) {
2344
- return this.redemptionSDK.toggleRedemptionActive(redemptionId);
2345
- }
2346
- /**
2347
- * Admin: Create redemption token unit
2348
- *
2349
- * @param redemptionId - ID of redemption
2350
- * @param tokenUnit - Token unit data
2351
- * @returns Promise resolving to updated redemption
2352
- */
2353
- async createRedemptionTokenUnit(redemptionId, tokenUnit) {
2354
- return this.redemptionSDK.createRedemptionTokenUnit(redemptionId, tokenUnit);
2355
- }
2356
- /**
2357
- * Admin: Delete redemption token unit
2358
- *
2359
- * @param redemptionId - ID of redemption
2360
- * @param tokenUnitId - ID of token unit to delete
2361
- * @returns Promise resolving to updated redemption
2362
- */
2363
- async deleteRedemptionTokenUnit(redemptionId, tokenUnitId) {
2364
- return this.redemptionSDK.deleteRedemptionTokenUnit(redemptionId, tokenUnitId);
2365
- }
2366
- /**
2367
- * Get the full redemption SDK for advanced operations
2368
- *
2369
- * @returns RedemptionSDK instance
2370
- */
2371
- getRedemptionSDK() {
2372
- return this.redemptionSDK;
2373
- }
2374
- }
2375
-
2376
- /**
2377
- * Transaction Manager - Clean, high-level interface for transaction operations
2378
- *
2379
- * Provides a simplified API for common transaction management tasks while maintaining
2380
- * access to the full transaction SDK for advanced use cases.
2381
- */
2382
- class TransactionManager {
2383
- constructor(apiClient) {
2384
- this.apiClient = apiClient;
2385
- this.transactionSDK = transaction.createTransactionSDK(apiClient);
2386
- }
2387
- /**
2388
- * Get transaction by ID
2389
- *
2390
- * @param transactionId - ID of the transaction
2391
- * @returns Promise resolving to transaction data
2392
- */
2393
- async getTransactionById(transactionId) {
2394
- return this.transactionSDK.getTransactionById(transactionId);
2395
- }
2396
- /**
2397
- * Create a new transaction
2398
- *
2399
- * @param transactionData - Transaction data
2400
- * @returns Promise resolving to transaction response
2401
- */
2402
- async createTransaction(transactionData) {
2403
- return this.transactionSDK.createTransaction(transactionData);
2404
- }
2405
- /**
2406
- * Get user's transaction history
2407
- *
2408
- * @param type - Transaction type filter
2409
- * @returns Promise resolving to array of user's transactions
2410
- */
2411
- async getUserTransactionHistory(type) {
2412
- return this.transactionSDK.getUserTransactionHistory(type);
2413
- }
2414
- /**
2415
- * Admin: Get all tenant transactions
2416
- *
2417
- * @returns Promise resolving to array of tenant transactions
2418
- */
2419
- async getTenantTransactions() {
2420
- return this.transactionSDK.getTenantTransactions();
2421
- }
2422
- /**
2423
- * Admin: Get paginated transactions
2424
- *
2425
- * @param params - Pagination parameters
2426
- * @returns Promise resolving to paginated transaction results
2427
- */
2428
- async getPaginatedTransactions(params) {
2429
- return this.transactionSDK.getPaginatedTransactions(params);
2430
- }
2431
- /**
2432
- * Admin: Export transactions as CSV
2433
- *
2434
- * @returns Promise resolving to CSV blob
2435
- */
2436
- async exportTransactionsCSV() {
2437
- return this.transactionSDK.exportTransactionsCSV();
2438
- }
2439
- /**
2440
- * Get the full transaction SDK for advanced operations
2441
- *
2442
- * @returns TransactionSDK instance
2443
- */
2444
- getTransactionSDK() {
2445
- return this.transactionSDK;
2446
- }
2447
- }
2448
-
2449
- /**
2450
- * Purchase Manager - Clean, high-level interface for purchase operations
2451
- *
2452
- * Provides a simplified API for common purchase management tasks while maintaining
2453
- * access to the full payment SDK for advanced use cases.
2454
- */
2455
- class PurchaseManager {
2456
- constructor(apiClient) {
2457
- this.apiClient = apiClient;
2458
- this.paymentSDK = payment.createPaymentSDK(apiClient);
2459
- }
2460
- /**
2461
- * Create a payment intent
2462
- *
2463
- * @param amount - Payment amount
2464
- * @param currency - Payment currency
2465
- * @param receiptEmail - Receipt email
2466
- * @param description - Payment description
2467
- * @returns Promise resolving to created payment intent
2468
- */
2469
- async createPaymentIntent(amount, currency, receiptEmail, description) {
2470
- return this.paymentSDK.createPaymentIntent(amount, currency, receiptEmail, description);
2471
- }
2472
- /**
2473
- * Get active purchase tokens
2474
- *
2475
- * @param active - Filter by active status
2476
- * @returns Promise resolving to purchase tokens
2477
- */
2478
- async getActivePurchaseTokens(active) {
2479
- return this.paymentSDK.getActivePurchaseTokens(active);
2480
- }
2481
- /**
2482
- * Get all user purchases
2483
- *
2484
- * @returns Promise resolving to array of user's purchases
2485
- */
2486
- async getAllUserPurchases() {
2487
- return this.paymentSDK.getAllUserPurchases();
2488
- }
2489
- /**
2490
- * Get the full purchase SDK for advanced operations
2491
- *
2492
- * @returns PaymentSDK instance
2493
- */
2494
- getPurchaseSDK() {
2495
- return this.paymentSDK;
2496
- }
2497
- }
2498
-
2499
- /**
2500
- * Platform-Agnostic File API Client
2501
- *
2502
- * Handles file operations using the PERS backend's RESTful endpoints.
2503
- */
2504
- class FileApi {
2505
- constructor(apiClient) {
2506
- this.apiClient = apiClient;
2507
- this.basePath = '/files';
2508
- }
2509
- // ==========================================
2510
- // PUBLIC OPERATIONS
2511
- // ==========================================
2512
- /**
2513
- * PUBLIC: Get signed URL for file operations
2514
- *
2515
- * @param request - Signed URL request parameters
2516
- * @returns Promise resolving to signed URL response
2517
- */
2518
- async getSignedUrl(request) {
2519
- return this.apiClient.post(`${this.basePath}/entity-storage-url`, request);
2520
- }
2521
- /**
2522
- * PUBLIC: Get signed GET URL for file access
2523
- *
2524
- * @param url - File URL
2525
- * @param expireSeconds - Optional expiration time in seconds
2526
- * @returns Promise resolving to signed URL response
2527
- */
2528
- async getSignedGetUrl(url, expireSeconds) {
2529
- const searchParams = new URLSearchParams({ url });
2530
- if (expireSeconds) {
2531
- searchParams.set('expireSeconds', expireSeconds.toString());
2532
- }
2533
- return this.apiClient.get(`${this.basePath}/signed-url?${searchParams.toString()}`);
2534
- }
2535
- /**
2536
- * PUBLIC: Optimize media from URL
2537
- *
2538
- * @param request - File optimization request
2539
- * @returns Promise resolving to optimized file URL
2540
- */
2541
- async optimizeMediaFromUrl(request) {
2542
- const searchParams = new URLSearchParams({ url: request.url });
2543
- if (request.width)
2544
- searchParams.set('width', request.width.toString());
2545
- if (request.height)
2546
- searchParams.set('height', request.height.toString());
2547
- return this.apiClient.get(`/file/optimize-url?${searchParams.toString()}`);
2548
- }
2549
- }
2550
-
2551
- /**
2552
- * File Service - High-level file operations
2553
- *
2554
- * Provides convenient methods for file upload, signed URLs, and media optimization.
2555
- */
2556
- class FileService {
2557
- constructor(apiClient) {
2558
- this.fileApi = new FileApi(apiClient);
2559
- }
2560
- /**
2561
- * Get signed PUT URL for file upload
2562
- *
2563
- * @param entityId - Entity ID to associate the file with
2564
- * @param entityType - Type of entity (token, campaign, etc.)
2565
- * @param fileExtension - File extension (e.g., 'jpg', 'png')
2566
- * @returns Promise resolving to signed upload URL
2567
- */
2568
- async getSignedPutUrl(entityId, entityType, fileExtension) {
2569
- const request = {
2570
- entityId,
2571
- entityType,
2572
- signedUrlType: 'PUT',
2573
- fileExtension
2574
- };
2575
- const response = await this.fileApi.getSignedUrl(request);
2576
- return response.signedUrl;
2577
- }
2578
- /**
2579
- * Get signed GET URL for file access
2580
- *
2581
- * @param entityId - Entity ID
2582
- * @param entityType - Type of entity
2583
- * @param expireSeconds - Optional expiration time in seconds
2584
- * @returns Promise resolving to signed access URL
2585
- */
2586
- async getSignedGetUrl(entityId, entityType, expireSeconds) {
2587
- const request = {
2588
- entityId,
2589
- entityType,
2590
- signedUrlType: 'GET'
2591
- };
2592
- const response = await this.fileApi.getSignedUrl(request);
2593
- return response.signedUrl;
2594
- }
2595
- /**
2596
- * Get signed URL for any file operation
2597
- *
2598
- * @param request - Signed URL request
2599
- * @returns Promise resolving to signed URL
2600
- */
2601
- async getSignedUrl(request) {
2602
- const response = await this.fileApi.getSignedUrl(request);
2603
- return response.signedUrl;
2604
- }
2605
- /**
2606
- * Optimize media from URL
2607
- *
2608
- * @param url - Original file URL
2609
- * @param width - Optional target width
2610
- * @param height - Optional target height
2611
- * @returns Promise resolving to optimized file URL
2612
- */
2613
- async optimizeMedia(url, width, height) {
2614
- const request = { url, width, height };
2615
- const response = await this.fileApi.optimizeMediaFromUrl(request);
2616
- return response.optimizedUrl;
2617
- }
2618
- /**
2619
- * Get the file API instance for advanced operations
2620
- *
2621
- * @returns FileApi instance
2622
- */
2623
- getFileApi() {
2624
- return this.fileApi;
2625
- }
2626
- }
2627
- /**
2628
- * Factory function for creating file service
2629
- */
2630
- function createFileSDK(apiClient) {
2631
- return new FileService(apiClient);
2632
- }
2633
-
2634
- /**
2635
- * File Manager - Clean, high-level interface for file operations
2636
- *
2637
- * Provides a simplified API for common file management tasks while maintaining
2638
- * access to the full file SDK for advanced use cases.
2639
- */
2640
- class FileManager {
2641
- constructor(apiClient) {
2642
- this.apiClient = apiClient;
2643
- this.fileSDK = createFileSDK(apiClient);
2644
- }
2645
- /**
2646
- * Get signed URL for file upload
2647
- *
2648
- * @param entityId - Entity ID to associate the file with
2649
- * @param entityType - Type of entity (token, campaign, etc.)
2650
- * @param fileExtension - File extension (e.g., 'jpg', 'png')
2651
- * @returns Promise resolving to signed upload URL
2652
- */
2653
- async getSignedPutUrl(entityId, entityType, fileExtension) {
2654
- return this.fileSDK.getSignedPutUrl(entityId, entityType, fileExtension);
2655
- }
2656
- /**
2657
- * Get signed URL for file access
2658
- *
2659
- * @param entityId - Entity ID
2660
- * @param entityType - Type of entity
2661
- * @param expireSeconds - Optional expiration time in seconds
2662
- * @returns Promise resolving to signed access URL
2663
- */
2664
- async getSignedGetUrl(entityId, entityType, expireSeconds) {
2665
- return this.fileSDK.getSignedGetUrl(entityId, entityType, expireSeconds);
2666
- }
2667
- /**
2668
- * Get signed URL for any file operation
2669
- *
2670
- * @param request - Signed URL request
2671
- * @returns Promise resolving to signed URL
2672
- */
2673
- async getSignedUrl(request) {
2674
- return this.fileSDK.getSignedUrl(request);
2675
- }
2676
- /**
2677
- * Optimize media file
2678
- *
2679
- * @param url - Original file URL
2680
- * @param width - Optional target width
2681
- * @param height - Optional target height
2682
- * @returns Promise resolving to optimized file URL
2683
- */
2684
- async optimizeMedia(url, width, height) {
2685
- return this.fileSDK.optimizeMedia(url, width, height);
2686
- }
2687
- /**
2688
- * Get the full file SDK for advanced operations
2689
- *
2690
- * @returns FileService instance
2691
- */
2692
- getFileSDK() {
2693
- return this.fileSDK;
2694
- }
2695
- }
2696
-
2697
- /**
2698
- * Tenant Manager - Clean, high-level interface for tenant operations
2699
- *
2700
- * Provides a simplified API for common tenant management tasks while maintaining
2701
- * access to the full tenant SDK for advanced use cases.
2702
- */
2703
- class TenantManager {
2704
- constructor(apiClient) {
2705
- this.apiClient = apiClient;
2706
- this.tenantSDK = tenant.createTenantSDK(apiClient);
2707
- }
2708
- /**
2709
- * Get current tenant information
2710
- *
2711
- * @returns Promise resolving to tenant data
2712
- */
2713
- async getTenantInfo() {
2714
- return this.tenantSDK.getRemoteTenant();
2715
- }
2716
- /**
2717
- * Get tenant login token
2718
- *
2719
- * @returns Promise resolving to login token
2720
- */
2721
- async getLoginToken() {
2722
- return this.tenantSDK.getRemoteLoginToken();
2723
- }
2724
- /**
2725
- * Get tenant client configuration
2726
- *
2727
- * @returns Promise resolving to client config
2728
- */
2729
- async getClientConfig() {
2730
- return this.tenantSDK.getRemoteClientConfig();
2731
- }
2732
- /**
2733
- * Admin: Update tenant data
2734
- *
2735
- * @param tenantData - Updated tenant data
2736
- * @returns Promise resolving to updated tenant
2737
- */
2738
- async updateTenant(tenantData) {
2739
- return this.tenantSDK.updateRemoteTenant(tenantData);
2740
- }
2741
- /**
2742
- * Admin: Get all admins
2743
- *
2744
- * @returns Promise resolving to array of admins
2745
- */
2746
- async getAdmins() {
2747
- return this.tenantSDK.getAdmins();
2748
- }
2749
- /**
2750
- * Admin: Create new admin
2751
- *
2752
- * @param adminData - Admin data
2753
- * @returns Promise resolving to created admin
2754
- */
2755
- async createAdmin(adminData) {
2756
- return this.tenantSDK.postAdmin(adminData);
2757
- }
2758
- /**
2759
- * Admin: Update existing admin
2760
- *
2761
- * @param adminId - ID of the admin to update
2762
- * @param adminData - Updated admin data
2763
- * @returns Promise resolving to updated admin
2764
- */
2765
- async updateAdmin(adminId, adminData) {
2766
- return this.tenantSDK.putAdmin(adminId, adminData);
2767
- }
2768
- /**
2769
- * Get the full tenant SDK for advanced operations
2770
- *
2771
- * @returns TenantSDK instance
2772
- */
2773
- getTenantSDK() {
2774
- return this.tenantSDK;
2775
- }
2776
- }
2777
-
2778
- /**
2779
- * Analytics Manager - Clean, high-level interface for analytics operations
2780
- *
2781
- * Provides a simplified API for common analytics tasks while maintaining
2782
- * access to the full analytics SDK for advanced use cases.
2783
- */
2784
- class AnalyticsManager {
2785
- constructor(apiClient) {
2786
- this.apiClient = apiClient;
2787
- this.analyticsSDK = analytics.createAnalyticsSDK(apiClient);
2788
- }
2789
- /**
2790
- * Get transaction analytics
2791
- *
2792
- * @param request - Analytics request parameters
2793
- * @returns Promise resolving to transaction analytics data
2794
- */
2795
- async getTransactionAnalytics(request) {
2796
- return this.analyticsSDK.getTransactionAnalytics(request);
2797
- }
2798
- /**
2799
- * Get the full analytics SDK for advanced operations
2800
- *
2801
- * @returns AnalyticsSDK instance
2802
- */
2803
- getAnalyticsSDK() {
2804
- return this.analyticsSDK;
2805
- }
2806
- }
2807
-
2808
- /**
2809
- * Donation Manager - Clean, high-level interface for donation operations
2810
- *
2811
- * Provides a simplified API for common donation tasks while maintaining
2812
- * access to the full donation SDK for advanced use cases.
2813
- */
2814
- class DonationManager {
2815
- constructor(apiClient) {
2816
- this.apiClient = apiClient;
2817
- this.donationSDK = donation.createDonationSDK(apiClient);
2818
- }
2819
- /**
2820
- * Get available donation types
2821
- *
2822
- * @returns Promise resolving to array of donation types
2823
- */
2824
- async getDonationTypes() {
2825
- return this.donationSDK.getAllDonationTypes();
2826
- }
2827
- /**
2828
- * Get the full donation SDK for advanced operations
2829
- *
2830
- * @returns DonationSDK instance
2831
- */
2832
- getDonationSDK() {
2833
- return this.donationSDK;
2834
- }
2835
- }
2836
-
2837
- /**
2838
- * Web3 Manager - Clean, high-level interface for Web3 operations
2839
- *
2840
- * Provides a simplified API for common Web3 blockchain tasks while maintaining
2841
- * access to the full Web3 SDK for advanced use cases.
2842
- */
2843
- class Web3Manager {
2844
- constructor(apiClient) {
2845
- this.apiClient = apiClient;
2846
- this.web3SDK = web3.createWeb3SDK(apiClient);
2847
- this.web3ChainSDK = web3Chain.createWeb3ChainSDK(apiClient);
2848
- }
2849
- /**
2850
- * Get token balance for a specific token
2851
- *
2852
- * @param request - Token balance request parameters
2853
- * @returns Promise resolving to token balance
2854
- */
2855
- async getTokenBalance(request) {
2856
- return this.web3SDK.getTokenBalance(request);
2857
- }
2858
- /**
2859
- * Get token metadata
2860
- *
2861
- * @param request - Token metadata request parameters
2862
- * @returns Promise resolving to token metadata or null if not found
2863
- */
2864
- async getTokenMetadata(request) {
2865
- return this.web3SDK.getTokenMetadata(request);
2866
- }
2867
- /**
2868
- * Get token collection
2869
- *
2870
- * @param request - Token collection request parameters
2871
- * @returns Promise resolving to token collection
2872
- */
2873
- async getTokenCollection(request) {
2874
- return this.web3SDK.getTokenCollection(request);
2875
- }
2876
- /**
2877
- * Resolve IPFS URL to accessible URL
2878
- *
2879
- * @param url - IPFS URL to resolve
2880
- * @param chainId - Chain ID for context
2881
- * @returns Promise resolving to accessible URL
2882
- */
2883
- async resolveIPFSUrl(url, chainId) {
2884
- return this.web3SDK.resolveIPFSUrl(url, chainId);
2885
- }
2886
- /**
2887
- * Fetch and process token metadata
2888
- *
2889
- * @param tokenUri - Token URI to fetch metadata from
2890
- * @param chainId - Chain ID for context
2891
- * @returns Promise resolving to processed metadata or null if not found
2892
- */
2893
- async fetchAndProcessMetadata(tokenUri, chainId) {
2894
- return this.web3SDK.fetchAndProcessMetadata(tokenUri, chainId);
2895
- }
2896
- /**
2897
- * Get blockchain chain data by chain ID
2898
- *
2899
- * @param chainId - Chain ID to get data for
2900
- * @returns Promise resolving to chain data or null if not found
2901
- */
2902
- async getChainDataById(chainId) {
2903
- return this.web3ChainSDK.getChainDataById(chainId);
2904
- }
2905
- /**
2906
- * Get explorer URL for a given address or transaction
2907
- *
2908
- * @param chainId - Chain ID to get explorer URL for
2909
- * @param address - Address or transaction hash
2910
- * @param type - Type of explorer URL ('address' or 'tx')
2911
- * @returns Promise resolving to explorer URL
2912
- */
2913
- async getExplorerUrl(chainId, address, type) {
2914
- return web3.getExplorerUrlByChainId((id) => this.getChainDataById(id), chainId, address, type);
2915
- }
2916
- /**
2917
- * Get the full Web3 SDK for advanced operations
2918
- *
2919
- * @returns Web3SDK instance
2920
- */
2921
- getWeb3SDK() {
2922
- return this.web3SDK;
2923
- }
2924
- }
2925
-
2926
- /**
2927
- * PERS SDK - Platform-agnostic TypeScript SDK with High-Level Managers
2928
- *
2929
- * ## Overview
2930
- *
2931
- * The PERS SDK provides a comprehensive interface for integrating with the PERS
2932
- * (Phygital Experience Rewards System) platform. It features a clean manager-based
2933
- * architecture that abstracts complex domain operations into intuitive high-level APIs.
2934
- *
2935
- * ## Architecture
2936
- *
2937
- * ```
2938
- * PersSDK
2939
- * ├── Domain Managers (Recommended) // High-level, intuitive APIs
2940
- * │ ├── auth: AuthManager // Authentication & user sessions
2941
- * │ ├── users: UserManager // User profile management
2942
- * │ ├── tokens: TokenManager // Token balances & transfers
2943
- * │ ├── businesses: BusinessManager // Business operations
2944
- * │ ├── campaigns: CampaignManager // Marketing campaigns
2945
- * │ ├── redemptions: RedemptionManager // Reward redemptions
2946
- * │ ├── transactions: TransactionManager // Transaction history
2947
- * │ ├── purchases: PurchaseManager // Purchase processing
2948
- * │ └── analytics: AnalyticsManager // Reporting & analytics
2949
- * ├── Domain SDKs (Advanced) // Full-featured domain access
2950
- * │ ├── createBusinessSDK()
2951
- * │ ├── createCampaignSDK()
2952
- * │ └── TokenSDK, etc.
2953
- * └── Core API Client (Expert) // Direct REST API access
2954
- * └── api(): PersApiClient
2955
- * ```
2956
- *
2957
- * ## Usage Patterns
2958
- *
2959
- * ### 1. High-Level Manager Pattern (Recommended)
2960
- *
2961
- * ```typescript
2962
- * import { PersSDK } from '@explorins/pers-sdk';
2963
- * import { BrowserFetchClientAdapter } from '@explorins/pers-sdk/platform-adapters';
2964
- *
2965
- * const sdk = new PersSDK(new BrowserFetchClientAdapter(), {
2966
- * environment: 'production',
2967
- * apiProjectKey: 'your-project-key'
2968
- * });
2969
- *
2970
- * // Clean, intuitive manager interface
2971
- * const user = await sdk.auth.getCurrentUser();
2972
- * const campaigns = await sdk.campaigns.getActiveCampaigns();
2973
- * const balances = await sdk.tokens.getTokens();
2974
- * ```
2975
- *
2976
- * ### 2. Advanced Domain SDK Access
2977
- *
2978
- * ```typescript
2979
- * // Access full SDK capabilities when needed
2980
- * const campaignSDK = sdk.campaigns.getCampaignSDK();
2981
- * const advancedCampaignOps = await campaignSDK.api.createComplexCampaign(data);
2982
- * ```
2983
- *
2984
- * ### 3. Direct API Client Access
2985
- *
2986
- * ```typescript
2987
- * // For custom endpoints or advanced operations
2988
- * const apiClient = sdk.api();
2989
- * const customData = await apiClient.get('/custom-endpoint');
2990
- * ```
2991
- *
2992
- * ## Platform Integration
2993
- *
2994
- * The SDK provides pre-built adapters for common platforms:
2995
- *
2996
- * - **Angular**: `AngularHttpClientAdapter`
2997
- * - **Browser/React/Vue**: `BrowserFetchClientAdapter`
2998
- * - **Node.js**: `NodeHttpClientAdapter`
2999
- * - **Custom**: Implement `HttpClient` interface
3000
- *
3001
- * ## Features
3002
- *
3003
- * - ✅ **Type-safe**: Full TypeScript support with comprehensive type definitions
3004
- * - ✅ **Platform-agnostic**: Works in browsers, Node.js, React Native, and more
3005
- * - ✅ **Authentication**: Automatic token management and refresh
3006
- * - ✅ **Error handling**: Comprehensive error handling with typed exceptions
3007
- * - ✅ **Modular**: Import only the domains you need
3008
- * - ✅ **Manager pattern**: Clean, high-level APIs for common operations
3009
- * - ✅ **Backward compatible**: Maintains compatibility with existing integrations
3010
- * - ✅ **Tree-shakable**: Optimized for minimal bundle size
3011
- *
3012
- * @example Basic Setup
3013
- * ```typescript
3014
- * import { PersSDK } from '@explorins/pers-sdk';
3015
- * import { BrowserFetchClientAdapter } from '@explorins/pers-sdk/platform-adapters';
3016
- *
3017
- * const sdk = new PersSDK(new BrowserFetchClientAdapter(), {
3018
- * environment: 'production',
3019
- * apiProjectKey: 'your-project-key'
3020
- * });
3021
- * ```
3022
- *
3023
- * @example Authentication Flow
3024
- * ```typescript
3025
- * // Login with external JWT (Firebase, Auth0, etc.)
3026
- * await sdk.auth.loginWithToken(firebaseJWT, 'user');
3027
- *
3028
- * // Check authentication status
3029
- * if (await sdk.auth.isAuthenticated()) {
3030
- * const user = await sdk.auth.getCurrentUser();
3031
- * console.log('Welcome,', user.name);
3032
- * }
3033
- * ```
3034
- *
3035
- * @example Business Operations
3036
- * ```typescript
3037
- * // Get active businesses
3038
- * const businesses = await sdk.businesses.getActiveBusinesses();
3039
- *
3040
- * // Get business details
3041
- * const business = await sdk.businesses.getBusinessById(businessId);
3042
- *
3043
- * // Admin: Create new business
3044
- * const newBusiness = await sdk.businesses.createBusiness({
3045
- * name: 'New Business',
3046
- * location: 'City Center',
3047
- * type: 'restaurant'
3048
- * });
3049
- * ```
3050
- *
3051
- * @example Campaign Management
3052
- * ```typescript
3053
- * // Get active campaigns
3054
- * const campaigns = await sdk.campaigns.getActiveCampaigns();
3055
- *
3056
- * // Claim a campaign
3057
- * await sdk.campaigns.claimCampaign({
3058
- * campaignId: 'campaign-123',
3059
- * metadata: { source: 'mobile-app' }
3060
- * });
3061
- *
3062
- * // Get user's claims
3063
- * const claims = await sdk.campaigns.getUserClaims();
3064
- * ```
3065
- *
3066
- * @example Token Operations
3067
- * ```typescript
3068
- * // Get user's token balances
3069
- * const tokens = await sdk.tokens.getTokens();
3070
- *
3071
- * // Transfer tokens between users
3072
- * await sdk.tokens.transferTokens({
3073
- * fromUserId: 'user-1',
3074
- * toUserId: 'user-2',
3075
- * tokenType: 'CREDIT',
3076
- * amount: 100
3077
- * });
3078
- * ```
3079
- *
3080
- * @since 1.3.0 - Manager pattern architecture
3081
- */
3082
- /**
3083
- * PERS SDK class with domain managers
3084
- *
3085
- * Main SDK interface providing clean, high-level managers for common operations
3086
- * while maintaining full access to the underlying API client and domain SDKs.
3087
- *
3088
- * @example
3089
- * ```typescript
3090
- * import { PersSDK, createAuthProvider } from '@explorins/pers-sdk/core';
3091
- * import { BrowserHttpClient } from '@explorins/pers-sdk/browser';
3092
- *
3093
- * const authProvider = createAuthProvider({
3094
- * tokenProvider: () => getFirebaseToken()
3095
- * });
3096
- *
3097
- * const sdk = new PersSDK(new BrowserHttpClient(), {
3098
- * environment: 'production',
3099
- * apiProjectKey: 'your-project-key',
3100
- * authProvider
3101
- * });
3102
- *
3103
- * // High-level manager interface
3104
- * const user = await sdk.auth.getCurrentUser();
3105
- * const tokens = await sdk.tokens.getTokens();
3106
- * const businesses = await sdk.business.getActiveBusinesses();
3107
- *
3108
- * // Direct API access for advanced operations
3109
- * const apiClient = sdk.api();
3110
- * const customData = await apiClient.get('/custom-endpoint');
3111
- * ```
3112
- */
3113
- class PersSDK {
3114
- /**
3115
- * Creates a new PERS SDK instance
3116
- *
3117
- * @param httpClient Platform-specific HTTP client implementation
3118
- * @param config SDK configuration options
3119
- */
3120
- constructor(httpClient, config) {
3121
- this.apiClient = new PersApiClient(httpClient, config);
3122
- // Initialize domain managers
3123
- this._auth = new AuthManager(this.apiClient);
3124
- this._users = new UserManager(this.apiClient);
3125
- this._userStatus = new UserStatusManager(this.apiClient);
3126
- this._tokens = new TokenManager(this.apiClient);
3127
- this._businesses = new BusinessManager(this.apiClient);
3128
- this._campaigns = new CampaignManager(this.apiClient);
3129
- this._redemptions = new RedemptionManager(this.apiClient);
3130
- this._transactions = new TransactionManager(this.apiClient);
3131
- this._purchases = new PurchaseManager(this.apiClient);
3132
- this._files = new FileManager(this.apiClient);
3133
- this._tenants = new TenantManager(this.apiClient);
3134
- this._analytics = new AnalyticsManager(this.apiClient);
3135
- this._donations = new DonationManager(this.apiClient);
3136
- this._web3 = new Web3Manager(this.apiClient);
3137
- }
3138
- /**
3139
- * Authentication manager - High-level auth operations
3140
- *
3141
- * @example
3142
- * ```typescript
3143
- * await sdk.auth.loginWithToken(jwtToken);
3144
- * const user = await sdk.auth.getCurrentUser();
3145
- * const isAuth = await sdk.auth.isAuthenticated();
3146
- * ```
3147
- */
3148
- get auth() {
3149
- return this._auth;
3150
- }
3151
- /**
3152
- * User manager - High-level user operations
3153
- *
3154
- * @example
3155
- * ```typescript
3156
- * const user = await sdk.user.getCurrentUser();
3157
- * await sdk.user.updateCurrentUser(userData);
3158
- * const users = await sdk.user.getAllUsersPublic();
3159
- * ```
3160
- */
3161
- get users() {
3162
- return this._users;
3163
- }
3164
- /**
3165
- * User Status manager - High-level user status operations
3166
- *
3167
- * @example
3168
- * ```typescript
3169
- * const statusTypes = await sdk.userStatus.getUserStatusTypes();
3170
- * const earnedStatus = await sdk.userStatus.getEarnedUserStatus();
3171
- * await sdk.userStatus.createUserStatusType(statusData);
3172
- * ```
3173
- */
3174
- get userStatus() {
3175
- return this._userStatus;
3176
- }
3177
- /**
3178
- * Token manager - High-level token operations
3179
- *
3180
- * @example
3181
- * ```typescript
3182
- * const tokens = await sdk.tokens.getTokens();
3183
- * const creditToken = await sdk.tokens.getActiveCreditToken();
3184
- * const rewards = await sdk.tokens.getRewardTokens();
3185
- * ```
3186
- */
3187
- get tokens() {
3188
- return this._tokens;
3189
- }
3190
- /**
3191
- * Business manager - High-level business operations
3192
- *
3193
- * @example
3194
- * ```typescript
3195
- * const businesses = await sdk.business.getActiveBusinesses();
3196
- * const business = await sdk.business.getBusinessById(id);
3197
- * const types = await sdk.business.getBusinessTypes();
3198
- * ```
3199
- */
3200
- get businesses() {
3201
- return this._businesses;
3202
- }
3203
- /**
3204
- * Campaign manager - High-level campaign operations
3205
- *
3206
- * @example
3207
- * ```typescript
3208
- * const campaigns = await sdk.campaigns.getActiveCampaigns();
3209
- * await sdk.campaigns.claimCampaign(claimData);
3210
- * const claims = await sdk.campaigns.getUserClaims();
3211
- * ```
3212
- */
3213
- get campaigns() {
3214
- return this._campaigns;
3215
- }
3216
- /**
3217
- * Redemption manager - High-level redemption operations
3218
- *
3219
- * @example
3220
- * ```typescript
3221
- * const redemptions = await sdk.redemptions.getActiveRedemptions();
3222
- * await sdk.redemptions.redeemOffer(redemptionId);
3223
- * const history = await sdk.redemptions.getUserRedemptions();
3224
- * ```
3225
- */
3226
- get redemptions() {
3227
- return this._redemptions;
3228
- }
3229
- /**
3230
- * Transaction manager - High-level transaction operations
3231
- *
3232
- * @example
3233
- * ```typescript
3234
- * const transaction = await sdk.transactions.getTransactionById(id);
3235
- * await sdk.transactions.createTransaction(txData);
3236
- * const history = await sdk.transactions.getUserTransactionHistory('all');
3237
- * ```
3238
- */
3239
- get transactions() {
3240
- return this._transactions;
3241
- }
3242
- /**
3243
- * Purchase manager - High-level purchase operations
3244
- *
3245
- * @example
3246
- * ```typescript
3247
- * const intent = await sdk.purchases.createPaymentIntent(100, 'usd', 'email@example.com', 'Purchase');
3248
- * const tokens = await sdk.purchases.getActivePurchaseTokens();
3249
- * const purchases = await sdk.purchases.getAllUserPurchases();
3250
- * ```
3251
- */
3252
- get purchases() {
3253
- return this._purchases;
3254
- }
3255
- /**
3256
- * File manager - High-level file operations
3257
- *
3258
- * @example
3259
- * ```typescript
3260
- * const uploadUrl = await sdk.files.getSignedPutUrl('entity-123', 'token', 'jpg');
3261
- * const accessUrl = await sdk.files.getSignedGetUrl('entity-123', 'token');
3262
- * const optimizedUrl = await sdk.files.optimizeMedia(originalUrl, 800, 600);
3263
- * ```
3264
- */
3265
- get files() {
3266
- return this._files;
3267
- }
3268
- /**
3269
- * Tenant manager - High-level tenant operations
3270
- *
3271
- * @example
3272
- * ```typescript
3273
- * const tenant = await sdk.tenant.getTenantInfo();
3274
- * const config = await sdk.tenant.getClientConfig();
3275
- * const admins = await sdk.tenant.getAdmins();
3276
- * ```
3277
- */
3278
- get tenants() {
3279
- return this._tenants;
3280
- }
3281
- /**
3282
- * Analytics manager - High-level analytics operations
3283
- *
3284
- * @example
3285
- * ```typescript
3286
- * const analytics = await sdk.analytics.getTransactionAnalytics(request);
3287
- * ```
3288
- */
3289
- get analytics() {
3290
- return this._analytics;
3291
- }
3292
- /**
3293
- * Donation manager - High-level donation operations
3294
- *
3295
- * @example
3296
- * ```typescript
3297
- * const types = await sdk.donations.getDonationTypes();
3298
- * ```
3299
- */
3300
- get donations() {
3301
- return this._donations;
3302
- }
3303
- /**
3304
- * Web3 manager - High-level blockchain operations
3305
- *
3306
- * @example
3307
- * ```typescript
3308
- * const balance = await sdk.web3.getTokenBalance(request);
3309
- * const metadata = await sdk.web3.getTokenMetadata(request);
3310
- * const collection = await sdk.web3.getTokenCollection(request);
3311
- * ```
3312
- */
3313
- get web3() {
3314
- return this._web3;
3315
- }
3316
- /**
3317
- * Gets the API client for direct PERS API requests
3318
- *
3319
- * Use this for advanced operations not covered by the managers.
3320
- * The returned client handles authentication, token refresh, and error handling automatically.
3321
- *
3322
- * @returns Configured PersApiClient instance
3323
- *
3324
- * @example
3325
- * ```typescript
3326
- * const apiClient = sdk.api();
3327
- * const customData = await apiClient.get<CustomType>('/custom-endpoint');
3328
- * await apiClient.post('/custom-endpoint', customData);
3329
- * ```
3330
- */
3331
- api() {
3332
- return this.apiClient;
3333
- }
3334
- /**
3335
- * Checks if SDK is configured for production environment
3336
- *
3337
- * @returns True if environment is 'production', false otherwise
3338
- */
3339
- isProduction() {
3340
- return this.apiClient.getConfig().environment === 'production';
3341
- }
3342
- }
3343
- /**
3344
- * Factory function for creating PERS SDK
3345
- *
3346
- * @param httpClient Platform-specific HTTP client implementation
3347
- * @param config SDK configuration options
3348
- * @returns PERS SDK instance
3349
- */
3350
- function createPersSDK(httpClient, config) {
3351
- return new PersSDK(httpClient, config);
3352
- }
3353
-
3354
- exports.AnalyticsManager = AnalyticsManager;
3355
- exports.AuthManager = AuthManager;
3356
- exports.BusinessManager = BusinessManager;
3357
- exports.CampaignManager = CampaignManager;
3358
- exports.DEFAULT_PERS_CONFIG = DEFAULT_PERS_CONFIG;
3359
- exports.DonationManager = DonationManager;
3360
- exports.FileApi = FileApi;
3361
- exports.FileManager = FileManager;
3362
- exports.FileService = FileService;
3363
- exports.PersApiClient = PersApiClient;
3364
- exports.PersSDK = PersSDK;
3365
- exports.PurchaseManager = PurchaseManager;
3366
- exports.RedemptionManager = RedemptionManager;
3367
- exports.TenantManager = TenantManager;
3368
- exports.TokenManager = TokenManager;
3369
- exports.TransactionManager = TransactionManager;
3370
- exports.UserManager = UserManager;
3371
- exports.UserStatusManager = UserStatusManager;
3372
- exports.Web3Manager = Web3Manager;
3373
- exports.buildApiRoot = buildApiRoot;
3374
- exports.createAuthProvider = createAuthProvider;
3375
- exports.createFileSDK = createFileSDK;
3376
- exports.createPersSDK = createPersSDK;
3377
- exports.mergeWithDefaults = mergeWithDefaults;
3378
- //# sourceMappingURL=pers-sdk-DbPwFKrf.cjs.map