vaultwarden.js 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/dist/chunk-34VL7JLT.js +406 -0
- package/dist/chunk-34VL7JLT.js.map +1 -0
- package/dist/chunk-P3KALNLE.js +265 -0
- package/dist/chunk-P3KALNLE.js.map +1 -0
- package/dist/chunk-SM355NU6.js +233 -0
- package/dist/chunk-SM355NU6.js.map +1 -0
- package/dist/crypto-BWGLRXUT.js +38 -0
- package/dist/crypto-BWGLRXUT.js.map +1 -0
- package/dist/encryption-IJ5MC47T.js +24 -0
- package/dist/encryption-IJ5MC47T.js.map +1 -0
- package/dist/index.cjs +4870 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2527 -0
- package/dist/index.d.ts +2527 -0
- package/dist/index.js +3894 -0
- package/dist/index.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
A modern, type-safe, object-oriented TypeScript SDK for Vaultwarden/Bitwarden servers. Inspired by [discord.js](https://discord.js.org/) with a focus on developer experience and comprehensive type safety.
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/vaultwarden.js)
|
|
6
6
|
[](https://www.typescriptlang.org/)
|
|
7
|
-
[](LICENSE)
|
|
8
8
|
|
|
9
9
|
## Features
|
|
10
10
|
|
|
@@ -19,13 +19,13 @@ A modern, type-safe, object-oriented TypeScript SDK for Vaultwarden/Bitwarden se
|
|
|
19
19
|
## Installation
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
npm install vaultwarden
|
|
22
|
+
npm install vaultwarden.
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
## Quick Start
|
|
26
26
|
|
|
27
27
|
```typescript
|
|
28
|
-
import { VaultwardenClient } from 'vaultwarden
|
|
28
|
+
import { VaultwardenClient } from 'vaultwarden.js';
|
|
29
29
|
|
|
30
30
|
const client = new VaultwardenClient({
|
|
31
31
|
baseUrl: 'https://vault.example.com',
|
|
@@ -259,7 +259,7 @@ const trash = client.ciphers.trash;
|
|
|
259
259
|
## Password Generation
|
|
260
260
|
git remote add origin https://github.com/MarkIt-host/VaultWarden.js.git
|
|
261
261
|
```typescript
|
|
262
|
-
import { generatePassword, generatePassphrase } from 'vaultwarden
|
|
262
|
+
import { generatePassword, generatePassphrase } from 'vaultwarden.js';
|
|
263
263
|
|
|
264
264
|
// Generate strong password
|
|
265
265
|
const { password, entropy } = generatePassword({
|
|
@@ -337,7 +337,7 @@ import {
|
|
|
337
337
|
AuthenticationError,
|
|
338
338
|
NotFoundError,
|
|
339
339
|
RateLimitError,
|
|
340
|
-
} from 'vaultwarden
|
|
340
|
+
} from 'vaultwarden.js';
|
|
341
341
|
|
|
342
342
|
try {
|
|
343
343
|
await client.login({ username, password });
|
|
@@ -375,7 +375,7 @@ const client = new VaultwardenClient({
|
|
|
375
375
|
baseUrl: 'https://vault.example.com',
|
|
376
376
|
|
|
377
377
|
// Optional
|
|
378
|
-
deviceName: 'MyApp', // Default: 'vaultwarden
|
|
378
|
+
deviceName: 'MyApp', // Default: 'vaultwarden.js'
|
|
379
379
|
deviceType: 8, // Default: 8 (Windows Desktop)
|
|
380
380
|
timeout: 30000, // Request timeout in ms
|
|
381
381
|
maxRetries: 3, // Max retry attempts
|
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
// src/errors/index.ts
|
|
2
|
+
var VaultwardenError = class _VaultwardenError extends Error {
|
|
3
|
+
/** Error code for programmatic handling */
|
|
4
|
+
code;
|
|
5
|
+
/** HTTP status code if applicable */
|
|
6
|
+
statusCode;
|
|
7
|
+
/** Additional error context */
|
|
8
|
+
context;
|
|
9
|
+
constructor(message, code, statusCode, context) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.name = "VaultwardenError";
|
|
12
|
+
this.code = code;
|
|
13
|
+
this.statusCode = statusCode;
|
|
14
|
+
this.context = context;
|
|
15
|
+
Object.setPrototypeOf(this, _VaultwardenError.prototype);
|
|
16
|
+
if (Error.captureStackTrace) {
|
|
17
|
+
Error.captureStackTrace(this, this.constructor);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Convert error to JSON representation
|
|
22
|
+
*/
|
|
23
|
+
toJSON() {
|
|
24
|
+
return {
|
|
25
|
+
name: this.name,
|
|
26
|
+
message: this.message,
|
|
27
|
+
code: this.code,
|
|
28
|
+
statusCode: this.statusCode,
|
|
29
|
+
context: this.context,
|
|
30
|
+
stack: this.stack
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
var AuthenticationError = class _AuthenticationError extends VaultwardenError {
|
|
35
|
+
constructor(message = "Authentication failed", code = "AUTH_FAILED", context) {
|
|
36
|
+
super(message, code, 401, context);
|
|
37
|
+
this.name = "AuthenticationError";
|
|
38
|
+
Object.setPrototypeOf(this, _AuthenticationError.prototype);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Create error for invalid credentials
|
|
42
|
+
*/
|
|
43
|
+
static invalidCredentials() {
|
|
44
|
+
return new _AuthenticationError(
|
|
45
|
+
"Invalid username or password",
|
|
46
|
+
"INVALID_CREDENTIALS"
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Create error for missing 2FA
|
|
51
|
+
*/
|
|
52
|
+
static twoFactorRequired(method) {
|
|
53
|
+
return new _AuthenticationError(
|
|
54
|
+
"Two-factor authentication required",
|
|
55
|
+
"2FA_REQUIRED",
|
|
56
|
+
{ method }
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Create error for invalid 2FA code
|
|
61
|
+
*/
|
|
62
|
+
static invalidTwoFactorCode() {
|
|
63
|
+
return new _AuthenticationError(
|
|
64
|
+
"Invalid two-factor authentication code",
|
|
65
|
+
"INVALID_2FA_CODE"
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Create error for expired session
|
|
70
|
+
*/
|
|
71
|
+
static sessionExpired() {
|
|
72
|
+
return new _AuthenticationError(
|
|
73
|
+
"Session has expired, please log in again",
|
|
74
|
+
"SESSION_EXPIRED"
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
var APIError = class _APIError extends VaultwardenError {
|
|
79
|
+
/** Response body if available */
|
|
80
|
+
responseBody;
|
|
81
|
+
/** Request endpoint */
|
|
82
|
+
endpoint;
|
|
83
|
+
/** Request method */
|
|
84
|
+
method;
|
|
85
|
+
constructor(message, statusCode, code = "API_ERROR", context) {
|
|
86
|
+
super(message, code, statusCode, context);
|
|
87
|
+
this.name = "APIError";
|
|
88
|
+
this.responseBody = context?.responseBody;
|
|
89
|
+
this.endpoint = context?.endpoint;
|
|
90
|
+
this.method = context?.method;
|
|
91
|
+
Object.setPrototypeOf(this, _APIError.prototype);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Create error from HTTP response
|
|
95
|
+
*/
|
|
96
|
+
static fromResponse(response, endpoint, method, body) {
|
|
97
|
+
const messages = {
|
|
98
|
+
400: "Bad request",
|
|
99
|
+
401: "Unauthorized",
|
|
100
|
+
403: "Forbidden",
|
|
101
|
+
404: "Not found",
|
|
102
|
+
405: "Method not allowed",
|
|
103
|
+
409: "Conflict",
|
|
104
|
+
429: "Rate limited",
|
|
105
|
+
500: "Internal server error",
|
|
106
|
+
502: "Bad gateway",
|
|
107
|
+
503: "Service unavailable"
|
|
108
|
+
};
|
|
109
|
+
const message = messages[response.status] ?? `HTTP ${response.status} error`;
|
|
110
|
+
const code = `HTTP_${response.status}`;
|
|
111
|
+
return new _APIError(message, response.status, code, {
|
|
112
|
+
endpoint,
|
|
113
|
+
method,
|
|
114
|
+
responseBody: body,
|
|
115
|
+
statusText: response.statusText
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Check if error is a rate limit error
|
|
120
|
+
*/
|
|
121
|
+
get isRateLimit() {
|
|
122
|
+
return this.statusCode === 429;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Check if error is a server error (5xx)
|
|
126
|
+
*/
|
|
127
|
+
get isServerError() {
|
|
128
|
+
return this.statusCode !== void 0 && this.statusCode >= 500;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Check if error is a client error (4xx)
|
|
132
|
+
*/
|
|
133
|
+
get isClientError() {
|
|
134
|
+
return this.statusCode !== void 0 && this.statusCode >= 400 && this.statusCode < 500;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Check if request should be retried
|
|
138
|
+
*/
|
|
139
|
+
get shouldRetry() {
|
|
140
|
+
if (this.statusCode === void 0) return true;
|
|
141
|
+
return this.isRateLimit || this.isServerError || [408, 409, 422].includes(this.statusCode);
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
var ValidationError = class _ValidationError extends VaultwardenError {
|
|
145
|
+
/** Field that failed validation */
|
|
146
|
+
field;
|
|
147
|
+
/** Validation constraints that failed */
|
|
148
|
+
constraints;
|
|
149
|
+
constructor(message, field, constraints) {
|
|
150
|
+
super(message, "VALIDATION_ERROR", void 0, { field, constraints });
|
|
151
|
+
this.name = "ValidationError";
|
|
152
|
+
this.field = field;
|
|
153
|
+
this.constraints = constraints;
|
|
154
|
+
Object.setPrototypeOf(this, _ValidationError.prototype);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Create error for missing required field
|
|
158
|
+
*/
|
|
159
|
+
static requiredField(field) {
|
|
160
|
+
return new _ValidationError(
|
|
161
|
+
`Field '${field}' is required`,
|
|
162
|
+
field,
|
|
163
|
+
["required"]
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Create error for invalid field value
|
|
168
|
+
*/
|
|
169
|
+
static invalidValue(field, expectedType) {
|
|
170
|
+
return new _ValidationError(
|
|
171
|
+
`Field '${field}' must be ${expectedType}`,
|
|
172
|
+
field,
|
|
173
|
+
[`type:${expectedType}`]
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Create error for empty value
|
|
178
|
+
*/
|
|
179
|
+
static notEmpty(field) {
|
|
180
|
+
return new _ValidationError(
|
|
181
|
+
`Field '${field}' cannot be empty`,
|
|
182
|
+
field,
|
|
183
|
+
["notEmpty"]
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Create error for invalid URL
|
|
188
|
+
*/
|
|
189
|
+
static invalidUrl(field) {
|
|
190
|
+
return new _ValidationError(
|
|
191
|
+
`Field '${field}' must be a valid URL`,
|
|
192
|
+
field,
|
|
193
|
+
["url"]
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Create error for invalid email
|
|
198
|
+
*/
|
|
199
|
+
static invalidEmail(field) {
|
|
200
|
+
return new _ValidationError(
|
|
201
|
+
`Field '${field}' must be a valid email address`,
|
|
202
|
+
field,
|
|
203
|
+
["email"]
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
var PermissionError = class _PermissionError extends VaultwardenError {
|
|
208
|
+
/** Required permission */
|
|
209
|
+
requiredPermission;
|
|
210
|
+
/** Resource being accessed */
|
|
211
|
+
resource;
|
|
212
|
+
constructor(message = "Permission denied", code = "PERMISSION_DENIED", context) {
|
|
213
|
+
super(message, code, 403, context);
|
|
214
|
+
this.name = "PermissionError";
|
|
215
|
+
this.requiredPermission = context?.requiredPermission;
|
|
216
|
+
this.resource = context?.resource;
|
|
217
|
+
Object.setPrototypeOf(this, _PermissionError.prototype);
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Create error for insufficient permissions
|
|
221
|
+
*/
|
|
222
|
+
static insufficientPermission(requiredPermission, resource) {
|
|
223
|
+
return new _PermissionError(
|
|
224
|
+
`Insufficient permissions: ${requiredPermission} required`,
|
|
225
|
+
"INSUFFICIENT_PERMISSION",
|
|
226
|
+
{ requiredPermission, resource }
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Create error for organization access denied
|
|
231
|
+
*/
|
|
232
|
+
static organizationAccessDenied(orgId) {
|
|
233
|
+
return new _PermissionError(
|
|
234
|
+
"Access denied to organization",
|
|
235
|
+
"ORG_ACCESS_DENIED",
|
|
236
|
+
{ organizationId: orgId }
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Create error for collection access denied
|
|
241
|
+
*/
|
|
242
|
+
static collectionAccessDenied(collectionId) {
|
|
243
|
+
return new _PermissionError(
|
|
244
|
+
"Access denied to collection",
|
|
245
|
+
"COLLECTION_ACCESS_DENIED",
|
|
246
|
+
{ collectionId }
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
var NotFoundError = class _NotFoundError extends VaultwardenError {
|
|
251
|
+
/** Resource type */
|
|
252
|
+
resourceType;
|
|
253
|
+
/** Resource identifier */
|
|
254
|
+
resourceId;
|
|
255
|
+
constructor(resourceType, resourceId, message) {
|
|
256
|
+
const msg = message ?? `${resourceType ?? "Resource"}${resourceId ? ` '${resourceId}'` : ""} not found`;
|
|
257
|
+
super(msg, "NOT_FOUND", 404, { resourceType, resourceId });
|
|
258
|
+
this.name = "NotFoundError";
|
|
259
|
+
this.resourceType = resourceType;
|
|
260
|
+
this.resourceId = resourceId;
|
|
261
|
+
Object.setPrototypeOf(this, _NotFoundError.prototype);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Create error for cipher not found
|
|
265
|
+
*/
|
|
266
|
+
static cipher(id) {
|
|
267
|
+
return new _NotFoundError("Cipher", id);
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Create error for folder not found
|
|
271
|
+
*/
|
|
272
|
+
static folder(id) {
|
|
273
|
+
return new _NotFoundError("Folder", id);
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Create error for organization not found
|
|
277
|
+
*/
|
|
278
|
+
static organization(id) {
|
|
279
|
+
return new _NotFoundError("Organization", id);
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Create error for collection not found
|
|
283
|
+
*/
|
|
284
|
+
static collection(id) {
|
|
285
|
+
return new _NotFoundError("Collection", id);
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
var RateLimitError = class _RateLimitError extends VaultwardenError {
|
|
289
|
+
/** Time to wait before retry (seconds) */
|
|
290
|
+
retryAfter;
|
|
291
|
+
/** Limit that was hit */
|
|
292
|
+
limit;
|
|
293
|
+
constructor(retryAfter, limit, message) {
|
|
294
|
+
const msg = message ?? `Rate limit exceeded. Retry after ${retryAfter ?? "some"} seconds.`;
|
|
295
|
+
super(msg, "RATE_LIMITED", 429, { retryAfter, limit });
|
|
296
|
+
this.name = "RateLimitError";
|
|
297
|
+
this.retryAfter = retryAfter;
|
|
298
|
+
this.limit = limit;
|
|
299
|
+
Object.setPrototypeOf(this, _RateLimitError.prototype);
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Check if retry should be attempted
|
|
303
|
+
*/
|
|
304
|
+
get shouldRetry() {
|
|
305
|
+
return true;
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
var TimeoutError = class _TimeoutError extends VaultwardenError {
|
|
309
|
+
/** Request endpoint that timed out */
|
|
310
|
+
endpoint;
|
|
311
|
+
/** Timeout duration in milliseconds */
|
|
312
|
+
timeoutMs;
|
|
313
|
+
constructor(endpoint, timeoutMs, message) {
|
|
314
|
+
const msg = message ?? `Request${endpoint ? ` to ${endpoint}` : ""} timed out after ${timeoutMs ?? ""}ms`;
|
|
315
|
+
super(msg, "TIMEOUT", void 0, { endpoint, timeoutMs });
|
|
316
|
+
this.name = "TimeoutError";
|
|
317
|
+
this.endpoint = endpoint;
|
|
318
|
+
this.timeoutMs = timeoutMs;
|
|
319
|
+
Object.setPrototypeOf(this, _TimeoutError.prototype);
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
var CryptoError = class _CryptoError extends VaultwardenError {
|
|
323
|
+
/** Operation that failed */
|
|
324
|
+
operation;
|
|
325
|
+
constructor(message, operation, context) {
|
|
326
|
+
super(message, "CRYPTO_ERROR", void 0, { ...context, operation });
|
|
327
|
+
this.name = "CryptoError";
|
|
328
|
+
this.operation = operation;
|
|
329
|
+
Object.setPrototypeOf(this, _CryptoError.prototype);
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Create error for key derivation failure
|
|
333
|
+
*/
|
|
334
|
+
static keyDerivation() {
|
|
335
|
+
return new _CryptoError(
|
|
336
|
+
"Failed to derive encryption key",
|
|
337
|
+
"keyDerivation"
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Create error for decryption failure
|
|
342
|
+
*/
|
|
343
|
+
static decryption() {
|
|
344
|
+
return new _CryptoError(
|
|
345
|
+
"Failed to decrypt data",
|
|
346
|
+
"decryption"
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Create error for encryption failure
|
|
351
|
+
*/
|
|
352
|
+
static encryption() {
|
|
353
|
+
return new _CryptoError(
|
|
354
|
+
"Failed to encrypt data",
|
|
355
|
+
"encryption"
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
var StateError = class _StateError extends VaultwardenError {
|
|
360
|
+
constructor(message, code = "INVALID_STATE") {
|
|
361
|
+
super(message, code);
|
|
362
|
+
this.name = "StateError";
|
|
363
|
+
Object.setPrototypeOf(this, _StateError.prototype);
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Create error for not authenticated
|
|
367
|
+
*/
|
|
368
|
+
static notAuthenticated() {
|
|
369
|
+
return new _StateError(
|
|
370
|
+
"Not authenticated. Call login() first.",
|
|
371
|
+
"NOT_AUTHENTICATED"
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Create error for already authenticated
|
|
376
|
+
*/
|
|
377
|
+
static alreadyAuthenticated() {
|
|
378
|
+
return new _StateError(
|
|
379
|
+
"Already authenticated. Logout first.",
|
|
380
|
+
"ALREADY_AUTHENTICATED"
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Create error for client not ready
|
|
385
|
+
*/
|
|
386
|
+
static notReady() {
|
|
387
|
+
return new _StateError(
|
|
388
|
+
"Client not ready. Ensure login() completed successfully.",
|
|
389
|
+
"NOT_READY"
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
export {
|
|
395
|
+
VaultwardenError,
|
|
396
|
+
AuthenticationError,
|
|
397
|
+
APIError,
|
|
398
|
+
ValidationError,
|
|
399
|
+
PermissionError,
|
|
400
|
+
NotFoundError,
|
|
401
|
+
RateLimitError,
|
|
402
|
+
TimeoutError,
|
|
403
|
+
CryptoError,
|
|
404
|
+
StateError
|
|
405
|
+
};
|
|
406
|
+
//# sourceMappingURL=chunk-34VL7JLT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors/index.ts"],"sourcesContent":["/**\n * Custom error classes for Vaultwarden Client\n * @module errors\n */\n\n/**\n * Base error class for all Vaultwarden client errors\n * @extends Error\n */\nexport class VaultwardenError extends Error {\n /** Error code for programmatic handling */\n public readonly code: string;\n /** HTTP status code if applicable */\n public readonly statusCode?: number;\n /** Additional error context */\n public readonly context?: Record<string, unknown>;\n\n constructor(\n message: string,\n code: string,\n statusCode?: number,\n context?: Record<string, unknown>\n ) {\n super(message);\n this.name = 'VaultwardenError';\n this.code = code;\n this.statusCode = statusCode!;\n this.context = context!;\n\n // Fix prototype chain for instanceof checks\n Object.setPrototypeOf(this, VaultwardenError.prototype);\n\n // Capture stack trace\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n /**\n * Convert error to JSON representation\n */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n statusCode: this.statusCode,\n context: this.context,\n stack: this.stack,\n };\n }\n}\n\n/**\n * Error thrown when authentication fails\n * @extends VaultwardenError\n */\nexport class AuthenticationError extends VaultwardenError {\n constructor(\n message = 'Authentication failed',\n code = 'AUTH_FAILED',\n context?: Record<string, unknown>\n ) {\n super(message, code, 401, context);\n this.name = 'AuthenticationError';\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n\n /**\n * Create error for invalid credentials\n */\n static invalidCredentials(): AuthenticationError {\n return new AuthenticationError(\n 'Invalid username or password',\n 'INVALID_CREDENTIALS'\n );\n }\n\n /**\n * Create error for missing 2FA\n */\n static twoFactorRequired(method?: string): AuthenticationError {\n return new AuthenticationError(\n 'Two-factor authentication required',\n '2FA_REQUIRED',\n { method }\n );\n }\n\n /**\n * Create error for invalid 2FA code\n */\n static invalidTwoFactorCode(): AuthenticationError {\n return new AuthenticationError(\n 'Invalid two-factor authentication code',\n 'INVALID_2FA_CODE'\n );\n }\n\n /**\n * Create error for expired session\n */\n static sessionExpired(): AuthenticationError {\n return new AuthenticationError(\n 'Session has expired, please log in again',\n 'SESSION_EXPIRED'\n );\n }\n}\n\n/**\n * Error thrown when an API request fails\n * @extends VaultwardenError\n */\nexport class APIError extends VaultwardenError {\n /** Response body if available */\n public readonly responseBody?: string;\n /** Request endpoint */\n public readonly endpoint?: string;\n /** Request method */\n public readonly method?: string;\n\n constructor(\n message: string,\n statusCode: number,\n code = 'API_ERROR',\n context?: Record<string, unknown>\n ) {\n super(message, code, statusCode, context);\n this.name = 'APIError';\n this.responseBody = (context?.responseBody as string | undefined)!;\n this.endpoint = (context?.endpoint as string | undefined)!;\n this.method = (context?.method as string | undefined)!;\n Object.setPrototypeOf(this, APIError.prototype);\n }\n\n /**\n * Create error from HTTP response\n */\n static fromResponse(\n response: Response,\n endpoint: string,\n method: string,\n body?: string\n ): APIError {\n const messages: Record<number, string> = {\n 400: 'Bad request',\n 401: 'Unauthorized',\n 403: 'Forbidden',\n 404: 'Not found',\n 405: 'Method not allowed',\n 409: 'Conflict',\n 429: 'Rate limited',\n 500: 'Internal server error',\n 502: 'Bad gateway',\n 503: 'Service unavailable',\n };\n\n const message = messages[response.status] ?? `HTTP ${response.status} error`;\n const code = `HTTP_${response.status}`;\n\n return new APIError(message, response.status, code, {\n endpoint,\n method,\n responseBody: body,\n statusText: response.statusText,\n });\n }\n\n /**\n * Check if error is a rate limit error\n */\n get isRateLimit(): boolean {\n return this.statusCode === 429;\n }\n\n /**\n * Check if error is a server error (5xx)\n */\n get isServerError(): boolean {\n return this.statusCode !== undefined && this.statusCode >= 500;\n }\n\n /**\n * Check if error is a client error (4xx)\n */\n get isClientError(): boolean {\n return this.statusCode !== undefined && this.statusCode >= 400 && this.statusCode < 500;\n }\n\n /**\n * Check if request should be retried\n */\n get shouldRetry(): boolean {\n if (this.statusCode === undefined) return true;\n // Retry on rate limit, server errors, and specific client errors\n return this.isRateLimit || this.isServerError || [408, 409, 422].includes(this.statusCode);\n }\n}\n\n/**\n * Error thrown for validation failures\n * @extends VaultwardenError\n */\nexport class ValidationError extends VaultwardenError {\n /** Field that failed validation */\n public readonly field?: string;\n /** Validation constraints that failed */\n public readonly constraints?: string[];\n\n constructor(\n message: string,\n field?: string,\n constraints?: string[]\n ) {\n super(message, 'VALIDATION_ERROR', undefined, { field, constraints });\n this.name = 'ValidationError';\n this.field = field!;\n this.constraints = constraints!;\n Object.setPrototypeOf(this, ValidationError.prototype);\n }\n\n /**\n * Create error for missing required field\n */\n static requiredField(field: string): ValidationError {\n return new ValidationError(\n `Field '${field}' is required`,\n field,\n ['required']\n );\n }\n\n /**\n * Create error for invalid field value\n */\n static invalidValue(field: string, expectedType: string): ValidationError {\n return new ValidationError(\n `Field '${field}' must be ${expectedType}`,\n field,\n [`type:${expectedType}`]\n );\n }\n\n /**\n * Create error for empty value\n */\n static notEmpty(field: string): ValidationError {\n return new ValidationError(\n `Field '${field}' cannot be empty`,\n field,\n ['notEmpty']\n );\n }\n\n /**\n * Create error for invalid URL\n */\n static invalidUrl(field: string): ValidationError {\n return new ValidationError(\n `Field '${field}' must be a valid URL`,\n field,\n ['url']\n );\n }\n\n /**\n * Create error for invalid email\n */\n static invalidEmail(field: string): ValidationError {\n return new ValidationError(\n `Field '${field}' must be a valid email address`,\n field,\n ['email']\n );\n }\n}\n\n/**\n * Error thrown for permission-related failures\n * @extends VaultwardenError\n */\nexport class PermissionError extends VaultwardenError {\n /** Required permission */\n public readonly requiredPermission?: string;\n /** Resource being accessed */\n public readonly resource?: string;\n\n constructor(\n message = 'Permission denied',\n code = 'PERMISSION_DENIED',\n context?: Record<string, unknown>\n ) {\n super(message, code, 403, context);\n this.name = 'PermissionError';\n this.requiredPermission = (context?.requiredPermission as string | undefined)!;\n this.resource = (context?.resource as string | undefined)!;\n Object.setPrototypeOf(this, PermissionError.prototype);\n }\n\n /**\n * Create error for insufficient permissions\n */\n static insufficientPermission(\n requiredPermission: string,\n resource?: string\n ): PermissionError {\n return new PermissionError(\n `Insufficient permissions: ${requiredPermission} required`,\n 'INSUFFICIENT_PERMISSION',\n { requiredPermission, resource }\n );\n }\n\n /**\n * Create error for organization access denied\n */\n static organizationAccessDenied(orgId: string): PermissionError {\n return new PermissionError(\n 'Access denied to organization',\n 'ORG_ACCESS_DENIED',\n { organizationId: orgId }\n );\n }\n\n /**\n * Create error for collection access denied\n */\n static collectionAccessDenied(collectionId: string): PermissionError {\n return new PermissionError(\n 'Access denied to collection',\n 'COLLECTION_ACCESS_DENIED',\n { collectionId }\n );\n }\n}\n\n/**\n * Error thrown when a resource is not found\n * @extends VaultwardenError\n */\nexport class NotFoundError extends VaultwardenError {\n /** Resource type */\n public readonly resourceType?: string;\n /** Resource identifier */\n public readonly resourceId?: string;\n\n constructor(\n resourceType?: string,\n resourceId?: string,\n message?: string\n ) {\n const msg = message ?? `${resourceType ?? 'Resource'}${resourceId ? ` '${resourceId}'` : ''} not found`;\n super(msg, 'NOT_FOUND', 404, { resourceType, resourceId });\n this.name = 'NotFoundError';\n this.resourceType = resourceType!;\n this.resourceId = resourceId!;\n Object.setPrototypeOf(this, NotFoundError.prototype);\n }\n\n /**\n * Create error for cipher not found\n */\n static cipher(id: string): NotFoundError {\n return new NotFoundError('Cipher', id);\n }\n\n /**\n * Create error for folder not found\n */\n static folder(id: string): NotFoundError {\n return new NotFoundError('Folder', id);\n }\n\n /**\n * Create error for organization not found\n */\n static organization(id: string): NotFoundError {\n return new NotFoundError('Organization', id);\n }\n\n /**\n * Create error for collection not found\n */\n static collection(id: string): NotFoundError {\n return new NotFoundError('Collection', id);\n }\n}\n\n/**\n * Error thrown for rate limiting\n * @extends VaultwardenError\n */\nexport class RateLimitError extends VaultwardenError {\n /** Time to wait before retry (seconds) */\n public readonly retryAfter?: number;\n /** Limit that was hit */\n public readonly limit?: number;\n\n constructor(\n retryAfter?: number,\n limit?: number,\n message?: string\n ) {\n const msg = message ?? `Rate limit exceeded. Retry after ${retryAfter ?? 'some'} seconds.`;\n super(msg, 'RATE_LIMITED', 429, { retryAfter, limit });\n this.name = 'RateLimitError';\n this.retryAfter = retryAfter!;\n this.limit = limit!;\n Object.setPrototypeOf(this, RateLimitError.prototype);\n }\n\n /**\n * Check if retry should be attempted\n */\n get shouldRetry(): boolean {\n return true;\n }\n}\n\n/**\n * Error thrown for timeout failures\n * @extends VaultwardenError\n */\nexport class TimeoutError extends VaultwardenError {\n /** Request endpoint that timed out */\n public readonly endpoint?: string;\n /** Timeout duration in milliseconds */\n public readonly timeoutMs?: number;\n\n constructor(\n endpoint?: string,\n timeoutMs?: number,\n message?: string\n ) {\n const msg = message ?? `Request${endpoint ? ` to ${endpoint}` : ''} timed out after ${timeoutMs ?? ''}ms`;\n super(msg, 'TIMEOUT', undefined, { endpoint, timeoutMs });\n this.name = 'TimeoutError';\n this.endpoint = endpoint!;\n this.timeoutMs = timeoutMs!;\n Object.setPrototypeOf(this, TimeoutError.prototype);\n }\n}\n\n/**\n * Error thrown for crypto operation failures\n * @extends VaultwardenError\n */\nexport class CryptoError extends VaultwardenError {\n /** Operation that failed */\n public readonly operation?: string;\n\n constructor(\n message: string,\n operation?: string,\n context?: Record<string, unknown>\n ) {\n super(message, 'CRYPTO_ERROR', undefined, { ...context, operation });\n this.name = 'CryptoError';\n this.operation = operation!;\n Object.setPrototypeOf(this, CryptoError.prototype);\n }\n\n /**\n * Create error for key derivation failure\n */\n static keyDerivation(): CryptoError {\n return new CryptoError(\n 'Failed to derive encryption key',\n 'keyDerivation'\n );\n }\n\n /**\n * Create error for decryption failure\n */\n static decryption(): CryptoError {\n return new CryptoError(\n 'Failed to decrypt data',\n 'decryption'\n );\n }\n\n /**\n * Create error for encryption failure\n */\n static encryption(): CryptoError {\n return new CryptoError(\n 'Failed to encrypt data',\n 'encryption'\n );\n }\n}\n\n/**\n * Error thrown when state is invalid\n * @extends VaultwardenError\n */\nexport class StateError extends VaultwardenError {\n constructor(\n message: string,\n code = 'INVALID_STATE'\n ) {\n super(message, code);\n this.name = 'StateError';\n Object.setPrototypeOf(this, StateError.prototype);\n }\n\n /**\n * Create error for not authenticated\n */\n static notAuthenticated(): StateError {\n return new StateError(\n 'Not authenticated. Call login() first.',\n 'NOT_AUTHENTICATED'\n );\n }\n\n /**\n * Create error for already authenticated\n */\n static alreadyAuthenticated(): StateError {\n return new StateError(\n 'Already authenticated. Logout first.',\n 'ALREADY_AUTHENTICATED'\n );\n }\n\n /**\n * Create error for client not ready\n */\n static notReady(): StateError {\n return new StateError(\n 'Client not ready. Ensure login() completed successfully.',\n 'NOT_READY'\n );\n }\n}\n"],"mappings":"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","names":[]}
|