@meistrari/vault-sdk 0.0.13 → 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/README.md +102 -41
- package/dist/index.cjs +330 -79
- package/dist/index.d.cts +219 -42
- package/dist/index.d.mts +219 -42
- package/dist/index.d.ts +219 -42
- package/dist/index.mjs +330 -79
- package/package.json +14 -12
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
|
+
import { GetUploadUrlResponseV2, GetDownloadUrlResponse } from '@meistrari/vault-shared/schemas';
|
|
2
|
+
|
|
1
3
|
class FetchError extends Error {
|
|
2
|
-
constructor(message, response) {
|
|
4
|
+
constructor(message, url, method, response) {
|
|
3
5
|
super(message);
|
|
6
|
+
this.message = message;
|
|
7
|
+
this.url = url;
|
|
8
|
+
this.method = method;
|
|
4
9
|
this.response = response;
|
|
5
10
|
this.name = "FetchError";
|
|
6
11
|
}
|
|
12
|
+
static async from(url, method, response) {
|
|
13
|
+
const text = await response.clone().json().then((json) => JSON.stringify(json, null, 2)).catch(() => response.clone().text());
|
|
14
|
+
const error = new FetchError(`Failed to ${method} ${url}: ${response.status} ${response.statusText}:
|
|
15
|
+
${text}`, url, method, response);
|
|
16
|
+
return error;
|
|
17
|
+
}
|
|
7
18
|
}
|
|
8
19
|
|
|
9
20
|
async function blobToBase64(blob) {
|
|
@@ -28,114 +39,348 @@ var __publicField$1 = (obj, key, value) => {
|
|
|
28
39
|
__defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
29
40
|
return value;
|
|
30
41
|
};
|
|
42
|
+
const compatibilityDate = "2025-05-19";
|
|
43
|
+
function removeVaultPrefix(url) {
|
|
44
|
+
return url.replace("vault://", "");
|
|
45
|
+
}
|
|
46
|
+
async function wrappedFetch(...params) {
|
|
47
|
+
const request = new Request(...params);
|
|
48
|
+
const response = await fetch(request);
|
|
49
|
+
if (!response.ok) {
|
|
50
|
+
throw await FetchError.from(request.url, request.method, response);
|
|
51
|
+
}
|
|
52
|
+
return response;
|
|
53
|
+
}
|
|
31
54
|
class VaultFile {
|
|
32
|
-
|
|
33
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Constructs a new VaultFile instance. Direct usage of the constructor is not recommended,
|
|
57
|
+
* instead use the static methods {@link VaultFile.fromVaultReference} when dealing with an existing file in the vault,
|
|
58
|
+
* or {@link VaultFile.fromContent} when preparing a new file for upload.
|
|
59
|
+
*
|
|
60
|
+
* @param params - The parameters for the VaultFile constructor
|
|
61
|
+
* @param params.config - The configuration for the VaultFile
|
|
62
|
+
* @param params.content - The content of the file
|
|
63
|
+
* @param params.id - The ID of the file
|
|
64
|
+
* @param params.name - The name of the file
|
|
65
|
+
* @param params.metadata - The metadata of the file
|
|
66
|
+
*/
|
|
67
|
+
constructor({ config, content, id, name, metadata }) {
|
|
68
|
+
__publicField$1(this, "id");
|
|
34
69
|
__publicField$1(this, "name");
|
|
35
|
-
__publicField$1(this, "
|
|
36
|
-
this
|
|
37
|
-
this
|
|
38
|
-
this
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
70
|
+
__publicField$1(this, "metadata");
|
|
71
|
+
__publicField$1(this, "config");
|
|
72
|
+
__publicField$1(this, "content");
|
|
73
|
+
__publicField$1(this, "lastDownloadUrl");
|
|
74
|
+
__publicField$1(this, "lastUploadUrl");
|
|
75
|
+
this.config = config;
|
|
76
|
+
this.content = content;
|
|
77
|
+
this.id = id;
|
|
78
|
+
this.name = name;
|
|
79
|
+
this.metadata = metadata;
|
|
45
80
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
});
|
|
54
|
-
return new URL(response.url);
|
|
55
|
-
}
|
|
56
|
-
async getDownloadUrl() {
|
|
57
|
-
const response = await this._fetch({
|
|
58
|
-
method: "GET",
|
|
59
|
-
path: `/v2/files/${this.removeVaultPrefix(this.name)}`
|
|
60
|
-
});
|
|
61
|
-
return new URL(response.url);
|
|
62
|
-
}
|
|
63
|
-
refreshAuth(authStrategy) {
|
|
64
|
-
this.headers = authStrategy.getHeaders();
|
|
81
|
+
/**
|
|
82
|
+
* Gets the headers for the request based on the auth strategy.
|
|
83
|
+
*
|
|
84
|
+
* @returns The headers for the request
|
|
85
|
+
*/
|
|
86
|
+
get headers() {
|
|
87
|
+
return this.config.authStrategy.getHeaders();
|
|
65
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Performs a request to the vault service and handles the response or errors.
|
|
91
|
+
*
|
|
92
|
+
* @param params - The parameters for the fetch
|
|
93
|
+
* @param params.method - The method to use for the fetch
|
|
94
|
+
* @param params.path - The path to fetch
|
|
95
|
+
* @param params.body - The body of the request
|
|
96
|
+
* @returns The response from the vault
|
|
97
|
+
* @throws {FetchError} If the fetch fails
|
|
98
|
+
*/
|
|
66
99
|
async _fetch(params) {
|
|
67
|
-
const { method, path, body
|
|
68
|
-
const url = new URL(this.vaultUrl + path).toString();
|
|
69
|
-
const
|
|
100
|
+
const { method, path, body } = params;
|
|
101
|
+
const url = new URL(this.config.vaultUrl + path).toString();
|
|
102
|
+
const headers = new Headers(this.headers);
|
|
103
|
+
headers.set("x-compatibility-date", compatibilityDate);
|
|
104
|
+
const response = await wrappedFetch(url, {
|
|
70
105
|
method,
|
|
71
106
|
body,
|
|
72
|
-
headers
|
|
107
|
+
headers
|
|
73
108
|
});
|
|
74
|
-
if (!response.ok) {
|
|
75
|
-
throw new FetchError(`Failed to ${method} ${url}: ${response.status} ${response.statusText}`, response);
|
|
76
|
-
}
|
|
77
109
|
const content = await response.json();
|
|
78
110
|
return content;
|
|
79
111
|
}
|
|
80
112
|
/**
|
|
81
|
-
*
|
|
82
|
-
*
|
|
113
|
+
* Creates a new file in the vault.
|
|
114
|
+
*
|
|
115
|
+
* @returns The metadata of the file
|
|
116
|
+
* @throws {Error} If the file ID is not set
|
|
117
|
+
* @throws {FetchError} If the metadata fetch fails
|
|
118
|
+
*/
|
|
119
|
+
async _createFile() {
|
|
120
|
+
const response = await this._fetch({
|
|
121
|
+
method: "POST",
|
|
122
|
+
path: `/v2/files`,
|
|
123
|
+
body: JSON.stringify({
|
|
124
|
+
fileName: this.name,
|
|
125
|
+
sha256sum: this.id ?? this.metadata?.id ?? (this.content ? await getFileHash(this.content) : void 0)
|
|
126
|
+
})
|
|
127
|
+
}).then((data) => GetUploadUrlResponseV2.safeParse(data));
|
|
128
|
+
if (!response.success) {
|
|
129
|
+
throw new Error(`Invalid response from vault service. ${JSON.stringify(response.error)}`);
|
|
130
|
+
}
|
|
131
|
+
this.id = response.data.id;
|
|
132
|
+
this.metadata = response.data.metadata;
|
|
133
|
+
this.name = response.data.metadata?.originalFileName;
|
|
134
|
+
return response.data;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Creates a new VaultFile instance from a vault reference.
|
|
83
138
|
*
|
|
84
|
-
* The
|
|
139
|
+
* @param params - The parameters for creating a VaultFile from a vault reference
|
|
140
|
+
* @param params.reference - The reference to the file in the vault
|
|
141
|
+
* @param params.config - The configuration for the VaultFile
|
|
142
|
+
* @param params.download - Whether to download the file content (default: false)
|
|
143
|
+
* @returns A new VaultFile instance
|
|
85
144
|
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* the file
|
|
145
|
+
* @example
|
|
146
|
+
* ```ts
|
|
147
|
+
* // Lazily download the file content
|
|
148
|
+
* const vaultFile = await VaultFile.fromVaultReference({
|
|
149
|
+
* reference: 'vault://1234567890',
|
|
150
|
+
* config: {
|
|
151
|
+
* vaultUrl,
|
|
152
|
+
* authStrategy,
|
|
153
|
+
* }
|
|
154
|
+
* })
|
|
155
|
+
* const content = await vaultFile.download()
|
|
156
|
+
* ```
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```ts
|
|
160
|
+
* // Download the file content while creating the instance
|
|
161
|
+
* const vaultFile = await VaultFile.fromVaultReference({
|
|
162
|
+
* reference: 'vault://1234567890',
|
|
163
|
+
* config: {
|
|
164
|
+
* vaultUrl,
|
|
165
|
+
* authStrategy,
|
|
166
|
+
* },
|
|
167
|
+
* download: true
|
|
168
|
+
* })
|
|
169
|
+
* const content = vaultFile.content
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
static async fromVaultReference(params) {
|
|
173
|
+
const { reference, config, download = false } = params;
|
|
174
|
+
const { vaultUrl, authStrategy } = config;
|
|
175
|
+
const id = removeVaultPrefix(reference);
|
|
176
|
+
const response = await wrappedFetch(`${vaultUrl}/v2/files/${id}`, {
|
|
177
|
+
method: "GET",
|
|
178
|
+
headers: authStrategy.getHeaders()
|
|
179
|
+
}).then((response2) => response2.json()).then((data) => GetDownloadUrlResponse.safeParse(data));
|
|
180
|
+
if (!response.success) {
|
|
181
|
+
throw new Error("Invalid response from vault service");
|
|
182
|
+
}
|
|
183
|
+
const fileParams = {
|
|
184
|
+
id,
|
|
185
|
+
metadata: response.data.metadata,
|
|
186
|
+
config: {
|
|
187
|
+
vaultUrl,
|
|
188
|
+
authStrategy
|
|
189
|
+
},
|
|
190
|
+
name: response.data.metadata?.originalFileName
|
|
191
|
+
};
|
|
192
|
+
if (download) {
|
|
193
|
+
await wrappedFetch(response.data.url, { method: "GET" }).then((response2) => response2.blob()).then((blob) => fileParams.content = blob);
|
|
194
|
+
}
|
|
195
|
+
return new VaultFile(fileParams);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Creates a new VaultFile instance from given content.
|
|
199
|
+
*
|
|
200
|
+
* @param params - The parameters for creating a VaultFile from content
|
|
201
|
+
* @param params.name - The name of the file
|
|
202
|
+
* @param params.content - The content of the file
|
|
203
|
+
* @param params.config - The configuration for the VaultFile
|
|
204
|
+
* @param params.upload - Whether to upload the file (default: false)
|
|
205
|
+
* @returns A new VaultFile instance
|
|
206
|
+
*
|
|
207
|
+
* @example
|
|
208
|
+
* ```ts
|
|
209
|
+
* // Lazily upload the file content
|
|
210
|
+
* const file = new File(['content'], 'document.txt')
|
|
211
|
+
* const vaultFile = await VaultFile.fromContent({
|
|
212
|
+
* name: 'document.txt',
|
|
213
|
+
* content: file,
|
|
214
|
+
* config: {
|
|
215
|
+
* vaultUrl,
|
|
216
|
+
* authStrategy,
|
|
217
|
+
* }
|
|
218
|
+
* })
|
|
219
|
+
* await vaultFile.upload()
|
|
220
|
+
* ```
|
|
89
221
|
*
|
|
90
222
|
* @example
|
|
223
|
+
* ```ts
|
|
224
|
+
* // Upload the file content while creating the instance
|
|
91
225
|
* const file = new File(['content'], 'document.txt')
|
|
92
|
-
* await
|
|
93
|
-
*
|
|
226
|
+
* const vaultFile = await VaultFile.fromContent({
|
|
227
|
+
* name: 'document.txt',
|
|
228
|
+
* content: file,
|
|
229
|
+
* config: {
|
|
230
|
+
* vaultUrl,
|
|
231
|
+
* authStrategy,
|
|
232
|
+
* },
|
|
233
|
+
* upload: true
|
|
234
|
+
* })
|
|
235
|
+
* ```
|
|
236
|
+
*/
|
|
237
|
+
static async fromContent(params) {
|
|
238
|
+
const { name, content, config, upload = false } = params;
|
|
239
|
+
const { vaultUrl, authStrategy } = config;
|
|
240
|
+
const sha256sum = await getFileHash(content);
|
|
241
|
+
const file = new VaultFile({
|
|
242
|
+
content,
|
|
243
|
+
config: {
|
|
244
|
+
vaultUrl,
|
|
245
|
+
authStrategy
|
|
246
|
+
},
|
|
247
|
+
id: sha256sum,
|
|
248
|
+
name
|
|
249
|
+
});
|
|
250
|
+
const createdFile = await file._createFile();
|
|
251
|
+
if (upload) {
|
|
252
|
+
await file.upload(file.content, createdFile.uploadUrl);
|
|
253
|
+
}
|
|
254
|
+
return file;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Populates the metadata of the file instance.
|
|
94
258
|
*
|
|
95
|
-
* @
|
|
96
|
-
* @
|
|
259
|
+
* @returns The file instance
|
|
260
|
+
* @throws {Error} If the file ID is not set
|
|
261
|
+
* @throws {FetchError} If the metadata fetch fails
|
|
97
262
|
*/
|
|
98
|
-
async
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
this.name =
|
|
102
|
-
|
|
263
|
+
async populateMetadata() {
|
|
264
|
+
try {
|
|
265
|
+
this.metadata = await this.getFileMetadata();
|
|
266
|
+
this.name = this.metadata.originalFileName;
|
|
267
|
+
this.id = this.metadata.id;
|
|
268
|
+
return this;
|
|
269
|
+
} catch (error) {
|
|
270
|
+
console.error("Error fetching file metadata", error);
|
|
271
|
+
}
|
|
103
272
|
}
|
|
104
273
|
/**
|
|
105
|
-
*
|
|
274
|
+
* Gets the vault reference for this file.
|
|
275
|
+
*
|
|
276
|
+
* @returns The vault reference in the format `vault://{fileId}`
|
|
277
|
+
* @throws {Error} If the file ID is not set
|
|
278
|
+
*/
|
|
279
|
+
getVaultReference() {
|
|
280
|
+
if (!this.id) {
|
|
281
|
+
throw new Error("File ID is not set");
|
|
282
|
+
}
|
|
283
|
+
return `vault://${this.id}`;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Fetches the metadata of the file.
|
|
287
|
+
*
|
|
288
|
+
* @returns The metadata of the file
|
|
289
|
+
* @throws {Error} If the file ID is not set
|
|
290
|
+
* @throws {FetchError} If the metadata fetch fails
|
|
291
|
+
*/
|
|
292
|
+
async getFileMetadata() {
|
|
293
|
+
if (!this.id) {
|
|
294
|
+
throw new Error("File ID is not set");
|
|
295
|
+
}
|
|
296
|
+
const response = await this._fetch({
|
|
297
|
+
method: "GET",
|
|
298
|
+
path: `/v2/files/${this.id}/metadata`
|
|
299
|
+
});
|
|
300
|
+
return response;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Fetches a upload URL for the file.
|
|
304
|
+
*
|
|
305
|
+
* @returns The upload URL for the file
|
|
306
|
+
* @throws {Error} If the vault service returns an invalid response
|
|
307
|
+
* @throws {FetchError} If the upload URL fetch fails
|
|
308
|
+
*/
|
|
309
|
+
async getUploadUrl() {
|
|
310
|
+
if (this.lastUploadUrl && this.lastUploadUrl.expiresAt > /* @__PURE__ */ new Date()) {
|
|
311
|
+
return this.lastUploadUrl.url;
|
|
312
|
+
}
|
|
313
|
+
if (!this.id) {
|
|
314
|
+
const createdFile = await this._createFile();
|
|
315
|
+
this.id = createdFile.id;
|
|
316
|
+
this.metadata = createdFile.metadata;
|
|
317
|
+
this.name = createdFile.metadata?.originalFileName;
|
|
318
|
+
this.lastUploadUrl = { url: new URL(createdFile.uploadUrl), expiresAt: new Date(createdFile.expiresAt) };
|
|
319
|
+
return this.lastUploadUrl.url;
|
|
320
|
+
}
|
|
321
|
+
const response = await this._fetch({
|
|
322
|
+
method: "PUT",
|
|
323
|
+
path: `/v2/files/${this.id}`
|
|
324
|
+
}).then(GetUploadUrlResponseV2.safeParse);
|
|
325
|
+
if (!response.success) {
|
|
326
|
+
throw new Error(`Invalid response from vault service. ${JSON.stringify(response.error)}`);
|
|
327
|
+
}
|
|
328
|
+
this.lastUploadUrl = { url: new URL(response.data.uploadUrl), expiresAt: new Date(response.data.expiresAt) };
|
|
329
|
+
return this.lastUploadUrl.url;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Fetches a download URL for the file.
|
|
106
333
|
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
334
|
+
* @returns The download URL for the file
|
|
335
|
+
* @throws {Error} If the vault service returns an invalid response
|
|
336
|
+
* @throws {Error} If not file ID, name or content is set
|
|
337
|
+
* @throws {FetchError} If the download URL fetch fails
|
|
338
|
+
*/
|
|
339
|
+
async getDownloadUrl() {
|
|
340
|
+
if (this.lastDownloadUrl && this.lastDownloadUrl.expiresAt > /* @__PURE__ */ new Date()) {
|
|
341
|
+
return this.lastDownloadUrl.url;
|
|
342
|
+
}
|
|
343
|
+
if (!this.id && !this.name && !this.content) {
|
|
344
|
+
throw new Error("File was not created yet");
|
|
345
|
+
}
|
|
346
|
+
const id = this.id ?? this.metadata?.id ?? (this.content ? await getFileHash(this.content) : this.name);
|
|
347
|
+
const response = await this._fetch({
|
|
348
|
+
method: "GET",
|
|
349
|
+
path: `/v2/files/${id}`
|
|
350
|
+
});
|
|
351
|
+
this.lastDownloadUrl = { url: new URL(response.url), expiresAt: new Date(response.expiresAt) };
|
|
352
|
+
return this.lastDownloadUrl.url;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Uploads a file to the vault.
|
|
111
356
|
*
|
|
112
357
|
* @example
|
|
358
|
+
* ```ts
|
|
113
359
|
* const file = new File(['content'], 'document.txt')
|
|
114
|
-
* await
|
|
360
|
+
* const vaultFile = await VaultFile.fromBlob('document.txt', file, { vaultUrl, authStrategy })
|
|
115
361
|
* await vaultFile.upload(file)
|
|
362
|
+
* ```
|
|
116
363
|
*
|
|
117
|
-
* @param file - The file to upload to the vault
|
|
364
|
+
* @param file - The file to upload to the vault. If not provided, the file content will be taken from the `content` property.
|
|
118
365
|
* @throws {FetchError} If the upload fails
|
|
366
|
+
* @throws {Error} If the file content is not set and no file is provided
|
|
119
367
|
* @returns Promise that resolves when upload is complete
|
|
120
368
|
*/
|
|
121
|
-
async upload(file) {
|
|
122
|
-
|
|
123
|
-
|
|
369
|
+
async upload(file, url) {
|
|
370
|
+
if (!file && !this.content) {
|
|
371
|
+
throw new Error("Missing file content. Use fromBlob() to create a file with content, or provide a file to upload.");
|
|
372
|
+
}
|
|
373
|
+
const uploadUrl = url ?? await this.getUploadUrl();
|
|
374
|
+
await wrappedFetch(uploadUrl, {
|
|
124
375
|
method: "PUT",
|
|
125
|
-
body: file
|
|
376
|
+
body: file ?? this.content
|
|
126
377
|
});
|
|
127
|
-
if (!response.ok) {
|
|
128
|
-
throw new FetchError(`Error uploading file ${this.name}: ${response.status} ${response.statusText}`, response);
|
|
129
|
-
}
|
|
130
378
|
}
|
|
131
379
|
async download(responseType = "blob") {
|
|
132
380
|
const downloadUrl = await this.getDownloadUrl();
|
|
133
|
-
const response = await
|
|
381
|
+
const response = await wrappedFetch(downloadUrl, {
|
|
134
382
|
method: "GET"
|
|
135
383
|
});
|
|
136
|
-
if (!response.ok) {
|
|
137
|
-
throw new FetchError(`Error downloading file ${this.name}: ${response.status} ${response.statusText}`, response);
|
|
138
|
-
}
|
|
139
384
|
const blob = await response.blob();
|
|
140
385
|
if (responseType === "blob")
|
|
141
386
|
return blob;
|
|
@@ -172,15 +417,21 @@ class APIKeyAuthStrategy {
|
|
|
172
417
|
}
|
|
173
418
|
}
|
|
174
419
|
|
|
175
|
-
function
|
|
176
|
-
function
|
|
177
|
-
return
|
|
420
|
+
function vaultClient(config) {
|
|
421
|
+
function createFromContent(name, content) {
|
|
422
|
+
return VaultFile.fromContent({
|
|
178
423
|
name,
|
|
179
|
-
|
|
180
|
-
|
|
424
|
+
content,
|
|
425
|
+
config
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
function createFromReference(reference) {
|
|
429
|
+
return VaultFile.fromVaultReference({
|
|
430
|
+
reference,
|
|
431
|
+
config
|
|
181
432
|
});
|
|
182
433
|
}
|
|
183
|
-
return {
|
|
434
|
+
return { createFromContent, createFromReference };
|
|
184
435
|
}
|
|
185
436
|
|
|
186
|
-
export { APIKeyAuthStrategy, DataTokenAuthStrategy, FetchError, VaultFile,
|
|
437
|
+
export { APIKeyAuthStrategy, DataTokenAuthStrategy, FetchError, VaultFile, vaultClient };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meistrari/vault-sdk",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -18,26 +18,28 @@
|
|
|
18
18
|
"files": [
|
|
19
19
|
"dist"
|
|
20
20
|
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"test": "vitest",
|
|
23
|
+
"build": "unbuild",
|
|
24
|
+
"lint": "eslint .",
|
|
25
|
+
"lint:fix": "eslint . --fix",
|
|
26
|
+
"check": "bun run lint && bun tsc --noEmit"
|
|
27
|
+
},
|
|
21
28
|
"dependencies": {
|
|
22
|
-
"
|
|
29
|
+
"@meistrari/vault-shared": "workspace:*",
|
|
30
|
+
"ofetch": "1.4.1",
|
|
31
|
+
"zod": "3.23.8"
|
|
23
32
|
},
|
|
24
33
|
"devDependencies": {
|
|
25
|
-
"vitest": "2.1.9",
|
|
26
34
|
"@types/bun": "latest",
|
|
27
35
|
"msw": "2.6.8",
|
|
28
|
-
"unbuild": "2.0.0"
|
|
36
|
+
"unbuild": "2.0.0",
|
|
37
|
+
"vitest": "2.1.9"
|
|
29
38
|
},
|
|
30
39
|
"peerDependencies": {
|
|
31
40
|
"typescript": "^5.0.0"
|
|
32
41
|
},
|
|
33
42
|
"publishConfig": {
|
|
34
43
|
"access": "public"
|
|
35
|
-
},
|
|
36
|
-
"scripts": {
|
|
37
|
-
"test": "vitest",
|
|
38
|
-
"build": "unbuild",
|
|
39
|
-
"lint": "eslint .",
|
|
40
|
-
"lint:fix": "eslint . --fix",
|
|
41
|
-
"check": "bun run lint && bun tsc --noEmit"
|
|
42
44
|
}
|
|
43
|
-
}
|
|
45
|
+
}
|