@explorins/pers-sdk 1.2.6 → 1.3.1

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 (87) hide show
  1. package/README.md +416 -0
  2. package/dist/campaign/api/campaign-api.d.ts +19 -65
  3. package/dist/campaign/api/campaign-api.d.ts.map +1 -1
  4. package/dist/campaign.cjs +51 -105
  5. package/dist/campaign.cjs.map +1 -1
  6. package/dist/campaign.js +49 -103
  7. package/dist/campaign.js.map +1 -1
  8. package/dist/chunks/base-token-service-BA81_Ouq.js +532 -0
  9. package/dist/chunks/base-token-service-BA81_Ouq.js.map +1 -0
  10. package/dist/chunks/base-token-service-BQ6uFoki.cjs +537 -0
  11. package/dist/chunks/base-token-service-BQ6uFoki.cjs.map +1 -0
  12. package/dist/chunks/jwt.function-BYiyl-z_.cjs +25 -0
  13. package/dist/chunks/jwt.function-BYiyl-z_.cjs.map +1 -0
  14. package/dist/chunks/jwt.function-d6jPtBqI.js +23 -0
  15. package/dist/chunks/jwt.function-d6jPtBqI.js.map +1 -0
  16. package/dist/chunks/pers-sdk-JC-hSYUd.js +1377 -0
  17. package/dist/chunks/pers-sdk-JC-hSYUd.js.map +1 -0
  18. package/dist/chunks/pers-sdk-_1sTi9x9.cjs +1384 -0
  19. package/dist/chunks/pers-sdk-_1sTi9x9.cjs.map +1 -0
  20. package/dist/core/auth/api/auth-api.d.ts +4 -2
  21. package/dist/core/auth/api/auth-api.d.ts.map +1 -1
  22. package/dist/core/auth/auth-constants.d.ts +33 -0
  23. package/dist/core/auth/auth-constants.d.ts.map +1 -0
  24. package/dist/core/auth/auth-errors.d.ts +8 -0
  25. package/dist/core/auth/auth-errors.d.ts.map +1 -0
  26. package/dist/core/auth/auth-provider.interface.d.ts +49 -3
  27. package/dist/core/auth/auth-provider.interface.d.ts.map +1 -1
  28. package/dist/core/auth/create-auth-provider.d.ts.map +1 -1
  29. package/dist/core/auth/default-auth-provider.d.ts +71 -0
  30. package/dist/core/auth/default-auth-provider.d.ts.map +1 -0
  31. package/dist/core/auth/index.d.ts +1 -22
  32. package/dist/core/auth/index.d.ts.map +1 -1
  33. package/dist/core/auth/services/auth-service.d.ts.map +1 -1
  34. package/dist/core/auth/token-refresh.d.ts +91 -0
  35. package/dist/core/auth/token-refresh.d.ts.map +1 -0
  36. package/dist/core/auth/token-storage.d.ts +74 -0
  37. package/dist/core/auth/token-storage.d.ts.map +1 -0
  38. package/dist/core/errors/index.d.ts +80 -0
  39. package/dist/core/errors/index.d.ts.map +1 -0
  40. package/dist/core/index.d.ts +1 -1
  41. package/dist/core/index.d.ts.map +1 -1
  42. package/dist/core/pers-api-client.d.ts +155 -17
  43. package/dist/core/pers-api-client.d.ts.map +1 -1
  44. package/dist/core/pers-config.d.ts +36 -1
  45. package/dist/core/pers-config.d.ts.map +1 -1
  46. package/dist/core/utils/jwt.function.d.ts.map +1 -1
  47. package/dist/core.cjs +8 -814
  48. package/dist/core.cjs.map +1 -1
  49. package/dist/core.js +2 -803
  50. package/dist/core.js.map +1 -1
  51. package/dist/index.cjs +77 -4912
  52. package/dist/index.cjs.map +1 -1
  53. package/dist/index.js +19 -4857
  54. package/dist/index.js.map +1 -1
  55. package/dist/package.json +129 -129
  56. package/dist/pers-sdk.d.ts +49 -7
  57. package/dist/pers-sdk.d.ts.map +1 -1
  58. package/dist/redemption/api/redemption-api.d.ts +12 -13
  59. package/dist/redemption/api/redemption-api.d.ts.map +1 -1
  60. package/dist/redemption.cjs +24 -24
  61. package/dist/redemption.cjs.map +1 -1
  62. package/dist/redemption.js +24 -24
  63. package/dist/redemption.js.map +1 -1
  64. package/dist/shared/interfaces/pers-shared-lib.interfaces.d.ts +1 -0
  65. package/dist/shared/interfaces/pers-shared-lib.interfaces.d.ts.map +1 -1
  66. package/dist/tenant/api/tenant-api.d.ts +28 -10
  67. package/dist/tenant/api/tenant-api.d.ts.map +1 -1
  68. package/dist/tenant/index.d.ts +4 -4
  69. package/dist/tenant.cjs +40 -11
  70. package/dist/tenant.cjs.map +1 -1
  71. package/dist/tenant.js +40 -11
  72. package/dist/tenant.js.map +1 -1
  73. package/dist/token.cjs +7 -534
  74. package/dist/token.cjs.map +1 -1
  75. package/dist/token.js +1 -532
  76. package/dist/token.js.map +1 -1
  77. package/dist/web3-chain.cjs +7 -148
  78. package/dist/web3-chain.cjs.map +1 -1
  79. package/dist/web3-chain.js +6 -147
  80. package/dist/web3-chain.js.map +1 -1
  81. package/dist/web3.cjs +8 -538
  82. package/dist/web3.cjs.map +1 -1
  83. package/dist/web3.js +6 -536
  84. package/dist/web3.js.map +1 -1
  85. package/package.json +129 -129
  86. package/dist/core/auth/simple-sdk-auth-provider.d.ts +0 -27
  87. package/dist/core/auth/simple-sdk-auth-provider.d.ts.map +0 -1
