@meistrari/vault-sdk 1.6.2 → 1.7.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/README.md +386 -89
- package/dist/index.cjs +22 -2
- package/dist/index.mjs +22 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,159 +8,456 @@ This is the SDK for Vault V2.
|
|
|
8
8
|
ni @meistrari/vault-sdk-sdk
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Table of Contents
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
- [Core Concepts](#core-concepts)
|
|
14
|
+
- [Quick Start](#quick-start)
|
|
15
|
+
- [Authentication Strategies](#authentication-strategies)
|
|
16
|
+
- [API Reference](#api-reference)
|
|
17
|
+
- [VaultFile](#vaultfile)
|
|
18
|
+
- [Vault Client](#vault-client)
|
|
19
|
+
- [Permalinks](#permalinks)
|
|
20
|
+
- [Advanced Usage](#advanced-usage)
|
|
15
21
|
|
|
16
|
-
|
|
22
|
+
## Core Concepts
|
|
17
23
|
|
|
18
|
-
|
|
24
|
+
The SDK revolves around two main components:
|
|
25
|
+
|
|
26
|
+
1. **VaultFile** - The primary class for interacting with files in the vault
|
|
27
|
+
2. **Vault Client** - A helper function (`vaultClient`) that simplifies creating VaultFile instances with shared configuration
|
|
28
|
+
|
|
29
|
+
Files in the vault are identified by vault references in the format `vault://{fileId}`.
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
19
32
|
|
|
20
33
|
```ts
|
|
34
|
+
import { VaultFile, DataTokenAuthStrategy } from '@meistrari/vault-sdk'
|
|
35
|
+
|
|
36
|
+
const config = {
|
|
37
|
+
vaultUrl: 'https://vault.tela.com',
|
|
38
|
+
authStrategy: new DataTokenAuthStrategy('[your-data-token]')
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Upload a new file
|
|
42
|
+
const file = new File(['Hello World'], 'hello.txt')
|
|
21
43
|
const vaultFile = await VaultFile.fromContent({
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
config
|
|
25
|
-
|
|
26
|
-
authStrategy: new DataTokenAuthStrategy(dataToken)
|
|
27
|
-
},
|
|
28
|
-
upload: true // Optional: upload immediately
|
|
44
|
+
name: 'hello.txt',
|
|
45
|
+
content: file,
|
|
46
|
+
config,
|
|
47
|
+
upload: true
|
|
29
48
|
})
|
|
49
|
+
|
|
50
|
+
// Get the vault reference to store in your database
|
|
51
|
+
const reference = vaultFile.getVaultReference() // 'vault://abc123...'
|
|
52
|
+
|
|
53
|
+
// Later, retrieve and download the file
|
|
54
|
+
const retrieved = await VaultFile.fromVaultReference({
|
|
55
|
+
reference,
|
|
56
|
+
config
|
|
57
|
+
})
|
|
58
|
+
const content = await retrieved.download() // Returns a Blob
|
|
30
59
|
```
|
|
31
60
|
|
|
32
|
-
|
|
61
|
+
## Authentication Strategies
|
|
62
|
+
|
|
63
|
+
The SDK provides two authentication strategies:
|
|
33
64
|
|
|
34
|
-
|
|
65
|
+
### DataTokenAuthStrategy
|
|
66
|
+
|
|
67
|
+
Used for internal calls to the vault service. Passes the data token as the `x-data-token` header.
|
|
35
68
|
|
|
36
69
|
```ts
|
|
37
|
-
|
|
38
|
-
reference: 'vault://1234567890', // The vault reference
|
|
39
|
-
config: {
|
|
40
|
-
vaultUrl,
|
|
41
|
-
authStrategy: new DataTokenAuthStrategy(dataToken)
|
|
42
|
-
},
|
|
43
|
-
download: false // Optional: download immediately if true
|
|
44
|
-
})
|
|
45
|
-
```
|
|
70
|
+
import { DataTokenAuthStrategy } from '@meistrari/vault-sdk'
|
|
46
71
|
|
|
47
|
-
|
|
72
|
+
const authStrategy = new DataTokenAuthStrategy('[your-data-token]')
|
|
73
|
+
```
|
|
48
74
|
|
|
49
|
-
|
|
75
|
+
### APIKeyAuthStrategy
|
|
50
76
|
|
|
51
|
-
|
|
52
|
-
2. Getting a reference to that file with `getVaultReference()`
|
|
53
|
-
3. Later, retrieving the file using `VaultFile.fromVaultReference`
|
|
77
|
+
Used for external calls **through the API Gateway**. Passes the API key as the `Authorization` header.
|
|
54
78
|
|
|
55
|
-
|
|
79
|
+
> [!WARNING]
|
|
80
|
+
> The vault service itself does not support API Keys directly. When using this strategy, requests **must** go through the API Gateway.
|
|
81
|
+
>
|
|
82
|
+
> ✅ Use: `https://staging.api.tela.com/_services/vault`
|
|
83
|
+
> ❌ Not: `https://staging.vault.tela.com`
|
|
56
84
|
|
|
57
85
|
```ts
|
|
58
|
-
import {
|
|
86
|
+
import { APIKeyAuthStrategy } from '@meistrari/vault-sdk'
|
|
87
|
+
|
|
88
|
+
const authStrategy = new APIKeyAuthStrategy('[your-api-key]')
|
|
89
|
+
```
|
|
59
90
|
|
|
60
|
-
|
|
61
|
-
const vaultUrl = Bun.env.VAULT_URL ?? 'https://vault.tela.com'
|
|
91
|
+
## API Reference
|
|
62
92
|
|
|
63
|
-
|
|
64
|
-
|
|
93
|
+
### VaultFile
|
|
94
|
+
|
|
95
|
+
The main class for interacting with vault files.
|
|
96
|
+
|
|
97
|
+
#### Static Methods
|
|
98
|
+
|
|
99
|
+
##### `VaultFile.fromContent(params, options?)`
|
|
100
|
+
|
|
101
|
+
Creates a new VaultFile from content (File or Blob).
|
|
102
|
+
|
|
103
|
+
```ts
|
|
65
104
|
const vaultFile = await VaultFile.fromContent({
|
|
66
|
-
|
|
67
|
-
|
|
105
|
+
name: 'document.txt',
|
|
106
|
+
content: new File(['content'], 'document.txt'),
|
|
68
107
|
config: {
|
|
69
108
|
vaultUrl,
|
|
70
|
-
authStrategy
|
|
109
|
+
authStrategy
|
|
71
110
|
},
|
|
72
|
-
upload:
|
|
73
|
-
})
|
|
111
|
+
upload: false // Set to true to upload immediately
|
|
112
|
+
}, { signal: abortSignal }) // Optional abort signal
|
|
113
|
+
```
|
|
74
114
|
|
|
75
|
-
|
|
76
|
-
const vaultReference = vaultFile.getVaultReference() // e.g. 'vault://1234567890'
|
|
77
|
-
console.log(`Store this reference: ${vaultReference}`)
|
|
115
|
+
##### `VaultFile.fromVaultReference(params, options?)`
|
|
78
116
|
|
|
79
|
-
|
|
117
|
+
Creates a VaultFile instance from an existing vault reference.
|
|
80
118
|
|
|
81
|
-
|
|
82
|
-
const
|
|
83
|
-
reference:
|
|
119
|
+
```ts
|
|
120
|
+
const vaultFile = await VaultFile.fromVaultReference({
|
|
121
|
+
reference: 'vault://abc123...',
|
|
84
122
|
config: {
|
|
85
123
|
vaultUrl,
|
|
86
|
-
authStrategy
|
|
124
|
+
authStrategy
|
|
87
125
|
},
|
|
88
126
|
download: false // Set to true to download immediately
|
|
127
|
+
}, { signal: abortSignal }) // Optional abort signal
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
##### `VaultFile.fromStream(params, options?)`
|
|
131
|
+
|
|
132
|
+
Creates a VaultFile for streaming upload workflows. Useful for large files to avoid loading the entire file into memory.
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
const vaultFile = await VaultFile.fromStream({
|
|
136
|
+
name: 'large-video.mp4',
|
|
137
|
+
contentLength: 100 * 1024 * 1024, // 100MB
|
|
138
|
+
contentType: 'video/mp4',
|
|
139
|
+
config: { vaultUrl, authStrategy }
|
|
140
|
+
}, { signal: abortSignal })
|
|
141
|
+
|
|
142
|
+
// Upload using a stream
|
|
143
|
+
const stream = file.stream()
|
|
144
|
+
await vaultFile.uploadStream(stream, {
|
|
145
|
+
contentLength: file.size,
|
|
146
|
+
contentType: file.type
|
|
89
147
|
})
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
#### Instance Methods
|
|
151
|
+
|
|
152
|
+
##### `upload(file?, url?, options?)`
|
|
153
|
+
|
|
154
|
+
Uploads the file to the vault. If no file is provided, uses the content from the VaultFile instance.
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
await vaultFile.upload() // Uses vaultFile.content
|
|
158
|
+
// or
|
|
159
|
+
await vaultFile.upload(someBlob) // Upload specific blob
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
##### `uploadStream(stream, options)`
|
|
163
|
+
|
|
164
|
+
Uploads a file using a ReadableStream for memory-efficient processing of large files.
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
const stream = file.stream()
|
|
168
|
+
await vaultFile.uploadStream(stream, {
|
|
169
|
+
contentLength: file.size,
|
|
170
|
+
contentType: 'video/mp4'
|
|
171
|
+
})
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
##### `download(responseType?, options?)`
|
|
175
|
+
|
|
176
|
+
Downloads the file content from the vault.
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
const blob = await vaultFile.download() // Returns Blob
|
|
180
|
+
const base64 = await vaultFile.download('base64') // Returns base64 string
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
##### `downloadStream(options?)`
|
|
184
|
+
|
|
185
|
+
Downloads the file as a ReadableStream for memory-efficient processing.
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
const stream = await vaultFile.downloadStream()
|
|
189
|
+
const reader = stream.getReader()
|
|
190
|
+
|
|
191
|
+
while (true) {
|
|
192
|
+
const { done, value } = await reader.read()
|
|
193
|
+
if (done)
|
|
194
|
+
break
|
|
195
|
+
console.log('Chunk size:', value.length)
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
##### `getVaultReference()`
|
|
200
|
+
|
|
201
|
+
Returns the vault reference string for this file.
|
|
202
|
+
|
|
203
|
+
```ts
|
|
204
|
+
const reference = vaultFile.getVaultReference() // 'vault://abc123...'
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
##### `getFileMetadata(options?)`
|
|
208
|
+
|
|
209
|
+
Fetches the file's metadata from the vault.
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
const metadata = await vaultFile.getFileMetadata()
|
|
213
|
+
// Returns FileMetadata with properties like originalFileName, mimeType, size, etc.
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
##### `populateMetadata(options?)`
|
|
90
217
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
218
|
+
Populates the file instance's metadata by fetching it from the vault.
|
|
219
|
+
|
|
220
|
+
```ts
|
|
221
|
+
await vaultFile.populateMetadata()
|
|
222
|
+
console.log(vaultFile.metadata)
|
|
94
223
|
```
|
|
95
224
|
|
|
96
|
-
|
|
225
|
+
##### `getUploadUrl(options?)`
|
|
97
226
|
|
|
98
|
-
|
|
227
|
+
Gets a pre-signed upload URL for the file.
|
|
99
228
|
|
|
100
229
|
```ts
|
|
101
|
-
|
|
230
|
+
const uploadUrl = await vaultFile.getUploadUrl({ expiresIn: 3600 }) // 1 hour
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
##### `getDownloadUrl(options?)`
|
|
234
|
+
|
|
235
|
+
Gets a pre-signed download URL for the file.
|
|
102
236
|
|
|
103
|
-
|
|
104
|
-
const
|
|
237
|
+
```ts
|
|
238
|
+
const downloadUrl = await vaultFile.getDownloadUrl({ expiresIn: 3600 }) // 1 hour
|
|
239
|
+
```
|
|
105
240
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
241
|
+
##### `delete(options?)`
|
|
242
|
+
|
|
243
|
+
Deletes the file from the vault.
|
|
244
|
+
|
|
245
|
+
```ts
|
|
246
|
+
await vaultFile.delete()
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
##### `createPermalink(params?, options?)`
|
|
250
|
+
|
|
251
|
+
Creates a permalink for the file. Requires workspace ID to be set in metadata.
|
|
252
|
+
|
|
253
|
+
```ts
|
|
254
|
+
await vaultFile.populateMetadata() // Ensure metadata is loaded
|
|
255
|
+
const permalink = await vaultFile.createPermalink({ expiresIn: 86400 }) // 24 hours
|
|
256
|
+
console.log(permalink.url) // Public URL
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
##### `getPermalinks(options?)`
|
|
260
|
+
|
|
261
|
+
Gets all valid permalinks for the file.
|
|
262
|
+
|
|
263
|
+
```ts
|
|
264
|
+
const permalinks = await vaultFile.getPermalinks()
|
|
265
|
+
for (const permalink of permalinks) {
|
|
266
|
+
console.log(permalink.url, permalink.expiresAt)
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Vault Client
|
|
271
|
+
|
|
272
|
+
The `vaultClient` helper simplifies working with multiple files using shared configuration.
|
|
273
|
+
|
|
274
|
+
```ts
|
|
275
|
+
import { vaultClient, DataTokenAuthStrategy } from '@meistrari/vault-sdk'
|
|
276
|
+
|
|
277
|
+
const client = vaultClient({
|
|
278
|
+
vaultUrl: 'https://vault.tela.com',
|
|
279
|
+
authStrategy: new DataTokenAuthStrategy('[your-data-token]')
|
|
110
280
|
})
|
|
111
281
|
|
|
112
|
-
// Create
|
|
113
|
-
const
|
|
282
|
+
// Create from content
|
|
283
|
+
const vaultFile = await client.createFromContent(
|
|
114
284
|
'document.txt',
|
|
115
285
|
new File(['content'], 'document.txt')
|
|
116
286
|
)
|
|
117
287
|
|
|
118
|
-
// Create
|
|
119
|
-
const
|
|
288
|
+
// Create from reference
|
|
289
|
+
const retrieved = await client.createFromReference('vault://abc123...')
|
|
290
|
+
|
|
291
|
+
// Create from stream
|
|
292
|
+
const streamFile = await client.createFromStream(
|
|
293
|
+
'video.mp4',
|
|
294
|
+
100 * 1024 * 1024, // 100MB
|
|
295
|
+
{ contentType: 'video/mp4' }
|
|
296
|
+
)
|
|
120
297
|
```
|
|
121
298
|
|
|
122
|
-
|
|
299
|
+
### Permalinks
|
|
123
300
|
|
|
124
|
-
|
|
125
|
-
- `createFromReference(reference)`: Creates a new `VaultFile` instance from a vault reference string
|
|
301
|
+
Permalinks are public, optionally time-limited URLs for files.
|
|
126
302
|
|
|
127
|
-
|
|
303
|
+
#### `Permalink.create(config, params, options?)`
|
|
128
304
|
|
|
129
|
-
|
|
305
|
+
Creates a new permalink.
|
|
130
306
|
|
|
131
|
-
|
|
307
|
+
```ts
|
|
308
|
+
import { Permalink } from '@meistrari/vault-sdk'
|
|
132
309
|
|
|
133
|
-
|
|
310
|
+
const permalink = await Permalink.create(config, {
|
|
311
|
+
fileId: 'abc123...',
|
|
312
|
+
workspaceId: 'workspace-id',
|
|
313
|
+
expiresIn: 86400 // 24 hours (optional)
|
|
314
|
+
})
|
|
134
315
|
|
|
135
|
-
|
|
136
|
-
|
|
316
|
+
console.log(permalink.url)
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
#### `Permalink.fromId(config, id)`
|
|
320
|
+
|
|
321
|
+
Retrieves a permalink by its ID.
|
|
137
322
|
|
|
138
323
|
```ts
|
|
139
|
-
|
|
324
|
+
const permalink = await Permalink.fromId(config, 'permalink-id')
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
#### `permalink.delete(options?)`
|
|
140
328
|
|
|
141
|
-
|
|
329
|
+
Deletes the permalink.
|
|
142
330
|
|
|
143
|
-
|
|
331
|
+
```ts
|
|
332
|
+
await permalink.delete()
|
|
144
333
|
```
|
|
145
334
|
|
|
146
|
-
|
|
335
|
+
## Advanced Usage
|
|
147
336
|
|
|
148
|
-
|
|
149
|
-
Use this when performing external calls **through the API Gateway**, such as from the frontend.
|
|
150
|
-
Since the clerk token is also passed as the `Authorization` header, this strategy can also be used with the value of the `__session` cookie instead of an API key.
|
|
337
|
+
### Complete Workflow Example
|
|
151
338
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
339
|
+
```ts
|
|
340
|
+
import { VaultFile, DataTokenAuthStrategy } from '@meistrari/vault-sdk'
|
|
341
|
+
|
|
342
|
+
const config = {
|
|
343
|
+
vaultUrl: 'https://vault.tela.com',
|
|
344
|
+
authStrategy: new DataTokenAuthStrategy('[your-data-token]')
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// 1. Create and upload a file
|
|
348
|
+
const file = new File(['content'], 'document.txt')
|
|
349
|
+
const vaultFile = await VaultFile.fromContent({
|
|
350
|
+
name: 'document.txt',
|
|
351
|
+
content: file,
|
|
352
|
+
config,
|
|
353
|
+
upload: true
|
|
354
|
+
})
|
|
355
|
+
|
|
356
|
+
// 2. Store the reference in your database
|
|
357
|
+
const reference = vaultFile.getVaultReference()
|
|
358
|
+
await db.saveDocument({ vaultReference: reference })
|
|
359
|
+
|
|
360
|
+
// 3. Later, retrieve the file
|
|
361
|
+
const doc = await db.getDocument()
|
|
362
|
+
const retrieved = await VaultFile.fromVaultReference({
|
|
363
|
+
reference: doc.vaultReference,
|
|
364
|
+
config,
|
|
365
|
+
download: true
|
|
366
|
+
})
|
|
367
|
+
|
|
368
|
+
// 4. Use the content
|
|
369
|
+
const blob = retrieved.content // Already downloaded
|
|
370
|
+
console.log('File size:', blob.size)
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### Streaming Large Files
|
|
159
374
|
|
|
160
375
|
```ts
|
|
161
|
-
|
|
376
|
+
// Upload a large file efficiently
|
|
377
|
+
const vaultFile = await VaultFile.fromStream({
|
|
378
|
+
name: 'large-file.bin',
|
|
379
|
+
contentLength: largeFile.size,
|
|
380
|
+
contentType: largeFile.type,
|
|
381
|
+
config
|
|
382
|
+
})
|
|
383
|
+
|
|
384
|
+
await vaultFile.uploadStream(largeFile.stream(), {
|
|
385
|
+
contentLength: largeFile.size,
|
|
386
|
+
contentType: largeFile.type
|
|
387
|
+
})
|
|
388
|
+
|
|
389
|
+
// Download a large file efficiently
|
|
390
|
+
const stream = await vaultFile.downloadStream()
|
|
391
|
+
// Process stream in chunks without loading entire file
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### Abort Requests
|
|
395
|
+
|
|
396
|
+
All methods that make network requests support AbortSignal for request cancellation:
|
|
397
|
+
|
|
398
|
+
```ts
|
|
399
|
+
const controller = new AbortController()
|
|
400
|
+
|
|
401
|
+
// Cancel after 5 seconds
|
|
402
|
+
setTimeout(() => controller.abort(), 5000)
|
|
403
|
+
|
|
404
|
+
try {
|
|
405
|
+
const vaultFile = await VaultFile.fromContent({
|
|
406
|
+
name: 'document.txt',
|
|
407
|
+
content: file,
|
|
408
|
+
config
|
|
409
|
+
}, { signal: controller.signal })
|
|
410
|
+
|
|
411
|
+
// Upload with abort signal
|
|
412
|
+
await vaultFile.upload(undefined, undefined, { signal: controller.signal })
|
|
413
|
+
|
|
414
|
+
console.log('Upload successful')
|
|
415
|
+
}
|
|
416
|
+
catch (error) {
|
|
417
|
+
if (error.name === 'AbortError') {
|
|
418
|
+
console.log('Upload was cancelled')
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
throw error
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
You can also cancel downloads and other operations:
|
|
427
|
+
|
|
428
|
+
```ts
|
|
429
|
+
const controller = new AbortController()
|
|
430
|
+
|
|
431
|
+
// Start download
|
|
432
|
+
const downloadPromise = vaultFile.download('blob', { signal: controller.signal })
|
|
433
|
+
|
|
434
|
+
// Cancel if user clicks a button
|
|
435
|
+
cancelButton.addEventListener('click', () => controller.abort())
|
|
436
|
+
|
|
437
|
+
try {
|
|
438
|
+
const blob = await downloadPromise
|
|
439
|
+
console.log('Download complete:', blob.size)
|
|
440
|
+
}
|
|
441
|
+
catch (error) {
|
|
442
|
+
if (error.name === 'AbortError') {
|
|
443
|
+
console.log('Download cancelled by user')
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
### Working with Metadata
|
|
449
|
+
|
|
450
|
+
```ts
|
|
451
|
+
const vaultFile = await VaultFile.fromVaultReference({
|
|
452
|
+
reference: 'vault://abc123...',
|
|
453
|
+
config
|
|
454
|
+
})
|
|
162
455
|
|
|
163
|
-
|
|
456
|
+
// Load metadata
|
|
457
|
+
await vaultFile.populateMetadata()
|
|
164
458
|
|
|
165
|
-
|
|
459
|
+
console.log(vaultFile.metadata.originalFileName)
|
|
460
|
+
console.log(vaultFile.metadata.mimeType)
|
|
461
|
+
console.log(vaultFile.metadata.size)
|
|
462
|
+
console.log(vaultFile.metadata.workspaceId)
|
|
166
463
|
```
|
package/dist/index.cjs
CHANGED
|
@@ -221,7 +221,7 @@ async function detectFileMimeType(blob) {
|
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
const name = "@meistrari/vault-sdk";
|
|
224
|
-
const version = "1.
|
|
224
|
+
const version = "1.7.0";
|
|
225
225
|
const license = "UNLICENSED";
|
|
226
226
|
const repository = {
|
|
227
227
|
type: "git",
|
|
@@ -846,9 +846,29 @@ class VaultFile {
|
|
|
846
846
|
const headers = new Headers();
|
|
847
847
|
headers.set("Content-Type", mimeType);
|
|
848
848
|
headers.set("Content-Length", contentLength.toString());
|
|
849
|
+
let content = stream;
|
|
850
|
+
if (stream instanceof ReadableStream && typeof Bun !== "undefined") {
|
|
851
|
+
console.warn(
|
|
852
|
+
"[Vault SDK - WARNING] Buffering file upload due to Bun fetch implementation. Large files may cause memory issues. Consider using Node.js for streaming uploads.",
|
|
853
|
+
{ fileName: this.name, fileSize: contentLength }
|
|
854
|
+
);
|
|
855
|
+
const chunks = [];
|
|
856
|
+
const reader = stream.getReader();
|
|
857
|
+
try {
|
|
858
|
+
while (true) {
|
|
859
|
+
const { done, value } = await reader.read();
|
|
860
|
+
if (done)
|
|
861
|
+
break;
|
|
862
|
+
chunks.push(value);
|
|
863
|
+
}
|
|
864
|
+
} finally {
|
|
865
|
+
reader.releaseLock();
|
|
866
|
+
}
|
|
867
|
+
content = new Blob(chunks, { type: mimeType });
|
|
868
|
+
}
|
|
849
869
|
await wrappedFetch(uploadUrl, {
|
|
850
870
|
method: "PUT",
|
|
851
|
-
body:
|
|
871
|
+
body: content,
|
|
852
872
|
headers,
|
|
853
873
|
signal
|
|
854
874
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -219,7 +219,7 @@ async function detectFileMimeType(blob) {
|
|
|
219
219
|
}
|
|
220
220
|
|
|
221
221
|
const name = "@meistrari/vault-sdk";
|
|
222
|
-
const version = "1.
|
|
222
|
+
const version = "1.7.0";
|
|
223
223
|
const license = "UNLICENSED";
|
|
224
224
|
const repository = {
|
|
225
225
|
type: "git",
|
|
@@ -844,9 +844,29 @@ class VaultFile {
|
|
|
844
844
|
const headers = new Headers();
|
|
845
845
|
headers.set("Content-Type", mimeType);
|
|
846
846
|
headers.set("Content-Length", contentLength.toString());
|
|
847
|
+
let content = stream;
|
|
848
|
+
if (stream instanceof ReadableStream && typeof Bun !== "undefined") {
|
|
849
|
+
console.warn(
|
|
850
|
+
"[Vault SDK - WARNING] Buffering file upload due to Bun fetch implementation. Large files may cause memory issues. Consider using Node.js for streaming uploads.",
|
|
851
|
+
{ fileName: this.name, fileSize: contentLength }
|
|
852
|
+
);
|
|
853
|
+
const chunks = [];
|
|
854
|
+
const reader = stream.getReader();
|
|
855
|
+
try {
|
|
856
|
+
while (true) {
|
|
857
|
+
const { done, value } = await reader.read();
|
|
858
|
+
if (done)
|
|
859
|
+
break;
|
|
860
|
+
chunks.push(value);
|
|
861
|
+
}
|
|
862
|
+
} finally {
|
|
863
|
+
reader.releaseLock();
|
|
864
|
+
}
|
|
865
|
+
content = new Blob(chunks, { type: mimeType });
|
|
866
|
+
}
|
|
847
867
|
await wrappedFetch(uploadUrl, {
|
|
848
868
|
method: "PUT",
|
|
849
|
-
body:
|
|
869
|
+
body: content,
|
|
850
870
|
headers,
|
|
851
871
|
signal
|
|
852
872
|
});
|