@spfn/auth 0.2.0-beta.26 → 0.2.0-beta.28

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/README.md CHANGED
@@ -1044,6 +1044,44 @@ Change password.
1044
1044
 
1045
1045
  ---
1046
1046
 
1047
+ #### `GET /_auth/users/username/check`
1048
+
1049
+ Check if a username is available.
1050
+
1051
+ **Query:**
1052
+ ```typescript
1053
+ {
1054
+ username: string; // Min 1 char
1055
+ }
1056
+ ```
1057
+
1058
+ **Response:**
1059
+ ```typescript
1060
+ {
1061
+ available: boolean;
1062
+ }
1063
+ ```
1064
+
1065
+ ---
1066
+
1067
+ #### `PATCH /_auth/users/username`
1068
+
1069
+ Update authenticated user's username. Validates uniqueness before updating.
1070
+
1071
+ **Request:**
1072
+ ```typescript
1073
+ {
1074
+ username: string | null; // New username or null to clear
1075
+ }
1076
+ ```
1077
+
1078
+ **Response:** Updated user object.
1079
+
1080
+ **Errors:**
1081
+ - `409 UsernameAlreadyTakenError` - Username is already in use by another user
1082
+
1083
+ ---
1084
+
1047
1085
  ## Events
1048
1086
 
1049
1087
  `@spfn/auth`는 `@spfn/core/event`를 사용하여 인증 관련 이벤트를 발행합니다. 이를 통해 로그인/회원가입 시 추가 로직(환영 이메일, 분석, 알림 등)을 디커플링된 방식으로 처리할 수 있습니다.
@@ -1488,6 +1526,7 @@ CREATE TABLE users (
1488
1526
  id BIGSERIAL PRIMARY KEY,
1489
1527
  email TEXT UNIQUE,
1490
1528
  phone TEXT UNIQUE,
1529
+ username TEXT UNIQUE,
1491
1530
  password_hash TEXT NOT NULL,
1492
1531
  password_change_required BOOLEAN DEFAULT false,
1493
1532
  role_id BIGINT REFERENCES roles(id) NOT NULL,
@@ -1506,6 +1545,7 @@ CREATE TABLE users (
1506
1545
 
1507
1546
  **Key Points:**
1508
1547
  - At least one of `email` OR `phone` required
1548
+ - `username` is unique and nullable (optional display/mention identifier)
1509
1549
  - `passwordHash` is bcrypt ($2b$10$..., 60 chars)
1510
1550
  - `roleId` references roles table (NOT NULL)
1511
1551
 
package/dist/errors.d.ts CHANGED
@@ -132,6 +132,18 @@ declare class VerificationTokenTargetMismatchError extends ValidationError {
132
132
  details?: Record<string, any>;
133
133
  });
134
134
  }