package/dist/core.cjs CHANGED
@@ -1,820 +1,14 @@
1
1
  'use strict';
2
2
 
3
- var persShared = require('@explorins/pers-shared');
3
+ var persSdk = require('./chunks/pers-sdk-_1sTi9x9.cjs');
4
+ require('@explorins/pers-shared');
4
5
 
5
- /**
6
- * PERS SDK Configuration interfaces
7
- */
8
- /**
9
- * Default configuration values
10
- */
11
- const DEFAULT_PERS_CONFIG = {
12
- environment: 'production',
13
- apiVersion: 'v2',
14
- timeout: 30000,
15
- retries: 3
16
- };
17
- /**
18
- * Internal function to construct API root from environment
19
- * Now defaults to production and v2
20
- */
21
- function buildApiRoot(environment = 'production', version = 'v2') {
22
- const baseUrls = {
23
- development: 'https://explorins-loyalty.ngrok.io',
24
- staging: `https://dev.api.pers.ninja/${version}`,
25
- production: `https://api.pers.ninja/${version}`
26
- };
27
- return `${baseUrls[environment]}`;
28
- }
29
- /**
30
- * Merge user config with defaults
31
- */
32
- function mergeWithDefaults(config) {
33
- return {
34
- ...DEFAULT_PERS_CONFIG,
35
- ...config,
36
- environment: config.environment ?? DEFAULT_PERS_CONFIG.environment,
37
- apiVersion: config.apiVersion ?? DEFAULT_PERS_CONFIG.apiVersion,
38
- timeout: config.timeout ?? DEFAULT_PERS_CONFIG.timeout,
39
- retries: config.retries ?? DEFAULT_PERS_CONFIG.retries
40
- };
41
- }
42
6
 
43
- /**
44
- * Platform-Agnostic Auth Admin API Client
45
- *
46
- * Handles authentication and authorization admin operations using the PERS backend.
47
- * Uses @explorins/pers-shared DTOs for consistency with backend.
48
- *
49
- * Note: Special header handling (bypass-auth-interceptor) may need to be implemented
50
- * at the PersApiClient level or through a specialized auth client.
51
- */
52
- class AuthApi {
53
- constructor(apiClient) {
54
- this.apiClient = apiClient;
55
- this.basePath = '/auth';
56
- }
57
- // ==========================================
58
- // ADMIN AUTHENTICATION OPERATIONS
59
- // ==========================================
60
- /**
61
- * ADMIN: Login tenant admin with JWT
62
- * Note: JWT handling and auth bypass headers may need special implementation
63
- */
64
- async loginTenantAdmin(jwt) {
65
- const body = {
66
- authToken: jwt,
67
- authType: persShared.AccountOwnerType.TENANT
68
- };
69
- return this.apiClient.post(`${this.basePath}/token`, body);
70
- }
71
- async loginUser(jwt) {
72
- const body = {
73
- authToken: jwt,
74
- authType: persShared.AccountOwnerType.USER
75
- };
76
- return this.apiClient.post(`${this.basePath}/token`, body);
77
- }
78
- /**
79
- * ADMIN: Refresh access token
80
- * Note: Bypass header handling may need special implementation
81
- */
82
- async refreshAccessToken(refreshToken) {
83
- return this.apiClient.post(`${this.basePath}/refresh`, { refreshToken });
84
- }
85
- }
86
7
 
