vaultwarden.js 1.0.0
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/LICENSE +21 -0
- package/README.md +455 -0
- package/package.json +59 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Marki
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
# Vaultwarden Client
|
|
2
|
+
|
|
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
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/vaultwarden-client)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **Object-Oriented Architecture** - Manager/Structure pattern like discord.js
|
|
12
|
+
- **Full Type Safety** - Strict TypeScript with `exactOptionalPropertyTypes`
|
|
13
|
+
- **Event-Driven** - Typed EventEmitter for real-time updates
|
|
14
|
+
- **Smart Caching** - LRU cache with TTL support for all entities
|
|
15
|
+
- **Complete Encryption** - PBKDF2, AES-256-CBC, HKDF support
|
|
16
|
+
- **Well Tested** - Comprehensive test suite with Vitest
|
|
17
|
+
- **ESM + CJS** - Dual module support
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install vaultwarden-client
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { VaultwardenClient } from 'vaultwarden-client';
|
|
29
|
+
|
|
30
|
+
const client = new VaultwardenClient({
|
|
31
|
+
baseUrl: 'https://vault.example.com',
|
|
32
|
+
deviceName: 'MyApp',
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Login
|
|
36
|
+
await client.login({
|
|
37
|
+
username: 'user@example.com',
|
|
38
|
+
password: 'masterpassword',
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Sync data from server
|
|
42
|
+
await client.sync();
|
|
43
|
+
|
|
44
|
+
// Access your vault
|
|
45
|
+
console.log(`You have ${client.ciphers.cache.size} items`);
|
|
46
|
+
|
|
47
|
+
// Find a specific login
|
|
48
|
+
const github = client.ciphers.cache.find(
|
|
49
|
+
(c) => c.name === 'GitHub'
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
if (github) {
|
|
53
|
+
console.log(`Username: ${github.username}`);
|
|
54
|
+
console.log(`Password: ${github.password}`);
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Authentication
|
|
59
|
+
|
|
60
|
+
### Login with Password
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
await client.login({
|
|
64
|
+
username: 'user@example.com',
|
|
65
|
+
password: 'masterpassword',
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Login with 2FA
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
await client.login({
|
|
73
|
+
username: 'user@example.com',
|
|
74
|
+
password: 'masterpassword',
|
|
75
|
+
twoFactorCode: '123456',
|
|
76
|
+
twoFactorProvider: 0, // Authenticator app
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Available 2FA Methods
|
|
81
|
+
|
|
82
|
+
| Provider | Value | Description |
|
|
83
|
+
|----------|-------|-------------|
|
|
84
|
+
| `Authenticator` | `0` | TOTP (Google Authenticator, etc.) |
|
|
85
|
+
| `Email` | `1` | Email-based 2FA |
|
|
86
|
+
| `Duo` | `2` | Duo Security |
|
|
87
|
+
| `Yubikey` | `3` | YubiKey OTP |
|
|
88
|
+
| `FIDO2` | `4` | FIDO2 WebAuthn |
|
|
89
|
+
|
|
90
|
+
## Core Concepts
|
|
91
|
+
|
|
92
|
+
### Managers
|
|
93
|
+
|
|
94
|
+
Managers handle CRUD operations and maintain caches:
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
// Ciphers (passwords, cards, notes, identities)
|
|
98
|
+
client.ciphers
|
|
99
|
+
|
|
100
|
+
// Folders
|
|
101
|
+
client.folders
|
|
102
|
+
|
|
103
|
+
// Organizations
|
|
104
|
+
client.organizations
|
|
105
|
+
|
|
106
|
+
// Collections
|
|
107
|
+
client.collections
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Structures
|
|
111
|
+
|
|
112
|
+
Structures represent individual vault items:
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
// Cipher types
|
|
116
|
+
LoginCipher // Website passwords
|
|
117
|
+
CardCipher // Credit cards
|
|
118
|
+
SecureNoteCipher // Encrypted notes
|
|
119
|
+
IdentityCipher // Personal information
|
|
120
|
+
|
|
121
|
+
// Other structures
|
|
122
|
+
FolderStructure
|
|
123
|
+
CollectionStructure
|
|
124
|
+
OrganizationStructure
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Collections
|
|
128
|
+
|
|
129
|
+
Enhanced Map with utility methods:
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
// Get all login ciphers
|
|
133
|
+
const logins = client.ciphers.logins;
|
|
134
|
+
|
|
135
|
+
// Filter by predicate
|
|
136
|
+
const favorites = client.ciphers.cache.filter(
|
|
137
|
+
(c) => c.favorite
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
// Find by predicate
|
|
141
|
+
const github = client.ciphers.cache.find(
|
|
142
|
+
(c) => c.name === 'GitHub'
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
// Map to array
|
|
146
|
+
const names = client.ciphers.cache.map((c) => c.name);
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Working with Ciphers
|
|
150
|
+
|
|
151
|
+
### Create a Login
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
const login = await client.ciphers.createLogin({
|
|
155
|
+
name: 'GitHub',
|
|
156
|
+
username: 'myuser',
|
|
157
|
+
password: 'securepassword123',
|
|
158
|
+
uri: 'https://github.com',
|
|
159
|
+
notes: 'My GitHub account',
|
|
160
|
+
favorite: true,
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
console.log(`Created: ${login.name} (${login.id})`);
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Create a Card
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
const card = await client.ciphers.createCard({
|
|
170
|
+
name: 'Personal Visa',
|
|
171
|
+
cardholderName: 'John Doe',
|
|
172
|
+
brand: 'Visa',
|
|
173
|
+
number: '4111111111111111',
|
|
174
|
+
expMonth: '12',
|
|
175
|
+
expYear: '2027',
|
|
176
|
+
code: '123',
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Create a Secure Note
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
const note = await client.ciphers.createSecureNote({
|
|
184
|
+
name: 'WiFi Password',
|
|
185
|
+
content: 'Network: HomeWiFi_5G\nPassword: SuperSecret!',
|
|
186
|
+
});
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Create an Identity
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
const identity = await client.ciphers.createIdentity({
|
|
193
|
+
name: 'Personal Identity',
|
|
194
|
+
title: 'Mr',
|
|
195
|
+
firstName: 'John',
|
|
196
|
+
lastName: 'Doe',
|
|
197
|
+
email: 'john@example.com',
|
|
198
|
+
address1: '123 Main St',
|
|
199
|
+
city: 'New York',
|
|
200
|
+
state: 'NY',
|
|
201
|
+
postalCode: '10001',
|
|
202
|
+
country: 'US',
|
|
203
|
+
});
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Update and Delete
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
// Update
|
|
210
|
+
await login.update({ name: 'GitHub (Personal)' });
|
|
211
|
+
await login.setFavorite(false);
|
|
212
|
+
await login.moveToFolder(folderId);
|
|
213
|
+
|
|
214
|
+
// Soft delete (move to trash)
|
|
215
|
+
await login.softDelete();
|
|
216
|
+
|
|
217
|
+
// Restore from trash
|
|
218
|
+
await login.restore();
|
|
219
|
+
|
|
220
|
+
// Permanent delete
|
|
221
|
+
await login.delete();
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Working with Folders
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
// Create a folder
|
|
228
|
+
const folder = await client.folders.create('Work Accounts');
|
|
229
|
+
|
|
230
|
+
// Update folder
|
|
231
|
+
await client.folders.update(folder.id, 'Work Accounts 2024');
|
|
232
|
+
|
|
233
|
+
// Delete folder
|
|
234
|
+
await client.folders.delete(folder.id);
|
|
235
|
+
|
|
236
|
+
// Get ciphers in folder
|
|
237
|
+
const workLogins = client.ciphers.cache.filter(
|
|
238
|
+
(c) => c.folderId === folder.id
|
|
239
|
+
);
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## Searching
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
// Search by name/notes
|
|
246
|
+
const results = client.ciphers.search('github');
|
|
247
|
+
|
|
248
|
+
// Find by domain
|
|
249
|
+
const logins = client.ciphers.findByDomain('github.com');
|
|
250
|
+
|
|
251
|
+
// Find by folder
|
|
252
|
+
const folderCiphers = client.ciphers.findByFolder(folderId);
|
|
253
|
+
|
|
254
|
+
// Filtered accessors
|
|
255
|
+
const favorites = client.ciphers.favorites;
|
|
256
|
+
const trash = client.ciphers.trash;
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Password Generation
|
|
260
|
+
git remote add origin https://github.com/MarkIt-host/VaultWarden.js.git
|
|
261
|
+
```typescript
|
|
262
|
+
import { generatePassword, generatePassphrase } from 'vaultwarden-client';
|
|
263
|
+
|
|
264
|
+
// Generate strong password
|
|
265
|
+
const { password, entropy } = generatePassword({
|
|
266
|
+
length: 20,
|
|
267
|
+
uppercase: true,
|
|
268
|
+
lowercase: true,
|
|
269
|
+
numbers: true,
|
|
270
|
+
special: true,
|
|
271
|
+
minNumbers: 2,
|
|
272
|
+
minSpecial: 1,
|
|
273
|
+
ambiguous: false, // Exclude 0, O, 1, l
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
// Generate memorable passphrase
|
|
277
|
+
const { passphrase, wordCount } = generatePassphrase({
|
|
278
|
+
numWords: 5,
|
|
279
|
+
wordSeparator: '-',
|
|
280
|
+
capitalize: true,
|
|
281
|
+
includeNumber: true,
|
|
282
|
+
});
|
|
283
|
+
// Result: "Blue-Tiger-Happy-Cloud-42"
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## Events
|
|
287
|
+
|
|
288
|
+
Listen for real-time updates:
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
client.on('ready', () => {
|
|
292
|
+
console.log('Client is ready!');
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
client.on('sync', () => {
|
|
296
|
+
console.log('Data synced!');
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
client.on('cipherCreate', (cipher) => {
|
|
300
|
+
console.log(`Created: ${cipher.name}`);
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
client.on('cipherUpdate', (cipher) => {
|
|
304
|
+
console.log(`Updated: ${cipher.name}`);
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
client.on('cipherDelete', (id) => {
|
|
308
|
+
console.log(`Deleted cipher: ${id}`);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
client.on('error', (error) => {
|
|
312
|
+
console.error('Client error:', error);
|
|
313
|
+
});
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Event Types
|
|
317
|
+
|
|
318
|
+
| Event | Payload | Description |
|
|
319
|
+
|-------|---------|-------------|
|
|
320
|
+
| `ready` | - | Client is authenticated and ready |
|
|
321
|
+
| `login` | `AuthTokenResponse` | Login successful |
|
|
322
|
+
| `logout` | - | Logged out |
|
|
323
|
+
| `sync` | - | Data synced from server |
|
|
324
|
+
| `cipherCreate` | `Cipher` | New cipher created |
|
|
325
|
+
| `cipherUpdate` | `Cipher` | Cipher updated |
|
|
326
|
+
| `cipherDelete` | `string` | Cipher deleted (ID) |
|
|
327
|
+
| `folderCreate` | `FolderStructure` | New folder created |
|
|
328
|
+
| `folderUpdate` | `FolderStructure` | Folder updated |
|
|
329
|
+
| `folderDelete` | `string` | Folder deleted (ID) |
|
|
330
|
+
| `error` | `Error` | Error occurred |
|
|
331
|
+
|
|
332
|
+
## Error Handling
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
import {
|
|
336
|
+
VaultwardenError,
|
|
337
|
+
AuthenticationError,
|
|
338
|
+
NotFoundError,
|
|
339
|
+
RateLimitError,
|
|
340
|
+
} from 'vaultwarden-client';
|
|
341
|
+
|
|
342
|
+
try {
|
|
343
|
+
await client.login({ username, password });
|
|
344
|
+
} catch (error) {
|
|
345
|
+
if (error instanceof AuthenticationError) {
|
|
346
|
+
console.error('Invalid credentials');
|
|
347
|
+
} else if (error instanceof RateLimitError) {
|
|
348
|
+
console.error(`Rate limited. Retry after ${error.retryAfter}s`);
|
|
349
|
+
} else if (error instanceof VaultwardenError) {
|
|
350
|
+
console.error(`Error ${error.code}: ${error.message}`);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Error Types
|
|
356
|
+
|
|
357
|
+
| Error | Description |
|
|
358
|
+
|-------|-------------|
|
|
359
|
+
| `VaultwardenError` | Base error class |
|
|
360
|
+
| `AuthenticationError` | Invalid credentials or 2FA needed |
|
|
361
|
+
| `APIError` | API request failed |
|
|
362
|
+
| `NotFoundError` | Resource not found |
|
|
363
|
+
| `ValidationError` | Invalid input data |
|
|
364
|
+
| `PermissionError` | Insufficient permissions |
|
|
365
|
+
| `RateLimitError` | Rate limit hit |
|
|
366
|
+
| `TimeoutError` | Request timed out |
|
|
367
|
+
| `CryptoError` | Encryption/decryption failed |
|
|
368
|
+
| `StateError` | Invalid client state |
|
|
369
|
+
|
|
370
|
+
## Configuration Options
|
|
371
|
+
|
|
372
|
+
```typescript
|
|
373
|
+
const client = new VaultwardenClient({
|
|
374
|
+
// Required
|
|
375
|
+
baseUrl: 'https://vault.example.com',
|
|
376
|
+
|
|
377
|
+
// Optional
|
|
378
|
+
deviceName: 'MyApp', // Default: 'vaultwarden-client'
|
|
379
|
+
deviceType: 8, // Default: 8 (Windows Desktop)
|
|
380
|
+
timeout: 30000, // Request timeout in ms
|
|
381
|
+
maxRetries: 3, // Max retry attempts
|
|
382
|
+
});
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### Device Types
|
|
386
|
+
|
|
387
|
+
| Type | Value |
|
|
388
|
+
|------|-------|
|
|
389
|
+
| Android | 0 |
|
|
390
|
+
| iOS | 1 |
|
|
391
|
+
| Chrome Extension | 2 |
|
|
392
|
+
| Firefox Extension | 3 |
|
|
393
|
+
| Opera Extension | 4 |
|
|
394
|
+
| Edge Extension | 5 |
|
|
395
|
+
| Windows Desktop | 8 |
|
|
396
|
+
| macOS Desktop | 9 |
|
|
397
|
+
| Linux Desktop | 10 |
|
|
398
|
+
| Chrome | 11 |
|
|
399
|
+
| Safari | 12 |
|
|
400
|
+
| Firefox | 16 |
|
|
401
|
+
|
|
402
|
+
## Testing Script
|
|
403
|
+
|
|
404
|
+
A CLI script is included for testing:
|
|
405
|
+
|
|
406
|
+
```bash
|
|
407
|
+
# Login and show stats
|
|
408
|
+
npx tsx scripts/vault-tester.ts login \
|
|
409
|
+
--url https://vault.example.com \
|
|
410
|
+
--email user@example.com \
|
|
411
|
+
--password pass
|
|
412
|
+
|
|
413
|
+
# Fill vault with test data
|
|
414
|
+
npx tsx scripts/vault-tester.ts fill \
|
|
415
|
+
--url https://vault.example.com \
|
|
416
|
+
--email user@example.com \
|
|
417
|
+
--password pass \
|
|
418
|
+
--count 50 \
|
|
419
|
+
--folder "Test Items"
|
|
420
|
+
|
|
421
|
+
# List vault contents
|
|
422
|
+
npx tsx scripts/vault-tester.ts list \
|
|
423
|
+
--url https://vault.example.com \
|
|
424
|
+
--email user@example.com \
|
|
425
|
+
--password pass
|
|
426
|
+
|
|
427
|
+
# Delete all items
|
|
428
|
+
npx tsx scripts/vault-tester.ts delete \
|
|
429
|
+
--url https://vault.example.com \
|
|
430
|
+
--email user@example.com \
|
|
431
|
+
--password pass \
|
|
432
|
+
--all
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
## API Reference
|
|
436
|
+
|
|
437
|
+
See [API.md](./docs/API.md) for complete API documentation.
|
|
438
|
+
|
|
439
|
+
## Examples
|
|
440
|
+
|
|
441
|
+
See [examples/](./examples/) directory for usage examples:
|
|
442
|
+
|
|
443
|
+
- [Basic Auth](./examples/basic-auth.ts)
|
|
444
|
+
- [Cipher CRUD](./examples/cipher-crud.ts)
|
|
445
|
+
- [Folder Management](./examples/folder-management.ts)
|
|
446
|
+
- [Organizations](./examples/organizations.ts)
|
|
447
|
+
- [Password Generator](./examples/password-generator.ts)
|
|
448
|
+
|
|
449
|
+
## Migration from 2.x
|
|
450
|
+
|
|
451
|
+
See [MIGRATION.md](./docs/MIGRATION.md) for migration guide.
|
|
452
|
+
|
|
453
|
+
## License
|
|
454
|
+
|
|
455
|
+
MIT © [Marki](https://marki.dev)
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vaultwarden.js",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A modern, object-oriented TypeScript SDK for Vaultwarden/Bitwarden servers",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"vaultwarden",
|
|
7
|
+
"bitwarden",
|
|
8
|
+
"password-manager",
|
|
9
|
+
"vault",
|
|
10
|
+
"sdk",
|
|
11
|
+
"oop",
|
|
12
|
+
"discord.js-style"
|
|
13
|
+
],
|
|
14
|
+
"author": "",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"type": "module",
|
|
17
|
+
"main": "./dist/index.js",
|
|
18
|
+
"module": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"import": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"default": "./dist/index.js"
|
|
25
|
+
},
|
|
26
|
+
"require": {
|
|
27
|
+
"types": "./dist/index.d.cts",
|
|
28
|
+
"default": "./dist/index.cjs"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"./package.json": "./package.json"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist",
|
|
35
|
+
"README.md",
|
|
36
|
+
"LICENSE"
|
|
37
|
+
],
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=18.0.0"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsup src/index.ts --format cjs,esm --dts --sourcemap --clean",
|
|
43
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
44
|
+
"test": "vitest run",
|
|
45
|
+
"test:watch": "vitest",
|
|
46
|
+
"test:coverage": "vitest run --coverage",
|
|
47
|
+
"lint": "tsc --noEmit",
|
|
48
|
+
"typecheck": "tsc --noEmit",
|
|
49
|
+
"vault-tester": "tsx scripts/vault-tester.ts"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@types/node": "^20.0.0",
|
|
53
|
+
"@vitest/coverage-v8": "^1.0.0",
|
|
54
|
+
"tsup": "^8.0.0",
|
|
55
|
+
"tsx": "^4.22.3",
|
|
56
|
+
"typescript": "^5.3.0",
|
|
57
|
+
"vitest": "^1.0.0"
|
|
58
|
+
}
|
|
59
|
+
}
|