mulguard 1.1.2 → 1.1.3
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/core/auth/oauth-providers.d.ts +175 -49
- package/dist/core/mulguard/auth-handlers.d.ts +100 -0
- package/dist/core/mulguard/defaults.d.ts +58 -0
- package/dist/core/mulguard/index.d.ts +9 -0
- package/dist/core/mulguard/oauth-handler.d.ts +93 -0
- package/dist/core/mulguard/session-manager.d.ts +94 -0
- package/dist/core/security/index.d.ts +113 -9
- package/dist/core/security/validation.d.ts +231 -33
- package/dist/core/types/auth.d.ts +234 -75
- package/dist/core/types/errors.d.ts +174 -18
- package/dist/core/types/index.d.ts +397 -333
- package/dist/core/utils/logger.d.ts +112 -8
- package/dist/handlers/route.d.ts +59 -5
- package/dist/index/index.js +1 -1
- package/dist/index/index.mjs +1536 -1213
- package/dist/mulguard.d.ts +76 -1
- package/dist/server/helpers.d.ts +3 -3
- package/dist/server/utils.d.ts +3 -3
- package/package.json +1 -1
|
@@ -1,15 +1,37 @@
|
|
|
1
1
|
import { AuthErrorCode } from './errors';
|
|
2
|
+
/**
|
|
3
|
+
* User interface representing an authenticated user.
|
|
4
|
+
*
|
|
5
|
+
* @property id - Unique user identifier
|
|
6
|
+
* @property email - User email address
|
|
7
|
+
* @property name - User display name
|
|
8
|
+
* @property avatar - Optional avatar URL
|
|
9
|
+
* @property roles - Optional user roles array
|
|
10
|
+
* @property emailVerified - Email verification status
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const user: User = {
|
|
15
|
+
* id: '123',
|
|
16
|
+
* email: 'user@example.com',
|
|
17
|
+
* name: 'John Doe',
|
|
18
|
+
* emailVerified: true
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
2
22
|
export interface User {
|
|
3
|
-
id: string;
|
|
4
|
-
email: string;
|
|
5
|
-
name: string;
|
|
6
|
-
avatar?: string;
|
|
7
|
-
roles?: string[];
|
|
8
|
-
emailVerified?: boolean;
|
|
9
|
-
[key: string]: unknown;
|
|
23
|
+
readonly id: string;
|
|
24
|
+
readonly email: string;
|
|
25
|
+
readonly name: string;
|
|
26
|
+
readonly avatar?: string;
|
|
27
|
+
readonly roles?: readonly string[];
|
|
28
|
+
readonly emailVerified?: boolean;
|
|
29
|
+
readonly [key: string]: unknown;
|
|
10
30
|
}
|
|
11
31
|
/**
|
|
12
|
-
* Session object containing user information and authentication tokens
|
|
32
|
+
* Session object containing user information and authentication tokens.
|
|
33
|
+
*
|
|
34
|
+
* @template TUser - User type (defaults to base User)
|
|
13
35
|
*
|
|
14
36
|
* @property user - User object with authentication information
|
|
15
37
|
* @property expiresAt - Session expiration date/time
|
|
@@ -18,114 +40,251 @@ export interface User {
|
|
|
18
40
|
* @property tokenType - Type of token (default: 'Bearer')
|
|
19
41
|
* @property expiresIn - Token expiration time in seconds (optional)
|
|
20
42
|
* @property refreshTokenExpiresAt - Refresh token expiration date/time (optional)
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* const session: Session = {
|
|
47
|
+
* user: { id: '123', email: 'user@example.com', name: 'John' },
|
|
48
|
+
* expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
|
|
49
|
+
* accessToken: 'token123',
|
|
50
|
+
* tokenType: 'Bearer'
|
|
51
|
+
* }
|
|
52
|
+
* ```
|
|
21
53
|
*/
|
|
22
|
-
export interface Session {
|
|
23
|
-
user:
|
|
24
|
-
expiresAt: Date | string;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
/** Token expiration time in seconds (optional) */
|
|
32
|
-
expiresIn?: number;
|
|
33
|
-
/** Refresh token expiration date/time (optional) */
|
|
34
|
-
refreshTokenExpiresAt?: Date | string;
|
|
35
|
-
[key: string]: unknown;
|
|
54
|
+
export interface Session<TUser extends User = User> {
|
|
55
|
+
readonly user: TUser;
|
|
56
|
+
readonly expiresAt: Date | string;
|
|
57
|
+
readonly accessToken?: string;
|
|
58
|
+
readonly refreshToken?: string;
|
|
59
|
+
readonly tokenType?: 'Bearer' | 'Basic';
|
|
60
|
+
readonly expiresIn?: number;
|
|
61
|
+
readonly refreshTokenExpiresAt?: Date | string;
|
|
62
|
+
readonly [key: string]: unknown;
|
|
36
63
|
}
|
|
37
64
|
/**
|
|
38
|
-
*
|
|
65
|
+
* Base authentication result type.
|
|
66
|
+
*
|
|
67
|
+
* @template TUser - User type (defaults to base User)
|
|
68
|
+
* @template TSession - Session type (defaults to base Session)
|
|
39
69
|
*
|
|
40
70
|
* @property success - Whether the authentication was successful
|
|
41
71
|
* @property user - User object if authentication succeeded
|
|
42
72
|
* @property session - Session object if authentication succeeded
|
|
43
73
|
* @property error - Error message if authentication failed
|
|
44
74
|
* @property errorCode - Specific error code for programmatic error handling
|
|
45
|
-
* @property requires2FA - Whether 2FA verification is required
|
|
75
|
+
* @property requires2FA - Whether 2FA verification is required
|
|
46
76
|
* @property email - Email address (required when requires2FA is true)
|
|
47
77
|
* @property userId - User ID (required when requires2FA is true)
|
|
48
78
|
*
|
|
49
79
|
* @example
|
|
50
80
|
* ```typescript
|
|
51
|
-
* const result = await auth.signIn.email(
|
|
81
|
+
* const result = await auth.signIn.email(credentials)
|
|
52
82
|
* if (result.success) {
|
|
53
|
-
* //
|
|
54
|
-
* console.log(
|
|
83
|
+
* // TypeScript knows result.user and result.session exist
|
|
84
|
+
* console.log(result.user.email)
|
|
55
85
|
* } else if (result.requires2FA) {
|
|
56
|
-
* //
|
|
57
|
-
*
|
|
58
|
-
* } else {
|
|
59
|
-
* // Authentication failed
|
|
60
|
-
* console.error('Error:', result.error, result.errorCode)
|
|
86
|
+
* // TypeScript knows result.email and result.userId exist
|
|
87
|
+
* await auth.verify2FA({ email: result.email, userId: result.userId, code: '123456' })
|
|
61
88
|
* }
|
|
62
89
|
* ```
|
|
63
90
|
*/
|
|
64
|
-
export interface AuthResult {
|
|
65
|
-
success: boolean;
|
|
66
|
-
user?:
|
|
67
|
-
session?:
|
|
68
|
-
error?: string;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
/** Email for 2FA flow */
|
|
74
|
-
email?: string;
|
|
75
|
-
/** User ID for 2FA flow */
|
|
76
|
-
userId?: string;
|
|
91
|
+
export interface AuthResult<TUser extends User = User, TSession extends Session<TUser> = Session<TUser>> {
|
|
92
|
+
readonly success: boolean;
|
|
93
|
+
readonly user?: TUser;
|
|
94
|
+
readonly session?: TSession;
|
|
95
|
+
readonly error?: string;
|
|
96
|
+
readonly errorCode?: AuthErrorCode;
|
|
97
|
+
readonly requires2FA?: boolean;
|
|
98
|
+
readonly email?: string;
|
|
99
|
+
readonly userId?: string;
|
|
77
100
|
}
|
|
78
101
|
/**
|
|
79
|
-
*
|
|
102
|
+
* Successful authentication result type.
|
|
103
|
+
*
|
|
104
|
+
* @template TUser - User type
|
|
105
|
+
* @template TSession - Session type
|
|
106
|
+
*/
|
|
107
|
+
export type SuccessfulAuthResult<TUser extends User = User, TSession extends Session<TUser> = Session<TUser>> = AuthResult<TUser, TSession> & {
|
|
108
|
+
readonly success: true;
|
|
109
|
+
readonly user: TUser;
|
|
110
|
+
readonly session: TSession;
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Failed authentication result type.
|
|
114
|
+
*
|
|
115
|
+
* @template TUser - User type
|
|
116
|
+
* @template TSession - Session type
|
|
117
|
+
*/
|
|
118
|
+
export type FailedAuthResult<TUser extends User = User, TSession extends Session<TUser> = Session<TUser>> = AuthResult<TUser, TSession> & {
|
|
119
|
+
readonly success: false;
|
|
120
|
+
readonly error: string;
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* Two-factor authentication required result type.
|
|
80
124
|
*
|
|
81
125
|
* This type is returned when 2FA verification is required after initial authentication.
|
|
82
|
-
* Use the `isTwoFactorRequired()`
|
|
126
|
+
* Use the `isTwoFactorRequired()` type guard to narrow to this type.
|
|
127
|
+
*
|
|
128
|
+
* @template TUser - User type
|
|
129
|
+
* @template TSession - Session type
|
|
83
130
|
*
|
|
84
|
-
* @property success - Always false
|
|
131
|
+
* @property success - Always false
|
|
85
132
|
* @property requires2FA - Always true
|
|
86
133
|
* @property email - Email address of the user requiring 2FA
|
|
87
134
|
* @property userId - User ID requiring 2FA
|
|
88
135
|
* @property errorCode - Always AuthErrorCode.TWO_FA_REQUIRED
|
|
89
|
-
* @property twoFactorMethod - Method of 2FA (
|
|
90
|
-
* @property challengeToken - Challenge token for 2FA verification
|
|
136
|
+
* @property twoFactorMethod - Method of 2FA (optional)
|
|
137
|
+
* @property challengeToken - Challenge token for 2FA verification (optional)
|
|
91
138
|
*
|
|
92
139
|
* @example
|
|
93
140
|
* ```typescript
|
|
94
|
-
* const result = await auth.signIn.email(
|
|
141
|
+
* const result = await auth.signIn.email(credentials)
|
|
95
142
|
* if (isTwoFactorRequired(result)) {
|
|
96
143
|
* // TypeScript knows result is TwoFactorAuthResult here
|
|
97
144
|
* console.log('2FA required for:', result.email)
|
|
98
|
-
* console.log('Method:', result.twoFactorMethod)
|
|
145
|
+
* console.log('Method:', result.twoFactorMethod)
|
|
99
146
|
* }
|
|
100
147
|
* ```
|
|
101
148
|
*/
|
|
102
|
-
export interface TwoFactorAuthResult extends AuthResult {
|
|
103
|
-
success: false;
|
|
104
|
-
requires2FA: true;
|
|
105
|
-
email: string;
|
|
106
|
-
userId: string;
|
|
107
|
-
error: '2FA_REQUIRED';
|
|
108
|
-
errorCode: AuthErrorCode.TWO_FA_REQUIRED;
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
/** Challenge token for 2FA verification - optional */
|
|
112
|
-
challengeToken?: string;
|
|
149
|
+
export interface TwoFactorAuthResult<TUser extends User = User, TSession extends Session<TUser> = Session<TUser>> extends AuthResult<TUser, TSession> {
|
|
150
|
+
readonly success: false;
|
|
151
|
+
readonly requires2FA: true;
|
|
152
|
+
readonly email: string;
|
|
153
|
+
readonly userId: string;
|
|
154
|
+
readonly error: '2FA_REQUIRED';
|
|
155
|
+
readonly errorCode: AuthErrorCode.TWO_FA_REQUIRED;
|
|
156
|
+
readonly twoFactorMethod?: 'totp' | 'sms' | 'email';
|
|
157
|
+
readonly challengeToken?: string;
|
|
113
158
|
}
|
|
114
159
|
/**
|
|
115
|
-
*
|
|
160
|
+
* Email and password credentials for authentication.
|
|
161
|
+
*
|
|
162
|
+
* @property email - User email address
|
|
163
|
+
* @property password - User password
|
|
116
164
|
*/
|
|
117
|
-
export interface Verify2FAData {
|
|
118
|
-
email: string;
|
|
119
|
-
userId: string;
|
|
120
|
-
code: string;
|
|
121
|
-
}
|
|
122
165
|
export interface EmailCredentials {
|
|
123
|
-
email: string;
|
|
124
|
-
password: string;
|
|
166
|
+
readonly email: string;
|
|
167
|
+
readonly password: string;
|
|
125
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* User registration data.
|
|
171
|
+
*
|
|
172
|
+
* @property email - User email address
|
|
173
|
+
* @property password - User password
|
|
174
|
+
* @property name - User display name
|
|
175
|
+
*/
|
|
126
176
|
export interface RegisterData {
|
|
127
|
-
email: string;
|
|
128
|
-
password: string;
|
|
129
|
-
name: string;
|
|
130
|
-
[key: string]: unknown;
|
|
177
|
+
readonly email: string;
|
|
178
|
+
readonly password: string;
|
|
179
|
+
readonly name: string;
|
|
180
|
+
readonly [key: string]: unknown;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Data required for 2FA verification.
|
|
184
|
+
*
|
|
185
|
+
* @property email - User email address
|
|
186
|
+
* @property userId - User ID
|
|
187
|
+
* @property code - 2FA verification code
|
|
188
|
+
*/
|
|
189
|
+
export interface Verify2FAData {
|
|
190
|
+
readonly email: string;
|
|
191
|
+
readonly userId: string;
|
|
192
|
+
readonly code: string;
|
|
131
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* Type predicate to check if AuthResult indicates success.
|
|
196
|
+
*
|
|
197
|
+
* @template TUser - User type
|
|
198
|
+
* @template TSession - Session type
|
|
199
|
+
* @param result - AuthResult to check
|
|
200
|
+
* @returns True if result is successful
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* ```typescript
|
|
204
|
+
* const result = await auth.signIn.email(credentials)
|
|
205
|
+
* if (isAuthSuccess(result)) {
|
|
206
|
+
* // TypeScript narrows to SuccessfulAuthResult
|
|
207
|
+
* console.log(result.user.email) // ✅ Type-safe
|
|
208
|
+
* console.log(result.session.expiresAt) // ✅ Type-safe
|
|
209
|
+
* }
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
212
|
+
export declare function isAuthSuccess<TUser extends User = User, TSession extends Session<TUser> = Session<TUser>>(result: AuthResult<TUser, TSession>): result is SuccessfulAuthResult<TUser, TSession>;
|
|
213
|
+
/**
|
|
214
|
+
* Type predicate to check if AuthResult indicates failure.
|
|
215
|
+
*
|
|
216
|
+
* @template TUser - User type
|
|
217
|
+
* @template TSession - Session type
|
|
218
|
+
* @param result - AuthResult to check
|
|
219
|
+
* @returns True if result indicates failure
|
|
220
|
+
*
|
|
221
|
+
* @example
|
|
222
|
+
* ```typescript
|
|
223
|
+
* const result = await auth.signIn.email(credentials)
|
|
224
|
+
* if (isAuthFailure(result)) {
|
|
225
|
+
* // TypeScript narrows to FailedAuthResult
|
|
226
|
+
* console.error(result.error) // ✅ Type-safe
|
|
227
|
+
* }
|
|
228
|
+
* ```
|
|
229
|
+
*/
|
|
230
|
+
export declare function isAuthFailure<TUser extends User = User, TSession extends Session<TUser> = Session<TUser>>(result: AuthResult<TUser, TSession>): result is FailedAuthResult<TUser, TSession>;
|
|
231
|
+
/**
|
|
232
|
+
* Type predicate to check if AuthResult indicates 2FA is required.
|
|
233
|
+
*
|
|
234
|
+
* @template TUser - User type
|
|
235
|
+
* @template TSession - Session type
|
|
236
|
+
* @param result - AuthResult to check
|
|
237
|
+
* @returns True if 2FA is required
|
|
238
|
+
*
|
|
239
|
+
* @example
|
|
240
|
+
* ```typescript
|
|
241
|
+
* const result = await auth.signIn.email(credentials)
|
|
242
|
+
* if (isTwoFactorRequired(result)) {
|
|
243
|
+
* // TypeScript narrows to TwoFactorAuthResult
|
|
244
|
+
* await auth.verify2FA({
|
|
245
|
+
* email: result.email, // ✅ Type-safe
|
|
246
|
+
* userId: result.userId, // ✅ Type-safe
|
|
247
|
+
* code: '123456'
|
|
248
|
+
* })
|
|
249
|
+
* }
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
252
|
+
export declare function isTwoFactorRequired<TUser extends User = User, TSession extends Session<TUser> = Session<TUser>>(result: AuthResult<TUser, TSession>): result is TwoFactorAuthResult<TUser, TSession>;
|
|
253
|
+
/**
|
|
254
|
+
* TODO: Performance
|
|
255
|
+
* - [ ] Consider using branded types for User.id to prevent ID mixing
|
|
256
|
+
* - [ ] Add type-level optimizations for discriminated unions
|
|
257
|
+
* - [ ] Implement compile-time validation for email format
|
|
258
|
+
* - [ ] Add type-level session expiration checking
|
|
259
|
+
*
|
|
260
|
+
* TODO: Features
|
|
261
|
+
* - [ ] Add conditional types for provider-specific result variants
|
|
262
|
+
* - [ ] Implement type-safe error handling with exhaustiveness checking
|
|
263
|
+
* - [ ] Create type-level validation for credentials strength
|
|
264
|
+
* - [ ] Add generic constraints for custom User/Session extensions
|
|
265
|
+
* - [ ] Implement type-safe middleware chain types
|
|
266
|
+
*
|
|
267
|
+
* TODO: Type Safety
|
|
268
|
+
* - [ ] Add branded types for sensitive data (tokens, passwords)
|
|
269
|
+
* - [ ] Create type guards for all public interfaces
|
|
270
|
+
* - [ ] Add type-level validation for registration data
|
|
271
|
+
* - [ ] Implement type-safe error codes with const assertions
|
|
272
|
+
*
|
|
273
|
+
* TODO: Testing
|
|
274
|
+
* - [ ] Add type-level tests using ts-expect
|
|
275
|
+
* - [ ] Test type inference in various scenarios
|
|
276
|
+
* - [ ] Verify type narrowing with type predicates
|
|
277
|
+
* - [ ] Test generic constraints and conditional types
|
|
278
|
+
* - [ ] Add tests for discriminated union narrowing
|
|
279
|
+
*
|
|
280
|
+
* TODO: Documentation
|
|
281
|
+
* - [ ] Add more JSDoc examples for generic types
|
|
282
|
+
* - [ ] Document type-level patterns and best practices
|
|
283
|
+
* - [ ] Create migration guide for custom User/Session types
|
|
284
|
+
*
|
|
285
|
+
* TODO: Limitations
|
|
286
|
+
* - [ ] Type inference may be limited with very deep generic chains
|
|
287
|
+
* - [ ] Branded types add minimal runtime overhead
|
|
288
|
+
* - [ ] Deep readonly types may impact performance with large objects
|
|
289
|
+
* - [ ] Discriminated unions require explicit type guards for narrowing
|
|
290
|
+
*/
|
|
@@ -1,44 +1,200 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Authentication error codes
|
|
2
|
+
* Authentication error codes and error handling types.
|
|
3
|
+
*
|
|
4
|
+
* @module @mulguard/core/types/errors
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Authentication error code enumeration.
|
|
8
|
+
*
|
|
9
|
+
* Provides specific error codes for programmatic error handling.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* if (result.errorCode === AuthErrorCode.INVALID_CREDENTIALS) {
|
|
14
|
+
* // Handle invalid credentials
|
|
15
|
+
* } else if (result.errorCode === AuthErrorCode.TWO_FA_REQUIRED) {
|
|
16
|
+
* // Handle 2FA requirement
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
3
19
|
*/
|
|
4
20
|
export declare enum AuthErrorCode {
|
|
5
|
-
/** Invalid email or password */
|
|
21
|
+
/** Invalid email or password credentials */
|
|
6
22
|
INVALID_CREDENTIALS = "INVALID_CREDENTIALS",
|
|
7
|
-
/** Account is temporarily locked */
|
|
23
|
+
/** Account is temporarily locked due to failed attempts */
|
|
8
24
|
ACCOUNT_LOCKED = "ACCOUNT_LOCKED",
|
|
9
25
|
/** Account is inactive or disabled */
|
|
10
26
|
ACCOUNT_INACTIVE = "ACCOUNT_INACTIVE",
|
|
11
|
-
/** Two-factor authentication required */
|
|
27
|
+
/** Two-factor authentication is required */
|
|
12
28
|
TWO_FA_REQUIRED = "TWO_FA_REQUIRED",
|
|
13
29
|
/** Invalid two-factor authentication code */
|
|
14
30
|
INVALID_TWO_FA_CODE = "INVALID_TWO_FA_CODE",
|
|
15
31
|
/** Session has expired */
|
|
16
32
|
SESSION_EXPIRED = "SESSION_EXPIRED",
|
|
17
|
-
/** User is not authorized */
|
|
33
|
+
/** User is not authorized for this operation */
|
|
18
34
|
UNAUTHORIZED = "UNAUTHORIZED",
|
|
19
|
-
/** Network or API error */
|
|
35
|
+
/** Network or API communication error */
|
|
20
36
|
NETWORK_ERROR = "NETWORK_ERROR",
|
|
21
|
-
/**
|
|
37
|
+
/** Input validation error */
|
|
22
38
|
VALIDATION_ERROR = "VALIDATION_ERROR",
|
|
23
39
|
/** Rate limit exceeded */
|
|
24
40
|
RATE_LIMITED = "RATE_LIMITED",
|
|
25
|
-
/** Unknown error */
|
|
41
|
+
/** Unknown or unexpected error */
|
|
26
42
|
UNKNOWN_ERROR = "UNKNOWN_ERROR"
|
|
27
43
|
}
|
|
28
44
|
/**
|
|
29
|
-
* Authentication error interface
|
|
45
|
+
* Authentication error interface.
|
|
46
|
+
*
|
|
47
|
+
* Provides structured error information with code, message, and optional metadata.
|
|
48
|
+
*
|
|
49
|
+
* @property code - Specific error code
|
|
50
|
+
* @property message - Human-readable error message
|
|
51
|
+
* @property statusCode - HTTP status code (if applicable)
|
|
52
|
+
* @property details - Additional error details (optional)
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* const error: AuthError = {
|
|
57
|
+
* code: AuthErrorCode.INVALID_CREDENTIALS,
|
|
58
|
+
* message: 'Invalid email or password',
|
|
59
|
+
* statusCode: 401
|
|
60
|
+
* }
|
|
61
|
+
* ```
|
|
30
62
|
*/
|
|
31
63
|
export interface AuthError {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
/** HTTP status code (if applicable) */
|
|
37
|
-
statusCode?: number;
|
|
38
|
-
/** Additional error details */
|
|
39
|
-
details?: unknown;
|
|
64
|
+
readonly code: AuthErrorCode;
|
|
65
|
+
readonly message: string;
|
|
66
|
+
readonly statusCode?: number;
|
|
67
|
+
readonly details?: unknown;
|
|
40
68
|
}
|
|
41
69
|
/**
|
|
42
|
-
*
|
|
70
|
+
* Error result type for failed operations.
|
|
71
|
+
*
|
|
72
|
+
* @template TCode - Error code type (defaults to AuthErrorCode)
|
|
73
|
+
*/
|
|
74
|
+
export type ErrorResult<TCode extends AuthErrorCode = AuthErrorCode> = {
|
|
75
|
+
readonly success: false;
|
|
76
|
+
readonly error: string;
|
|
77
|
+
readonly errorCode: TCode;
|
|
78
|
+
readonly details?: unknown;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Creates an authentication error object.
|
|
82
|
+
*
|
|
83
|
+
* @param code - Error code
|
|
84
|
+
* @param message - Human-readable error message
|
|
85
|
+
* @param statusCode - HTTP status code (optional)
|
|
86
|
+
* @param details - Additional error details (optional)
|
|
87
|
+
* @returns AuthError object
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```typescript
|
|
91
|
+
* const error = createAuthError(
|
|
92
|
+
* AuthErrorCode.INVALID_CREDENTIALS,
|
|
93
|
+
* 'Invalid email or password',
|
|
94
|
+
* 401
|
|
95
|
+
* )
|
|
96
|
+
* ```
|
|
43
97
|
*/
|
|
44
98
|
export declare function createAuthError(code: AuthErrorCode, message: string, statusCode?: number, details?: unknown): AuthError;
|
|
99
|
+
/**
|
|
100
|
+
* Creates an error result for failed authentication operations.
|
|
101
|
+
*
|
|
102
|
+
* @template TCode - Error code type
|
|
103
|
+
* @param code - Error code
|
|
104
|
+
* @param message - Error message
|
|
105
|
+
* @param details - Additional error details (optional)
|
|
106
|
+
* @returns ErrorResult object
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* const result = createErrorResult(
|
|
111
|
+
* AuthErrorCode.INVALID_CREDENTIALS,
|
|
112
|
+
* 'Invalid email or password'
|
|
113
|
+
* )
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
export declare function createErrorResult<TCode extends AuthErrorCode = AuthErrorCode>(code: TCode, message: string, details?: unknown): ErrorResult<TCode>;
|
|
117
|
+
/**
|
|
118
|
+
* HTTP status code mapping for error codes.
|
|
119
|
+
*
|
|
120
|
+
* Maps authentication error codes to appropriate HTTP status codes.
|
|
121
|
+
*/
|
|
122
|
+
export declare const ERROR_STATUS_MAP: Readonly<Record<AuthErrorCode, number>>;
|
|
123
|
+
/**
|
|
124
|
+
* Gets the HTTP status code for an error code.
|
|
125
|
+
*
|
|
126
|
+
* @param code - Error code
|
|
127
|
+
* @returns HTTP status code
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```typescript
|
|
131
|
+
* const statusCode = getErrorStatusCode(AuthErrorCode.INVALID_CREDENTIALS)
|
|
132
|
+
* // Returns 401
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
export declare function getErrorStatusCode(code: AuthErrorCode): number;
|
|
136
|
+
/**
|
|
137
|
+
* Type predicate to check if a value is an AuthError.
|
|
138
|
+
*
|
|
139
|
+
* @param value - Value to check
|
|
140
|
+
* @returns True if value is an AuthError
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```typescript
|
|
144
|
+
* if (isAuthError(error)) {
|
|
145
|
+
* // TypeScript knows error is AuthError here
|
|
146
|
+
* console.log(error.code, error.message)
|
|
147
|
+
* }
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
export declare function isAuthError(value: unknown): value is AuthError;
|
|
151
|
+
/**
|
|
152
|
+
* Type predicate to check if a value is an ErrorResult.
|
|
153
|
+
*
|
|
154
|
+
* @param value - Value to check
|
|
155
|
+
* @returns True if value is an ErrorResult
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```typescript
|
|
159
|
+
* if (isErrorResult(result)) {
|
|
160
|
+
* // TypeScript knows result is ErrorResult here
|
|
161
|
+
* console.log(result.errorCode, result.error)
|
|
162
|
+
* }
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
export declare function isErrorResult(value: unknown): value is ErrorResult;
|
|
166
|
+
/**
|
|
167
|
+
* TODO: Performance
|
|
168
|
+
* - [ ] Consider using const assertions for error code strings
|
|
169
|
+
* - [ ] Add type-level validation for error code mappings
|
|
170
|
+
* - [ ] Implement compile-time error code exhaustiveness checking
|
|
171
|
+
*
|
|
172
|
+
* TODO: Features
|
|
173
|
+
* - [ ] Add error recovery strategies
|
|
174
|
+
* - [ ] Implement error code hierarchies/categories
|
|
175
|
+
* - [ ] Add localized error messages support
|
|
176
|
+
* - [ ] Create error code to user-friendly message mapping
|
|
177
|
+
* - [ ] Add error code metadata (retryable, transient, etc.)
|
|
178
|
+
*
|
|
179
|
+
* TODO: Type Safety
|
|
180
|
+
* - [ ] Add branded types for error codes
|
|
181
|
+
* - [ ] Implement type-safe error code unions
|
|
182
|
+
* - [ ] Add exhaustiveness checking for error handling
|
|
183
|
+
* - [ ] Create type-safe error code validation
|
|
184
|
+
*
|
|
185
|
+
* TODO: Testing
|
|
186
|
+
* - [ ] Add tests for error code mappings
|
|
187
|
+
* - [ ] Test type guards with various inputs
|
|
188
|
+
* - [ ] Verify error result type narrowing
|
|
189
|
+
* - [ ] Test error factory functions
|
|
190
|
+
*
|
|
191
|
+
* TODO: Documentation
|
|
192
|
+
* - [ ] Add examples for each error code
|
|
193
|
+
* - [ ] Document error handling best practices
|
|
194
|
+
* - [ ] Create error code reference guide
|
|
195
|
+
*
|
|
196
|
+
* TODO: Limitations
|
|
197
|
+
* - [ ] Error code enum may need extension for custom errors
|
|
198
|
+
* - [ ] Status code mapping is fixed (consider configurable)
|
|
199
|
+
* - [ ] Error details type is unknown (consider generic)
|
|
200
|
+
*/
|