87
- /**
88
- * Platform-Agnostic Auth Admin Service
89
- *
90
- * Contains auth admin business logic and operations that work across platforms.
91
- * No framework dependencies - pure TypeScript business logic.
92
- *
93
- * Focuses only on actual backend capabilities.
94
- */
95
- class AuthService {
96
- constructor(authApi, authProvider) {
97
- this.authApi = authApi;
98
- this.authProvider = authProvider;
99
- }
100
- // ==========================================
101
- // ADMIN AUTHENTICATION OPERATIONS
102
- // ==========================================
103
- /**
104
- * ADMIN: Login tenant admin with JWT
105
- * Automatically stores tokens if auth provider supports token storage
106
- */
107
- async loginTenantAdmin(jwt) {
108
- const response = await this.authApi.loginTenantAdmin(jwt);
109
- // Store tokens if auth provider supports it
110
- if (this.authProvider && response.accessToken) {
111
- await this.storeTokens(response.accessToken, response.refreshToken);
112
- }
113
- return response;
114
- }
115
- /**
116
- * ADMIN: Login user with JWT
117
- * Automatically stores tokens if auth provider supports token storage
118
- */
119
- async loginUser(jwt) {
120
- const response = await this.authApi.loginUser(jwt);
121
- // Store tokens if auth provider supports it
122
- if (this.authProvider && response.accessToken) {
123
- await this.storeTokens(response.accessToken, response.refreshToken);
124
- }
125
- return response;
126
- }
127
- /**
128
- * ADMIN: Refresh access token
129
- * Automatically stores new tokens if auth provider supports token storage
130
- */
131
- async refreshAccessToken(refreshToken) {
132
- // Use provided refresh token or get from auth provider
133
- const tokenToUse = refreshToken || (this.authProvider?.getRefreshToken ? await this.authProvider.getRefreshToken() : null);
134
- if (!tokenToUse) {
135
- throw new Error('No refresh token available for token refresh');
136
- }
137
- const response = await this.authApi.refreshAccessToken(tokenToUse);
138
- // Store new tokens if auth provider supports it
139
- if (this.authProvider && response.accessToken) {
140
- await this.storeTokens(response.accessToken, response.refreshToken);
141
- }
142
- return response;
143
- }
144
- /**
145
- * Automatic token refresh using stored refresh token
146
- * Convenience method for 401 error handling
147
- */
148
- async autoRefreshToken() {
149
- return this.refreshAccessToken(); // Uses stored refresh token
150
- }
151
- /**
152
- * Clear stored tokens if auth provider supports it
153
- */
154
- async clearTokens() {
155
- if (this.authProvider?.clearTokens) {
156
- await this.authProvider.clearTokens();
157
- }
158
- }
159
- /**
160
- * Check if we have valid tokens for authentication
161
- */
162
- hasValidAuth() {
163
- return this.authProvider?.hasValidToken?.() ?? false;
164
- }
165
- // ==========================================
166
- // PRIVATE HELPERS
167
- // ==========================================
168
- /**
169
- * Store tokens using auth provider if it supports token storage
170
- */
171
- async storeTokens(accessToken, refreshToken) {
172
- if (!this.authProvider)
173
- return;
174
- try {
175
- // Store access token
176
- if (this.authProvider.setAccessToken) {
177
- await this.authProvider.setAccessToken(accessToken);
178
- }
179
- // Store refresh token if provided and supported
180
- if (refreshToken && this.authProvider.setRefreshToken) {
181
- await this.authProvider.setRefreshToken(refreshToken);
182
- }
183
- }
184
- catch (error) {
185
- console.error('Failed to store tokens in auth provider:', error);
186
- // Don't throw - token storage failure shouldn't break authentication
187
- }
188
- }
189
- }
190
-
191
- /**
192
- * Simple, self-contained authentication provider for SDK
193
- *
194
- * Manages tokens internally without external dependencies.
195
- * Perfect for platform-agnostic usage.
196
- */
197
- class SimpleSdkAuthProvider {
198
- constructor(projectKey) {
199
- this.accessToken = null;
200
- this.refreshToken = null;
201
- this.projectKey = null;
202
- this.authType = 'admin';
203
- this.projectKey = projectKey || null;
204
- // Try to load tokens from localStorage if available
205
- this.loadTokensFromStorage();
206
- }
207
- async getToken() {
208
- // Return stored access token
209
- return this.accessToken;
210
- }
211
- async getProjectKey() {
212
- return this.projectKey;
213
- }
214
- async onTokenExpired() {
215
- console.log('SimpleSdkAuthProvider: Token expired, attempting refresh...');
216
- if (!this.refreshToken) {
217
- console.warn('SimpleSdkAuthProvider: No refresh token available');
218
- throw new Error('No refresh token available for refresh');
219
- }
220
- // Note: Actual refresh logic would be handled by the SDK's AuthService
221
- // This provider just manages token storage
222
- console.warn('SimpleSdkAuthProvider: Token refresh should be handled by SDK AuthService');
223
- }
224
- // Token storage methods
225
- async setAccessToken(token) {
226
- this.accessToken = token;
227
- this.saveTokenToStorage('pers_access_token', token);
228
- }
229
- async setRefreshToken(token) {
230
- this.refreshToken = token;
231
- this.saveTokenToStorage('pers_refresh_token', token);
232
- }
233
- async getRefreshToken() {
234
- return this.refreshToken;
235
- }
236
- async clearTokens() {
237
- this.accessToken = null;
238
- this.refreshToken = null;
239
- // Clear from storage
240
- this.removeTokenFromStorage('pers_access_token');
241
- this.removeTokenFromStorage('pers_refresh_token');
242
- }
243
- // Internal methods for token persistence
244
- loadTokensFromStorage() {
245
- if (typeof localStorage !== 'undefined') {
246
- try {
247
- this.accessToken = localStorage.getItem('pers_access_token');
248
- this.refreshToken = localStorage.getItem('pers_refresh_token');
249
- }
250
- catch (error) {
251
- console.error('Failed to load tokens from localStorage:', error);
252
- }
253
- }
254
- else {
255
- console.warn('localStorage is not available for token persistence');
256
- }
257
- }
258
- saveTokenToStorage(key, value) {
259
- if (typeof localStorage !== 'undefined') {
260
- localStorage.setItem(key, value);
261
- }
262
- }
263
- removeTokenFromStorage(key) {
264
- if (typeof localStorage !== 'undefined') {
265
- localStorage.removeItem(key);
266
- }
267
- }
268
- // Utility methods for external integration
269
- hasValidToken() {
270
- const hasToken = !!this.accessToken;
271
- return hasToken;
272
- }
273
- hasRefreshToken() {
274
- return !!this.refreshToken;
275
- }
276
- }
277
-
278
- // packages/pers-sdk/src/core/pers-api-client.ts
279
- /**
280
- * PERS API Client - Core platform-agnostic client for PERS backend
281
- */
282
- class PersApiClient {
283
- constructor(httpClient, config) {
284
- this.httpClient = httpClient;
285
- this.config = config;
286
- // Merge user config with defaults (production + v2)
287
- this.mergedConfig = mergeWithDefaults(config);
288
- // Auto-create auth provider if none provided
289
- if (!this.mergedConfig.authProvider) {
290
- this.mergedConfig.authProvider = new SimpleSdkAuthProvider(this.mergedConfig.apiProjectKey);
291
- }
292
- // Build API root from merged environment and version
293
- this.apiRoot = buildApiRoot(this.mergedConfig.environment, this.mergedConfig.apiVersion);
294
- // Initialize auth services for direct authentication
295
- this.authApi = new AuthApi(this);
296
- this.authService = new AuthService(this.authApi, this.mergedConfig.authProvider);
297
- }
298
- /**
299
- * Get request headers including auth token and project key
300
- */
301
- async getHeaders() {
302
- const headers = {
303
- 'Content-Type': 'application/json',
304
- };
305
- // Add authentication token
306
- if (this.mergedConfig.authProvider) {
307
- const token = await this.mergedConfig.authProvider.getToken();
308
- if (token) {
309
- headers['Authorization'] = `Bearer ${token}`;
310
- }
311
- }
312
- // Add project key
313
- if (this.mergedConfig.authProvider) {
314
- const projectKey = await this.mergedConfig.authProvider.getProjectKey();
315
- if (projectKey) {
316
- headers['x-project-key'] = projectKey;
317
- }
318
- }
319
- else if (this.mergedConfig.apiProjectKey) {
320
- // Fallback to config project key if no auth provider
321
- headers['x-project-key'] = this.mergedConfig.apiProjectKey;
322
- }
323
- return headers;
324
- }
325
- /**
326
- * Make a request with proper headers, auth, and error handling
327
- */
328
- async request(method, endpoint, body, options) {
329
- const { retryCount = 0, responseType = 'json' } = options || {};
330
- const url = `${this.apiRoot}${endpoint}`;
331
- // ✅ DEBUGGING: Add extensive logging for CSV endpoint
332
- const isCSVEndpoint = endpoint.includes('/export/csv');
333
- const requestOptions = {
334
- headers: await this.getHeaders(),
335
- timeout: this.mergedConfig.timeout,
336
- responseType
337
- };
338
- try {
339
- let result;
340
- switch (method) {
341
- case 'GET':
342
- result = await this.httpClient.get(url, requestOptions);
343
- break;
344
- case 'POST':
345
- result = await this.httpClient.post(url, body, requestOptions);
346
- break;
347
- case 'PUT':
348
- result = await this.httpClient.put(url, body, requestOptions);
349
- break;
350
- case 'DELETE':
351
- result = await this.httpClient.delete(url, requestOptions);
352
- break;
353
- default:
354
- throw new Error(`Unsupported HTTP method: ${method}`);
355
- }
356
- return result;
357
- }
358
- catch (error) {
359
- if (isCSVEndpoint) {
360
- console.error('❌ [PERS API CLIENT] CSV Request failed:', error);
361
- }
362
- // Handle 401 errors with automatic token refresh
363
- const apiError = error;
364
- if (apiError.status === 401 && retryCount === 0 && this.mergedConfig.authProvider?.onTokenExpired) {
365
- try {
366
- await this.mergedConfig.authProvider.onTokenExpired();
367
- // Retry once with refreshed token
368
- return this.request(method, endpoint, body, { ...options, retryCount: 1 });
369
- }
370
- catch (refreshError) {
371
- throw new PersApiError(`Authentication refresh failed: ${refreshError}`, endpoint, method, 401);
372
- }
373
- }
374
- throw new PersApiError(`PERS API request failed: ${apiError.message || error}`, endpoint, method, apiError.status);
375
- }
376
- }
377
- /**
378
- * Generic GET request
379
- */
380
- async get(endpoint, responseType) {
381
- return this.request('GET', endpoint, undefined, { responseType });
382
- }
383
- /**
384
- * Generic POST request
385
- */
386
- async post(endpoint, body) {
387
- return this.request('POST', endpoint, body);
388
- }
389
- /**
390
- * Generic PUT request
391
- */
392
- async put(endpoint, body) {
393
- return this.request('PUT', endpoint, body);
394
- }
395
- /**
396
- * Generic DELETE request
397
- */
398
- async delete(endpoint) {
399
- return this.request('DELETE', endpoint);
400
- }
401
- // ==========================================
402
- // AUTHENTICATION METHODS
403
- // ==========================================
404
- /**
405
- * Login admin user with external JWT (e.g., Firebase)
406
- * Automatically stores tokens in auth provider if available
407
- */
408
- async loginAdmin(externalJwt) {
409
- return this.authService.loginTenantAdmin(externalJwt);
410
- }
411
- /**
412
- * Login regular user with external JWT
413
- * Automatically stores tokens in auth provider if available
414
- */
415
- async loginUser(externalJwt) {
416
- return this.authService.loginUser(externalJwt);
417
- }
418
- /**
419
- * Refresh access token using stored refresh token
420
- */
421
- async refreshToken() {
422
- const refreshToken = await this.mergedConfig.authProvider?.getRefreshToken?.();
423
- if (!refreshToken) {
424
- throw new Error('No refresh token available');
425
- }
426
- return this.authService.refreshAccessToken(refreshToken);
427
- }
428
- /**
429
- * Clear all stored authentication tokens
430
- */
431
- async clearAuth() {
432
- return this.authService.clearTokens();
433
- }
434
- /**
435
- * Check if user has valid authentication token
436
- */
437
- hasValidAuth() {
438
- return this.mergedConfig.authProvider?.hasValidToken?.() || false;
439
- }
440
- /**
441
- * Get current configuration (returns merged config)
442
- */
443
- getConfig() {
444
- return this.mergedConfig;
445
- }
446
- /**
447
- * Get original user configuration
448
- */
449
- getOriginalConfig() {
450
- return this.config;
451
- }
452
- }
453
- class PersApiError extends Error {
454
- constructor(message, endpoint, method, statusCode) {
455
- super(message);
456
- this.endpoint = endpoint;
457
- this.method = method;
458
- this.statusCode = statusCode;
459
- this.name = 'PersApiError';
460
- }
461
- }
462
-
463
- /**
464
- * Memory-based token storage (default)
465
- */
466
- class MemoryTokenStorage {
467
- constructor() {
468
- this.storage = new Map();
469
- }
470
- async setItem(key, value) {
471
- this.storage.set(key, value);
472
- }
473
- async getItem(key) {
474
- return this.storage.get(key) || null;
475
- }
476
- async removeItem(key) {
477
- this.storage.delete(key);
478
- }
479
- }
480
- /**
481
- * localStorage-based token storage (browser only)
482
- */
483
- class LocalStorageTokenStorage {
484
- async setItem(key, value) {
485
- if (typeof localStorage !== 'undefined') {
486
- localStorage.setItem(key, value);
487
- }
488
- else {
489
- throw new Error('localStorage is not available in this environment');
490
- }
491
- }
492
- async getItem(key) {
493
- if (typeof localStorage !== 'undefined') {
494
- return localStorage.getItem(key);
495
- }
496
- return null;
497
- }
498
- async removeItem(key) {
499
- if (typeof localStorage !== 'undefined') {
500
- localStorage.removeItem(key);
501
- }
502
- }
503
- }
504
- /**
505
- * Creates a platform-agnostic AuthProvider from simple configuration
506
- *
507
- * This factory function is completely platform-agnostic and can be used
508
- * across Angular, React, Vue, Node.js, or any other JavaScript environment.
509
- *
510
- * Features:
511
- * - Token caching with refresh support
512
- * - Automatic token refresh on expiration
513
- * - Configurable token providers
514
- * - Token storage (memory, localStorage, custom)
515
- * - Platform-independent
516
- *
517
- * @param config - Simple auth configuration
518
- * @returns AuthProvider implementation
519
- */
520
- function createAuthProvider(config) {
521
- // Initialize token storage
522
- let tokenStorage;
523
- switch (config.tokenStorage) {
524
- case 'localStorage':
525
- tokenStorage = new LocalStorageTokenStorage();
526
- break;
527
- case 'custom':
528
- if (!config.customTokenStorage) {
529
- throw new Error('Custom token storage configuration is required when tokenStorage is "custom"');
530
- }
531
- tokenStorage = config.customTokenStorage;
532
- break;
533
- case 'memory':
534
- default:
535
- tokenStorage = new MemoryTokenStorage();
536
- break;
537
- }
538
- // Token storage keys
539
- const ACCESS_TOKEN_KEY = `pers_access_token_${config.authType || 'user'}`;
540
- const REFRESH_TOKEN_KEY = `pers_refresh_token_${config.authType || 'user'}`;
541
- // Store current token for refresh scenarios and caching
542
- let currentToken = config.token || null;
543
- let isRefreshing = false; // Prevent concurrent refresh attempts
544
- let refreshPromise = null;
545
- return {
546
- authType: config.authType || 'user',
547
- async getToken() {
548
- // If currently refreshing, wait for it to complete
549
- if (isRefreshing && refreshPromise) {
550
- await refreshPromise;
551
- return currentToken;
552
- }
553
- // Use cached current token (updated after refresh)
554
- if (currentToken) {
555
- return currentToken;
556
- }
557
- // Try to get token from storage
558
- try {
559
- const storedToken = await tokenStorage.getItem(ACCESS_TOKEN_KEY);
560
- if (storedToken) {
561
- currentToken = storedToken;
562
- return storedToken;
563
- }
564
- }
565
- catch (error) {
566
- console.warn('Failed to retrieve token from storage:', error);
567
- }
568
- // Custom token provider function (always fresh)
569
- if (config.tokenProvider) {
570
- const token = await config.tokenProvider();
571
- currentToken = token; // Cache for future calls
572
- return token;
573
- }
574
- // No token available
575
- return null;
576
- },
577
- async getProjectKey() {
578
- return config.projectKey || null;
579
- },
580
- // Token storage methods
581
- async setAccessToken(token) {
582
- currentToken = token;
583
- try {
584
- await tokenStorage.setItem(ACCESS_TOKEN_KEY, token);
585
- }
586
- catch (error) {
587
- console.error('Failed to store access token:', error);
588
- throw error;
589
- }
590
- },
591
- async setRefreshToken(token) {
592
- try {
593
- await tokenStorage.setItem(REFRESH_TOKEN_KEY, token);
594
- }
595
- catch (error) {
596
- console.error('Failed to store refresh token:', error);
597
- throw error;
598
- }
599
- },
600
- async getRefreshToken() {
601
- try {
602
- return await tokenStorage.getItem(REFRESH_TOKEN_KEY);
603
- }
604
- catch (error) {
605
- console.warn('Failed to retrieve refresh token from storage:', error);
606
- return null;
607
- }
608
- },
609
- async clearTokens() {
610
- currentToken = null;
611
- try {
612
- await Promise.all([
613
- tokenStorage.removeItem(ACCESS_TOKEN_KEY),
614
- tokenStorage.removeItem(REFRESH_TOKEN_KEY)
615
- ]);
616
- }
617
- catch (error) {
618
- console.error('Failed to clear tokens from storage:', error);
619
- throw error;
620
- }
621
- },
622
- async onTokenExpired() {
623
- // Prevent concurrent refresh attempts
624
- if (isRefreshing) {
625
- if (refreshPromise) {
626
- await refreshPromise;
627
- }
628
- return;
629
- }
630
- // No refresh logic provided
631
- if (!config.onTokenExpired) {
632
- console.warn('Token expired but no refresh logic provided');
633
- currentToken = null;
634
- try {
635
- await tokenStorage.removeItem(ACCESS_TOKEN_KEY);
636
- }
637
- catch (error) {
638
- console.warn('Failed to clear expired token from storage:', error);
639
- }
640
- return;
641
- }
642
- // Start refresh process
643
- isRefreshing = true;
644
- refreshPromise = (async () => {
645
- try {
646
- // Execute refresh logic (should update token source)
647
- await config.onTokenExpired();
648
- // After refresh, get the new token
649
- if (config.tokenProvider) {
650
- const newToken = await config.tokenProvider();
651
- if (newToken && newToken !== currentToken) {
652
- currentToken = newToken;
653
- // Store the new token
654
- try {
655
- await tokenStorage.setItem(ACCESS_TOKEN_KEY, newToken);
656
- }
657
- catch (error) {
658
- console.warn('Failed to store refreshed token:', error);
659
- }
660
- // Notify about successful token refresh
661
- if (config.onTokenRefreshed) {
662
- config.onTokenRefreshed(newToken);
663
- }
664
- }
665
- else {
666
- console.warn('Token refresh completed but no new token received');
667
- currentToken = null;
668
- try {
669
- await tokenStorage.removeItem(ACCESS_TOKEN_KEY);
670
- }
671
- catch (error) {
672
- console.warn('Failed to clear token after failed refresh:', error);
673
- }
674
- }
675
- }
676
- else {
677
- // For static token configs, clear the token since we can't refresh
678
- console.warn('Token expired for static token config - clearing token');
679
- currentToken = null;
680
- try {
681
- await tokenStorage.removeItem(ACCESS_TOKEN_KEY);
682
- }
683
- catch (error) {
684
- console.warn('Failed to clear expired static token:', error);
685
- }
686
- }
687
- }
688
- catch (error) {
689
- console.error('Token refresh failed:', error);
690
- currentToken = null; // Clear token on refresh failure
691
- try {
692
- await tokenStorage.removeItem(ACCESS_TOKEN_KEY);
693
- }
694
- catch (storageError) {
695
- console.warn('Failed to clear token after refresh failure:', storageError);
696
- }
697
- throw error; // Re-throw to let SDK handle the error
698
- }
699
- finally {
700
- isRefreshing = false;
701
- refreshPromise = null;
702
- }
703
- })();
704
- await refreshPromise;
705
- }
706
- };
707
- }
708
- /**
709
- * Platform-specific localStorage token provider for browsers
710
- * This is a convenience function for browser environments
711
- */
712
- /* export function createBrowserTokenProvider(tokenKey: string = 'userJwt'): () => Promise<string | null> {
713
- return async () => {
714
- if (typeof localStorage !== 'undefined') {
715
- return localStorage.getItem(tokenKey);
716
- }
717
- return null;
718
- };
719
- } */
720
- /**
721
- * Platform-specific environment variable token provider for Node.js
722
- * This is a convenience function for Node.js environments
723
- */
724
- /* export function createNodeTokenProvider(envVar: string = 'JWT_TOKEN'): () => Promise<string | null> {
725
- return async () => {
726
- if (typeof process !== 'undefined' && process.env) {
727
- return process.env[envVar] || null;
728
- }
729
- return null;
730
- };
731
- } */
732
-
733
- /**
734
- * @explorins/pers-sdk/core/auth - Consolidated Auth Module
735
- *
736
- * All authentication functionality in one place:
737
- * - Auth provider interfaces and implementations
738
- * - Auth API and service logic
739
- * - Token management
740
- */
741
- // Auth provider interfaces and implementations
742
- /**
743
- * Create a complete Auth SDK instance (for backward compatibility)
744
- * Note: This is now handled directly by PersApiClient
745
- *
746
- * @param apiClient - Configured PERS API client
747
- * @param authProvider - Optional auth provider. If not provided, uses SimpleSdkAuthProvider
748
- * @returns Auth SDK with flattened structure for better DX
749
- */
750
- function createAuthSDK(apiClient, authProvider) {
751
- // Use simple internal auth provider if none provided
752
- const provider = authProvider || new SimpleSdkAuthProvider();
753
- const authApi = new AuthApi(apiClient);
754
- const authService = new AuthService(authApi, provider);
755
- return {
756
- // Direct access to service methods (primary interface)
757
- // Admin authentication methods
758
- loginTenantAdmin: (jwt) => authService.loginTenantAdmin(jwt),
759
- loginUser: (jwt) => authService.loginUser(jwt),
760
- refreshAccessToken: (refreshToken) => authService.refreshAccessToken(refreshToken),
761
- clearTokens: () => authService.clearTokens(),
762
- // Auth provider access for external integration
763
- getAuthProvider: () => provider,
764
- hasValidToken: () => provider.hasValidToken?.() || false,
765
- // Advanced access for edge cases
766
- api: authApi,
767
- service: authService
768
- };
769
- }
770
-
771
- /**
772
- * PERS SDK - Minimal platform-agnostic client with built-in authentication
773
- * Authentication is now handled at the SDK core level for better scalability
774
- */
775
- /**
776
- * Minimal PERS SDK - API client with authentication built-in
777
- * Platform adapters provide auth providers and HTTP clients
778
- */
779
- class PersSDK {
780
- constructor(httpClient, config) {
781
- this.apiClient = new PersApiClient(httpClient, config);
782
- }
783
- /**
784
- * Get the API client for direct PERS API calls
785
- * This is the main interface - keep it simple!
786
- */
787
- api() {
788
- return this.apiClient;
789
- }
790
- /**
791
- * Quick config check
792
- */
793
- isProduction() {
794
- return this.apiClient.getConfig().environment === 'production';
795
- }
796
- }
797
- /**
798
- * Simple factory function
799
- */
800
- function createPersSDK(httpClient, config) {
801
- return new PersSDK(httpClient, config);
802
- }
803
-
804
- Object.defineProperty(exports, "AccountOwnerType", {
805
- enumerable: true,
806
- get: function () { return persShared.AccountOwnerType; }
807
- });
808
- exports.AuthApi = AuthApi;
809
- exports.AuthService = AuthService;
810
- exports.DEFAULT_PERS_CONFIG = DEFAULT_PERS_CONFIG;
811
- exports.PersApiClient = PersApiClient;
812
- exports.PersApiError = PersApiError;
813
- exports.PersSDK = PersSDK;
814
- exports.SimpleSdkAuthProvider = SimpleSdkAuthProvider;
815
- exports.buildApiRoot = buildApiRoot;
816
- exports.createAuthProvider = createAuthProvider;
817
- exports.createAuthSDK = createAuthSDK;
818
- exports.createPersSDK = createPersSDK;
819
- exports.mergeWithDefaults = mergeWithDefaults;
8
+ exports.DEFAULT_PERS_CONFIG = persSdk.DEFAULT_PERS_CONFIG;
9
+ exports.PersApiClient = persSdk.PersApiClient;
10
+ exports.PersSDK = persSdk.PersSDK;
11
+ exports.buildApiRoot = persSdk.buildApiRoot;
12
+ exports.createPersSDK = persSdk.createPersSDK;
13
+ exports.mergeWithDefaults = persSdk.mergeWithDefaults;
820
14
  //# sourceMappingURL=core.cjs.map