@nauth-toolkit/client 0.1.14 → 0.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,6 +1,19 @@
1
+ /**
2
+ * MFA device method type (methods that require device setup).
3
+ * Excludes 'backup' as it's not a device method.
4
+ */
1
5
  type MFADeviceMethod = 'sms' | 'email' | 'totp' | 'passkey';
6
+ /**
7
+ * All MFA methods including backup codes (for verification).
8
+ */
2
9
  type MFAMethod = MFADeviceMethod | 'backup';
10
+ /**
11
+ * MFA challenge method subset (for challenge-data retrieval).
12
+ */
3
13
  type MFAChallengeMethod = 'passkey' | 'sms' | 'email' | 'totp' | 'backup';
14
+ /**
15
+ * MFA status for authenticated user.
16
+ */
4
17
  interface MFAStatus {
5
18
  enabled: boolean;
6
19
  required: boolean;
@@ -12,6 +25,9 @@ interface MFAStatus {
12
25
  mfaExemptReason: string | null;
13
26
  mfaExemptGrantedAt: string | Date | null;
14
27
  }
28
+ /**
29
+ * MFA device information.
30
+ */
15
31
  interface MFADevice {
16
32
  id: number;
17
33
  type: MFADeviceMethod;
@@ -20,6 +36,9 @@ interface MFADevice {
20
36
  isActive: boolean;
21
37
  createdAt: string | Date;
22
38
  }
39
+ /**
40
+ * MFA setup data returned by providers.
41
+ */
23
42
  interface MFASetupData {
24
43
  secret?: string;
25
44
  qrCode?: string;
@@ -28,16 +47,30 @@ interface MFASetupData {
28
47
  challenge?: Record<string, unknown>;
29
48
  [key: string]: unknown;
30
49
  }
50
+ /**
51
+ * Response from getSetupData API call.
52
+ * Contains provider-specific MFA setup information.
53
+ */
31
54
  interface GetSetupDataResponse {
32
55
  setupData: Record<string, unknown>;
33
56
  }
57
+ /**
58
+ * Response from getChallengeData API call.
59
+ * Contains challenge-specific data (e.g., passkey options).
60
+ */
34
61
  interface GetChallengeDataResponse {
35
62
  challengeData: Record<string, unknown>;
36
63
  }
64
+ /**
65
+ * Backup codes response.
66
+ */
37
67
  interface BackupCodesResponse {
38
68
  codes: string[];
39
69
  }
40
70
 
71
+ /**
72
+ * Authentication challenge types returned by the backend.
73
+ */
41
74
  declare enum AuthChallenge {
42
75
  VERIFY_EMAIL = "VERIFY_EMAIL",
43
76
  VERIFY_PHONE = "VERIFY_PHONE",
@@ -59,6 +92,9 @@ interface AuthResponse {
59
92
  challengeParameters?: Record<string, unknown>;
60
93
  userSub?: string;
61
94
  }
95
+ /**
96
+ * Minimal user information returned inside auth responses.
97
+ */
62
98
  interface AuthUserSummary {
63
99
  sub: string;
64
100
  email: string;
@@ -70,12 +106,18 @@ interface AuthUserSummary {
70
106
  socialProviders?: string[] | null;
71
107
  hasPasswordHash?: boolean;
72
108
  }
109
+ /**
110
+ * Token response returned by refresh endpoint.
111
+ */
73
112
  interface TokenResponse {
74
113
  accessToken: string;
75
114
  refreshToken: string;
76
115
  accessTokenExpiresAt: number;
77
116
  refreshTokenExpiresAt: number;
78
117
  }
118
+ /**
119
+ * Signup request payload.
120
+ */
79
121
  interface SignupRequest {
80
122
  email: string;
81
123
  password: string;
@@ -84,30 +126,58 @@ interface SignupRequest {
84
126
  phone?: string;
85
127
  metadata?: Record<string, unknown>;
86
128
  }
129
+ /**
130
+ * Login request payload.
131
+ */
87
132
  interface LoginRequest {
88
133
  identifier: string;
89
134
  password: string;
90
135
  }
136
+ /**
137
+ * Logout request payload.
138
+ */
91
139
  interface LogoutRequest {
92
140
  sub?: string;
93
141
  forgetMe?: boolean;
94
142
  }
143
+ /**
144
+ * Logout all sessions request payload.
145
+ */
95
146
  interface LogoutAllRequest {
147
+ /**
148
+ * Whether to also revoke all trusted devices
149
+ * Default: false (devices remain trusted)
150
+ */
96
151
  forgetDevices?: boolean;
97
152
  sub?: string;
98
153
  }
154
+ /**
155
+ * Resend code request payload.
156
+ */
99
157
  interface ResendCodeRequest {
100
158
  session: string;
101
159
  }
160
+ /**
161
+ * MFA setup data request payload during challenge flows.
162
+ */
102
163
  interface GetSetupDataRequest {
103
164
  session: string;
104
165
  method: MFAMethod;
105
166
  }
167
+ /**
168
+ * Challenge data request payload (e.g., passkey options).
169
+ */
106
170
  interface GetChallengeDataRequest {
107
171
  session: string;
108
172
  method: MFAChallengeMethod;
109
173
  }
174
+ /**
175
+ * Unified challenge response discriminated union.
176
+ */
110
177
  type ChallengeResponse = VerifyEmailResponse | VerifyPhoneCollectResponse | VerifyPhoneCodeResponse | MFACodeResponse | MFAPasskeyResponse | MFASetupResponse | ForceChangePasswordResponse;
178
+ /**
179
+ * Base challenge response shape.
180
+ */
111
181
  interface BaseChallengeResponse {
112
182
  session: string;
113
183
  }
@@ -143,6 +213,9 @@ interface ForceChangePasswordResponse extends BaseChallengeResponse {
143
213
  newPassword: string;
144
214
  }
145
215
 
216
+ /**
217
+ * Full user profile returned from profile endpoints.
218
+ */
146
219
  interface AuthUser {
147
220
  sub: string;
148
221
  email: string;
@@ -159,51 +232,87 @@ interface AuthUser {
159
232
  createdAt?: string | Date;
160
233
  updatedAt?: string | Date;
161
234
  }
235
+ /**
236
+ * Profile update request.
237
+ */
162
238
  interface UpdateProfileRequest {
163
239
  firstName?: string;
164
240
  lastName?: string;
165
241
  email?: string;
166
242
  phone?: string;
167
243
  }
244
+ /**
245
+ * Change password request.
246
+ */
168
247
  interface ChangePasswordRequest {
169
248
  currentPassword: string;
170
249
  newPassword: string;
171
250
  }
251
+ /**
252
+ * Forgot password request payload.
253
+ */
172
254
  interface ForgotPasswordRequest {
173
255
  identifier: string;
174
256
  }
257
+ /**
258
+ * Forgot password response payload.
259
+ */
175
260
  interface ForgotPasswordResponse {
176
261
  success: boolean;
177
262
  destination?: string;
178
263
  deliveryMedium?: 'email' | 'sms';
179
264
  expiresIn?: number;
180
265
  }
266
+ /**
267
+ * Confirm forgot password request payload.
268
+ */
181
269
  interface ConfirmForgotPasswordRequest {
182
270
  identifier: string;
183
271
  code: string;
184
272
  newPassword: string;
185
273
  }
274
+ /**
275
+ * Confirm forgot password response payload.
276
+ */
186
277
  interface ConfirmForgotPasswordResponse {
187
278
  success: boolean;
188
279
  mustChangePassword: boolean;
189
280
  }
190
281
 
282
+ /**
283
+ * Social provider identifiers.
284
+ */
191
285
  type SocialProvider = 'google' | 'apple' | 'facebook';
286
+ /**
287
+ * Request to obtain social auth URL.
288
+ */
192
289
  interface SocialAuthUrlRequest {
193
290
  provider: SocialProvider;
194
291
  state?: string;
195
292
  }
293
+ /**
294
+ * Response containing social auth URL.
295
+ */
196
296
  interface SocialAuthUrlResponse {
197
297
  url: string;
198
298
  }
299
+ /**
300
+ * Social callback parameters.
301
+ */
199
302
  interface SocialCallbackRequest {
200
303
  provider: SocialProvider;
201
304
  code: string;
202
305
  state: string;
203
306
  }
307
+ /**
308
+ * Linked social accounts response.
309
+ */
204
310
  interface LinkedAccountsResponse {
205
311
  providers: SocialProvider[];
206
312
  }
313
+ /**
314
+ * Native social verification request (mobile).
315
+ */
207
316
  interface SocialVerifyRequest {
208
317
  provider: SocialProvider;
209
318
  idToken?: string;
@@ -211,6 +320,9 @@ interface SocialVerifyRequest {
211
320
  authorizationCode?: string;
212
321
  }
213
322
 
323
+ /**
324
+ * Standardized error codes mirroring backend AuthErrorCode.
325
+ */
214
326
  declare enum NAuthErrorCode {
215
327
  AUTH_INVALID_CREDENTIALS = "AUTH_INVALID_CREDENTIALS",
216
328
  AUTH_ACCOUNT_LOCKED = "AUTH_ACCOUNT_LOCKED",
@@ -268,6 +380,9 @@ declare enum NAuthErrorCode {
268
380
  INTERNAL_ERROR = "INTERNAL_ERROR",
269
381
  SERVICE_UNAVAILABLE = "SERVICE_UNAVAILABLE"
270
382
  }
383
+ /**
384
+ * Structured client error.
385
+ */
271
386
  interface NAuthError {
272
387
  code: NAuthErrorCode;
273
388
  message: string;
@@ -276,30 +391,121 @@ interface NAuthError {
276
391
  statusCode?: number;
277
392
  }
278
393
 
394
+ /**
395
+ * Storage adapter interface used by the client SDK.
396
+ */
279
397
  interface NAuthStorageAdapter {
398
+ /**
399
+ * Retrieve a value by key.
400
+ */
280
401
  getItem(key: string): Promise<string | null>;
402
+ /**
403
+ * Persist a value.
404
+ */
281
405
  setItem(key: string, value: string): Promise<void>;
406
+ /**
407
+ * Remove a stored value.
408
+ */
282
409
  removeItem(key: string): Promise<void>;
283
410
  }
284
411
 
412
+ /**
413
+ * HTTP request configuration.
414
+ *
415
+ * Platform-agnostic request format that can be implemented by any HTTP client.
416
+ */
285
417
  interface HttpRequest {
418
+ /**
419
+ * HTTP method
420
+ */
286
421
  method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
422
+ /**
423
+ * Full URL (already resolved with baseUrl)
424
+ */
287
425
  url: string;
426
+ /**
427
+ * Request headers
428
+ */
288
429
  headers?: Record<string, string>;
430
+ /**
431
+ * Request body (will be JSON stringified by adapter)
432
+ */
289
433
  body?: unknown;
434
+ /**
435
+ * Credentials mode for cookies
436
+ * - 'include': Send cookies (for cookies mode)
437
+ * - 'omit': Don't send cookies (for JSON mode)
438
+ */
290
439
  credentials?: 'include' | 'omit' | 'same-origin';
440
+ /**
441
+ * Abort signal for request cancellation
442
+ */
291
443
  signal?: AbortSignal;
292
444
  }
445
+ /**
446
+ * HTTP response returned by adapter.
447
+ */
293
448
  interface HttpResponse<T> {
449
+ /**
450
+ * Response data (already parsed)
451
+ */
294
452
  data: T;
453
+ /**
454
+ * HTTP status code
455
+ */
295
456
  status: number;
457
+ /**
458
+ * Response headers
459
+ */
296
460
  headers: Record<string, string>;
297
461
  }
462
+ /**
463
+ * Platform-agnostic HTTP adapter interface.
464
+ *
465
+ * Implementations:
466
+ * - FetchAdapter: For vanilla JS, Node.js (uses native fetch)
467
+ * - AngularHttpAdapter: For Angular (uses HttpClient)
468
+ * - AxiosAdapter: For React/Vue (uses Axios)
469
+ *
470
+ * @example
471
+ * ```typescript
472
+ * class MyAdapter implements HttpAdapter {
473
+ * async request<T>(config: HttpRequest): Promise<HttpResponse<T>> {
474
+ * // Use any HTTP client
475
+ * const response = await myHttpClient.request(config);
476
+ * return { data: response.data, status: response.status, headers: {} };
477
+ * }
478
+ * }
479
+ * ```
480
+ */
298
481
  interface HttpAdapter {
482
+ /**
483
+ * Execute an HTTP request.
484
+ *
485
+ * @param config - Request configuration
486
+ * @returns Response with data, status, and headers
487
+ * @throws Error if request fails (adapter should throw descriptive errors)
488
+ */
299
489
  request<T>(config: HttpRequest): Promise<HttpResponse<T>>;
300
490
  }
301
491
 
492
+ /**
493
+ * Token delivery mode for the frontend SDK.
494
+ *
495
+ * - `'cookies'` - For web applications. Tokens sent as httpOnly cookies by backend.
496
+ * Uses `withCredentials`, CSRF tokens, no Authorization header.
497
+ *
498
+ * - `'json'` - For mobile/native apps (Capacitor, React Native). Tokens returned
499
+ * in response body, stored locally, sent via Authorization header.
500
+ *
501
+ * Note: "Hybrid" is a backend deployment pattern (supporting both web and mobile
502
+ * via separate endpoints), not a frontend mode. The frontend chooses ONE mode
503
+ * based on whether it's a web or mobile build.
504
+ */
302
505
  type TokenDeliveryMode = 'json' | 'cookies';
506
+ /**
507
+ * Endpoint paths for the client SDK.
508
+ */
303
509
  interface NAuthEndpoints {
304
510
  login: string;
305
511
  signup: string;
@@ -334,35 +540,116 @@ interface NAuthEndpoints {
334
540
  auditHistory: string;
335
541
  updateProfile: string;
336
542
  }
543
+ /**
544
+ * Client configuration.
545
+ */
337
546
  interface NAuthClientConfig {
547
+ /**
548
+ * Base URL for authentication API.
549
+ *
550
+ * For web apps using cookies: `'https://api.example.com/auth'`
551
+ * For mobile apps using JSON: `'https://api.example.com/mobile/auth'`
552
+ *
553
+ * When backend uses hybrid deployment, mobile apps should use a different
554
+ * base URL that points to the JSON-based mobile auth endpoints.
555
+ */
338
556
  baseUrl: string;
557
+ /**
558
+ * How tokens are delivered between client and server.
559
+ *
560
+ * - `'cookies'` - For web apps. Backend sets httpOnly cookies.
561
+ * - `'json'` - For mobile apps. Tokens in response body, stored locally.
562
+ */
339
563
  tokenDelivery: TokenDeliveryMode;
564
+ /** Custom storage adapter. Defaults to localStorage (web) or memory (SSR). */
340
565
  storage?: NAuthStorageAdapter;
566
+ /**
567
+ * CSRF configuration (required for cookies mode).
568
+ * Default cookie name: 'csrf_token', header name: 'x-csrf-token'
569
+ */
341
570
  csrf?: {
342
571
  cookieName?: string;
343
572
  headerName?: string;
344
573
  };
574
+ /** Custom endpoint paths (merged with defaults). */
345
575
  endpoints?: Partial<NAuthEndpoints>;
576
+ /** Device trust configuration for "remember this device" feature. */
346
577
  deviceTrust?: {
347
578
  headerName?: string;
348
579
  storageKey?: string;
349
580
  };
581
+ /** Additional headers to include in all requests. */
350
582
  headers?: Record<string, string>;
583
+ /** Request timeout in milliseconds. Default: 30000 */
351
584
  timeout?: number;
585
+ /**
586
+ * Redirect URLs for various authentication scenarios.
587
+ * Used by guards and interceptors to handle routing in a platform-agnostic way.
588
+ */
352
589
  redirects?: {
590
+ /**
591
+ * URL to redirect to after successful authentication (login, signup, or OAuth).
592
+ * @default '/'
593
+ */
353
594
  success?: string;
595
+ /**
596
+ * URL to redirect to when session expires (refresh fails with 401).
597
+ * @default '/login'
598
+ */
354
599
  sessionExpired?: string;
600
+ /**
601
+ * URL to redirect to when OAuth authentication fails.
602
+ * @default '/login'
603
+ */
355
604
  oauthError?: string;
605
+ /**
606
+ * Base URL for challenge routes (email verification, MFA, etc.).
607
+ * The challenge type will be appended (e.g., '/auth/challenge/verify-email').
608
+ * @default '/auth/challenge'
609
+ */
356
610
  challengeBase?: string;
357
611
  };
612
+ /**
613
+ * Called when session expires (refresh fails with 401).
614
+ */
358
615
  onSessionExpired?: () => void;
616
+ /** Called after successful token refresh. */
359
617
  onTokenRefresh?: () => void;
618
+ /** Called when authentication state changes (login/logout). */
360
619
  onAuthStateChange?: (user: AuthUser | null) => void;
620
+ /** Called on authentication errors. */
361
621
  onError?: (error: NAuthError) => void;
622
+ /** Enable debug logging. */
362
623
  debug?: boolean;
624
+ /**
625
+ * HTTP adapter for making requests.
626
+ *
627
+ * - **Auto-provided in Angular**: Uses HttpClient (works with interceptors)
628
+ * - **Manual setup in React/Vue**: Provide AxiosAdapter or custom adapter
629
+ * - **Defaults to FetchAdapter**: If not provided, uses native fetch
630
+ *
631
+ * @example
632
+ * ```typescript
633
+ * // Angular (automatic)
634
+ * // AuthService auto-injects AngularHttpAdapter
635
+ *
636
+ * // React with Axios
637
+ * const client = new NAuthClient({
638
+ * httpAdapter: new AxiosAdapter(axiosInstance),
639
+ * });
640
+ *
641
+ * // Vanilla JS (auto-defaults to fetch)
642
+ * const client = new NAuthClient({
643
+ * // httpAdapter auto-defaults to FetchAdapter
644
+ * });
645
+ * ```
646
+ */
363
647
  httpAdapter?: HttpAdapter;
364
648
  }
365
649
 
650
+ /**
651
+ * Audit event types.
652
+ */
366
653
  declare enum AuthAuditEventType {
367
654
  LOGIN_SUCCESS = "LOGIN_SUCCESS",
368
655
  LOGIN_FAILED = "LOGIN_FAILED",
@@ -390,7 +677,13 @@ declare enum AuthAuditEventType {
390
677
  SOCIAL_LINK_FAILED = "SOCIAL_LINK_FAILED",
391
678
  SOCIAL_UNLINK = "SOCIAL_UNLINK"
392
679
  }
680
+ /**
681
+ * Audit event status.
682
+ */
393
683
  type AuthAuditEventStatus = 'SUCCESS' | 'FAILURE' | 'INFO' | 'SUSPICIOUS';
684
+ /**
685
+ * Individual audit event record.
686
+ */
394
687
  interface AuthAuditEvent {
395
688
  id: number;
396
689
  userId: number;
@@ -419,6 +712,9 @@ interface AuthAuditEvent {
419
712
  metadata?: Record<string, unknown> | null;
420
713
  createdAt: string | Date;
421
714
  }
715
+ /**
716
+ * Paginated audit history response.
717
+ */
422
718
  interface AuditHistoryResponse {
423
719
  data: AuthAuditEvent[];
424
720
  total: number;
@@ -427,21 +723,94 @@ interface AuditHistoryResponse {
427
723
  totalPages: number;
428
724
  }
429
725
 
726
+ /**
727
+ * Client-side error wrapper for SDK operations.
728
+ *
729
+ * Mirrors the backend NAuthException structure for consistent error handling.
730
+ *
731
+ * @example
732
+ * ```typescript
733
+ * try {
734
+ * await client.login({ identifier: 'user@example.com', password: 'wrong' });
735
+ * } catch (error) {
736
+ * if (error instanceof NAuthClientError) {
737
+ * console.log(error.code); // 'AUTH_INVALID_CREDENTIALS'
738
+ * console.log(error.message); // 'Invalid credentials'
739
+ * console.log(error.timestamp); // '2025-12-06T...'
740
+ *
741
+ * // Check specific error code
742
+ * if (error.isCode(NAuthErrorCode.RATE_LIMIT_LOGIN)) {
743
+ * const retryAfter = error.details?.retryAfter as number;
744
+ * console.log(`Rate limited. Retry in ${retryAfter}s`);
745
+ * }
746
+ * }
747
+ * }
748
+ * ```
749
+ */
430
750
  declare class NAuthClientError extends Error implements NAuthError {
431
751
  readonly code: NAuthErrorCode;
432
752
  readonly details?: Record<string, unknown>;
433
753
  readonly statusCode?: number;
434
754
  readonly timestamp: string;
435
755
  readonly isNetworkError: boolean;
756
+ /**
757
+ * Create a new client error.
758
+ *
759
+ * @param code - Error code from NAuthErrorCode enum
760
+ * @param message - Human-readable error message
761
+ * @param options - Optional metadata including details, statusCode, timestamp, and network error flag
762
+ */
436
763
  constructor(code: NAuthErrorCode, message: string, options?: {
437
764
  details?: Record<string, unknown>;
438
765
  statusCode?: number;
439
766
  timestamp?: string;
440
767
  isNetworkError?: boolean;
441
768
  });
769
+ /**
770
+ * Check if error matches a specific error code.
771
+ *
772
+ * @param code - Error code to check against
773
+ * @returns True if the error code matches
774
+ *
775
+ * @example
776
+ * ```typescript
777
+ * if (error.isCode(NAuthErrorCode.RATE_LIMIT_SMS)) {
778
+ * // Handle SMS rate limit
779
+ * }
780
+ * ```
781
+ */
442
782
  isCode(code: NAuthErrorCode): boolean;
783
+ /**
784
+ * Get error details/metadata.
785
+ *
786
+ * @returns Error details object or undefined
787
+ *
788
+ * @example
789
+ * ```typescript
790
+ * const details = error.getDetails();
791
+ * if (details?.retryAfter) {
792
+ * console.log(`Retry after ${details.retryAfter} seconds`);
793
+ * }
794
+ * ```
795
+ */
443
796
  getDetails(): Record<string, unknown> | undefined;
797
+ /**
798
+ * Get the error code.
799
+ *
800
+ * @returns The error code enum value
801
+ */
444
802
  getCode(): NAuthErrorCode;
803
+ /**
804
+ * Serialize error to JSON object.
805
+ *
806
+ * @returns Plain object representation
807
+ *
808
+ * @example
809
+ * ```typescript
810
+ * const errorJson = error.toJSON();
811
+ * // { code: 'AUTH_INVALID_CREDENTIALS', message: '...', timestamp: '...', details: {...} }
812
+ * ```
813
+ */
445
814
  toJSON(): {
446
815
  code: string;
447
816
  message: string;
@@ -451,8 +820,22 @@ declare class NAuthClientError extends Error implements NAuthError {
451
820
  };
452
821
  }
453
822
 
823
+ /**
824
+ * Authentication event types emitted by NAuthClient
825
+ *
826
+ * Events are emitted throughout the authentication lifecycle,
827
+ * allowing applications to react to auth state changes.
828
+ */
454
829
  type AuthEventType = 'auth:login' | 'auth:signup' | 'auth:success' | 'auth:challenge' | 'auth:error' | 'auth:logout' | 'auth:refresh' | 'oauth:started' | 'oauth:callback' | 'oauth:completed' | 'oauth:error';
830
+ /**
831
+ * Discriminated union of all authentication events with type-safe payloads
832
+ *
833
+ * Each event has a specific payload type for better type safety.
834
+ */
455
835
  type AuthEvent = AuthLoginEvent | AuthSignupEvent | AuthSuccessEvent | AuthChallengeEvent | AuthErrorEvent | AuthLogoutEvent | AuthRefreshEvent | OAuthStartedEvent | OAuthCallbackEvent | OAuthCompletedEvent | OAuthErrorEvent;
836
+ /**
837
+ * Login initiated event
838
+ */
456
839
  interface AuthLoginEvent {
457
840
  type: 'auth:login';
458
841
  data: {
@@ -460,6 +843,9 @@ interface AuthLoginEvent {
460
843
  };
461
844
  timestamp: number;
462
845
  }
846
+ /**
847
+ * Signup initiated event
848
+ */
463
849
  interface AuthSignupEvent {
464
850
  type: 'auth:signup';
465
851
  data: {
@@ -467,21 +853,33 @@ interface AuthSignupEvent {
467
853
  };
468
854
  timestamp: number;
469
855
  }
856
+ /**
857
+ * Successful authentication event
858
+ */
470
859
  interface AuthSuccessEvent {
471
860
  type: 'auth:success';
472
861
  data: AuthResponse;
473
862
  timestamp: number;
474
863
  }
864
+ /**
865
+ * Challenge required event
866
+ */
475
867
  interface AuthChallengeEvent {
476
868
  type: 'auth:challenge';
477
869
  data: AuthResponse;
478
870
  timestamp: number;
479
871
  }
872
+ /**
873
+ * Authentication error event
874
+ */
480
875
  interface AuthErrorEvent {
481
876
  type: 'auth:error';
482
877
  data: NAuthClientError;
483
878
  timestamp: number;
484
879
  }
880
+ /**
881
+ * User logged out event
882
+ */
485
883
  interface AuthLogoutEvent {
486
884
  type: 'auth:logout';
487
885
  data: {
@@ -490,6 +888,9 @@ interface AuthLogoutEvent {
490
888
  };
491
889
  timestamp: number;
492
890
  }
891
+ /**
892
+ * Token refreshed event
893
+ */
493
894
  interface AuthRefreshEvent {
494
895
  type: 'auth:refresh';
495
896
  data: {
@@ -497,6 +898,9 @@ interface AuthRefreshEvent {
497
898
  };
498
899
  timestamp: number;
499
900
  }
901
+ /**
902
+ * OAuth flow started event
903
+ */
500
904
  interface OAuthStartedEvent {
501
905
  type: 'oauth:started';
502
906
  data: {
@@ -504,6 +908,9 @@ interface OAuthStartedEvent {
504
908
  };
505
909
  timestamp: number;
506
910
  }
911
+ /**
912
+ * OAuth callback received event
913
+ */
507
914
  interface OAuthCallbackEvent {
508
915
  type: 'oauth:callback';
509
916
  data: {
@@ -511,114 +918,509 @@ interface OAuthCallbackEvent {
511
918
  };
512
919
  timestamp: number;
513
920
  }
921
+ /**
922
+ * OAuth flow completed event
923
+ */
514
924
  interface OAuthCompletedEvent {
515
925
  type: 'oauth:completed';
516
926
  data: AuthResponse;
517
927
  timestamp: number;
518
928
  }
929
+ /**
930
+ * OAuth error event
931
+ */
519
932
  interface OAuthErrorEvent {
520
933
  type: 'oauth:error';
521
934
  data: NAuthClientError;
522
935
  timestamp: number;
523
936
  }
937
+ /**
938
+ * Event listener callback function
939
+ */
524
940
  type AuthEventListener = (event: AuthEvent) => void;
941
+ /**
942
+ * Internal event emitter for authentication events
943
+ *
944
+ * Provides pub/sub functionality for auth lifecycle events.
945
+ *
946
+ * @internal
947
+ */
525
948
  declare class EventEmitter {
526
949
  private listeners;
950
+ /**
951
+ * Subscribe to an authentication event
952
+ *
953
+ * @param event - Event type or '*' for all events
954
+ * @param listener - Callback function
955
+ * @returns Unsubscribe function
956
+ *
957
+ * @example
958
+ * ```typescript
959
+ * const unsubscribe = emitter.on('auth:success', (event) => {
960
+ * console.log('User logged in:', event.data);
961
+ * });
962
+ *
963
+ * // Later
964
+ * unsubscribe();
965
+ * ```
966
+ */
527
967
  on(event: AuthEventType | '*', listener: AuthEventListener): () => void;
968
+ /**
969
+ * Unsubscribe from an authentication event
970
+ *
971
+ * @param event - Event type or '*'
972
+ * @param listener - Callback function to remove
973
+ */
528
974
  off(event: AuthEventType | '*', listener: AuthEventListener): void;
975
+ /**
976
+ * Emit an authentication event
977
+ *
978
+ * Notifies all listeners for the specific event type and wildcard listeners.
979
+ *
980
+ * @param event - Event to emit
981
+ * @internal
982
+ */
529
983
  emit(event: AuthEvent): void;
984
+ /**
985
+ * Remove all listeners
986
+ *
987
+ * @internal
988
+ */
530
989
  clear(): void;
531
990
  }
532
991
 
992
+ /**
993
+ * Primary client for interacting with nauth-toolkit backend.
994
+ */
533
995
  declare class NAuthClient {
534
996
  private readonly config;
535
997
  private readonly tokenManager;
536
998
  private readonly eventEmitter;
537
999
  private currentUser;
1000
+ /**
1001
+ * Create a new client instance.
1002
+ *
1003
+ * @param userConfig - Client configuration
1004
+ */
538
1005
  constructor(userConfig: NAuthClientConfig);
1006
+ /**
1007
+ * Clean up resources.
1008
+ */
539
1009
  dispose(): void;
1010
+ /**
1011
+ * Login with identifier and password.
1012
+ */
540
1013
  login(identifier: string, password: string): Promise<AuthResponse>;
1014
+ /**
1015
+ * Signup with credentials.
1016
+ */
541
1017
  signup(payload: SignupRequest): Promise<AuthResponse>;
1018
+ /**
1019
+ * Refresh tokens manually.
1020
+ */
542
1021
  refreshTokens(): Promise<TokenResponse>;
1022
+ /**
1023
+ * Logout current session.
1024
+ *
1025
+ * Uses GET request to avoid CSRF token issues.
1026
+ *
1027
+ * @param forgetDevice - If true, also untrust the device (require MFA on next login)
1028
+ */
543
1029
  logout(forgetDevice?: boolean): Promise<void>;
1030
+ /**
1031
+ * Logout all sessions.
1032
+ *
1033
+ * Revokes all active sessions for the current user across all devices.
1034
+ * Optionally revokes all trusted devices if forgetDevices is true.
1035
+ *
1036
+ * @param forgetDevices - If true, also revokes all trusted devices (default: false)
1037
+ * @returns Number of sessions revoked
1038
+ */
544
1039
  logoutAll(forgetDevices?: boolean): Promise<{
545
1040
  revokedCount: number;
546
1041
  }>;
1042
+ /**
1043
+ * Respond to a challenge.
1044
+ *
1045
+ * Validates challenge response data before sending to backend.
1046
+ * Provides helpful error messages for common validation issues.
1047
+ *
1048
+ * @param response - Challenge response data
1049
+ * @returns Auth response from backend
1050
+ * @throws {NAuthClientError} If validation fails
1051
+ */
547
1052
  respondToChallenge(response: ChallengeResponse): Promise<AuthResponse>;
1053
+ /**
1054
+ * Resend a challenge code.
1055
+ */
548
1056
  resendCode(session: string): Promise<{
549
1057
  destination: string;
550
1058
  }>;
1059
+ /**
1060
+ * Get setup data for MFA.
1061
+ *
1062
+ * Returns method-specific setup information:
1063
+ * - TOTP: { secret, qrCode, manualEntryKey }
1064
+ * - SMS: { maskedPhone }
1065
+ * - Email: { maskedEmail }
1066
+ * - Passkey: WebAuthn registration options
1067
+ *
1068
+ * @param session - Challenge session token
1069
+ * @param method - MFA method to set up
1070
+ * @returns Setup data wrapped in GetSetupDataResponse
1071
+ */
551
1072
  getSetupData(session: string, method: GetSetupDataRequest['method']): Promise<GetSetupDataResponse>;
1073
+ /**
1074
+ * Get challenge data (e.g., WebAuthn options).
1075
+ *
1076
+ * Returns challenge-specific data for verification flows.
1077
+ *
1078
+ * @param session - Challenge session token
1079
+ * @param method - Challenge method to get data for
1080
+ * @returns Challenge data wrapped in GetChallengeDataResponse
1081
+ */
552
1082
  getChallengeData(session: string, method: GetChallengeDataRequest['method']): Promise<GetChallengeDataResponse>;
1083
+ /**
1084
+ * Get current user profile.
1085
+ */
553
1086
  getProfile(): Promise<AuthUser>;
1087
+ /**
1088
+ * Update user profile.
1089
+ */
554
1090
  updateProfile(updates: UpdateProfileRequest): Promise<AuthUser>;
1091
+ /**
1092
+ * Change user password.
1093
+ */
555
1094
  changePassword(oldPassword: string, newPassword: string): Promise<void>;
1095
+ /**
1096
+ * Request a password reset code (forgot password).
1097
+ */
556
1098
  forgotPassword(identifier: string): Promise<ForgotPasswordResponse>;
1099
+ /**
1100
+ * Confirm a password reset code and set a new password.
1101
+ */
557
1102
  confirmForgotPassword(identifier: string, code: string, newPassword: string): Promise<ConfirmForgotPasswordResponse>;
1103
+ /**
1104
+ * Request password change (must change on next login).
1105
+ */
558
1106
  requestPasswordChange(): Promise<void>;
1107
+ /**
1108
+ * Get MFA status.
1109
+ */
559
1110
  getMfaStatus(): Promise<MFAStatus>;
1111
+ /**
1112
+ * Get MFA devices.
1113
+ */
560
1114
  getMfaDevices(): Promise<unknown[]>;
1115
+ /**
1116
+ * Setup MFA device (authenticated user).
1117
+ */
561
1118
  setupMfaDevice(method: string): Promise<unknown>;
1119
+ /**
1120
+ * Verify MFA setup (authenticated user).
1121
+ */
562
1122
  verifyMfaSetup(method: string, setupData: Record<string, unknown>, deviceName?: string): Promise<{
563
1123
  deviceId: number;
564
1124
  }>;
1125
+ /**
1126
+ * Remove MFA method.
1127
+ */
565
1128
  removeMfaDevice(method: string): Promise<{
566
1129
  message: string;
567
1130
  }>;
1131
+ /**
1132
+ * Set preferred MFA method.
1133
+ *
1134
+ * @param method - Device method to set as preferred ('totp', 'sms', 'email', or 'passkey'). Cannot be 'backup'.
1135
+ * @returns Success message
1136
+ */
568
1137
  setPreferredMfaMethod(method: 'totp' | 'sms' | 'email' | 'passkey'): Promise<{
569
1138
  message: string;
570
1139
  }>;
1140
+ /**
1141
+ * Generate backup codes.
1142
+ */
571
1143
  generateBackupCodes(): Promise<string[]>;
1144
+ /**
1145
+ * Set MFA exemption (admin/test scenarios).
1146
+ */
572
1147
  setMfaExemption(exempt: boolean, reason?: string): Promise<void>;
1148
+ /**
1149
+ * Subscribe to authentication events.
1150
+ *
1151
+ * Emits events throughout the auth lifecycle for custom logic, analytics, or UI updates.
1152
+ *
1153
+ * @param event - Event type to listen for, or '*' for all events
1154
+ * @param listener - Callback function to handle the event
1155
+ * @returns Unsubscribe function
1156
+ *
1157
+ * @example
1158
+ * ```typescript
1159
+ * // Listen to successful authentication
1160
+ * const unsubscribe = client.on('auth:success', (event) => {
1161
+ * console.log('User logged in:', event.data.user);
1162
+ * analytics.track('login_success');
1163
+ * });
1164
+ *
1165
+ * // Listen to all events
1166
+ * client.on('*', (event) => {
1167
+ * console.log('Auth event:', event.type, event.data);
1168
+ * });
1169
+ *
1170
+ * // Unsubscribe when done
1171
+ * unsubscribe();
1172
+ * ```
1173
+ */
573
1174
  on(event: AuthEventType | '*', listener: AuthEventListener): () => void;
1175
+ /**
1176
+ * Unsubscribe from authentication events.
1177
+ *
1178
+ * @param event - Event type
1179
+ * @param listener - Callback function to remove
1180
+ */
574
1181
  off(event: AuthEventType | '*', listener: AuthEventListener): void;
1182
+ /**
1183
+ * Start social OAuth flow with automatic state management.
1184
+ *
1185
+ * Generates a secure state token, stores OAuth context, and redirects to the OAuth provider.
1186
+ * After OAuth callback, use `handleOAuthCallback()` to complete authentication.
1187
+ *
1188
+ * @param provider - OAuth provider ('google', 'apple', 'facebook')
1189
+ * @param options - Optional configuration
1190
+ *
1191
+ * @example
1192
+ * ```typescript
1193
+ * // Simple usage
1194
+ * await client.loginWithSocial('google');
1195
+ *
1196
+ * // With custom redirect URI
1197
+ * await client.loginWithSocial('apple', {
1198
+ * redirectUri: 'https://example.com/auth/callback'
1199
+ * });
1200
+ * ```
1201
+ */
575
1202
  loginWithSocial(provider: SocialProvider, _options?: {
576
1203
  redirectUri?: string;
577
1204
  }): Promise<void>;
1205
+ /**
1206
+ * Auto-detect and handle OAuth callback.
1207
+ *
1208
+ * Call this on app initialization or in callback route.
1209
+ * Returns null if not an OAuth callback (no provider/code params).
1210
+ *
1211
+ * The SDK validates the state token, completes authentication via backend,
1212
+ * and emits appropriate events.
1213
+ *
1214
+ * @param urlOrParams - Optional URL string or URLSearchParams (auto-detects from window.location if not provided)
1215
+ * @returns AuthResponse if OAuth callback detected, null otherwise
1216
+ *
1217
+ * @example
1218
+ * ```typescript
1219
+ * // Auto-detect on app init
1220
+ * const response = await client.handleOAuthCallback();
1221
+ * if (response) {
1222
+ * if (response.challengeName) {
1223
+ * router.navigate(['/challenge', response.challengeName]);
1224
+ * } else {
1225
+ * router.navigate(['/']); // Navigate to your app's home route
1226
+ * }
1227
+ * }
1228
+ *
1229
+ * // In callback route
1230
+ * const response = await client.handleOAuthCallback(window.location.search);
1231
+ * ```
1232
+ */
578
1233
  handleOAuthCallback(urlOrParams?: string | URLSearchParams): Promise<AuthResponse | null>;
1234
+ /**
1235
+ * Get social auth URL (low-level API).
1236
+ *
1237
+ * For most cases, use `loginWithSocial()` which handles state management automatically.
1238
+ */
579
1239
  getSocialAuthUrl(request: SocialAuthUrlRequest): Promise<{
580
1240
  url: string;
581
1241
  }>;
1242
+ /**
1243
+ * Handle social callback.
1244
+ */
582
1245
  handleSocialCallback(request: SocialCallbackRequest): Promise<AuthResponse>;
1246
+ /**
1247
+ * Verify native social token (mobile).
1248
+ */
583
1249
  verifyNativeSocial(request: SocialVerifyRequest): Promise<AuthResponse>;
1250
+ /**
1251
+ * Get linked accounts.
1252
+ */
584
1253
  getLinkedAccounts(): Promise<LinkedAccountsResponse>;
1254
+ /**
1255
+ * Link social account.
1256
+ */
585
1257
  linkSocialAccount(provider: string, code: string, state: string): Promise<{
586
1258
  message: string;
587
1259
  }>;
1260
+ /**
1261
+ * Unlink social account.
1262
+ */
588
1263
  unlinkSocialAccount(provider: string): Promise<{
589
1264
  message: string;
590
1265
  }>;
1266
+ /**
1267
+ * Trust current device.
1268
+ */
591
1269
  trustDevice(): Promise<{
592
1270
  deviceToken: string;
593
1271
  }>;
1272
+ /**
1273
+ * Check if the current device is trusted.
1274
+ *
1275
+ * Returns whether the current device is trusted based on the device token
1276
+ * (from cookie in cookies mode, or header in JSON mode).
1277
+ *
1278
+ * This performs a server-side validation of the device token and checks:
1279
+ * - Device token exists and is valid
1280
+ * - Device token matches a trusted device record in the database
1281
+ * - Trust has not expired
1282
+ *
1283
+ * @returns Object with trusted status
1284
+ *
1285
+ * @example
1286
+ * ```typescript
1287
+ * const result = await client.isTrustedDevice();
1288
+ * if (result.trusted) {
1289
+ * console.log('This device is trusted');
1290
+ * }
1291
+ * ```
1292
+ */
594
1293
  isTrustedDevice(): Promise<{
595
1294
  trusted: boolean;
596
1295
  }>;
1296
+ /**
1297
+ * Get paginated audit history for the current user.
1298
+ *
1299
+ * Returns authentication and security events with full audit details including:
1300
+ * - Event type (login, logout, MFA, etc.)
1301
+ * - Event status (success, failure, suspicious)
1302
+ * - Device information, location, risk factors
1303
+ *
1304
+ * @param params - Query parameters for filtering and pagination
1305
+ * @returns Paginated audit history response
1306
+ *
1307
+ * @example
1308
+ * ```typescript
1309
+ * const history = await client.getAuditHistory({
1310
+ * page: 1,
1311
+ * limit: 20,
1312
+ * eventType: 'LOGIN_SUCCESS'
1313
+ * });
1314
+ * ```
1315
+ */
597
1316
  getAuditHistory(params?: Record<string, string | number | boolean>): Promise<AuditHistoryResponse>;
1317
+ /**
1318
+ * Initialize client by hydrating state from storage.
1319
+ * Call this on app startup to restore auth state.
1320
+ */
598
1321
  initialize(): Promise<void>;
1322
+ /**
1323
+ * Determine if user is authenticated (async - checks tokens).
1324
+ */
599
1325
  isAuthenticated(): Promise<boolean>;
1326
+ /**
1327
+ * Determine if user is authenticated (sync - checks cached user).
1328
+ * Use this for guards and sync checks. Use `isAuthenticated()` for definitive check.
1329
+ */
600
1330
  isAuthenticatedSync(): boolean;
1331
+ /**
1332
+ * Get current access token (may be null).
1333
+ */
601
1334
  getAccessToken(): Promise<string | null>;
1335
+ /**
1336
+ * Get current user (cached, sync).
1337
+ */
602
1338
  getCurrentUser(): AuthUser | null;
1339
+ /**
1340
+ * Get stored challenge session (for resuming challenge flows).
1341
+ */
603
1342
  getStoredChallenge(): Promise<AuthResponse | null>;
1343
+ /**
1344
+ * Clear stored challenge session.
1345
+ */
604
1346
  clearStoredChallenge(): Promise<void>;
1347
+ /**
1348
+ * Internal: handle auth response (tokens or challenge).
1349
+ *
1350
+ * In cookies mode: Tokens are set as httpOnly cookies by backend, not stored in client storage.
1351
+ * In JSON mode: Tokens are stored in tokenManager for Authorization header.
1352
+ */
605
1353
  private handleAuthResponse;
1354
+ /**
1355
+ * Persist challenge state.
1356
+ */
606
1357
  private persistChallenge;
1358
+ /**
1359
+ * Clear challenge state.
1360
+ */
607
1361
  private clearChallenge;
1362
+ /**
1363
+ * Persist user.
1364
+ */
608
1365
  private setUser;
1366
+ /**
1367
+ * Clear all auth state.
1368
+ *
1369
+ * @param forgetDevice - If true, also clear device token (for JSON mode)
1370
+ */
609
1371
  private clearAuthState;
1372
+ /**
1373
+ * Persist device token (json mode mobile).
1374
+ */
610
1375
  private setDeviceToken;
1376
+ /**
1377
+ * Determine token delivery mode for this environment.
1378
+ */
611
1379
  private getTokenDeliveryMode;
1380
+ /**
1381
+ * Build request URL by combining baseUrl with path.
1382
+ * @private
1383
+ */
612
1384
  private buildUrl;
1385
+ /**
1386
+ * Build request headers for authentication.
1387
+ * @private
1388
+ */
613
1389
  private buildHeaders;
1390
+ /**
1391
+ * Get CSRF token from cookie (browser only).
1392
+ * @private
1393
+ */
614
1394
  private getCsrfToken;
1395
+ /**
1396
+ * Execute GET request.
1397
+ * Note: 401 refresh is handled by framework interceptors (Angular) or manually.
1398
+ */
615
1399
  private get;
1400
+ /**
1401
+ * Execute POST request.
1402
+ * Note: 401 refresh is handled by framework interceptors (Angular) or manually.
1403
+ */
616
1404
  private post;
1405
+ /**
1406
+ * Execute PUT request.
1407
+ * Note: 401 refresh is handled by framework interceptors (Angular) or manually.
1408
+ */
617
1409
  private put;
1410
+ /**
1411
+ * Execute DELETE request.
1412
+ * Note: 401 refresh is handled by framework interceptors (Angular) or manually.
1413
+ */
618
1414
  private delete;
1415
+ /**
1416
+ * Handle cross-tab storage updates.
1417
+ */
619
1418
  private readonly handleStorageEvent;
620
1419
  }
621
1420
 
1421
+ /**
1422
+ * Fully resolved configuration with all defaults applied.
1423
+ */
622
1424
  type ResolvedNAuthClientConfig = Omit<NAuthClientConfig, 'endpoints' | 'storage' | 'tokenDelivery' | 'httpAdapter'> & {
623
1425
  tokenDelivery: TokenDeliveryMode;
624
1426
  endpoints: NAuthEndpoints;
@@ -635,23 +1437,122 @@ type ResolvedNAuthClientConfig = Omit<NAuthClientConfig, 'endpoints' | 'storage'
635
1437
  headers: Record<string, string>;
636
1438
  timeout: number;
637
1439
  };
1440
+ /**
1441
+ * Default endpoint paths matching backend controller.
1442
+ */
638
1443
  declare const defaultEndpoints: NAuthEndpoints;
1444
+ /**
1445
+ * Normalize user config with defaults.
1446
+ *
1447
+ * @param config - User supplied config
1448
+ * @param defaultAdapter - Default HTTP adapter (FetchAdapter for vanilla, AngularHttpAdapter for Angular)
1449
+ * @returns Resolved config with defaults applied
1450
+ */
639
1451
  declare const resolveConfig: (config: NAuthClientConfig, defaultAdapter: HttpAdapter) => ResolvedNAuthClientConfig;
640
1452
 
1453
+ /**
1454
+ * Helper utilities for working with authentication challenges.
1455
+ *
1456
+ * These utilities reduce boilerplate in consumer applications by providing
1457
+ * type-safe access to challenge parameters and state detection.
1458
+ */
1459
+ /**
1460
+ * Check if a challenge requires phone collection (user has no phone number).
1461
+ *
1462
+ * @param challenge - Auth response with challenge
1463
+ * @returns True if phone collection is required
1464
+ *
1465
+ * @example
1466
+ * ```typescript
1467
+ * const challenge = auth.getCurrentChallenge();
1468
+ * if (challenge && requiresPhoneCollection(challenge)) {
1469
+ * // Show phone input form
1470
+ * }
1471
+ * ```
1472
+ */
641
1473
  declare function requiresPhoneCollection(challenge: AuthResponse): boolean;
1474
+ /**
1475
+ * Get masked destination (email or phone) from challenge parameters.
1476
+ *
1477
+ * For VERIFY_EMAIL/VERIFY_PHONE challenges, returns `codeDeliveryDestination`.
1478
+ * For MFA_REQUIRED challenges, returns `maskedEmail` or `maskedPhone` based on method.
1479
+ *
1480
+ * @param challenge - Auth response with challenge
1481
+ * @returns Masked destination string or null if not available
1482
+ *
1483
+ * @example
1484
+ * ```typescript
1485
+ * const destination = getMaskedDestination(challenge);
1486
+ * if (destination) {
1487
+ * console.log(`Code sent to ${destination}`);
1488
+ * }
1489
+ * ```
1490
+ */
642
1491
  declare function getMaskedDestination(challenge: AuthResponse): string | null;
1492
+ /**
1493
+ * Get preferred MFA method from challenge parameters.
1494
+ *
1495
+ * @param challenge - Auth response with MFA_REQUIRED challenge
1496
+ * @returns MFA method or undefined if not available
1497
+ *
1498
+ * @example
1499
+ * ```typescript
1500
+ * const method = getMFAMethod(challenge);
1501
+ * if (method === 'totp') {
1502
+ * // Show TOTP input
1503
+ * }
1504
+ * ```
1505
+ */
643
1506
  declare function getMFAMethod(challenge: AuthResponse): MFAMethod | undefined;
1507
+ /**
1508
+ * Get challenge instructions from challenge parameters.
1509
+ *
1510
+ * @param challenge - Auth response with challenge
1511
+ * @returns Instructions string or undefined if not available
1512
+ *
1513
+ * @example
1514
+ * ```typescript
1515
+ * const instructions = getChallengeInstructions(challenge);
1516
+ * if (instructions) {
1517
+ * console.log(instructions);
1518
+ * }
1519
+ * ```
1520
+ */
644
1521
  declare function getChallengeInstructions(challenge: AuthResponse): string | undefined;
1522
+ /**
1523
+ * Check if challenge is OTP-based (requires code input).
1524
+ *
1525
+ * @param challenge - Auth response with challenge
1526
+ * @returns True if challenge requires OTP code
1527
+ *
1528
+ * @example
1529
+ * ```typescript
1530
+ * if (isOTPChallenge(challenge)) {
1531
+ * // Show OTP input component
1532
+ * }
1533
+ * ```
1534
+ */
645
1535
  declare function isOTPChallenge(challenge: AuthResponse): boolean;
646
1536
 
1537
+ /**
1538
+ * Browser storage adapter wrapping localStorage or sessionStorage.
1539
+ */
647
1540
  declare class BrowserStorage implements NAuthStorageAdapter {
648
1541
  private readonly storage;
1542
+ /**
1543
+ * Create a browser storage adapter.
1544
+ *
1545
+ * @param storage - Storage implementation (localStorage by default)
1546
+ */
649
1547
  constructor(storage?: Storage);
650
1548
  getItem(key: string): Promise<string | null>;
651
1549
  setItem(key: string, value: string): Promise<void>;
652
1550
  removeItem(key: string): Promise<void>;
653
1551
  }
654
1552
 
1553
+ /**
1554
+ * In-memory storage adapter for SSR, tests, or environments without Web Storage.
1555
+ */
655
1556
  declare class InMemoryStorage implements NAuthStorageAdapter {
656
1557
  private readonly store;
657
1558
  getItem(key: string): Promise<string | null>;
@@ -659,7 +1560,33 @@ declare class InMemoryStorage implements NAuthStorageAdapter {
659
1560
  removeItem(key: string): Promise<void>;
660
1561
  }
661
1562
 
1563
+ /**
1564
+ * HTTP adapter using native fetch API.
1565
+ *
1566
+ * Suitable for:
1567
+ * - Vanilla JavaScript/TypeScript
1568
+ * - Node.js (with fetch polyfill or Node 18+)
1569
+ * - Environments without framework-specific HTTP clients
1570
+ *
1571
+ * @example
1572
+ * ```typescript
1573
+ * import { NAuthClient } from '@nauth-toolkit/client';
1574
+ * import { FetchAdapter } from '@nauth-toolkit/client/adapters/fetch';
1575
+ *
1576
+ * const client = new NAuthClient({
1577
+ * baseUrl: 'https://api.example.com/auth',
1578
+ * httpAdapter: new FetchAdapter(),
1579
+ * });
1580
+ * ```
1581
+ */
662
1582
  declare class FetchAdapter implements HttpAdapter {
1583
+ /**
1584
+ * Execute HTTP request using native fetch.
1585
+ *
1586
+ * @param config - Request configuration
1587
+ * @returns Response with parsed data
1588
+ * @throws NAuthClientError if request fails
1589
+ */
663
1590
  request<T>(config: HttpRequest): Promise<HttpResponse<T>>;
664
1591
  }
665
1592