@lifestreamdynamics/vault-sdk 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.
Files changed (103) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1121 -0
  3. package/dist/client.d.ts +143 -0
  4. package/dist/client.d.ts.map +1 -0
  5. package/dist/client.js +286 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/errors.d.ts +28 -0
  8. package/dist/errors.d.ts.map +1 -0
  9. package/dist/errors.js +49 -0
  10. package/dist/errors.js.map +1 -0
  11. package/dist/handle-error.d.ts +8 -0
  12. package/dist/handle-error.d.ts.map +1 -0
  13. package/dist/handle-error.js +35 -0
  14. package/dist/handle-error.js.map +1 -0
  15. package/dist/index.d.ts +32 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +26 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/lib/audit-logger.d.ts +29 -0
  20. package/dist/lib/audit-logger.d.ts.map +1 -0
  21. package/dist/lib/audit-logger.js +99 -0
  22. package/dist/lib/audit-logger.js.map +1 -0
  23. package/dist/lib/encryption.d.ts +34 -0
  24. package/dist/lib/encryption.d.ts.map +1 -0
  25. package/dist/lib/encryption.js +87 -0
  26. package/dist/lib/encryption.js.map +1 -0
  27. package/dist/lib/signature.d.ts +47 -0
  28. package/dist/lib/signature.d.ts.map +1 -0
  29. package/dist/lib/signature.js +71 -0
  30. package/dist/lib/signature.js.map +1 -0
  31. package/dist/lib/token-manager.d.ts +80 -0
  32. package/dist/lib/token-manager.d.ts.map +1 -0
  33. package/dist/lib/token-manager.js +116 -0
  34. package/dist/lib/token-manager.js.map +1 -0
  35. package/dist/resources/admin.d.ts +280 -0
  36. package/dist/resources/admin.d.ts.map +1 -0
  37. package/dist/resources/admin.js +236 -0
  38. package/dist/resources/admin.js.map +1 -0
  39. package/dist/resources/ai.d.ts +184 -0
  40. package/dist/resources/ai.d.ts.map +1 -0
  41. package/dist/resources/ai.js +179 -0
  42. package/dist/resources/ai.js.map +1 -0
  43. package/dist/resources/api-keys.d.ts +172 -0
  44. package/dist/resources/api-keys.d.ts.map +1 -0
  45. package/dist/resources/api-keys.js +166 -0
  46. package/dist/resources/api-keys.js.map +1 -0
  47. package/dist/resources/connectors.d.ts +263 -0
  48. package/dist/resources/connectors.d.ts.map +1 -0
  49. package/dist/resources/connectors.js +226 -0
  50. package/dist/resources/connectors.js.map +1 -0
  51. package/dist/resources/documents.d.ts +334 -0
  52. package/dist/resources/documents.d.ts.map +1 -0
  53. package/dist/resources/documents.js +377 -0
  54. package/dist/resources/documents.js.map +1 -0
  55. package/dist/resources/hooks.d.ts +195 -0
  56. package/dist/resources/hooks.d.ts.map +1 -0
  57. package/dist/resources/hooks.js +166 -0
  58. package/dist/resources/hooks.js.map +1 -0
  59. package/dist/resources/publish.d.ts +165 -0
  60. package/dist/resources/publish.d.ts.map +1 -0
  61. package/dist/resources/publish.js +150 -0
  62. package/dist/resources/publish.js.map +1 -0
  63. package/dist/resources/search.d.ts +94 -0
  64. package/dist/resources/search.d.ts.map +1 -0
  65. package/dist/resources/search.js +76 -0
  66. package/dist/resources/search.js.map +1 -0
  67. package/dist/resources/shares.d.ts +130 -0
  68. package/dist/resources/shares.d.ts.map +1 -0
  69. package/dist/resources/shares.js +115 -0
  70. package/dist/resources/shares.js.map +1 -0
  71. package/dist/resources/subscription.d.ts +172 -0
  72. package/dist/resources/subscription.d.ts.map +1 -0
  73. package/dist/resources/subscription.js +166 -0
  74. package/dist/resources/subscription.js.map +1 -0
  75. package/dist/resources/teams.d.ts +356 -0
  76. package/dist/resources/teams.d.ts.map +1 -0
  77. package/dist/resources/teams.js +395 -0
  78. package/dist/resources/teams.js.map +1 -0
  79. package/dist/resources/user.d.ts +92 -0
  80. package/dist/resources/user.d.ts.map +1 -0
  81. package/dist/resources/user.js +64 -0
  82. package/dist/resources/user.js.map +1 -0
  83. package/dist/resources/vaults.d.ts +144 -0
  84. package/dist/resources/vaults.d.ts.map +1 -0
  85. package/dist/resources/vaults.js +158 -0
  86. package/dist/resources/vaults.js.map +1 -0
  87. package/dist/resources/webhooks.d.ts +187 -0
  88. package/dist/resources/webhooks.d.ts.map +1 -0
  89. package/dist/resources/webhooks.js +171 -0
  90. package/dist/resources/webhooks.js.map +1 -0
  91. package/dist/types/api.d.ts +17 -0
  92. package/dist/types/api.d.ts.map +1 -0
  93. package/dist/types/api.js +2 -0
  94. package/dist/types/api.js.map +1 -0
  95. package/dist/types/index.d.ts +3 -0
  96. package/dist/types/index.d.ts.map +1 -0
  97. package/dist/types/index.js +2 -0
  98. package/dist/types/index.js.map +1 -0
  99. package/dist/types/resources.d.ts +5 -0
  100. package/dist/types/resources.d.ts.map +1 -0
  101. package/dist/types/resources.js +2 -0
  102. package/dist/types/resources.js.map +1 -0
  103. package/package.json +58 -0
