@meistrari/vault-sdk 0.0.10 → 0.0.12
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 +97 -7
- package/dist/index.d.mts +37 -1
- package/dist/index.d.ts +37 -1
- package/dist/index.mjs +50 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,15 +1,105 @@
|
|
|
1
|
-
# sdk
|
|
1
|
+
# @meistrari/vault-sdk-sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This is the SDK for Vault V2.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
4
6
|
|
|
5
7
|
```bash
|
|
6
|
-
|
|
8
|
+
ni @meistrari/vault-sdk-sdk
|
|
7
9
|
```
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
## Usage
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
The main component of the SDK is the `VaultFile` class.
|
|
14
|
+
It accepts the vault url and an auth strategy, and provides methods to upload and download that file.
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
import { VaultFile } from '@meistrari/vault-sdk'
|
|
18
|
+
|
|
19
|
+
const dataToken = '[some-data-token]'
|
|
20
|
+
const vaultUrl = Bun.env.VAULT_URL ?? 'https://vault.tela.com'
|
|
21
|
+
|
|
22
|
+
const vaultFile = new VaultFile('file.txt', vaultUrl, new DataTokenAuthStrategy(dataToken))
|
|
23
|
+
const localFile = Bun.file('path/to/local/file.txt')
|
|
24
|
+
|
|
25
|
+
await vaultFile.upload(localFile)
|
|
26
|
+
|
|
27
|
+
const downloadedFile = await vaultFile.download()
|
|
28
|
+
|
|
29
|
+
console.log(downloadedFile)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### The `useVault` function
|
|
33
|
+
|
|
34
|
+
In order to simplify the creation of multiple `VaultFile` instances, the `useVault` function is exported.
|
|
35
|
+
It takes the vault url and an auth strategy, and returns a function that creates a `VaultFile` instance using those parameters.
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { useVault, DataTokenAuthStrategy } from '@meistrari/vault-sdk'
|
|
39
|
+
|
|
40
|
+
const dataToken = '[some-data-token]'
|
|
41
|
+
const vaultUrl = Bun.env.VAULT_URL ?? 'https://vault.tela.com'
|
|
42
|
+
|
|
43
|
+
const { createVaultFile } = useVault(vaultUrl, new DataTokenAuthStrategy(dataToken))
|
|
44
|
+
const vaultFile = createVaultFile('test.txt')
|
|
45
|
+
|
|
46
|
+
const localFile = Bun.file('./package.json')
|
|
47
|
+
|
|
48
|
+
await vaultFile.upload(localFile)
|
|
49
|
+
|
|
50
|
+
const downloadedFile = await vaultFile.download()
|
|
51
|
+
|
|
52
|
+
console.log(downloadedFile)
|
|
13
53
|
```
|
|
14
54
|
|
|
15
|
-
|
|
55
|
+
### Auth strategies
|
|
56
|
+
|
|
57
|
+
The SDK provides two auth strategies: `DataTokenAuthStrategy` and `APIKeyAuthStrategy`.
|
|
58
|
+
|
|
59
|
+
#### DataTokenAuthStrategy
|
|
60
|
+
|
|
61
|
+
It takes a data token, and passes it as the `x-data-token` header in requests to the vault.
|
|
62
|
+
Use this when performing internal calls to the vault, such as from `tela-api`.
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
import { DataTokenAuthStrategy } from '@meistrari/vault-sdk'
|
|
66
|
+
|
|
67
|
+
const dataToken = '[some-data-token]'
|
|
68
|
+
|
|
69
|
+
const authStrategy = new DataTokenAuthStrategy(dataToken)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
#### APIKeyAuthStrategy
|
|
73
|
+
|
|
74
|
+
It takes an API key, and passes it as the `Authorization` header in requests to the vault.
|
|
75
|
+
Use this when performing external calls to the vault, such as from the frontend.
|
|
76
|
+
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.
|
|
77
|
+
For vault, there's no real difference between using an API key and the clerk token, since it only needs the workspace ID, and that's provided by both types of credentials.
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
import { APIKeyAuthStrategy } from '@meistrari/vault-sdk'
|
|
81
|
+
|
|
82
|
+
const apiKey = '[some-api-key]'
|
|
83
|
+
|
|
84
|
+
const authStrategy = new APIKeyAuthStrategy(apiKey)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Retrieving files with a vault ref
|
|
88
|
+
|
|
89
|
+
Both the `VaultFile` class and the `createVaultFile` function accept a vault ref as the name of the file.
|
|
90
|
+
The vault ref is a string with the form `vault://file-name.ext`.
|
|
91
|
+
The workspace ID is obtained from the authentication data, and doesn't need to be explicitly passed.
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
import { useVault, DataTokenAuthStrategy } from '@meistrari/vault-sdk'
|
|
95
|
+
|
|
96
|
+
const dataToken = '[some-data-token]'
|
|
97
|
+
const vaultUrl = Bun.env.VAULT_URL ?? 'https://vault.tela.com'
|
|
98
|
+
|
|
99
|
+
const { createVaultFile } = useVault(vaultUrl, new DataTokenAuthStrategy(dataToken))
|
|
100
|
+
const vaultFile = createVaultFile('vault://file-name.ext')
|
|
101
|
+
|
|
102
|
+
const downloadedFile = await vaultFile.download()
|
|
103
|
+
|
|
104
|
+
console.log(downloadedFile)
|
|
105
|
+
```
|
package/dist/index.d.mts
CHANGED
|
@@ -24,8 +24,8 @@ type VaultParams = {
|
|
|
24
24
|
vaultUrl: string;
|
|
25
25
|
};
|
|
26
26
|
declare class VaultFile {
|
|
27
|
-
readonly name: string;
|
|
28
27
|
readonly vaultUrl: string;
|
|
28
|
+
name: string;
|
|
29
29
|
headers: Headers;
|
|
30
30
|
constructor(params: VaultParams);
|
|
31
31
|
getVaultUrl(): string;
|
|
@@ -34,6 +34,42 @@ declare class VaultFile {
|
|
|
34
34
|
getDownloadUrl(): Promise<URL>;
|
|
35
35
|
refreshAuth(authStrategy: AuthStrategy): void;
|
|
36
36
|
_fetch(params: FetchParams): Promise<any>;
|
|
37
|
+
/**
|
|
38
|
+
* Adds a SHA-256 hash of the file content as a prefix to the filename. This ensures uniqueness and prevents
|
|
39
|
+
* files with identical names but different content from overwriting each other in the vault.
|
|
40
|
+
*
|
|
41
|
+
* The resulting filename format is: "{hash}-{originalName}"
|
|
42
|
+
*
|
|
43
|
+
* IMPORTANT: The modified filename must be stored and used for all future operations with this file in the vault,
|
|
44
|
+
* as it becomes the file's unique identifier. The original filename alone will not be sufficient to retrieve
|
|
45
|
+
* the file later.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* const file = new File(['content'], 'document.txt')
|
|
49
|
+
* await vaultFile.addHashToName(file)
|
|
50
|
+
* // vaultFile.name becomes: "a1b2c3...xyz-document.txt"
|
|
51
|
+
*
|
|
52
|
+
* @param file - The file to generate a hash for
|
|
53
|
+
* @returns The new filename with the hash prefix
|
|
54
|
+
*/
|
|
55
|
+
addHashToName(file: Blob): Promise<string>;
|
|
56
|
+
/**
|
|
57
|
+
* Uploads a file to the vault.
|
|
58
|
+
*
|
|
59
|
+
* Files are saved with the given file names, so files with the same name within the same workspace
|
|
60
|
+
* will overwrite each other. To prevent accidental overwrites and support multiple files with the
|
|
61
|
+
* same original name, you should call addHashToName() before uploading to add a unique content-based
|
|
62
|
+
* hash to the filename.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* const file = new File(['content'], 'document.txt')
|
|
66
|
+
* await vaultFile.addHashToName(file) // Adds hash prefix to filename
|
|
67
|
+
* await vaultFile.upload(file)
|
|
68
|
+
*
|
|
69
|
+
* @param file - The file to upload to the vault
|
|
70
|
+
* @throws {FetchError} If the upload fails
|
|
71
|
+
* @returns Promise that resolves when upload is complete
|
|
72
|
+
*/
|
|
37
73
|
upload(file: Blob): Promise<void>;
|
|
38
74
|
download(responseType?: 'blob'): Promise<Blob>;
|
|
39
75
|
download(responseType: 'base64'): Promise<string>;
|
package/dist/index.d.ts
CHANGED
|
@@ -24,8 +24,8 @@ type VaultParams = {
|
|
|
24
24
|
vaultUrl: string;
|
|
25
25
|
};
|
|
26
26
|
declare class VaultFile {
|
|
27
|
-
readonly name: string;
|
|
28
27
|
readonly vaultUrl: string;
|
|
28
|
+
name: string;
|
|
29
29
|
headers: Headers;
|
|
30
30
|
constructor(params: VaultParams);
|
|
31
31
|
getVaultUrl(): string;
|
|
@@ -34,6 +34,42 @@ declare class VaultFile {
|
|
|
34
34
|
getDownloadUrl(): Promise<URL>;
|
|
35
35
|
refreshAuth(authStrategy: AuthStrategy): void;
|
|
36
36
|
_fetch(params: FetchParams): Promise<any>;
|
|
37
|
+
/**
|
|
38
|
+
* Adds a SHA-256 hash of the file content as a prefix to the filename. This ensures uniqueness and prevents
|
|
39
|
+
* files with identical names but different content from overwriting each other in the vault.
|
|
40
|
+
*
|
|
41
|
+
* The resulting filename format is: "{hash}-{originalName}"
|
|
42
|
+
*
|
|
43
|
+
* IMPORTANT: The modified filename must be stored and used for all future operations with this file in the vault,
|
|
44
|
+
* as it becomes the file's unique identifier. The original filename alone will not be sufficient to retrieve
|
|
45
|
+
* the file later.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* const file = new File(['content'], 'document.txt')
|
|
49
|
+
* await vaultFile.addHashToName(file)
|
|
50
|
+
* // vaultFile.name becomes: "a1b2c3...xyz-document.txt"
|
|
51
|
+
*
|
|
52
|
+
* @param file - The file to generate a hash for
|
|
53
|
+
* @returns The new filename with the hash prefix
|
|
54
|
+
*/
|
|
55
|
+
addHashToName(file: Blob): Promise<string>;
|
|
56
|
+
/**
|
|
57
|
+
* Uploads a file to the vault.
|
|
58
|
+
*
|
|
59
|
+
* Files are saved with the given file names, so files with the same name within the same workspace
|
|
60
|
+
* will overwrite each other. To prevent accidental overwrites and support multiple files with the
|
|
61
|
+
* same original name, you should call addHashToName() before uploading to add a unique content-based
|
|
62
|
+
* hash to the filename.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* const file = new File(['content'], 'document.txt')
|
|
66
|
+
* await vaultFile.addHashToName(file) // Adds hash prefix to filename
|
|
67
|
+
* await vaultFile.upload(file)
|
|
68
|
+
*
|
|
69
|
+
* @param file - The file to upload to the vault
|
|
70
|
+
* @throws {FetchError} If the upload fails
|
|
71
|
+
* @returns Promise that resolves when upload is complete
|
|
72
|
+
*/
|
|
37
73
|
upload(file: Blob): Promise<void>;
|
|
38
74
|
download(responseType?: 'blob'): Promise<Blob>;
|
|
39
75
|
download(responseType: 'base64'): Promise<string>;
|
package/dist/index.mjs
CHANGED
|
@@ -14,6 +14,14 @@ async function blobToBase64(blob) {
|
|
|
14
14
|
return btoa(content);
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
async function getFileHash(blob) {
|
|
18
|
+
const arrayBuffer = await blob.arrayBuffer();
|
|
19
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", arrayBuffer);
|
|
20
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
21
|
+
const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
22
|
+
return hashHex;
|
|
23
|
+
}
|
|
24
|
+
|
|
17
25
|
var __defProp$1 = Object.defineProperty;
|
|
18
26
|
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
19
27
|
var __publicField$1 = (obj, key, value) => {
|
|
@@ -22,8 +30,8 @@ var __publicField$1 = (obj, key, value) => {
|
|
|
22
30
|
};
|
|
23
31
|
class VaultFile {
|
|
24
32
|
constructor(params) {
|
|
25
|
-
__publicField$1(this, "name");
|
|
26
33
|
__publicField$1(this, "vaultUrl");
|
|
34
|
+
__publicField$1(this, "name");
|
|
27
35
|
__publicField$1(this, "headers");
|
|
28
36
|
this.name = params.name;
|
|
29
37
|
this.vaultUrl = params.vaultUrl;
|
|
@@ -69,6 +77,47 @@ class VaultFile {
|
|
|
69
77
|
const content = await response.json();
|
|
70
78
|
return content;
|
|
71
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Adds a SHA-256 hash of the file content as a prefix to the filename. This ensures uniqueness and prevents
|
|
82
|
+
* files with identical names but different content from overwriting each other in the vault.
|
|
83
|
+
*
|
|
84
|
+
* The resulting filename format is: "{hash}-{originalName}"
|
|
85
|
+
*
|
|
86
|
+
* IMPORTANT: The modified filename must be stored and used for all future operations with this file in the vault,
|
|
87
|
+
* as it becomes the file's unique identifier. The original filename alone will not be sufficient to retrieve
|
|
88
|
+
* the file later.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* const file = new File(['content'], 'document.txt')
|
|
92
|
+
* await vaultFile.addHashToName(file)
|
|
93
|
+
* // vaultFile.name becomes: "a1b2c3...xyz-document.txt"
|
|
94
|
+
*
|
|
95
|
+
* @param file - The file to generate a hash for
|
|
96
|
+
* @returns The new filename with the hash prefix
|
|
97
|
+
*/
|
|
98
|
+
async addHashToName(file) {
|
|
99
|
+
const fileHash = await getFileHash(file);
|
|
100
|
+
if (!this.name.includes(fileHash))
|
|
101
|
+
this.name = `${fileHash}-${this.name}`;
|
|
102
|
+
return this.name;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Uploads a file to the vault.
|
|
106
|
+
*
|
|
107
|
+
* Files are saved with the given file names, so files with the same name within the same workspace
|
|
108
|
+
* will overwrite each other. To prevent accidental overwrites and support multiple files with the
|
|
109
|
+
* same original name, you should call addHashToName() before uploading to add a unique content-based
|
|
110
|
+
* hash to the filename.
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* const file = new File(['content'], 'document.txt')
|
|
114
|
+
* await vaultFile.addHashToName(file) // Adds hash prefix to filename
|
|
115
|
+
* await vaultFile.upload(file)
|
|
116
|
+
*
|
|
117
|
+
* @param file - The file to upload to the vault
|
|
118
|
+
* @throws {FetchError} If the upload fails
|
|
119
|
+
* @returns Promise that resolves when upload is complete
|
|
120
|
+
*/
|
|
72
121
|
async upload(file) {
|
|
73
122
|
const uploadUrl = await this.getUploadUrl();
|
|
74
123
|
const response = await fetch(uploadUrl, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meistrari/vault-sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -18,10 +18,10 @@
|
|
|
18
18
|
"dist"
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"ofetch": "1.4.1"
|
|
22
|
-
"vitest": "2.1.8"
|
|
21
|
+
"ofetch": "1.4.1"
|
|
23
22
|
},
|
|
24
23
|
"devDependencies": {
|
|
24
|
+
"vitest": "2.1.9",
|
|
25
25
|
"@types/bun": "latest",
|
|
26
26
|
"msw": "2.6.8",
|
|
27
27
|
"unbuild": "2.0.0"
|