135
+ /**
136
+ * Username Already Taken Error (409)
137
+ *
138
+ * Thrown when trying to set a username that is already in use
139
+ */
140
+ declare class UsernameAlreadyTakenError extends ConflictError {
141
+ constructor(data?: {
142
+ username?: string;
143
+ message?: string;
144
+ details?: Record<string, any>;
145
+ });
146
+ }
135
147
  /**
136
148
  * Insufficient Permissions Error (403)
137
149
  *
@@ -179,12 +191,14 @@ type authErrors_KeyExpiredError = KeyExpiredError;
179
191
  declare const authErrors_KeyExpiredError: typeof KeyExpiredError;
180
192
  type authErrors_TokenExpiredError = TokenExpiredError;
181
193
  declare const authErrors_TokenExpiredError: typeof TokenExpiredError;
194
+ type authErrors_UsernameAlreadyTakenError = UsernameAlreadyTakenError;
195
+ declare const authErrors_UsernameAlreadyTakenError: typeof UsernameAlreadyTakenError;
182
196
  type authErrors_VerificationTokenPurposeMismatchError = VerificationTokenPurposeMismatchError;
183
197
  declare const authErrors_VerificationTokenPurposeMismatchError: typeof VerificationTokenPurposeMismatchError;
184
198
  type authErrors_VerificationTokenTargetMismatchError = VerificationTokenTargetMismatchError;
185
199
  declare const authErrors_VerificationTokenTargetMismatchError: typeof VerificationTokenTargetMismatchError;
186
200
  declare namespace authErrors {
187
- export { authErrors_AccountAlreadyExistsError as AccountAlreadyExistsError, authErrors_AccountDisabledError as AccountDisabledError, authErrors_InsufficientPermissionsError as InsufficientPermissionsError, authErrors_InsufficientRoleError as InsufficientRoleError, authErrors_InvalidCredentialsError as InvalidCredentialsError, authErrors_InvalidKeyFingerprintError as InvalidKeyFingerprintError, authErrors_InvalidTokenError as InvalidTokenError, authErrors_InvalidVerificationCodeError as InvalidVerificationCodeError, authErrors_InvalidVerificationTokenError as InvalidVerificationTokenError, authErrors_KeyExpiredError as KeyExpiredError, authErrors_TokenExpiredError as TokenExpiredError, authErrors_VerificationTokenPurposeMismatchError as VerificationTokenPurposeMismatchError, authErrors_VerificationTokenTargetMismatchError as VerificationTokenTargetMismatchError };
201
+ export { authErrors_AccountAlreadyExistsError as AccountAlreadyExistsError, authErrors_AccountDisabledError as AccountDisabledError, authErrors_InsufficientPermissionsError as InsufficientPermissionsError, authErrors_InsufficientRoleError as InsufficientRoleError, authErrors_InvalidCredentialsError as InvalidCredentialsError, authErrors_InvalidKeyFingerprintError as InvalidKeyFingerprintError, authErrors_InvalidTokenError as InvalidTokenError, authErrors_InvalidVerificationCodeError as InvalidVerificationCodeError, authErrors_InvalidVerificationTokenError as InvalidVerificationTokenError, authErrors_KeyExpiredError as KeyExpiredError, authErrors_TokenExpiredError as TokenExpiredError, authErrors_UsernameAlreadyTakenError as UsernameAlreadyTakenError, authErrors_VerificationTokenPurposeMismatchError as VerificationTokenPurposeMismatchError, authErrors_VerificationTokenTargetMismatchError as VerificationTokenTargetMismatchError };
188
202
  }
189
203
 
190
204
  /**
@@ -193,4 +207,4 @@ declare namespace authErrors {
193
207
 
194
208
  declare const authErrorRegistry: ErrorRegistry;
195
209
 
196
- export { AccountAlreadyExistsError, AccountDisabledError, authErrors as AuthError, InsufficientPermissionsError, InsufficientRoleError, InvalidCredentialsError, InvalidKeyFingerprintError, InvalidTokenError, InvalidVerificationCodeError, InvalidVerificationTokenError, KeyExpiredError, TokenExpiredError, VerificationTokenPurposeMismatchError, VerificationTokenTargetMismatchError, authErrorRegistry };
210
+ export { AccountAlreadyExistsError, AccountDisabledError, authErrors as AuthError, InsufficientPermissionsError, InsufficientRoleError, InvalidCredentialsError, InvalidKeyFingerprintError, InvalidTokenError, InvalidVerificationCodeError, InvalidVerificationTokenError, KeyExpiredError, TokenExpiredError, UsernameAlreadyTakenError, VerificationTokenPurposeMismatchError, VerificationTokenTargetMismatchError, authErrorRegistry };
package/dist/errors.js CHANGED
@@ -21,6 +21,7 @@ __export(auth_errors_exports, {
21
21
  InvalidVerificationTokenError: () => InvalidVerificationTokenError,
22
22
  KeyExpiredError: () => KeyExpiredError,
23
23
  TokenExpiredError: () => TokenExpiredError,
24
+ UsernameAlreadyTakenError: () => UsernameAlreadyTakenError,
24
25
  VerificationTokenPurposeMismatchError: () => VerificationTokenPurposeMismatchError,
25
26
  VerificationTokenTargetMismatchError: () => VerificationTokenTargetMismatchError
26
27
  });
@@ -115,6 +116,15 @@ var VerificationTokenTargetMismatchError = class extends ValidationError {
115
116
  this.name = "VerificationTokenTargetMismatchError";
116
117
  }
117
118
  };
119
+ var UsernameAlreadyTakenError = class extends ConflictError {
120
+ constructor(data = {}) {
121
+ super({
122
+ message: data.message || "Username is already taken",
123
+ details: { username: data.username, ...data.details }
124
+ });
125
+ this.name = "UsernameAlreadyTakenError";
126
+ }
127
+ };
118
128
  var InsufficientPermissionsError = class extends ForbiddenError {
119
129
  constructor(data = {}) {
120
130
  const requiredPermissions = data.requiredPermissions || [];
@@ -145,6 +155,7 @@ authErrorRegistry.append([
145
155
  KeyExpiredError,
146
156
  AccountDisabledError,
147
157
  AccountAlreadyExistsError,
158
+ UsernameAlreadyTakenError,
148
159
  InvalidVerificationCodeError,
149
160
  InvalidVerificationTokenError,
150
161
  InvalidKeyFingerprintError,
@@ -166,6 +177,7 @@ export {
166
177
  InvalidVerificationTokenError,
167
178
  KeyExpiredError,
168
179
  TokenExpiredError,
180
+ UsernameAlreadyTakenError,
169
181
  VerificationTokenPurposeMismatchError,
170
182
  VerificationTokenTargetMismatchError,
171
183
  authErrorRegistry
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors/index.ts","../src/errors/auth-errors.ts"],"sourcesContent":["/**\n * Auth Error Exports\n */\n\nimport { ErrorRegistry } from \"@spfn/core/errors\";\n\nimport {\n InvalidCredentialsError,\n InvalidTokenError,\n TokenExpiredError,\n KeyExpiredError,\n AccountDisabledError,\n AccountAlreadyExistsError,\n InvalidVerificationCodeError,\n InvalidVerificationTokenError,\n InvalidKeyFingerprintError,\n VerificationTokenPurposeMismatchError,\n VerificationTokenTargetMismatchError,\n InsufficientPermissionsError,\n InsufficientRoleError,\n} from './auth-errors';\n\nexport {\n InvalidCredentialsError,\n InvalidTokenError,\n TokenExpiredError,\n KeyExpiredError,\n AccountDisabledError,\n AccountAlreadyExistsError,\n InvalidVerificationCodeError,\n InvalidVerificationTokenError,\n InvalidKeyFingerprintError,\n VerificationTokenPurposeMismatchError,\n VerificationTokenTargetMismatchError,\n InsufficientPermissionsError,\n InsufficientRoleError,\n} from './auth-errors';\n\nexport const authErrorRegistry = new ErrorRegistry();\nauthErrorRegistry.append([\n InvalidCredentialsError,\n InvalidTokenError,\n TokenExpiredError,\n KeyExpiredError,\n AccountDisabledError,\n AccountAlreadyExistsError,\n InvalidVerificationCodeError,\n InvalidVerificationTokenError,\n InvalidKeyFingerprintError,\n VerificationTokenPurposeMismatchError,\n VerificationTokenTargetMismatchError,\n InsufficientPermissionsError,\n InsufficientRoleError,\n]);\n\nexport * as AuthError from './auth-errors';","/**\n * Authentication & Authorization Error Classes\n *\n * Custom error classes for auth-specific scenarios\n */\n\nimport {\n ValidationError,\n UnauthorizedError,\n ForbiddenError,\n ConflictError\n} from '@spfn/core/errors';\n\n/**\n * Invalid Credentials Error (401)\n *\n * Thrown when login credentials are incorrect\n */\nexport class InvalidCredentialsError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid credentials', details: data.details });\n this.name = 'InvalidCredentialsError';\n }\n}\n\n/**\n * Invalid Token Error (401)\n *\n * Thrown when authentication token is invalid or malformed\n */\nexport class InvalidTokenError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid authentication token', details: data.details });\n this.name = 'InvalidTokenError';\n }\n}\n\n/**\n * Token Expired Error (401)\n *\n * Thrown when authentication token has expired\n */\nexport class TokenExpiredError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Authentication token has expired', details: data.details });\n this.name = 'TokenExpiredError';\n }\n}\n\n/**\n * Key Expired Error (401)\n *\n * Thrown when public key has expired\n */\nexport class KeyExpiredError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Public key has expired', details: data.details });\n this.name = 'KeyExpiredError';\n }\n}\n\n/**\n * Account Disabled Error (403)\n *\n * Thrown when user account is disabled or inactive\n */\nexport class AccountDisabledError extends ForbiddenError\n{\n constructor(data: { status?: string; message?: string; details?: Record<string, any> } = {})\n {\n const status = data.status || 'disabled';\n super({\n message: data.message || `Account is ${status}`,\n details: { status, ...data.details }\n });\n this.name = 'AccountDisabledError';\n }\n}\n\n/**\n * Account Already Exists Error (409)\n *\n * Thrown when trying to register with existing email/phone\n */\nexport class AccountAlreadyExistsError extends ConflictError\n{\n constructor(data: { identifier?: string; identifierType?: 'email' | 'phone'; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Account already exists',\n details: {\n identifier: data.identifier,\n identifierType: data.identifierType,\n ...data.details\n }\n });\n this.name = 'AccountAlreadyExistsError';\n }\n}\n\n/**\n * Invalid Verification Code Error (400)\n *\n * Thrown when verification code is invalid, expired, or already used\n */\nexport class InvalidVerificationCodeError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid verification code', details: data.details });\n this.name = 'InvalidVerificationCodeError';\n }\n}\n\n/**\n * Invalid Verification Token Error (400)\n *\n * Thrown when verification token is invalid or expired\n */\nexport class InvalidVerificationTokenError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid or expired verification token', details: data.details });\n this.name = 'InvalidVerificationTokenError';\n }\n}\n\n/**\n * Invalid Key Fingerprint Error (400)\n *\n * Thrown when public key fingerprint doesn't match the public key\n */\nexport class InvalidKeyFingerprintError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid key fingerprint', details: data.details });\n this.name = 'InvalidKeyFingerprintError';\n }\n}\n\n/**\n * Verification Token Purpose Mismatch Error (400)\n *\n * Thrown when verification token purpose doesn't match expected purpose\n */\nexport class VerificationTokenPurposeMismatchError extends ValidationError\n{\n constructor(data: { expected?: string; actual?: string; message?: string; details?: Record<string, any> } = {})\n {\n const expected = data.expected || 'unknown';\n const actual = data.actual || 'unknown';\n super({\n message: data.message || `Verification token is for ${actual}, but ${expected} was expected`,\n details: { expected, actual, ...data.details }\n });\n this.name = 'VerificationTokenPurposeMismatchError';\n }\n}\n\n/**\n * Verification Token Target Mismatch Error (400)\n *\n * Thrown when verification token target doesn't match provided email/phone\n */\nexport class VerificationTokenTargetMismatchError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Verification token does not match provided email/phone',\n details: data.details\n });\n this.name = 'VerificationTokenTargetMismatchError';\n }\n}\n\n/**\n * Insufficient Permissions Error (403)\n *\n * Thrown when user lacks required permissions for the operation\n */\nexport class InsufficientPermissionsError extends ForbiddenError\n{\n constructor(data: { requiredPermissions?: string[]; message?: string; details?: Record<string, any> } = {})\n {\n const requiredPermissions = data.requiredPermissions || [];\n super({\n message: data.message || `Missing required permissions: ${requiredPermissions.join(', ')}`,\n details: { requiredPermissions, ...data.details }\n });\n this.name = 'InsufficientPermissionsError';\n }\n}\n\n/**\n * Insufficient Role Error (403)\n *\n * Thrown when user lacks required role for the operation\n */\nexport class InsufficientRoleError extends ForbiddenError\n{\n constructor(data: { requiredRoles?: string[]; message?: string; details?: Record<string, any> } = {})\n {\n const requiredRoles = data.requiredRoles || [];\n super({\n message: data.message || `Required roles: ${requiredRoles.join(', ')}`,\n details: { requiredRoles, ...data.details }\n });\n this.name = 'InsufficientRoleError';\n }\n}"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/errors/index.ts","../src/errors/auth-errors.ts"],"sourcesContent":["/**\n * Auth Error Exports\n */\n\nimport { ErrorRegistry } from \"@spfn/core/errors\";\n\nimport {\n InvalidCredentialsError,\n InvalidTokenError,\n TokenExpiredError,\n KeyExpiredError,\n AccountDisabledError,\n AccountAlreadyExistsError,\n UsernameAlreadyTakenError,\n InvalidVerificationCodeError,\n InvalidVerificationTokenError,\n InvalidKeyFingerprintError,\n VerificationTokenPurposeMismatchError,\n VerificationTokenTargetMismatchError,\n InsufficientPermissionsError,\n InsufficientRoleError,\n} from './auth-errors';\n\nexport {\n InvalidCredentialsError,\n InvalidTokenError,\n TokenExpiredError,\n KeyExpiredError,\n AccountDisabledError,\n AccountAlreadyExistsError,\n UsernameAlreadyTakenError,\n InvalidVerificationCodeError,\n InvalidVerificationTokenError,\n InvalidKeyFingerprintError,\n VerificationTokenPurposeMismatchError,\n VerificationTokenTargetMismatchError,\n InsufficientPermissionsError,\n InsufficientRoleError,\n} from './auth-errors';\n\nexport const authErrorRegistry = new ErrorRegistry();\nauthErrorRegistry.append([\n InvalidCredentialsError,\n InvalidTokenError,\n TokenExpiredError,\n KeyExpiredError,\n AccountDisabledError,\n AccountAlreadyExistsError,\n UsernameAlreadyTakenError,\n InvalidVerificationCodeError,\n InvalidVerificationTokenError,\n InvalidKeyFingerprintError,\n VerificationTokenPurposeMismatchError,\n VerificationTokenTargetMismatchError,\n InsufficientPermissionsError,\n InsufficientRoleError,\n]);\n\nexport * as AuthError from './auth-errors';","/**\n * Authentication & Authorization Error Classes\n *\n * Custom error classes for auth-specific scenarios\n */\n\nimport {\n ValidationError,\n UnauthorizedError,\n ForbiddenError,\n ConflictError\n} from '@spfn/core/errors';\n\n/**\n * Invalid Credentials Error (401)\n *\n * Thrown when login credentials are incorrect\n */\nexport class InvalidCredentialsError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid credentials', details: data.details });\n this.name = 'InvalidCredentialsError';\n }\n}\n\n/**\n * Invalid Token Error (401)\n *\n * Thrown when authentication token is invalid or malformed\n */\nexport class InvalidTokenError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid authentication token', details: data.details });\n this.name = 'InvalidTokenError';\n }\n}\n\n/**\n * Token Expired Error (401)\n *\n * Thrown when authentication token has expired\n */\nexport class TokenExpiredError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Authentication token has expired', details: data.details });\n this.name = 'TokenExpiredError';\n }\n}\n\n/**\n * Key Expired Error (401)\n *\n * Thrown when public key has expired\n */\nexport class KeyExpiredError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Public key has expired', details: data.details });\n this.name = 'KeyExpiredError';\n }\n}\n\n/**\n * Account Disabled Error (403)\n *\n * Thrown when user account is disabled or inactive\n */\nexport class AccountDisabledError extends ForbiddenError\n{\n constructor(data: { status?: string; message?: string; details?: Record<string, any> } = {})\n {\n const status = data.status || 'disabled';\n super({\n message: data.message || `Account is ${status}`,\n details: { status, ...data.details }\n });\n this.name = 'AccountDisabledError';\n }\n}\n\n/**\n * Account Already Exists Error (409)\n *\n * Thrown when trying to register with existing email/phone\n */\nexport class AccountAlreadyExistsError extends ConflictError\n{\n constructor(data: { identifier?: string; identifierType?: 'email' | 'phone'; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Account already exists',\n details: {\n identifier: data.identifier,\n identifierType: data.identifierType,\n ...data.details\n }\n });\n this.name = 'AccountAlreadyExistsError';\n }\n}\n\n/**\n * Invalid Verification Code Error (400)\n *\n * Thrown when verification code is invalid, expired, or already used\n */\nexport class InvalidVerificationCodeError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid verification code', details: data.details });\n this.name = 'InvalidVerificationCodeError';\n }\n}\n\n/**\n * Invalid Verification Token Error (400)\n *\n * Thrown when verification token is invalid or expired\n */\nexport class InvalidVerificationTokenError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid or expired verification token', details: data.details });\n this.name = 'InvalidVerificationTokenError';\n }\n}\n\n/**\n * Invalid Key Fingerprint Error (400)\n *\n * Thrown when public key fingerprint doesn't match the public key\n */\nexport class InvalidKeyFingerprintError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid key fingerprint', details: data.details });\n this.name = 'InvalidKeyFingerprintError';\n }\n}\n\n/**\n * Verification Token Purpose Mismatch Error (400)\n *\n * Thrown when verification token purpose doesn't match expected purpose\n */\nexport class VerificationTokenPurposeMismatchError extends ValidationError\n{\n constructor(data: { expected?: string; actual?: string; message?: string; details?: Record<string, any> } = {})\n {\n const expected = data.expected || 'unknown';\n const actual = data.actual || 'unknown';\n super({\n message: data.message || `Verification token is for ${actual}, but ${expected} was expected`,\n details: { expected, actual, ...data.details }\n });\n this.name = 'VerificationTokenPurposeMismatchError';\n }\n}\n\n/**\n * Verification Token Target Mismatch Error (400)\n *\n * Thrown when verification token target doesn't match provided email/phone\n */\nexport class VerificationTokenTargetMismatchError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Verification token does not match provided email/phone',\n details: data.details\n });\n this.name = 'VerificationTokenTargetMismatchError';\n }\n}\n\n/**\n * Username Already Taken Error (409)\n *\n * Thrown when trying to set a username that is already in use\n */\nexport class UsernameAlreadyTakenError extends ConflictError\n{\n constructor(data: { username?: string; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Username is already taken',\n details: { username: data.username, ...data.details }\n });\n this.name = 'UsernameAlreadyTakenError';\n }\n}\n\n/**\n * Insufficient Permissions Error (403)\n *\n * Thrown when user lacks required permissions for the operation\n */\nexport class InsufficientPermissionsError extends ForbiddenError\n{\n constructor(data: { requiredPermissions?: string[]; message?: string; details?: Record<string, any> } = {})\n {\n const requiredPermissions = data.requiredPermissions || [];\n super({\n message: data.message || `Missing required permissions: ${requiredPermissions.join(', ')}`,\n details: { requiredPermissions, ...data.details }\n });\n this.name = 'InsufficientPermissionsError';\n }\n}\n\n/**\n * Insufficient Role Error (403)\n *\n * Thrown when user lacks required role for the operation\n */\nexport class InsufficientRoleError extends ForbiddenError\n{\n constructor(data: { requiredRoles?: string[]; message?: string; details?: Record<string, any> } = {})\n {\n const requiredRoles = data.requiredRoles || [];\n super({\n message: data.message || `Required roles: ${requiredRoles.join(', ')}`,\n details: { requiredRoles, ...data.details }\n });\n this.name = 'InsufficientRoleError';\n }\n}"],"mappings":"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","names":[]}
package/dist/index.js CHANGED
@@ -102,6 +102,15 @@ var VerificationTokenTargetMismatchError = class extends ValidationError {
102
102
  this.name = "VerificationTokenTargetMismatchError";
103
103
  }
104
104
  };
105
+ var UsernameAlreadyTakenError = class extends ConflictError {
106
+ constructor(data = {}) {
107
+ super({
108
+ message: data.message || "Username is already taken",
109
+ details: { username: data.username, ...data.details }
110
+ });
111
+ this.name = "UsernameAlreadyTakenError";
112
+ }
113
+ };
105
114
  var InsufficientPermissionsError = class extends ForbiddenError {
106
115
  constructor(data = {}) {
107
116
  const requiredPermissions = data.requiredPermissions || [];
@@ -132,6 +141,7 @@ authErrorRegistry.append([
132
141
  KeyExpiredError,
133
142
  AccountDisabledError,
134
143
  AccountAlreadyExistsError,
144
+ UsernameAlreadyTakenError,
135
145
  InvalidVerificationCodeError,
136
146
  InvalidVerificationTokenError,
137
147
  InvalidKeyFingerprintError,