@meistrari/vault-sdk 1.2.0 → 1.4.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
@@ -4,15 +4,15 @@ const schemas = require('@meistrari/vault-shared/schemas');
4
4
  const fileType = require('file-type');
5
5
  const mimeTypes = require('mime-types');
6
6
 
7
- var __defProp$1 = Object.defineProperty;
8
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
- var __publicField$1 = (obj, key, value) => {
10
- __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
7
+ var __defProp$2 = Object.defineProperty;
8
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __publicField$2 = (obj, key, value) => {
10
+ __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
11
11
  return value;
12
12
  };
13
13
  class DataTokenAuthStrategy {
14
14
  constructor(dataToken) {
15
- __publicField$1(this, "dataToken");
15
+ __publicField$2(this, "dataToken");
16
16
  this.dataToken = dataToken;
17
17
  }
18
18
  getHeaders() {
@@ -23,7 +23,7 @@ class DataTokenAuthStrategy {
23
23
  }
24
24
  class APIKeyAuthStrategy {
25
25
  constructor(apiKey) {
26
- __publicField$1(this, "apiKey");
26
+ __publicField$2(this, "apiKey");
27
27
  this.apiKey = apiKey;
28
28
  }
29
29
  getHeaders() {
@@ -50,6 +50,103 @@ ${text}`, url, method, response);
50
50
  }
51
51
  }
52
52
 
53
+ var __defProp$1 = Object.defineProperty;
54
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
55
+ var __publicField$1 = (obj, key, value) => {
56
+ __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
57
+ return value;
58
+ };
59
+ class Permalink {
60
+ constructor(config, params) {
61
+ __publicField$1(this, "config");
62
+ __publicField$1(this, "id");
63
+ __publicField$1(this, "workspaceId");
64
+ __publicField$1(this, "createdAt");
65
+ __publicField$1(this, "createdBy");
66
+ __publicField$1(this, "expiresAt");
67
+ __publicField$1(this, "fileId");
68
+ this.config = config;
69
+ this.id = params.id;
70
+ this.workspaceId = params.workspaceId;
71
+ this.createdAt = new Date(params.createdAt);
72
+ this.createdBy = params.createdBy;
73
+ this.expiresAt = params.expiresAt ? new Date(params.expiresAt) : null;
74
+ this.fileId = params.fileId;
75
+ }
76
+ /**
77
+ * The URL for the permalink.
78
+ */
79
+ get url() {
80
+ return new URL(`/permalinks/${this.id}`, this.config.vaultUrl);
81
+ }
82
+ /**
83
+ * Get a new permalink instance from its ID.
84
+ *
85
+ * @param config - The vault config.
86
+ * @param id - The permalink ID.
87
+ * @returns The permalink.
88
+ */
89
+ static async fromId(config, id) {
90
+ const response = await fetch(`${config.vaultUrl}/permalinks/${id}/metadata`, {
91
+ headers: config.authStrategy.getHeaders()
92
+ });
93
+ if (!response.ok) {
94
+ throw await FetchError.from(response.url, "GET", response);
95
+ }
96
+ const data = await response.json();
97
+ return new Permalink(config, data);
98
+ }
99
+ /**
100
+ * Create a new permalink.
101
+ *
102
+ * @param config - The vault config.
103
+ * @param params - The parameters for the permalink.
104
+ * @param params.expiresIn - Time, in seconds, the permalink will be valid for.
105
+ * @param params.fileId - The ID of the file to create a permalink for.
106
+ * @param params.workspaceId - The ID of the workspace to create a permalink for.
107
+ *
108
+ * @param options - Additional options for the request.
109
+ * @param options.signal - The signal to abort the request.
110
+ *
111
+ * @returns The permalink.
112
+ */
113
+ static async create(config, params, options) {
114
+ const { expiresIn } = params;
115
+ const expiresAt = expiresIn ? new Date(Date.now() + expiresIn * 1e3) : void 0;
116
+ const headers = config.authStrategy.getHeaders();
117
+ headers.append("x-compatibility-date", "2025-07-29");
118
+ headers.append("content-type", "application/json");
119
+ const body = expiresAt ? JSON.stringify({ expiresAt: expiresAt.toISOString() }) : "{}";
120
+ const response = await fetch(`${config.vaultUrl}/files/${params.fileId}/permalinks`, {
121
+ method: "POST",
122
+ signal: options?.signal,
123
+ headers,
124
+ body
125
+ });
126
+ if (!response.ok) {
127
+ throw await FetchError.from(response.url, "POST", response);
128
+ }
129
+ const data = await response.json();
130
+ return new Permalink(config, data);
131
+ }
132
+ /**
133
+ * Delete the permalink.
134
+ *
135
+ * @param options - Additional options for the request.
136
+ * @param options.signal - The signal to abort the request.
137
+ */
138
+ async delete(options) {
139
+ const response = await fetch(`${this.config.vaultUrl}/permalinks/${this.id}`, {
140
+ method: "DELETE",
141
+ signal: options?.signal,
142
+ headers: this.config.authStrategy.getHeaders()
143
+ });
144
+ if (!response.ok) {
145
+ throw await FetchError.from(response.url, "DELETE", response);
146
+ }
147
+ }
148
+ }
149
+
53
150
  async function blobToBase64(blob) {
54
151
  const fileContent = new Uint8Array(await blob.arrayBuffer());
55
152
  let content = "";
@@ -150,10 +247,15 @@ class VaultFile {
150
247
  * @throws {FetchError} If the fetch fails
151
248
  */
152
249
  async _fetch(params) {
153
- const { method, path, body, signal } = params;
154
- const url = new URL(this.config.vaultUrl + path).toString();
250
+ const { method, path, body, signal, query } = params;
251
+ const url = new URL(path, this.config.vaultUrl);
155
252
  const headers = new Headers(this.headers);
156
253
  headers.set("x-compatibility-date", compatibilityDate);
254
+ if (query) {
255
+ Object.entries(query).forEach(([key, value]) => {
256
+ url.searchParams.set(key, value);
257
+ });
258
+ }
157
259
  const response = await wrappedFetch(url, {
158
260
  method,
159
261
  body,
@@ -178,7 +280,7 @@ class VaultFile {
178
280
  async _createFile(metadata = {}, options) {
179
281
  const response = await this._fetch({
180
282
  method: "POST",
181
- path: `/v2/files`,
283
+ path: `files`,
182
284
  body: JSON.stringify({
183
285
  ...metadata,
184
286
  fileName: this.name,
@@ -237,7 +339,8 @@ class VaultFile {
237
339
  const { reference, config, download = false } = params;
238
340
  const { vaultUrl, authStrategy } = config;
239
341
  const id = removeVaultPrefix(reference);
240
- const response = await wrappedFetch(`${vaultUrl}/v2/files/${id}`, {
342
+ const url = new URL(`files/${id}`, vaultUrl);
343
+ const response = await wrappedFetch(url, {
241
344
  method: "GET",
242
345
  headers: authStrategy.getHeaders(),
243
346
  signal: options?.signal
@@ -372,7 +475,7 @@ class VaultFile {
372
475
  }
373
476
  const response = await this._fetch({
374
477
  method: "GET",
375
- path: `/v2/files/${this.id}/metadata`,
478
+ path: `files/${this.id}/metadata`,
376
479
  signal: options?.signal
377
480
  });
378
481
  return response;
@@ -381,6 +484,7 @@ class VaultFile {
381
484
  * Fetches a upload URL for the file.
382
485
  * @param options - The options for the request
383
486
  * @param options.signal - The signal to abort the request
487
+ * @param options.expiresIn - The number of seconds the upload URL will be valid for
384
488
  *
385
489
  * @returns The upload URL for the file
386
490
  * @throws {Error} If the vault service returns an invalid response
@@ -400,8 +504,9 @@ class VaultFile {
400
504
  }
401
505
  const response = await this._fetch({
402
506
  method: "PUT",
403
- path: `/v2/files/${this.id}`,
404
- signal: options?.signal
507
+ path: `files/${this.id}`,
508
+ signal: options?.signal,
509
+ ...options?.expiresIn ? { query: { expiresIn: options.expiresIn.toString() } } : {}
405
510
  }).then(schemas.GetUploadUrlResponseV2.safeParse);
406
511
  if (!response.success) {
407
512
  throw new Error(`Invalid response from vault service. ${JSON.stringify(response.error)}`);
@@ -413,6 +518,7 @@ class VaultFile {
413
518
  * Fetches a download URL for the file.
414
519
  * @param options - The options for the request
415
520
  * @param options.signal - The signal to abort the request
521
+ * @param options.expiresIn - The number of seconds the download URL will be valid for
416
522
  *
417
523
  * @returns The download URL for the file
418
524
  * @throws {Error} If the vault service returns an invalid response
@@ -429,8 +535,9 @@ class VaultFile {
429
535
  const id = this.id ?? this.metadata?.id ?? (this.content ? await getFileHash(this.content) : this.name);
430
536
  const response = await this._fetch({
431
537
  method: "GET",
432
- path: `/v2/files/${id}`,
433
- signal: options?.signal
538
+ path: `files/${id}`,
539
+ signal: options?.signal,
540
+ ...options?.expiresIn ? { query: { expiresIn: options.expiresIn.toString() } } : {}
434
541
  });
435
542
  this.lastDownloadUrl = { url: new URL(response.url), expiresAt: new Date(response.expiresAt) };
436
543
  return this.lastDownloadUrl.url;
@@ -489,6 +596,62 @@ class VaultFile {
489
596
  return blob;
490
597
  return await blobToBase64(blob);
491
598
  }
599
+ /**
600
+ * Deletes the file from the vault.
601
+ * @param options - The options for the request
602
+ * @param options.signal - The signal to abort the request
603
+ *
604
+ */
605
+ async delete(options) {
606
+ if (!this.id) {
607
+ throw new Error("File ID is not set");
608
+ }
609
+ await this._fetch({
610
+ method: "DELETE",
611
+ path: `files/${this.id}`,
612
+ signal: options?.signal
613
+ });
614
+ }
615
+ /**
616
+ * Creates a permalink for the file.
617
+ * @param params - The parameters for the permalink
618
+ * @param params.expiresIn - The number of seconds the permalink will be valid for
619
+ * @param options - The options for the request
620
+ * @param options.signal - The signal to abort the request
621
+ *
622
+ * @returns The permalink for the file
623
+ */
624
+ async createPermalink(params = {}, options) {
625
+ if (!this.id) {
626
+ throw new Error("File ID is not set");
627
+ }
628
+ if (!this.metadata?.workspaceId) {
629
+ throw new Error("Workspace ID is not set. Call populateMetadata() to populate the metadata fields.");
630
+ }
631
+ return Permalink.create(this.config, {
632
+ fileId: this.id,
633
+ workspaceId: this.metadata.workspaceId,
634
+ expiresIn: params.expiresIn
635
+ }, options);
636
+ }
637
+ /**
638
+ * Gets a list of the valid permalinks for the file.
639
+ * @param options - Additional options for the request
640
+ * @param options.signal - Abort signal
641
+ *
642
+ * @returns The permalinks for the file
643
+ */
644
+ async getPermalinks(options) {
645
+ if (!this.id) {
646
+ throw new Error("File ID is not set");
647
+ }
648
+ const permalinks = await this._fetch({
649
+ method: "GET",
650
+ path: `files/${this.id}/permalinks`,
651
+ signal: options?.signal
652
+ });
653
+ return permalinks.map((data) => new Permalink(this.config, data));
654
+ }
492
655
  }
493
656
 
494
657
  function vaultClient(config) {
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { FileMetadata } from '@meistrari/vault-shared/schemas';
1
+ import { SerializedPermalink, FileMetadata } from '@meistrari/vault-shared/schemas';
2
2
 
3
3
  interface AuthStrategy {
4
4
  getHeaders: () => Headers;
@@ -27,6 +27,58 @@ type VaultConfig = {
27
27
  vaultUrl: string;
28
28
  authStrategy: AuthStrategy;
29
29
  };
30
+
31
+ declare class Permalink {
32
+ private readonly config;
33
+ readonly id: string;
34
+ readonly workspaceId: string;
35
+ readonly createdAt: Date;
36
+ readonly createdBy: string | null;
37
+ readonly expiresAt: Date | null;
38
+ readonly fileId: string;
39
+ constructor(config: VaultConfig, params: SerializedPermalink);
40
+ /**
41
+ * The URL for the permalink.
42
+ */
43
+ get url(): URL;
44
+ /**
45
+ * Get a new permalink instance from its ID.
46
+ *
47
+ * @param config - The vault config.
48
+ * @param id - The permalink ID.
49
+ * @returns The permalink.
50
+ */
51
+ static fromId(config: VaultConfig, id: string): Promise<Permalink>;
52
+ /**
53
+ * Create a new permalink.
54
+ *
55
+ * @param config - The vault config.
56
+ * @param params - The parameters for the permalink.
57
+ * @param params.expiresIn - Time, in seconds, the permalink will be valid for.
58
+ * @param params.fileId - The ID of the file to create a permalink for.
59
+ * @param params.workspaceId - The ID of the workspace to create a permalink for.
60
+ *
61
+ * @param options - Additional options for the request.
62
+ * @param options.signal - The signal to abort the request.
63
+ *
64
+ * @returns The permalink.
65
+ */
66
+ static create(config: VaultConfig, params: Pick<SerializedPermalink, 'fileId' | 'workspaceId'> & {
67
+ expiresIn?: number;
68
+ }, options?: {
69
+ signal?: AbortSignal;
70
+ }): Promise<Permalink>;
71
+ /**
72
+ * Delete the permalink.
73
+ *
74
+ * @param options - Additional options for the request.
75
+ * @param options.signal - The signal to abort the request.
76
+ */
77
+ delete(options?: {
78
+ signal?: AbortSignal;
79
+ }): Promise<void>;
80
+ }
81
+
30
82
  type VaultFileParams = {
31
83
  id?: string;
32
84
  name?: string;
@@ -235,6 +287,7 @@ declare class VaultFile {
235
287
  * Fetches a upload URL for the file.
236
288
  * @param options - The options for the request
237
289
  * @param options.signal - The signal to abort the request
290
+ * @param options.expiresIn - The number of seconds the upload URL will be valid for
238
291
  *
239
292
  * @returns The upload URL for the file
240
293
  * @throws {Error} If the vault service returns an invalid response
@@ -242,11 +295,13 @@ declare class VaultFile {
242
295
  */
243
296
  getUploadUrl(options?: {
244
297
  signal?: AbortSignal;
298
+ expiresIn?: number;
245
299
  }): Promise<URL>;
246
300
  /**
247
301
  * Fetches a download URL for the file.
248
302
  * @param options - The options for the request
249
303
  * @param options.signal - The signal to abort the request
304
+ * @param options.expiresIn - The number of seconds the download URL will be valid for
250
305
  *
251
306
  * @returns The download URL for the file
252
307
  * @throws {Error} If the vault service returns an invalid response
@@ -255,6 +310,7 @@ declare class VaultFile {
255
310
  */
256
311
  getDownloadUrl(options?: {
257
312
  signal?: AbortSignal;
313
+ expiresIn?: number;
258
314
  }): Promise<URL>;
259
315
  /**
260
316
  * Uploads a file to the vault.
@@ -306,6 +362,39 @@ declare class VaultFile {
306
362
  download(responseType: 'base64', options?: {
307
363
  signal?: AbortSignal;
308
364
  }): Promise<string>;
365
+ /**
366
+ * Deletes the file from the vault.
367
+ * @param options - The options for the request
368
+ * @param options.signal - The signal to abort the request
369
+ *
370
+ */
371
+ delete(options?: {
372
+ signal?: AbortSignal;
373
+ }): Promise<void>;
374
+ /**
375
+ * Creates a permalink for the file.
376
+ * @param params - The parameters for the permalink
377
+ * @param params.expiresIn - The number of seconds the permalink will be valid for
378
+ * @param options - The options for the request
379
+ * @param options.signal - The signal to abort the request
380
+ *
381
+ * @returns The permalink for the file
382
+ */
383
+ createPermalink(params?: {
384
+ expiresIn?: number;
385
+ }, options?: {
386
+ signal?: AbortSignal;
387
+ }): Promise<Permalink>;
388
+ /**
389
+ * Gets a list of the valid permalinks for the file.
390
+ * @param options - Additional options for the request
391
+ * @param options.signal - Abort signal
392
+ *
393
+ * @returns The permalinks for the file
394
+ */
395
+ getPermalinks(options?: {
396
+ signal?: AbortSignal;
397
+ }): Promise<Permalink[]>;
309
398
  }
310
399
 
311
400
  declare function vaultClient(config: VaultConfig): {
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { FileMetadata } from '@meistrari/vault-shared/schemas';
1
+ import { SerializedPermalink, FileMetadata } from '@meistrari/vault-shared/schemas';
2
2
 
3
3
  interface AuthStrategy {
4
4
  getHeaders: () => Headers;
@@ -27,6 +27,58 @@ type VaultConfig = {
27
27
  vaultUrl: string;
28
28
  authStrategy: AuthStrategy;
29
29
  };
30
+
31
+ declare class Permalink {
32
+ private readonly config;
33
+ readonly id: string;
34
+ readonly workspaceId: string;
35
+ readonly createdAt: Date;
36
+ readonly createdBy: string | null;
37
+ readonly expiresAt: Date | null;
38
+ readonly fileId: string;
39
+ constructor(config: VaultConfig, params: SerializedPermalink);
40
+ /**
41
+ * The URL for the permalink.
42
+ */
43
+ get url(): URL;
44
+ /**
45
+ * Get a new permalink instance from its ID.
46
+ *
47
+ * @param config - The vault config.
48
+ * @param id - The permalink ID.
49
+ * @returns The permalink.
50
+ */
51
+ static fromId(config: VaultConfig, id: string): Promise<Permalink>;
52
+ /**
53
+ * Create a new permalink.
54
+ *
55
+ * @param config - The vault config.
56
+ * @param params - The parameters for the permalink.
57
+ * @param params.expiresIn - Time, in seconds, the permalink will be valid for.
58
+ * @param params.fileId - The ID of the file to create a permalink for.
59
+ * @param params.workspaceId - The ID of the workspace to create a permalink for.
60
+ *
61
+ * @param options - Additional options for the request.
62
+ * @param options.signal - The signal to abort the request.
63
+ *
64
+ * @returns The permalink.
65
+ */
66
+ static create(config: VaultConfig, params: Pick<SerializedPermalink, 'fileId' | 'workspaceId'> & {
67
+ expiresIn?: number;
68
+ }, options?: {
69
+ signal?: AbortSignal;
70
+ }): Promise<Permalink>;
71
+ /**
72
+ * Delete the permalink.
73
+ *
74
+ * @param options - Additional options for the request.
75
+ * @param options.signal - The signal to abort the request.
76
+ */
77
+ delete(options?: {
78
+ signal?: AbortSignal;
79
+ }): Promise<void>;
80
+ }
81
+
30
82
  type VaultFileParams = {
31
83
  id?: string;
32
84
  name?: string;
@@ -235,6 +287,7 @@ declare class VaultFile {
235
287
  * Fetches a upload URL for the file.
236
288
  * @param options - The options for the request
237
289
  * @param options.signal - The signal to abort the request
290
+ * @param options.expiresIn - The number of seconds the upload URL will be valid for
238
291
  *
239
292
  * @returns The upload URL for the file
240
293
  * @throws {Error} If the vault service returns an invalid response
@@ -242,11 +295,13 @@ declare class VaultFile {
242
295
  */
243
296
  getUploadUrl(options?: {
244
297
  signal?: AbortSignal;
298
+ expiresIn?: number;
245
299
  }): Promise<URL>;
246
300
  /**
247
301
  * Fetches a download URL for the file.
248
302
  * @param options - The options for the request
249
303
  * @param options.signal - The signal to abort the request
304
+ * @param options.expiresIn - The number of seconds the download URL will be valid for
250
305
  *
251
306
  * @returns The download URL for the file
252
307
  * @throws {Error} If the vault service returns an invalid response
@@ -255,6 +310,7 @@ declare class VaultFile {
255
310
  */
256
311
  getDownloadUrl(options?: {
257
312
  signal?: AbortSignal;
313
+ expiresIn?: number;
258
314
  }): Promise<URL>;
259
315
  /**
260
316
  * Uploads a file to the vault.
@@ -306,6 +362,39 @@ declare class VaultFile {
306
362
  download(responseType: 'base64', options?: {
307
363
  signal?: AbortSignal;
308
364
  }): Promise<string>;
365
+ /**
366
+ * Deletes the file from the vault.
367
+ * @param options - The options for the request
368
+ * @param options.signal - The signal to abort the request
369
+ *
370
+ */
371
+ delete(options?: {
372
+ signal?: AbortSignal;
373
+ }): Promise<void>;
374
+ /**
375
+ * Creates a permalink for the file.
376
+ * @param params - The parameters for the permalink
377
+ * @param params.expiresIn - The number of seconds the permalink will be valid for
378
+ * @param options - The options for the request
379
+ * @param options.signal - The signal to abort the request
380
+ *
381
+ * @returns The permalink for the file
382
+ */
383
+ createPermalink(params?: {
384
+ expiresIn?: number;
385
+ }, options?: {
386
+ signal?: AbortSignal;
387
+ }): Promise<Permalink>;
388
+ /**
389
+ * Gets a list of the valid permalinks for the file.
390
+ * @param options - Additional options for the request
391
+ * @param options.signal - Abort signal
392
+ *
393
+ * @returns The permalinks for the file
394
+ */
395
+ getPermalinks(options?: {
396
+ signal?: AbortSignal;
397
+ }): Promise<Permalink[]>;
309
398
  }
310
399
 
311
400
  declare function vaultClient(config: VaultConfig): {
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { FileMetadata } from '@meistrari/vault-shared/schemas';
1
+ import { SerializedPermalink, FileMetadata } from '@meistrari/vault-shared/schemas';
2
2
 
3
3
  interface AuthStrategy {
4
4
  getHeaders: () => Headers;
@@ -27,6 +27,58 @@ type VaultConfig = {
27
27
  vaultUrl: string;
28
28
  authStrategy: AuthStrategy;
29
29
  };
30
+
31
+ declare class Permalink {
32
+ private readonly config;
33
+ readonly id: string;
34
+ readonly workspaceId: string;
35
+ readonly createdAt: Date;
36
+ readonly createdBy: string | null;
37
+ readonly expiresAt: Date | null;
38
+ readonly fileId: string;
39
+ constructor(config: VaultConfig, params: SerializedPermalink);
40
+ /**
41
+ * The URL for the permalink.
42
+ */
43
+ get url(): URL;
44
+ /**
45
+ * Get a new permalink instance from its ID.
46
+ *
47
+ * @param config - The vault config.
48
+ * @param id - The permalink ID.
49
+ * @returns The permalink.
50
+ */
51
+ static fromId(config: VaultConfig, id: string): Promise<Permalink>;
52
+ /**
53
+ * Create a new permalink.
54
+ *
55
+ * @param config - The vault config.
56
+ * @param params - The parameters for the permalink.
57
+ * @param params.expiresIn - Time, in seconds, the permalink will be valid for.
58
+ * @param params.fileId - The ID of the file to create a permalink for.
59
+ * @param params.workspaceId - The ID of the workspace to create a permalink for.
60
+ *
61
+ * @param options - Additional options for the request.
62
+ * @param options.signal - The signal to abort the request.
63
+ *
64
+ * @returns The permalink.
65
+ */
66
+ static create(config: VaultConfig, params: Pick<SerializedPermalink, 'fileId' | 'workspaceId'> & {
67
+ expiresIn?: number;
68
+ }, options?: {
69
+ signal?: AbortSignal;
70
+ }): Promise<Permalink>;
71
+ /**
72
+ * Delete the permalink.
73
+ *
74
+ * @param options - Additional options for the request.
75
+ * @param options.signal - The signal to abort the request.
76
+ */
77
+ delete(options?: {
78
+ signal?: AbortSignal;
79
+ }): Promise<void>;
80
+ }
81
+
30
82
  type VaultFileParams = {
31
83
  id?: string;
32
84
  name?: string;
@@ -235,6 +287,7 @@ declare class VaultFile {
235
287
  * Fetches a upload URL for the file.
236
288
  * @param options - The options for the request
237
289
  * @param options.signal - The signal to abort the request
290
+ * @param options.expiresIn - The number of seconds the upload URL will be valid for
238
291
  *
239
292
  * @returns The upload URL for the file
240
293
  * @throws {Error} If the vault service returns an invalid response
@@ -242,11 +295,13 @@ declare class VaultFile {
242
295
  */
243
296
  getUploadUrl(options?: {
244
297
  signal?: AbortSignal;
298
+ expiresIn?: number;
245
299
  }): Promise<URL>;
246
300
  /**
247
301
  * Fetches a download URL for the file.
248
302
  * @param options - The options for the request
249
303
  * @param options.signal - The signal to abort the request
304
+ * @param options.expiresIn - The number of seconds the download URL will be valid for
250
305
  *
251
306
  * @returns The download URL for the file
252
307
  * @throws {Error} If the vault service returns an invalid response
@@ -255,6 +310,7 @@ declare class VaultFile {
255
310
  */
256
311
  getDownloadUrl(options?: {
257
312
  signal?: AbortSignal;
313
+ expiresIn?: number;
258
314
  }): Promise<URL>;
259
315
  /**
260
316
  * Uploads a file to the vault.
@@ -306,6 +362,39 @@ declare class VaultFile {
306
362
  download(responseType: 'base64', options?: {
307
363
  signal?: AbortSignal;
308
364
  }): Promise<string>;
365
+ /**
366
+ * Deletes the file from the vault.
367
+ * @param options - The options for the request
368
+ * @param options.signal - The signal to abort the request
369
+ *
370
+ */
371
+ delete(options?: {
372
+ signal?: AbortSignal;
373
+ }): Promise<void>;
374
+ /**
375
+ * Creates a permalink for the file.
376
+ * @param params - The parameters for the permalink
377
+ * @param params.expiresIn - The number of seconds the permalink will be valid for
378
+ * @param options - The options for the request
379
+ * @param options.signal - The signal to abort the request
380
+ *
381
+ * @returns The permalink for the file
382
+ */
383
+ createPermalink(params?: {
384
+ expiresIn?: number;
385
+ }, options?: {
386
+ signal?: AbortSignal;
387
+ }): Promise<Permalink>;
388
+ /**
389
+ * Gets a list of the valid permalinks for the file.
390
+ * @param options - Additional options for the request
391
+ * @param options.signal - Abort signal
392
+ *
393
+ * @returns The permalinks for the file
394
+ */
395
+ getPermalinks(options?: {
396
+ signal?: AbortSignal;
397
+ }): Promise<Permalink[]>;
309
398
  }
310
399
 
311
400
  declare function vaultClient(config: VaultConfig): {
package/dist/index.mjs CHANGED
@@ -2,15 +2,15 @@ import { GetUploadUrlResponseV2, GetDownloadUrlResponse } from '@meistrari/vault
2
2
  import { fileTypeFromBlob } from 'file-type';
3
3
  import { lookup } from 'mime-types';
4
4
 
5
- var __defProp$1 = Object.defineProperty;
6
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
- var __publicField$1 = (obj, key, value) => {
8
- __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
5
+ var __defProp$2 = Object.defineProperty;
6
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
+ var __publicField$2 = (obj, key, value) => {
8
+ __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
9
9
  return value;
10
10
  };
11
11
  class DataTokenAuthStrategy {
12
12
  constructor(dataToken) {
13
- __publicField$1(this, "dataToken");
13
+ __publicField$2(this, "dataToken");
14
14
  this.dataToken = dataToken;
15
15
  }
16
16
  getHeaders() {
@@ -21,7 +21,7 @@ class DataTokenAuthStrategy {
21
21
  }
22
22
  class APIKeyAuthStrategy {
23
23
  constructor(apiKey) {
24
- __publicField$1(this, "apiKey");
24
+ __publicField$2(this, "apiKey");
25
25
  this.apiKey = apiKey;
26
26
  }
27
27
  getHeaders() {
@@ -48,6 +48,103 @@ ${text}`, url, method, response);
48
48
  }
49
49
  }
50
50
 
51
+ var __defProp$1 = Object.defineProperty;
52
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
53
+ var __publicField$1 = (obj, key, value) => {
54
+ __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
55
+ return value;
56
+ };
57
+ class Permalink {
58
+ constructor(config, params) {
59
+ __publicField$1(this, "config");
60
+ __publicField$1(this, "id");
61
+ __publicField$1(this, "workspaceId");
62
+ __publicField$1(this, "createdAt");
63
+ __publicField$1(this, "createdBy");
64
+ __publicField$1(this, "expiresAt");
65
+ __publicField$1(this, "fileId");
66
+ this.config = config;
67
+ this.id = params.id;
68
+ this.workspaceId = params.workspaceId;
69
+ this.createdAt = new Date(params.createdAt);
70
+ this.createdBy = params.createdBy;
71
+ this.expiresAt = params.expiresAt ? new Date(params.expiresAt) : null;
72
+ this.fileId = params.fileId;
73
+ }
74
+ /**
75
+ * The URL for the permalink.
76
+ */
77
+ get url() {
78
+ return new URL(`/permalinks/${this.id}`, this.config.vaultUrl);
79
+ }
80
+ /**
81
+ * Get a new permalink instance from its ID.
82
+ *
83
+ * @param config - The vault config.
84
+ * @param id - The permalink ID.
85
+ * @returns The permalink.
86
+ */
87
+ static async fromId(config, id) {
88
+ const response = await fetch(`${config.vaultUrl}/permalinks/${id}/metadata`, {
89
+ headers: config.authStrategy.getHeaders()
90
+ });
91
+ if (!response.ok) {
92
+ throw await FetchError.from(response.url, "GET", response);
93
+ }
94
+ const data = await response.json();
95
+ return new Permalink(config, data);
96
+ }
97
+ /**
98
+ * Create a new permalink.
99
+ *
100
+ * @param config - The vault config.
101
+ * @param params - The parameters for the permalink.
102
+ * @param params.expiresIn - Time, in seconds, the permalink will be valid for.
103
+ * @param params.fileId - The ID of the file to create a permalink for.
104
+ * @param params.workspaceId - The ID of the workspace to create a permalink for.
105
+ *
106
+ * @param options - Additional options for the request.
107
+ * @param options.signal - The signal to abort the request.
108
+ *
109
+ * @returns The permalink.
110
+ */
111
+ static async create(config, params, options) {
112
+ const { expiresIn } = params;
113
+ const expiresAt = expiresIn ? new Date(Date.now() + expiresIn * 1e3) : void 0;
114
+ const headers = config.authStrategy.getHeaders();
115
+ headers.append("x-compatibility-date", "2025-07-29");
116
+ headers.append("content-type", "application/json");
117
+ const body = expiresAt ? JSON.stringify({ expiresAt: expiresAt.toISOString() }) : "{}";
118
+ const response = await fetch(`${config.vaultUrl}/files/${params.fileId}/permalinks`, {
119
+ method: "POST",
120
+ signal: options?.signal,
121
+ headers,
122
+ body
123
+ });
124
+ if (!response.ok) {
125
+ throw await FetchError.from(response.url, "POST", response);
126
+ }
127
+ const data = await response.json();
128
+ return new Permalink(config, data);
129
+ }
130
+ /**
131
+ * Delete the permalink.
132
+ *
133
+ * @param options - Additional options for the request.
134
+ * @param options.signal - The signal to abort the request.
135
+ */
136
+ async delete(options) {
137
+ const response = await fetch(`${this.config.vaultUrl}/permalinks/${this.id}`, {
138
+ method: "DELETE",
139
+ signal: options?.signal,
140
+ headers: this.config.authStrategy.getHeaders()
141
+ });
142
+ if (!response.ok) {
143
+ throw await FetchError.from(response.url, "DELETE", response);
144
+ }
145
+ }
146
+ }
147
+
51
148
  async function blobToBase64(blob) {
52
149
  const fileContent = new Uint8Array(await blob.arrayBuffer());
53
150
  let content = "";
@@ -148,10 +245,15 @@ class VaultFile {
148
245
  * @throws {FetchError} If the fetch fails
149
246
  */
150
247
  async _fetch(params) {
151
- const { method, path, body, signal } = params;
152
- const url = new URL(this.config.vaultUrl + path).toString();
248
+ const { method, path, body, signal, query } = params;
249
+ const url = new URL(path, this.config.vaultUrl);
153
250
  const headers = new Headers(this.headers);
154
251
  headers.set("x-compatibility-date", compatibilityDate);
252
+ if (query) {
253
+ Object.entries(query).forEach(([key, value]) => {
254
+ url.searchParams.set(key, value);
255
+ });
256
+ }
155
257
  const response = await wrappedFetch(url, {
156
258
  method,
157
259
  body,
@@ -176,7 +278,7 @@ class VaultFile {
176
278
  async _createFile(metadata = {}, options) {
177
279
  const response = await this._fetch({
178
280
  method: "POST",
179
- path: `/v2/files`,
281
+ path: `files`,
180
282
  body: JSON.stringify({
181
283
  ...metadata,
182
284
  fileName: this.name,
@@ -235,7 +337,8 @@ class VaultFile {
235
337
  const { reference, config, download = false } = params;
236
338
  const { vaultUrl, authStrategy } = config;
237
339
  const id = removeVaultPrefix(reference);
238
- const response = await wrappedFetch(`${vaultUrl}/v2/files/${id}`, {
340
+ const url = new URL(`files/${id}`, vaultUrl);
341
+ const response = await wrappedFetch(url, {
239
342
  method: "GET",
240
343
  headers: authStrategy.getHeaders(),
241
344
  signal: options?.signal
@@ -370,7 +473,7 @@ class VaultFile {
370
473
  }
371
474
  const response = await this._fetch({
372
475
  method: "GET",
373
- path: `/v2/files/${this.id}/metadata`,
476
+ path: `files/${this.id}/metadata`,
374
477
  signal: options?.signal
375
478
  });
376
479
  return response;
@@ -379,6 +482,7 @@ class VaultFile {
379
482
  * Fetches a upload URL for the file.
380
483
  * @param options - The options for the request
381
484
  * @param options.signal - The signal to abort the request
485
+ * @param options.expiresIn - The number of seconds the upload URL will be valid for
382
486
  *
383
487
  * @returns The upload URL for the file
384
488
  * @throws {Error} If the vault service returns an invalid response
@@ -398,8 +502,9 @@ class VaultFile {
398
502
  }
399
503
  const response = await this._fetch({
400
504
  method: "PUT",
401
- path: `/v2/files/${this.id}`,
402
- signal: options?.signal
505
+ path: `files/${this.id}`,
506
+ signal: options?.signal,
507
+ ...options?.expiresIn ? { query: { expiresIn: options.expiresIn.toString() } } : {}
403
508
  }).then(GetUploadUrlResponseV2.safeParse);
404
509
  if (!response.success) {
405
510
  throw new Error(`Invalid response from vault service. ${JSON.stringify(response.error)}`);
@@ -411,6 +516,7 @@ class VaultFile {
411
516
  * Fetches a download URL for the file.
412
517
  * @param options - The options for the request
413
518
  * @param options.signal - The signal to abort the request
519
+ * @param options.expiresIn - The number of seconds the download URL will be valid for
414
520
  *
415
521
  * @returns The download URL for the file
416
522
  * @throws {Error} If the vault service returns an invalid response
@@ -427,8 +533,9 @@ class VaultFile {
427
533
  const id = this.id ?? this.metadata?.id ?? (this.content ? await getFileHash(this.content) : this.name);
428
534
  const response = await this._fetch({
429
535
  method: "GET",
430
- path: `/v2/files/${id}`,
431
- signal: options?.signal
536
+ path: `files/${id}`,
537
+ signal: options?.signal,
538
+ ...options?.expiresIn ? { query: { expiresIn: options.expiresIn.toString() } } : {}
432
539
  });
433
540
  this.lastDownloadUrl = { url: new URL(response.url), expiresAt: new Date(response.expiresAt) };
434
541
  return this.lastDownloadUrl.url;
@@ -487,6 +594,62 @@ class VaultFile {
487
594
  return blob;
488
595
  return await blobToBase64(blob);
489
596
  }
597
+ /**
598
+ * Deletes the file from the vault.
599
+ * @param options - The options for the request
600
+ * @param options.signal - The signal to abort the request
601
+ *
602
+ */
603
+ async delete(options) {
604
+ if (!this.id) {
605
+ throw new Error("File ID is not set");
606
+ }
607
+ await this._fetch({
608
+ method: "DELETE",
609
+ path: `files/${this.id}`,
610
+ signal: options?.signal
611
+ });
612
+ }
613
+ /**
614
+ * Creates a permalink for the file.
615
+ * @param params - The parameters for the permalink
616
+ * @param params.expiresIn - The number of seconds the permalink will be valid for
617
+ * @param options - The options for the request
618
+ * @param options.signal - The signal to abort the request
619
+ *
620
+ * @returns The permalink for the file
621
+ */
622
+ async createPermalink(params = {}, options) {
623
+ if (!this.id) {
624
+ throw new Error("File ID is not set");
625
+ }
626
+ if (!this.metadata?.workspaceId) {
627
+ throw new Error("Workspace ID is not set. Call populateMetadata() to populate the metadata fields.");
628
+ }
629
+ return Permalink.create(this.config, {
630
+ fileId: this.id,
631
+ workspaceId: this.metadata.workspaceId,
632
+ expiresIn: params.expiresIn
633
+ }, options);
634
+ }
635
+ /**
636
+ * Gets a list of the valid permalinks for the file.
637
+ * @param options - Additional options for the request
638
+ * @param options.signal - Abort signal
639
+ *
640
+ * @returns The permalinks for the file
641
+ */
642
+ async getPermalinks(options) {
643
+ if (!this.id) {
644
+ throw new Error("File ID is not set");
645
+ }
646
+ const permalinks = await this._fetch({
647
+ method: "GET",
648
+ path: `files/${this.id}/permalinks`,
649
+ signal: options?.signal
650
+ });
651
+ return permalinks.map((data) => new Permalink(this.config, data));
652
+ }
490
653
  }
491
654
 
492
655
  function vaultClient(config) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meistrari/vault-sdk",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "license": "UNLICENSED",
5
5
  "repository": {
6
6
  "type": "git",
@@ -18,12 +18,20 @@
18
18
  "files": [
19
19
  "dist"
20
20
  ],
21
+ "scripts": {
22
+ "test": "vitest --no-watch",
23
+ "test:watch": "vitest",
24
+ "build": "unbuild",
25
+ "lint": "eslint .",
26
+ "lint:fix": "eslint . --fix",
27
+ "check": "bun run lint && bun tsc --noEmit"
28
+ },
21
29
  "dependencies": {
30
+ "@meistrari/vault-shared": "0.0.3",
22
31
  "file-type": "21.0.0",
23
32
  "mime-types": "3.0.1",
24
33
  "ofetch": "1.4.1",
25
- "zod": "3.23.8",
26
- "@meistrari/vault-shared": "0.0.3"
34
+ "zod": "3.23.8"
27
35
  },
28
36
  "devDependencies": {
29
37
  "@types/bun": "latest",
@@ -37,12 +45,5 @@
37
45
  },
38
46
  "publishConfig": {
39
47
  "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"
47
48
  }
48
49
  }