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