@meistrari/vault-sdk 1.0.0 → 1.1.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/dist/index.cjs CHANGED
@@ -1,6 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  const schemas = require('@meistrari/vault-shared/schemas');
4
+ const fileType = require('file-type');
5
+ const mimeTypes = require('mime-types');
4
6
 
5
7
  class FetchError extends Error {
6
8
  constructor(message, url, method, response) {
@@ -34,6 +36,25 @@ async function getFileHash(blob) {
34
36
  const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
35
37
  return hashHex;
36
38
  }
39
+ async function detectFileMimeType(blob) {
40
+ const result = await fileType.fileTypeFromBlob(blob).catch(() => void 0);
41
+ if (result?.mime) {
42
+ return result.mime;
43
+ }
44
+ if ("name" in blob && typeof blob.name === "string") {
45
+ const extension = blob.name.split(".").pop()?.toLowerCase();
46
+ if (extension) {
47
+ const mimeType = mimeTypes.lookup(`.${extension}`);
48
+ if (mimeType) {
49
+ return mimeType;
50
+ }
51
+ }
52
+ }
53
+ if (blob instanceof Blob && blob.type) {
54
+ return blob.type;
55
+ }
56
+ return void 0;
57
+ }
37
58
 
38
59
  var __defProp$1 = Object.defineProperty;
39
60
  var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -118,11 +139,12 @@ class VaultFile {
118
139
  * @throws {Error} If the file ID is not set
119
140
  * @throws {FetchError} If the metadata fetch fails
120
141
  */
121
- async _createFile() {
142
+ async _createFile(params = {}) {
122
143
  const response = await this._fetch({
123
144
  method: "POST",
124
145
  path: `/v2/files`,
125
146
  body: JSON.stringify({
147
+ ...params,
126
148
  fileName: this.name,
127
149
  sha256sum: this.id ?? this.metadata?.id ?? (this.content ? await getFileHash(this.content) : void 0)
128
150
  })
@@ -240,6 +262,8 @@ class VaultFile {
240
262
  const { name, content, config, upload = false } = params;
241
263
  const { vaultUrl, authStrategy } = config;
242
264
  const sha256sum = await getFileHash(content);
265
+ const mimeType = await detectFileMimeType(content);
266
+ const size = content.size;
243
267
  const file = new VaultFile({
244
268
  content,
245
269
  config: {
@@ -249,7 +273,10 @@ class VaultFile {
249
273
  id: sha256sum,
250
274
  name
251
275
  });
252
- const createdFile = await file._createFile();
276
+ const createdFile = await file._createFile({
277
+ size,
278
+ mimeType
279
+ });
253
280
  if (upload) {
254
281
  await file.upload(file.content, createdFile.uploadUrl);
255
282
  }
@@ -359,7 +386,14 @@ class VaultFile {
359
386
  * @example
360
387
  * ```ts
361
388
  * const file = new File(['content'], 'document.txt')
362
- * const vaultFile = await VaultFile.fromBlob('document.txt', file, { vaultUrl, authStrategy })
389
+ * const vaultFile = await VaultFile.fromContent({
390
+ * name: 'document.txt',
391
+ * content: file,
392
+ * config: {
393
+ * vaultUrl,
394
+ * authStrategy,
395
+ * },
396
+ * })
363
397
  * await vaultFile.upload(file)
364
398
  * ```
365
399
  *
@@ -369,13 +403,19 @@ class VaultFile {
369
403
  * @returns Promise that resolves when upload is complete
370
404
  */
371
405
  async upload(file, url) {
372
- if (!file && !this.content) {
373
- throw new Error("Missing file content. Use fromBlob() to create a file with content, or provide a file to upload.");
406
+ const content = file ?? this.content;
407
+ if (!content) {
408
+ throw new Error("Missing file content. Use fromContent() to create a file with content, or provide a file to upload.");
374
409
  }
375
410
  const uploadUrl = url ?? await this.getUploadUrl();
411
+ const mimeType = this.metadata?.mimeType ?? await detectFileMimeType(content);
412
+ const headers = new Headers();
413
+ if (mimeType)
414
+ headers.set("Content-Type", mimeType);
376
415
  await wrappedFetch(uploadUrl, {
377
416
  method: "PUT",
378
- body: file ?? this.content
417
+ body: content,
418
+ headers
379
419
  });
380
420
  }
381
421
  async download(responseType = "blob") {
package/dist/index.d.cts CHANGED
@@ -221,7 +221,14 @@ declare class VaultFile {
221
221
  * @example
222
222
  * ```ts
223
223
  * const file = new File(['content'], 'document.txt')
224
- * const vaultFile = await VaultFile.fromBlob('document.txt', file, { vaultUrl, authStrategy })
224
+ * const vaultFile = await VaultFile.fromContent({
225
+ * name: 'document.txt',
226
+ * content: file,
227
+ * config: {
228
+ * vaultUrl,
229
+ * authStrategy,
230
+ * },
231
+ * })
225
232
  * await vaultFile.upload(file)
226
233
  * ```
227
234
  *
@@ -261,4 +268,5 @@ declare function vaultClient(config: VaultConfig): {
261
268
  createFromReference: (reference: string) => Promise<VaultFile>;
262
269
  };
263
270
 
264
- export { APIKeyAuthStrategy, type AuthStrategy, DataTokenAuthStrategy, FetchError, type VaultConfig, VaultFile, vaultClient };
271
+ export { APIKeyAuthStrategy, DataTokenAuthStrategy, FetchError, VaultFile, vaultClient };
272
+ export type { AuthStrategy, VaultConfig };
package/dist/index.d.mts CHANGED
@@ -221,7 +221,14 @@ declare class VaultFile {
221
221
  * @example
222
222
  * ```ts
223
223
  * const file = new File(['content'], 'document.txt')
224
- * const vaultFile = await VaultFile.fromBlob('document.txt', file, { vaultUrl, authStrategy })
224
+ * const vaultFile = await VaultFile.fromContent({
225
+ * name: 'document.txt',
226
+ * content: file,
227
+ * config: {
228
+ * vaultUrl,
229
+ * authStrategy,
230
+ * },
231
+ * })
225
232
  * await vaultFile.upload(file)
226
233
  * ```
227
234
  *
@@ -261,4 +268,5 @@ declare function vaultClient(config: VaultConfig): {
261
268
  createFromReference: (reference: string) => Promise<VaultFile>;
262
269
  };
263
270
 
264
- export { APIKeyAuthStrategy, type AuthStrategy, DataTokenAuthStrategy, FetchError, type VaultConfig, VaultFile, vaultClient };
271
+ export { APIKeyAuthStrategy, DataTokenAuthStrategy, FetchError, VaultFile, vaultClient };
272
+ export type { AuthStrategy, VaultConfig };
package/dist/index.d.ts CHANGED
@@ -221,7 +221,14 @@ declare class VaultFile {
221
221
  * @example
222
222
  * ```ts
223
223
  * const file = new File(['content'], 'document.txt')
224
- * const vaultFile = await VaultFile.fromBlob('document.txt', file, { vaultUrl, authStrategy })
224
+ * const vaultFile = await VaultFile.fromContent({
225
+ * name: 'document.txt',
226
+ * content: file,
227
+ * config: {
228
+ * vaultUrl,
229
+ * authStrategy,
230
+ * },
231
+ * })
225
232
  * await vaultFile.upload(file)
226
233
  * ```
227
234
  *
@@ -261,4 +268,5 @@ declare function vaultClient(config: VaultConfig): {
261
268
  createFromReference: (reference: string) => Promise<VaultFile>;
262
269
  };
263
270
 
264
- export { APIKeyAuthStrategy, type AuthStrategy, DataTokenAuthStrategy, FetchError, type VaultConfig, VaultFile, vaultClient };
271
+ export { APIKeyAuthStrategy, DataTokenAuthStrategy, FetchError, VaultFile, vaultClient };
272
+ export type { AuthStrategy, VaultConfig };
package/dist/index.mjs CHANGED
@@ -1,4 +1,6 @@
1
1
  import { GetUploadUrlResponseV2, GetDownloadUrlResponse } from '@meistrari/vault-shared/schemas';
2
+ import { fileTypeFromBlob } from 'file-type';
3
+ import { lookup } from 'mime-types';
2
4
 
3
5
  class FetchError extends Error {
4
6
  constructor(message, url, method, response) {
@@ -32,6 +34,25 @@ async function getFileHash(blob) {
32
34
  const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
33
35
  return hashHex;
34
36
  }
37
+ async function detectFileMimeType(blob) {
38
+ const result = await fileTypeFromBlob(blob).catch(() => void 0);
39
+ if (result?.mime) {
40
+ return result.mime;
41
+ }
42
+ if ("name" in blob && typeof blob.name === "string") {
43
+ const extension = blob.name.split(".").pop()?.toLowerCase();
44
+ if (extension) {
45
+ const mimeType = lookup(`.${extension}`);
46
+ if (mimeType) {
47
+ return mimeType;
48
+ }
49
+ }
50
+ }
51
+ if (blob instanceof Blob && blob.type) {
52
+ return blob.type;
53
+ }
54
+ return void 0;
55
+ }
35
56
 
36
57
  var __defProp$1 = Object.defineProperty;
37
58
  var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -116,11 +137,12 @@ class VaultFile {
116
137
  * @throws {Error} If the file ID is not set
117
138
  * @throws {FetchError} If the metadata fetch fails
118
139
  */
119
- async _createFile() {
140
+ async _createFile(params = {}) {
120
141
  const response = await this._fetch({
121
142
  method: "POST",
122
143
  path: `/v2/files`,
123
144
  body: JSON.stringify({
145
+ ...params,
124
146
  fileName: this.name,
125
147
  sha256sum: this.id ?? this.metadata?.id ?? (this.content ? await getFileHash(this.content) : void 0)
126
148
  })
@@ -238,6 +260,8 @@ class VaultFile {
238
260
  const { name, content, config, upload = false } = params;
239
261
  const { vaultUrl, authStrategy } = config;
240
262
  const sha256sum = await getFileHash(content);
263
+ const mimeType = await detectFileMimeType(content);
264
+ const size = content.size;
241
265
  const file = new VaultFile({
242
266
  content,
243
267
  config: {
@@ -247,7 +271,10 @@ class VaultFile {
247
271
  id: sha256sum,
248
272
  name
249
273
  });
250
- const createdFile = await file._createFile();
274
+ const createdFile = await file._createFile({
275
+ size,
276
+ mimeType
277
+ });
251
278
  if (upload) {
252
279
  await file.upload(file.content, createdFile.uploadUrl);
253
280
  }
@@ -357,7 +384,14 @@ class VaultFile {
357
384
  * @example
358
385
  * ```ts
359
386
  * const file = new File(['content'], 'document.txt')
360
- * const vaultFile = await VaultFile.fromBlob('document.txt', file, { vaultUrl, authStrategy })
387
+ * const vaultFile = await VaultFile.fromContent({
388
+ * name: 'document.txt',
389
+ * content: file,
390
+ * config: {
391
+ * vaultUrl,
392
+ * authStrategy,
393
+ * },
394
+ * })
361
395
  * await vaultFile.upload(file)
362
396
  * ```
363
397
  *
@@ -367,13 +401,19 @@ class VaultFile {
367
401
  * @returns Promise that resolves when upload is complete
368
402
  */
369
403
  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.");
404
+ const content = file ?? this.content;
405
+ if (!content) {
406
+ throw new Error("Missing file content. Use fromContent() to create a file with content, or provide a file to upload.");
372
407
  }
373
408
  const uploadUrl = url ?? await this.getUploadUrl();
409
+ const mimeType = this.metadata?.mimeType ?? await detectFileMimeType(content);
410
+ const headers = new Headers();
411
+ if (mimeType)
412
+ headers.set("Content-Type", mimeType);
374
413
  await wrappedFetch(uploadUrl, {
375
414
  method: "PUT",
376
- body: file ?? this.content
415
+ body: content,
416
+ headers
377
417
  });
378
418
  }
379
419
  async download(responseType = "blob") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meistrari/vault-sdk",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "license": "UNLICENSED",
5
5
  "repository": {
6
6
  "type": "git",
@@ -18,20 +18,16 @@
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
- },
28
21
  "dependencies": {
29
- "@meistrari/vault-shared": "workspace:*",
22
+ "file-type": "21.0.0",
23
+ "mime-types": "3.0.1",
30
24
  "ofetch": "1.4.1",
31
- "zod": "3.23.8"
25
+ "zod": "3.23.8",
26
+ "@meistrari/vault-shared": "0.0.3"
32
27
  },
33
28
  "devDependencies": {
34
29
  "@types/bun": "latest",
30
+ "@types/mime-types": "3.0.1",
35
31
  "msw": "2.6.8",
36
32
  "unbuild": "2.0.0",
37
33
  "vitest": "2.1.9"
@@ -41,5 +37,12 @@
41
37
  },
42
38
  "publishConfig": {
43
39
  "access": "public"
40
+ },
41
+ "scripts": {
42
+ "test": "vitest",
43
+ "build": "unbuild",
44
+ "lint": "eslint .",
45
+ "lint:fix": "eslint . --fix",
46
+ "check": "bun run lint && bun tsc --noEmit"
44
47
  }
45
- }
48
+ }