package/README.md ADDED
@@ -0,0 +1,1121 @@
1
+ # Lifestream Vault SDK
2
+
3
+ Official TypeScript SDK for the Lifestream Vault API. Build powerful integrations with your Lifestream Vault account using a modern, type-safe client library.
4
+
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
6
+ [![npm version](https://img.shields.io/npm/v/@lifestream-vault/sdk.svg)](https://www.npmjs.com/package/@lifestream-vault/sdk)
7
+
8
+ ## πŸ“– Table of Contents
9
+
10
+ - [Features](#-features)
11
+ - [Installation](#-installation)
12
+ - [Quick Start](#-quick-start)
13
+ - [Authentication](#-authentication)
14
+ - [API Reference](#-api-reference)
15
+ - [Configuration](#-configuration)
16
+ - [Examples](#-examples)
17
+ - [Error Handling](#-error-handling)
18
+ - [TypeScript](#-typescript)
19
+ - [Advanced Features](#-advanced-features)
20
+ - [Documentation](#-documentation)
21
+ - [Related Packages](#-related-packages)
22
+ - [Troubleshooting](#-troubleshooting)
23
+ - [Support](#-support)
24
+ - [License](#-license)
25
+
26
+ ## ✨ Features
27
+
28
+ - **Full API Coverage** - Complete support for all Lifestream Vault API endpoints
29
+ - **TypeScript First** - Built with TypeScript, includes full type definitions
30
+ - **Dual Authentication** - Supports both API keys (`lsv_k_*`) and JWT tokens
31
+ - **Auto Token Refresh** - Automatic JWT token renewal with configurable refresh buffer
32
+ - **Request Signing** - HMAC-SHA256 request signing for enhanced security
33
+ - **Client-Side Encryption** - Optional end-to-end encryption for vault content
34
+ - **Smart Error Handling** - Typed error classes with detailed context
35
+ - **Modern ESM** - ES modules for tree-shaking and optimal bundle size
36
+ - **Built on Ky** - Leverages the modern, lightweight HTTP client
37
+ - **Audit Logging** - Optional client-side request audit logging
38
+ - **Zero Dependencies** - Only requires `ky` for HTTP requests
39
+
40
+ ## πŸ“¦ Installation
41
+
42
+ ### NPM (Recommended)
43
+
44
+ ```bash
45
+ npm install @lifestream-vault/sdk
46
+ ```
47
+
48
+ ### Yarn
49
+
50
+ ```bash
51
+ yarn add @lifestream-vault/sdk
52
+ ```
53
+
54
+ ### pnpm
55
+
56
+ ```bash
57
+ pnpm add @lifestream-vault/sdk
58
+ ```
59
+
60
+ ### CDN
61
+
62
+ ```html
63
+ <!-- ES Module -->
64
+ <script type="module">
65
+ import { LifestreamVaultClient } from 'https://unpkg.com/@lifestream-vault/sdk/dist/index.js';
66
+ </script>
67
+
68
+ <!-- Or via jsDelivr -->
69
+ <script type="module">
70
+ import { LifestreamVaultClient } from 'https://cdn.jsdelivr.net/npm/@lifestream-vault/sdk/+esm';
71
+ </script>
72
+ ```
73
+
74
+ ## πŸš€ Quick Start
75
+
76
+ ### Basic Usage with API Key
77
+
78
+ ```typescript
79
+ import { LifestreamVaultClient } from '@lifestream-vault/sdk';
80
+
81
+ const client = new LifestreamVaultClient({
82
+ baseUrl: 'https://vault.example.com',
83
+ apiKey: 'lsv_k_your_api_key_here',
84
+ });
85
+
86
+ // List all vaults
87
+ const vaults = await client.vaults.list();
88
+ console.log(vaults);
89
+
90
+ // Get a document
91
+ const doc = await client.documents.get('vault-id', 'path/to/document.md');
92
+ console.log(doc.content);
93
+ ```
94
+
95
+ ### Login with Email and Password
96
+
97
+ ```typescript
98
+ import { LifestreamVaultClient } from '@lifestream-vault/sdk';
99
+
100
+ const { client, tokens } = await LifestreamVaultClient.login(
101
+ 'https://vault.example.com',
102
+ 'user@example.com',
103
+ 'your-password',
104
+ );
105
+
106
+ // Client is now authenticated with JWT tokens
107
+ const vaults = await client.vaults.list();
108
+ ```
109
+
110
+ ### Using an Existing JWT Token
111
+
112
+ ```typescript
113
+ const client = new LifestreamVaultClient({
114
+ baseUrl: 'https://vault.example.com',
115
+ accessToken: 'eyJhbGci...', // Your JWT access token
116
+ refreshToken: 'your_refresh_token', // Optional: enables auto-refresh
117
+ });
118
+ ```
119
+
120
+ ### Error Handling
121
+
122
+ ```typescript
123
+ import { LifestreamVaultClient, NotFoundError, AuthenticationError } from '@lifestream-vault/sdk';
124
+
125
+ try {
126
+ const vault = await client.vaults.get('non-existent-id');
127
+ } catch (error) {
128
+ if (error instanceof NotFoundError) {
129
+ console.error('Vault not found:', error.message);
130
+ } else if (error instanceof AuthenticationError) {
131
+ console.error('Authentication failed:', error.message);
132
+ } else {
133
+ console.error('Unexpected error:', error);
134
+ }
135
+ }
136
+ ```
137
+
138
+ ## πŸ” Authentication
139
+
140
+ The SDK supports two authentication methods:
141
+
142
+ ### 1. API Key Authentication
143
+
144
+ Best for server-side integrations, automation scripts, and long-running services.
145
+
146
+ ```typescript
147
+ const client = new LifestreamVaultClient({
148
+ baseUrl: 'https://vault.example.com',
149
+ apiKey: 'lsv_k_your_api_key_here', // Starts with 'lsv_k_'
150
+ });
151
+ ```
152
+
153
+ **Features:**
154
+ - Simple, static authentication
155
+ - No expiration or refresh required
156
+ - Automatic HMAC request signing for mutating operations
157
+ - Scoped permissions (read-only, read-write, or vault-specific)
158
+
159
+ **How to get an API key:**
160
+ 1. Log in to your Lifestream Vault account
161
+ 2. Navigate to Settings β†’ API Keys
162
+ 3. Click "Create API Key"
163
+ 4. Configure scopes and expiration
164
+ 5. Copy your key (starts with `lsv_k_`)
165
+
166
+ ### 2. JWT Token Authentication
167
+
168
+ Best for user-facing applications and scenarios requiring user-specific permissions.
169
+
170
+ ```typescript
171
+ const client = new LifestreamVaultClient({
172
+ baseUrl: 'https://vault.example.com',
173
+ accessToken: 'eyJhbGci...', // Your JWT access token
174
+ refreshToken: 'your_refresh_token', // Optional but recommended
175
+ refreshBufferMs: 60000, // Refresh 60s before expiry (default)
176
+ onTokenRefresh: (tokens) => {
177
+ // Save new tokens to your storage
178
+ localStorage.setItem('accessToken', tokens.accessToken);
179
+ },
180
+ });
181
+ ```
182
+
183
+ **Features:**
184
+ - User-specific permissions
185
+ - Automatic token refresh (when `refreshToken` provided)
186
+ - Configurable refresh timing
187
+ - Token refresh callbacks for persistence
188
+
189
+ **Login Helper:**
190
+ ```typescript
191
+ const { client, tokens, refreshToken } = await LifestreamVaultClient.login(
192
+ 'https://vault.example.com',
193
+ 'user@example.com',
194
+ 'password',
195
+ {
196
+ onTokenRefresh: (newTokens) => {
197
+ // Persist tokens for session restoration
198
+ sessionStorage.setItem('tokens', JSON.stringify(newTokens));
199
+ },
200
+ },
201
+ );
202
+ ```
203
+
204
+ ## πŸ“š API Reference
205
+
206
+ The SDK provides resource-based access to all API endpoints:
207
+
208
+ ### Vaults
209
+
210
+ Manage vault containers for organizing documents.
211
+
212
+ ```typescript
213
+ // List all vaults
214
+ const vaults = await client.vaults.list();
215
+
216
+ // Get a specific vault
217
+ const vault = await client.vaults.get('vault-id');
218
+
219
+ // Create a new vault
220
+ const newVault = await client.vaults.create({
221
+ name: 'My Notes',
222
+ slug: 'my-notes', // Optional: auto-generated from name
223
+ description: 'Personal notes and ideas',
224
+ encryptionEnabled: false,
225
+ });
226
+
227
+ // Update a vault
228
+ const updated = await client.vaults.update('vault-id', {
229
+ name: 'Updated Name',
230
+ description: 'New description',
231
+ });
232
+
233
+ // Delete a vault
234
+ await client.vaults.delete('vault-id');
235
+ ```
236
+
237
+ ### Documents
238
+
239
+ Read, write, and manage Markdown documents within vaults.
240
+
241
+ ```typescript
242
+ // List documents in a vault
243
+ const docs = await client.documents.list('vault-id');
244
+
245
+ // Get a document with content
246
+ const doc = await client.documents.get('vault-id', 'path/to/doc.md');
247
+ console.log(doc.content); // Raw Markdown content
248
+
249
+ // Create or update a document
250
+ await client.documents.put('vault-id', 'new-doc.md', '# Hello World\n\nMy content');
251
+
252
+ // Get document metadata only
253
+ const metadata = await client.documents.getMetadata('vault-id', 'path/to/doc.md');
254
+
255
+ // Delete a document
256
+ await client.documents.delete('vault-id', 'path/to/doc.md');
257
+
258
+ // Get directory tree structure
259
+ const tree = await client.documents.tree('vault-id');
260
+
261
+ // List document versions
262
+ const versions = await client.documents.listVersions('vault-id', 'path/to/doc.md');
263
+
264
+ // Get a specific version
265
+ const version = await client.documents.getVersion('vault-id', 'path/to/doc.md', 5);
266
+
267
+ // Compare versions (diff)
268
+ const diff = await client.documents.diffVersions('vault-id', 'path/to/doc.md', 3, 5);
269
+ ```
270
+
271
+ ### Search
272
+
273
+ Full-text search across your vaults with filtering.
274
+
275
+ ```typescript
276
+ // Search all vaults
277
+ const results = await client.search.search({
278
+ query: 'typescript',
279
+ vaultIds: ['vault-1', 'vault-2'], // Optional: filter by vaults
280
+ tags: ['code', 'tutorial'], // Optional: filter by tags
281
+ limit: 20,
282
+ offset: 0,
283
+ });
284
+
285
+ for (const result of results.results) {
286
+ console.log(result.title, result.highlight);
287
+ }
288
+
289
+ // Get autocomplete suggestions
290
+ const suggestions = await client.search.autocomplete('type');
291
+ ```
292
+
293
+ ### AI
294
+
295
+ AI-powered document chat and summarization.
296
+
297
+ ```typescript
298
+ // Create a chat session
299
+ const session = await client.ai.createSession({
300
+ vaultId: 'vault-id',
301
+ documentPaths: ['doc1.md', 'doc2.md'], // Optional: specific docs
302
+ systemPrompt: 'You are a helpful assistant.', // Optional
303
+ });
304
+
305
+ // Send a message
306
+ const response = await client.ai.sendMessage(session.id, {
307
+ message: 'Summarize the key points from these documents',
308
+ });
309
+
310
+ console.log(response.message); // AI response
311
+
312
+ // List all chat sessions
313
+ const sessions = await client.ai.listSessions();
314
+
315
+ // Get session details
316
+ const sessionDetail = await client.ai.getSession(session.id);
317
+
318
+ // Delete a session
319
+ await client.ai.deleteSession(session.id);
320
+ ```
321
+
322
+ ### Teams
323
+
324
+ Collaborate with team members on shared vaults.
325
+
326
+ ```typescript
327
+ // List your teams
328
+ const teams = await client.teams.list();
329
+
330
+ // Create a team
331
+ const team = await client.teams.create({
332
+ name: 'Engineering',
333
+ description: 'Engineering team workspace',
334
+ });
335
+
336
+ // Add a member
337
+ await client.teams.addMember(team.id, {
338
+ email: 'colleague@example.com',
339
+ role: 'member', // 'admin' or 'member'
340
+ });
341
+
342
+ // Create a team vault
343
+ const teamVault = await client.teams.createVault(team.id, {
344
+ name: 'Team Docs',
345
+ });
346
+
347
+ // List team vaults
348
+ const teamVaults = await client.teams.listVaults(team.id);
349
+ ```
350
+
351
+ ### API Keys
352
+
353
+ Manage API keys for programmatic access.
354
+
355
+ ```typescript
356
+ // List API keys
357
+ const keys = await client.apiKeys.list();
358
+
359
+ // Create an API key
360
+ const apiKey = await client.apiKeys.create({
361
+ name: 'CI/CD Key',
362
+ scopes: ['vaults:read', 'documents:read'],
363
+ vaultId: 'vault-id', // Optional: scope to specific vault
364
+ expiresAt: '2026-12-31T23:59:59Z', // Optional
365
+ });
366
+
367
+ console.log(apiKey.secret); // Only shown once! Save it securely
368
+
369
+ // Delete an API key
370
+ await client.apiKeys.delete('key-id');
371
+ ```
372
+
373
+ ### User
374
+
375
+ Manage user profile and storage information.
376
+
377
+ ```typescript
378
+ // Get current user profile
379
+ const user = await client.user.get();
380
+ console.log(user.email, user.name);
381
+
382
+ // Get storage usage
383
+ const storage = await client.user.getStorage();
384
+ console.log(`Used: ${storage.totalBytes} / ${storage.limitBytes} bytes`);
385
+ ```
386
+
387
+ ### Subscription
388
+
389
+ Manage subscription plans and billing.
390
+
391
+ ```typescript
392
+ // Get current subscription
393
+ const subscription = await client.subscription.get();
394
+ console.log(subscription.tier); // 'free', 'pro', or 'business'
395
+
396
+ // Get available plans
397
+ const plans = await client.subscription.getPlans();
398
+
399
+ // Create a checkout session for upgrading
400
+ const checkout = await client.subscription.createCheckout({
401
+ planId: 'pro-monthly',
402
+ successUrl: 'https://example.com/success',
403
+ cancelUrl: 'https://example.com/cancel',
404
+ });
405
+
406
+ // Open checkout.url in browser for payment
407
+
408
+ // Create a billing portal session
409
+ const portal = await client.subscription.createPortalSession({
410
+ returnUrl: 'https://example.com/settings',
411
+ });
412
+ ```
413
+
414
+ ### Shares
415
+
416
+ Create temporary share links for documents.
417
+
418
+ ```typescript
419
+ // Create a share link
420
+ const share = await client.shares.create({
421
+ vaultId: 'vault-id',
422
+ documentPath: 'path/to/doc.md',
423
+ expiresAt: '2026-03-01T00:00:00Z', // Optional
424
+ password: 'secret123', // Optional
425
+ });
426
+
427
+ console.log(share.shareUrl); // Share this URL
428
+
429
+ // List all shares
430
+ const shares = await client.shares.list();
431
+
432
+ // Revoke a share
433
+ await client.shares.delete('share-token');
434
+ ```
435
+
436
+ ### Publish
437
+
438
+ Publish documents for public access.
439
+
440
+ ```typescript
441
+ // Publish a document
442
+ const published = await client.publish.publish({
443
+ vaultId: 'vault-id',
444
+ documentPath: 'blog/post.md',
445
+ slug: 'my-blog-post', // Optional: auto-generated
446
+ });
447
+
448
+ console.log(published.publicUrl); // Public URL
449
+
450
+ // List published documents
451
+ const docs = await client.publish.list();
452
+
453
+ // Unpublish
454
+ await client.publish.unpublish('vault-id', 'blog/post.md');
455
+ ```
456
+
457
+ ### Connectors
458
+
459
+ Sync with external services like Google Drive.
460
+
461
+ ```typescript
462
+ // List connectors
463
+ const connectors = await client.connectors.list();
464
+
465
+ // Create a Google Drive connector
466
+ const connector = await client.connectors.create({
467
+ vaultId: 'vault-id',
468
+ provider: 'google_drive',
469
+ config: {
470
+ folderId: 'google-drive-folder-id',
471
+ credentials: { /* OAuth credentials */ },
472
+ },
473
+ syncDirection: 'bidirectional',
474
+ });
475
+
476
+ // Test connection
477
+ const testResult = await client.connectors.testConnection(connector.id);
478
+ console.log(testResult.success);
479
+
480
+ // Trigger manual sync
481
+ await client.connectors.triggerSync(connector.id);
482
+
483
+ // View sync logs
484
+ const logs = await client.connectors.getSyncLogs(connector.id);
485
+ ```
486
+
487
+ ### Hooks
488
+
489
+ Configure internal event handlers for automation.
490
+
491
+ ```typescript
492
+ // List hooks
493
+ const hooks = await client.hooks.list('vault-id');
494
+
495
+ // Create a hook
496
+ const hook = await client.hooks.create('vault-id', {
497
+ name: 'Auto-tag documents',
498
+ eventType: 'document.created',
499
+ handlerType: 'auto_tag',
500
+ config: {
501
+ tags: ['inbox'],
502
+ },
503
+ enabled: true,
504
+ });
505
+
506
+ // View hook executions
507
+ const executions = await client.hooks.getExecutions('vault-id', hook.id);
508
+ ```
509
+
510
+ ### Webhooks
511
+
512
+ Send HTTP notifications on vault events.
513
+
514
+ ```typescript
515
+ // List webhooks
516
+ const webhooks = await client.webhooks.list('vault-id');
517
+
518
+ // Create a webhook
519
+ const webhook = await client.webhooks.create('vault-id', {
520
+ url: 'https://example.com/webhook',
521
+ events: ['document.created', 'document.updated'],
522
+ enabled: true,
523
+ });
524
+
525
+ console.log(webhook.secret); // Use for HMAC verification
526
+
527
+ // View delivery logs
528
+ const deliveries = await client.webhooks.getDeliveries('vault-id', webhook.id);
529
+ ```
530
+
531
+ ### Admin
532
+
533
+ Administrative operations (requires admin role).
534
+
535
+ ```typescript
536
+ // Get system stats
537
+ const stats = await client.admin.getStats();
538
+ console.log(stats.totalUsers, stats.totalVaults);
539
+
540
+ // List all users (paginated)
541
+ const users = await client.admin.listUsers({ page: 1, limit: 50 });
542
+
543
+ // Get user details
544
+ const userDetail = await client.admin.getUser('user-id');
545
+
546
+ // Update user
547
+ await client.admin.updateUser('user-id', {
548
+ role: 'admin',
549
+ isActive: true,
550
+ });
551
+
552
+ // Get system health
553
+ const health = await client.admin.getHealth();
554
+ console.log(health.status); // 'healthy', 'degraded', or 'down'
555
+ ```
556
+
557
+ ## βš™οΈ Configuration
558
+
559
+ ### ClientOptions
560
+
561
+ | Option | Type | Default | Description |
562
+ |--------|------|---------|-------------|
563
+ | `baseUrl` | `string` | **required** | Base URL of your Lifestream Vault server |
564
+ | `apiKey` | `string` | - | API key for authentication (starts with `lsv_k_`) |
565
+ | `accessToken` | `string` | - | JWT access token for user authentication |
566
+ | `refreshToken` | `string` | - | JWT refresh token for automatic renewal |
567
+ | `timeout` | `number` | `30000` | Request timeout in milliseconds |
568
+ | `refreshBufferMs` | `number` | `60000` | Milliseconds before expiry to trigger proactive refresh |
569
+ | `onTokenRefresh` | `function` | - | Callback when tokens are refreshed |
570
+ | `enableRequestSigning` | `boolean` | `true` (API keys) | Enable HMAC request signing |
571
+ | `enableAuditLogging` | `boolean` | `false` | Enable client-side audit logging |
572
+ | `auditLogPath` | `string` | `~/.lsvault/audit.log` | Path to audit log file |
573
+
574
+ ### Full Configuration Example
575
+
576
+ ```typescript
577
+ const client = new LifestreamVaultClient({
578
+ baseUrl: 'https://vault.example.com',
579
+ apiKey: 'lsv_k_your_api_key',
580
+ timeout: 60000, // 60 seconds
581
+ enableRequestSigning: true,
582
+ enableAuditLogging: true,
583
+ auditLogPath: '/var/log/lsvault-audit.log',
584
+ });
585
+ ```
586
+
587
+ ### JWT Configuration Example
588
+
589
+ ```typescript
590
+ const client = new LifestreamVaultClient({
591
+ baseUrl: 'https://vault.example.com',
592
+ accessToken: 'eyJhbGci...',
593
+ refreshToken: 'refresh_token_here',
594
+ refreshBufferMs: 120000, // Refresh 2 minutes before expiry
595
+ onTokenRefresh: (tokens) => {
596
+ // Persist new tokens
597
+ localStorage.setItem('accessToken', tokens.accessToken);
598
+ console.log('Tokens refreshed successfully');
599
+ },
600
+ });
601
+ ```
602
+
603
+ ## πŸ’‘ Examples
604
+
605
+ ### Create a Vault and Upload Documents
606
+
607
+ ```typescript
608
+ import { LifestreamVaultClient } from '@lifestream-vault/sdk';
609
+
610
+ const client = new LifestreamVaultClient({
611
+ baseUrl: 'https://vault.example.com',
612
+ apiKey: 'lsv_k_your_api_key',
613
+ });
614
+
615
+ // Create a vault
616
+ const vault = await client.vaults.create({
617
+ name: 'Project Documentation',
618
+ description: 'Technical docs for the new project',
619
+ });
620
+
621
+ // Upload multiple documents
622
+ const docs = [
623
+ { path: 'README.md', content: '# Project Overview\n\nWelcome!' },
624
+ { path: 'setup/installation.md', content: '# Installation\n\n...' },
625
+ { path: 'api/reference.md', content: '# API Reference\n\n...' },
626
+ ];
627
+
628
+ for (const doc of docs) {
629
+ await client.documents.put(vault.id, doc.path, doc.content);
630
+ console.log(`Uploaded: ${doc.path}`);
631
+ }
632
+
633
+ console.log('Vault created and documents uploaded successfully!');
634
+ ```
635
+
636
+ ### Search and Export Documents
637
+
638
+ ```typescript
639
+ // Search for documents with specific tags
640
+ const results = await client.search.search({
641
+ query: 'API',
642
+ tags: ['documentation', 'tutorial'],
643
+ vaultIds: [vault.id],
644
+ });
645
+
646
+ // Export matching documents
647
+ for (const result of results.results) {
648
+ const doc = await client.documents.get(result.vaultId, result.path);
649
+
650
+ // Save to local file system
651
+ await fs.writeFile(`./export/${result.path}`, doc.content);
652
+ console.log(`Exported: ${result.path}`);
653
+ }
654
+ ```
655
+
656
+ ### AI-Powered Document Q&A
657
+
658
+ ```typescript
659
+ // Create an AI session with specific documents
660
+ const session = await client.ai.createSession({
661
+ vaultId: vault.id,
662
+ documentPaths: ['api/reference.md', 'setup/installation.md'],
663
+ systemPrompt: 'You are a technical documentation assistant.',
664
+ });
665
+
666
+ // Ask questions about the documents
667
+ const response1 = await client.ai.sendMessage(session.id, {
668
+ message: 'What are the authentication methods supported?',
669
+ });
670
+
671
+ console.log('AI:', response1.message);
672
+
673
+ const response2 = await client.ai.sendMessage(session.id, {
674
+ message: 'How do I install the SDK?',
675
+ });
676
+
677
+ console.log('AI:', response2.message);
678
+ ```
679
+
680
+ ### Automated Backup Script
681
+
682
+ ```typescript
683
+ import { LifestreamVaultClient } from '@lifestream-vault/sdk';
684
+ import fs from 'fs/promises';
685
+ import path from 'path';
686
+
687
+ const client = new LifestreamVaultClient({
688
+ baseUrl: 'https://vault.example.com',
689
+ apiKey: process.env.LSVAULT_API_KEY!,
690
+ });
691
+
692
+ async function backupAllVaults() {
693
+ const vaults = await client.vaults.list();
694
+ const backupDir = `./backups/${new Date().toISOString().split('T')[0]}`;
695
+
696
+ await fs.mkdir(backupDir, { recursive: true });
697
+
698
+ for (const vault of vaults) {
699
+ console.log(`Backing up vault: ${vault.name}`);
700
+ const documents = await client.documents.list(vault.id);
701
+
702
+ for (const doc of documents) {
703
+ const docData = await client.documents.get(vault.id, doc.path);
704
+ const filePath = path.join(backupDir, vault.slug, doc.path);
705
+
706
+ await fs.mkdir(path.dirname(filePath), { recursive: true });
707
+ await fs.writeFile(filePath, docData.content);
708
+ }
709
+
710
+ console.log(`βœ“ Backed up ${documents.length} documents from ${vault.name}`);
711
+ }
712
+
713
+ console.log(`Backup completed: ${backupDir}`);
714
+ }
715
+
716
+ backupAllVaults().catch(console.error);
717
+ ```
718
+
719
+ ### Team Collaboration Setup
720
+
721
+ ```typescript
722
+ // Create a team
723
+ const team = await client.teams.create({
724
+ name: 'Marketing Team',
725
+ description: 'Marketing team collaboration space',
726
+ });
727
+
728
+ // Add team members
729
+ const members = [
730
+ { email: 'alice@example.com', role: 'admin' },
731
+ { email: 'bob@example.com', role: 'member' },
732
+ { email: 'carol@example.com', role: 'member' },
733
+ ];
734
+
735
+ for (const member of members) {
736
+ await client.teams.addMember(team.id, member);
737
+ console.log(`Added ${member.email} as ${member.role}`);
738
+ }
739
+
740
+ // Create a shared vault for the team
741
+ const teamVault = await client.teams.createVault(team.id, {
742
+ name: 'Campaign Materials',
743
+ description: 'Shared marketing campaign documents',
744
+ });
745
+
746
+ // Upload initial documents
747
+ await client.documents.put(
748
+ teamVault.id,
749
+ 'campaigns/2026-q1.md',
750
+ '# Q1 2026 Campaign\n\n## Goals\n- Increase brand awareness\n- Launch new product',
751
+ );
752
+
753
+ console.log('Team setup complete!');
754
+ ```
755
+
756
+ ## 🚨 Error Handling
757
+
758
+ The SDK provides typed error classes for different error scenarios:
759
+
760
+ ### Error Types
761
+
762
+ ```typescript
763
+ import {
764
+ SDKError, // Base error class
765
+ ValidationError, // Invalid input or configuration
766
+ AuthenticationError,// Authentication failed
767
+ AuthorizationError, // Insufficient permissions
768
+ NotFoundError, // Resource not found
769
+ ConflictError, // Resource conflict (e.g., duplicate slug)
770
+ RateLimitError, // Rate limit exceeded
771
+ NetworkError, // Network or connection error
772
+ } from '@lifestream-vault/sdk';
773
+ ```
774
+
775
+ ### Handling Specific Errors
776
+
777
+ ```typescript
778
+ try {
779
+ await client.vaults.create({ name: 'My Vault', slug: 'existing-slug' });
780
+ } catch (error) {
781
+ if (error instanceof ConflictError) {
782
+ console.error('A vault with this slug already exists');
783
+ } else if (error instanceof ValidationError) {
784
+ console.error('Invalid vault configuration:', error.message);
785
+ } else if (error instanceof RateLimitError) {
786
+ console.error('Rate limit exceeded. Try again later.');
787
+ } else {
788
+ console.error('Unexpected error:', error);
789
+ }
790
+ }
791
+ ```
792
+
793
+ ### Error Properties
794
+
795
+ All SDK errors include:
796
+
797
+ ```typescript
798
+ error.message // Human-readable error message
799
+ error.status // HTTP status code (if applicable)
800
+ error.context // Additional error context (resource type, ID, etc.)
801
+ ```
802
+
803
+ ### Retry Logic Example
804
+
805
+ ```typescript
806
+ import { RateLimitError, NetworkError } from '@lifestream-vault/sdk';
807
+
808
+ async function fetchWithRetry(operation: () => Promise<any>, maxRetries = 3) {
809
+ for (let i = 0; i < maxRetries; i++) {
810
+ try {
811
+ return await operation();
812
+ } catch (error) {
813
+ if (error instanceof RateLimitError || error instanceof NetworkError) {
814
+ if (i < maxRetries - 1) {
815
+ const delay = Math.pow(2, i) * 1000; // Exponential backoff
816
+ console.log(`Retrying in ${delay}ms...`);
817
+ await new Promise(resolve => setTimeout(resolve, delay));
818
+ continue;
819
+ }
820
+ }
821
+ throw error;
822
+ }
823
+ }
824
+ }
825
+
826
+ // Usage
827
+ const vaults = await fetchWithRetry(() => client.vaults.list());
828
+ ```
829
+
830
+ ## πŸ“˜ TypeScript
831
+
832
+ The SDK is built with TypeScript and provides full type definitions out of the box.
833
+
834
+ ### Type Imports
835
+
836
+ ```typescript
837
+ import {
838
+ LifestreamVaultClient,
839
+ type ClientOptions,
840
+ type Vault,
841
+ type Document,
842
+ type DocumentWithContent,
843
+ type SearchResult,
844
+ type AiChatSession,
845
+ type Team,
846
+ type ApiKey,
847
+ type Subscription,
848
+ } from '@lifestream-vault/sdk';
849
+ ```
850
+
851
+ ### Type Safety
852
+
853
+ ```typescript
854
+ // Compiler catches missing required fields
855
+ const vault = await client.vaults.create({
856
+ name: 'My Vault',
857
+ // slug is optional, auto-generated
858
+ // TypeScript won't let you pass invalid fields
859
+ });
860
+
861
+ // Full autocomplete and type checking
862
+ const doc = await client.documents.get('vault-id', 'path.md');
863
+ doc.content; // string
864
+ doc.document.tags; // string[]
865
+ doc.document.sizeBytes; // number
866
+ ```
867
+
868
+ ### Generic Error Handling
869
+
870
+ ```typescript
871
+ import { SDKError } from '@lifestream-vault/sdk';
872
+
873
+ try {
874
+ await client.vaults.get('invalid-id');
875
+ } catch (error) {
876
+ if (error instanceof SDKError) {
877
+ // TypeScript knows about status, message, context
878
+ console.error(`Error ${error.status}: ${error.message}`);
879
+ }
880
+ }
881
+ ```
882
+
883
+ ## πŸ”§ Advanced Features
884
+
885
+ ### Request Signing (HMAC-SHA256)
886
+
887
+ Automatically enabled for API key authentication. Adds signature headers to mutating requests (PUT, POST, DELETE, PATCH) for enhanced security.
888
+
889
+ ```typescript
890
+ const client = new LifestreamVaultClient({
891
+ baseUrl: 'https://vault.example.com',
892
+ apiKey: 'lsv_k_your_api_key',
893
+ enableRequestSigning: true, // Default: true for API keys
894
+ });
895
+
896
+ // All mutating requests are now signed with HMAC-SHA256
897
+ await client.documents.put('vault-id', 'doc.md', 'content');
898
+ ```
899
+
900
+ **Manual Signing:**
901
+
902
+ ```typescript
903
+ import { signRequest } from '@lifestream-vault/sdk';
904
+
905
+ const headers = signRequest(
906
+ 'lsv_k_your_api_key',
907
+ 'POST',
908
+ '/api/v1/vaults',
909
+ JSON.stringify({ name: 'My Vault' }),
910
+ );
911
+
912
+ console.log(headers['X-Signature']); // HMAC signature
913
+ console.log(headers['X-Signature-Timestamp']); // ISO timestamp
914
+ console.log(headers['X-Signature-Nonce']); // Random nonce
915
+ ```
916
+
917
+ ### Audit Logging
918
+
919
+ Enable client-side request logging for compliance and debugging.
920
+
921
+ ```typescript
922
+ const client = new LifestreamVaultClient({
923
+ baseUrl: 'https://vault.example.com',
924
+ apiKey: 'lsv_k_your_api_key',
925
+ enableAuditLogging: true,
926
+ auditLogPath: '/var/log/lsvault/audit.log',
927
+ });
928
+
929
+ // All requests are now logged to the audit file
930
+ await client.vaults.list();
931
+
932
+ // Log entry format:
933
+ // {"timestamp":"2026-02-14T10:30:00.000Z","method":"GET","path":"/api/v1/vaults","status":200,"durationMs":145}
934
+ ```
935
+
936
+ **Standalone Audit Logger:**
937
+
938
+ ```typescript
939
+ import { AuditLogger } from '@lifestream-vault/sdk';
940
+
941
+ const logger = new AuditLogger({ logPath: './custom-audit.log' });
942
+
943
+ logger.log({
944
+ timestamp: new Date().toISOString(),
945
+ method: 'POST',
946
+ path: '/api/v1/vaults',
947
+ status: 201,
948
+ durationMs: 234,
949
+ });
950
+ ```
951
+
952
+ ### Client-Side Encryption
953
+
954
+ Encrypt vault content client-side before uploading (requires encryption-enabled vault).
955
+
956
+ ```typescript
957
+ import { generateVaultKey, encryptContent, decryptContent } from '@lifestream-vault/sdk';
958
+
959
+ // Generate a vault encryption key (save this securely!)
960
+ const vaultKey = generateVaultKey();
961
+ console.log('Save this key:', vaultKey); // Base64-encoded AES-256 key
962
+
963
+ // Create an encryption-enabled vault
964
+ const vault = await client.vaults.create({
965
+ name: 'Secure Vault',
966
+ encryptionEnabled: true,
967
+ });
968
+
969
+ // Encrypt content before uploading
970
+ const plaintext = '# Secret Document\n\nSensitive information here.';
971
+ const encrypted = encryptContent(plaintext, vaultKey);
972
+
973
+ await client.documents.put(vault.id, 'secret.md', encrypted);
974
+
975
+ // Decrypt when reading
976
+ const doc = await client.documents.get(vault.id, 'secret.md');
977
+ const decrypted = decryptContent(doc.content, vaultKey);
978
+ console.log(decrypted); // Original plaintext
979
+ ```
980
+
981
+ **Note:** The server never sees your encryption key. Store it securely and never lose itβ€”there's no recovery mechanism.
982
+
983
+ ### Token Management Utilities
984
+
985
+ ```typescript
986
+ import { decodeJwtPayload, isTokenExpired } from '@lifestream-vault/sdk';
987
+
988
+ const token = 'eyJhbGci...';
989
+
990
+ // Decode JWT payload without verification
991
+ const payload = decodeJwtPayload(token);
992
+ console.log(payload.userId, payload.email);
993
+
994
+ // Check if token is expired
995
+ if (isTokenExpired(token)) {
996
+ console.log('Token has expired, need to refresh');
997
+ }
998
+ ```
999
+
1000
+ ### Direct HTTP Access
1001
+
1002
+ Access the underlying `ky` HTTP client for custom requests:
1003
+
1004
+ ```typescript
1005
+ const client = new LifestreamVaultClient({
1006
+ baseUrl: 'https://vault.example.com',
1007
+ apiKey: 'lsv_k_your_api_key',
1008
+ });
1009
+
1010
+ // Make custom API requests
1011
+ const response = await client.http.get('custom/endpoint').json();
1012
+
1013
+ // The client is pre-configured with:
1014
+ // - Authentication headers
1015
+ // - Base URL (https://vault.example.com/api/v1)
1016
+ // - Timeout settings
1017
+ // - Request signing (if enabled)
1018
+ ```
1019
+
1020
+ ## πŸ“š Documentation
1021
+
1022
+ For complete API documentation, guides, and examples, visit:
1023
+
1024
+ **[https://vault.lifestreamdynamics.com/docs](https://vault.lifestreamdynamics.com/docs)**
1025
+
1026
+ ### Additional Resources
1027
+
1028
+ - **API Reference**: Full OpenAPI spec at your server's `/api/docs`
1029
+ - **Integration Guides**: Step-by-step tutorials for common use cases
1030
+ - **Best Practices**: Security, performance, and architecture recommendations
1031
+ - **Migration Guides**: Upgrade paths for major version changes
1032
+
1033
+ ## πŸ”— Related Packages
1034
+
1035
+ - **[@lifestream-vault/cli](https://www.npmjs.com/package/@lifestream-vault/cli)** - Command-line interface for Lifestream Vault
1036
+ - **[@lifestream-vault/shared](https://www.npmjs.com/package/@lifestream-vault/shared)** - Shared types and schemas
1037
+
1038
+ ## πŸ› Troubleshooting
1039
+
1040
+ ### Connection Issues
1041
+
1042
+ **Problem:** `NetworkError: Failed to fetch`
1043
+
1044
+ **Solutions:**
1045
+ - βœ… Verify the `baseUrl` is correct and accessible
1046
+ - βœ… Check network connectivity
1047
+ - βœ… Ensure CORS is configured on the server (for browser usage)
1048
+ - βœ… Try increasing the `timeout` option
1049
+
1050
+ ### Authentication Failures
1051
+
1052
+ **Problem:** `AuthenticationError: Invalid credentials`
1053
+
1054
+ **Solutions:**
1055
+ - βœ… Verify your API key or JWT token is valid
1056
+ - βœ… Check that the API key starts with `lsv_k_`
1057
+ - βœ… Ensure the token hasn't expired
1058
+ - βœ… For JWT auth, verify the `refreshToken` is correct
1059
+
1060
+ ### Rate Limiting
1061
+
1062
+ **Problem:** `RateLimitError: Too many requests`
1063
+
1064
+ **Solutions:**
1065
+ - βœ… Implement exponential backoff retry logic
1066
+ - βœ… Reduce request frequency
1067
+ - βœ… Consider upgrading your subscription plan
1068
+ - βœ… Cache frequently accessed data
1069
+
1070
+ ### TypeScript Errors
1071
+
1072
+ **Problem:** Type errors when importing
1073
+
1074
+ **Solutions:**
1075
+ - βœ… Ensure TypeScript version is 5.0 or higher
1076
+ - βœ… Check that `moduleResolution` is set to `node16` or `bundler` in `tsconfig.json`
1077
+ - βœ… Verify `"type": "module"` in your `package.json` for ESM projects
1078
+
1079
+ ### HMAC Signature Failures
1080
+
1081
+ **Problem:** `AuthorizationError: Invalid signature`
1082
+
1083
+ **Solutions:**
1084
+ - βœ… Ensure server and client clocks are synchronized
1085
+ - βœ… Verify `enableRequestSigning` is enabled on the client
1086
+ - βœ… Check that the API key is correct and has signing permissions
1087
+ - βœ… Ensure no middleware is modifying request bodies
1088
+
1089
+ ### Token Refresh Not Working
1090
+
1091
+ **Problem:** `AuthenticationError` despite having a refresh token
1092
+
1093
+ **Solutions:**
1094
+ - βœ… Verify `refreshToken` is provided in `ClientOptions`
1095
+ - βœ… Check that the refresh token hasn't expired
1096
+ - βœ… Ensure `onTokenRefresh` callback is saving new tokens
1097
+ - βœ… Verify server-side refresh endpoint is accessible
1098
+
1099
+ ## πŸ’¬ Support
1100
+
1101
+ Need help? We're here for you!
1102
+
1103
+ - **GitHub Issues**: [Report bugs or request features](https://github.com/lifestreamdynamics/lifestream-vault-sdk/issues)
1104
+ - **Email**: eric@lifestreamdynamics.com
1105
+ - **Documentation**: [vault.lifestreamdynamics.com/docs](https://vault.lifestreamdynamics.com/docs)
1106
+
1107
+ When reporting issues, please include:
1108
+ - SDK version (`npm list @lifestream-vault/sdk`)
1109
+ - Node.js version (`node --version`)
1110
+ - Error messages and stack traces
1111
+ - Minimal reproduction code (without sensitive credentials)
1112
+
1113
+ ## πŸ“„ License
1114
+
1115
+ MIT License - see [LICENSE](./LICENSE) file for details.
1116
+
1117
+ Copyright (c) 2025-2026 Lifestream Dynamics
1118
+
1119
+ ---
1120
+
1121
+ **Built with ❀️ by [Lifestream Dynamics](https://lifestreamdynamics.com)**