@meistrari/vault-sdk 1.7.0 → 1.8.1
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 +733 -81
- package/dist/index.d.cts +677 -72
- package/dist/index.d.mts +677 -72
- package/dist/index.d.ts +677 -72
- package/dist/index.mjs +729 -81
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
const schemas = require('@meistrari/vault-shared/schemas');
|
|
4
4
|
const fileType = require('@meistrari/file-type');
|
|
5
5
|
const mimeTypes = require('mime-types');
|
|
6
|
+
const vaultUtils = require('@meistrari/vault-shared/utils');
|
|
7
|
+
|
|
8
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
9
|
+
|
|
10
|
+
const vaultUtils__default = /*#__PURE__*/_interopDefaultCompat(vaultUtils);
|
|
6
11
|
|
|
7
12
|
var __defProp$2 = Object.defineProperty;
|
|
8
13
|
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -182,7 +187,7 @@ async function getFileHash(blob) {
|
|
|
182
187
|
}
|
|
183
188
|
async function detectFileMimeType(blob) {
|
|
184
189
|
if (blob instanceof Blob && blob.type) {
|
|
185
|
-
return blob.type;
|
|
190
|
+
return blob.type.split(";")[0].trim();
|
|
186
191
|
}
|
|
187
192
|
if ("name" in blob && typeof blob.name === "string") {
|
|
188
193
|
const extension = blob.name.split(".").pop()?.toLowerCase();
|
|
@@ -219,9 +224,20 @@ async function detectFileMimeType(blob) {
|
|
|
219
224
|
}
|
|
220
225
|
return void 0;
|
|
221
226
|
}
|
|
227
|
+
function basename(name, separator = "/") {
|
|
228
|
+
if (!name)
|
|
229
|
+
return void 0;
|
|
230
|
+
return name.substring(name.lastIndexOf(separator) + 1);
|
|
231
|
+
}
|
|
232
|
+
function getFileName(content) {
|
|
233
|
+
if ("name" in content && typeof content.name === "string") {
|
|
234
|
+
return basename(content.name);
|
|
235
|
+
}
|
|
236
|
+
return void 0;
|
|
237
|
+
}
|
|
222
238
|
|
|
223
239
|
const name = "@meistrari/vault-sdk";
|
|
224
|
-
const version = "1.
|
|
240
|
+
const version = "1.8.1";
|
|
225
241
|
const license = "UNLICENSED";
|
|
226
242
|
const repository = {
|
|
227
243
|
type: "git",
|
|
@@ -290,9 +306,6 @@ var __publicField = (obj, key, value) => {
|
|
|
290
306
|
return value;
|
|
291
307
|
};
|
|
292
308
|
const compatibilityDate = "2025-05-19";
|
|
293
|
-
function removeVaultPrefix(url) {
|
|
294
|
-
return url.replace("vault://", "");
|
|
295
|
-
}
|
|
296
309
|
function detectMimeTypeFromFilename(filename) {
|
|
297
310
|
const extension = filename.split(".").pop()?.toLowerCase();
|
|
298
311
|
if (extension) {
|
|
@@ -399,6 +412,7 @@ class VaultFile {
|
|
|
399
412
|
* @param metadata - The metadata for creating a file
|
|
400
413
|
* @param metadata.size - The size of the file
|
|
401
414
|
* @param metadata.mimeType - The mime type of the file
|
|
415
|
+
* @param metadata.parentId - The ID of the parent file for hierarchical file relationships
|
|
402
416
|
* @param options - The options for the request
|
|
403
417
|
* @param options.signal - The signal to abort the request
|
|
404
418
|
*
|
|
@@ -411,7 +425,9 @@ class VaultFile {
|
|
|
411
425
|
method: "POST",
|
|
412
426
|
path: `files`,
|
|
413
427
|
body: JSON.stringify({
|
|
414
|
-
|
|
428
|
+
size: metadata.size,
|
|
429
|
+
mimeType: metadata.mimeType,
|
|
430
|
+
parentId: metadata.parentId,
|
|
415
431
|
fileName: this.name,
|
|
416
432
|
sha256sum: this.id ?? this.metadata?.id ?? (this.content ? await getFileHash(this.content) : void 0)
|
|
417
433
|
}),
|
|
@@ -468,7 +484,7 @@ class VaultFile {
|
|
|
468
484
|
const { reference, config: vaultConfig, download = false } = params;
|
|
469
485
|
const config = resolveConfig(vaultConfig);
|
|
470
486
|
const { vaultUrl, authStrategy } = config;
|
|
471
|
-
const id =
|
|
487
|
+
const id = vaultUtils__default.file.getFileIdFromVaultReference(reference);
|
|
472
488
|
const url = new URL(`files/${id}`, config.vaultUrl);
|
|
473
489
|
const response = await wrappedFetch(url, {
|
|
474
490
|
method: "GET",
|
|
@@ -499,7 +515,9 @@ class VaultFile {
|
|
|
499
515
|
* @param params.name - The name of the file
|
|
500
516
|
* @param params.content - The content of the file
|
|
501
517
|
* @param params.config - The configuration for the VaultFile
|
|
518
|
+
* @param params.mimeType - The MIME type of the file (optional)
|
|
502
519
|
* @param params.upload - Whether to upload the file (default: false)
|
|
520
|
+
* @param params.parentId - The ID of the parent file for hierarchical file relationships
|
|
503
521
|
* @param options - The options for the request
|
|
504
522
|
* @param options.signal - The signal to abort the request
|
|
505
523
|
*
|
|
@@ -534,13 +552,30 @@ class VaultFile {
|
|
|
534
552
|
* upload: true
|
|
535
553
|
* })
|
|
536
554
|
* ```
|
|
555
|
+
*
|
|
556
|
+
* @example
|
|
557
|
+
* ```ts
|
|
558
|
+
* // Create a child file with a parent
|
|
559
|
+
* const file = new File(['content'], 'child.txt')
|
|
560
|
+
* const vaultFile = await VaultFile.fromContent({
|
|
561
|
+
* name: 'child.txt',
|
|
562
|
+
* content: file,
|
|
563
|
+
* parentId: 'parent-file-id',
|
|
564
|
+
* config: {
|
|
565
|
+
* vaultUrl,
|
|
566
|
+
* authStrategy,
|
|
567
|
+
* },
|
|
568
|
+
* upload: true
|
|
569
|
+
* })
|
|
570
|
+
* ```
|
|
537
571
|
*/
|
|
538
572
|
static async fromContent(params, options) {
|
|
539
|
-
const {
|
|
573
|
+
const { content, config: vaultConfig, upload = false, parentId } = params;
|
|
574
|
+
const name = basename(params.name) ?? getFileName(content);
|
|
540
575
|
const config = resolveConfig(vaultConfig);
|
|
541
576
|
const { vaultUrl, authStrategy } = config;
|
|
542
577
|
const sha256sum = await getFileHash(content);
|
|
543
|
-
const mimeType = await detectFileMimeType(content);
|
|
578
|
+
const mimeType = params.mimeType ?? await detectFileMimeType(content);
|
|
544
579
|
const size = content.size;
|
|
545
580
|
const file = new VaultFile({
|
|
546
581
|
content,
|
|
@@ -553,7 +588,8 @@ class VaultFile {
|
|
|
553
588
|
});
|
|
554
589
|
const createdFile = await file._createFile({
|
|
555
590
|
size,
|
|
556
|
-
mimeType
|
|
591
|
+
mimeType,
|
|
592
|
+
parentId
|
|
557
593
|
}, { signal: options?.signal });
|
|
558
594
|
if (upload) {
|
|
559
595
|
await file.upload(file.content, createdFile.uploadUrl, { signal: options?.signal });
|
|
@@ -569,6 +605,7 @@ class VaultFile {
|
|
|
569
605
|
* @param params.contentLength - The size of the content in bytes
|
|
570
606
|
* @param params.config - The configuration for the VaultFile
|
|
571
607
|
* @param params.contentType - The MIME type of the content (optional)
|
|
608
|
+
* @param params.parentId - The ID of the parent file for hierarchical file relationships
|
|
572
609
|
* @param options - The options for the request
|
|
573
610
|
* @param options.signal - The signal to abort the request
|
|
574
611
|
*
|
|
@@ -591,25 +628,66 @@ class VaultFile {
|
|
|
591
628
|
* contentType: file.type
|
|
592
629
|
* })
|
|
593
630
|
* ```
|
|
631
|
+
*
|
|
632
|
+
* @example
|
|
633
|
+
* ```ts
|
|
634
|
+
* // Create a child file with streaming
|
|
635
|
+
* const vaultFile = await VaultFile.fromStream({
|
|
636
|
+
* name: 'child-video.mp4',
|
|
637
|
+
* contentLength: 50 * 1024 * 1024,
|
|
638
|
+
* contentType: 'video/mp4',
|
|
639
|
+
* parentId: 'parent-file-id',
|
|
640
|
+
* config: { vaultUrl, authStrategy }
|
|
641
|
+
* })
|
|
642
|
+
* ```
|
|
594
643
|
*/
|
|
595
644
|
static async fromStream(params, options) {
|
|
596
|
-
const {
|
|
645
|
+
const { contentLength, config: vaultConfig, contentType, parentId } = params;
|
|
646
|
+
const name = basename(params.name);
|
|
597
647
|
const config = resolveConfig(vaultConfig);
|
|
598
648
|
const file = new VaultFile({ config, name });
|
|
599
649
|
await file._createFile({
|
|
600
650
|
size: contentLength,
|
|
601
|
-
mimeType: contentType || "application/octet-stream"
|
|
651
|
+
mimeType: contentType || "application/octet-stream",
|
|
652
|
+
parentId
|
|
602
653
|
}, { signal: options?.signal });
|
|
603
654
|
return file;
|
|
604
655
|
}
|
|
605
656
|
/**
|
|
606
|
-
*
|
|
607
|
-
*
|
|
608
|
-
*
|
|
657
|
+
* Fetches and populates the metadata fields for this VaultFile instance.
|
|
658
|
+
*
|
|
659
|
+
* This method retrieves the file's metadata from the vault server and updates the instance's
|
|
660
|
+
* metadata, name, and id properties. Useful when you have a VaultFile instance that was created
|
|
661
|
+
* without full metadata or when you need to refresh the metadata.
|
|
609
662
|
*
|
|
610
|
-
* @
|
|
663
|
+
* @param options - Additional options for the request
|
|
664
|
+
* @param options.signal - AbortSignal to cancel the request
|
|
665
|
+
*
|
|
666
|
+
* @returns The VaultFile instance with populated metadata (for method chaining)
|
|
611
667
|
* @throws {Error} If the file ID is not set
|
|
612
668
|
* @throws {FetchError} If the metadata fetch fails
|
|
669
|
+
*
|
|
670
|
+
* @example
|
|
671
|
+
* ```ts
|
|
672
|
+
* const vaultFile = await VaultFile.fromVaultReference({
|
|
673
|
+
* reference: 'vault://file-id',
|
|
674
|
+
* config: { vaultUrl, authStrategy }
|
|
675
|
+
* })
|
|
676
|
+
* await vaultFile.populateMetadata()
|
|
677
|
+
* console.log('File size:', vaultFile.metadata?.size)
|
|
678
|
+
* console.log('MIME type:', vaultFile.metadata?.mimeType)
|
|
679
|
+
* ```
|
|
680
|
+
*
|
|
681
|
+
* @example
|
|
682
|
+
* ```ts
|
|
683
|
+
* // Chain with other operations
|
|
684
|
+
* const file = await VaultFile.fromVaultReference({
|
|
685
|
+
* reference: 'vault://file-id',
|
|
686
|
+
* config: { vaultUrl, authStrategy }
|
|
687
|
+
* })
|
|
688
|
+
* await file.populateMetadata()
|
|
689
|
+
* const children = await file.getChildren()
|
|
690
|
+
* ```
|
|
613
691
|
*/
|
|
614
692
|
async populateMetadata(options) {
|
|
615
693
|
try {
|
|
@@ -622,10 +700,38 @@ class VaultFile {
|
|
|
622
700
|
}
|
|
623
701
|
}
|
|
624
702
|
/**
|
|
625
|
-
*
|
|
703
|
+
* Returns the vault URI reference for this file.
|
|
704
|
+
*
|
|
705
|
+
* The vault reference is a URI in the format `vault://{fileId}` that can be used to
|
|
706
|
+
* uniquely identify and retrieve this file from the vault. This reference can be stored
|
|
707
|
+
* in databases, passed to other services, or used with {@link VaultFile.fromVaultReference}
|
|
708
|
+
* to reconstruct a VaultFile instance.
|
|
626
709
|
*
|
|
627
|
-
* @returns The vault reference in the format `vault://{fileId}`
|
|
710
|
+
* @returns The vault reference string in the format `vault://{fileId}`
|
|
628
711
|
* @throws {Error} If the file ID is not set
|
|
712
|
+
*
|
|
713
|
+
* @example
|
|
714
|
+
* ```ts
|
|
715
|
+
* const file = await VaultFile.fromContent({
|
|
716
|
+
* name: 'document.txt',
|
|
717
|
+
* content: new Blob(['content']),
|
|
718
|
+
* config: { vaultUrl, authStrategy },
|
|
719
|
+
* upload: true
|
|
720
|
+
* })
|
|
721
|
+
* const reference = file.getVaultReference()
|
|
722
|
+
* // Returns: "vault://abc123..."
|
|
723
|
+
* // Store this reference in your database for later retrieval
|
|
724
|
+
* ```
|
|
725
|
+
*
|
|
726
|
+
* @example
|
|
727
|
+
* ```ts
|
|
728
|
+
* // Retrieve a file later using the reference
|
|
729
|
+
* const storedReference = database.get('file_reference')
|
|
730
|
+
* const file = await VaultFile.fromVaultReference({
|
|
731
|
+
* reference: storedReference,
|
|
732
|
+
* config: { vaultUrl, authStrategy }
|
|
733
|
+
* })
|
|
734
|
+
* ```
|
|
629
735
|
*/
|
|
630
736
|
getVaultReference() {
|
|
631
737
|
if (!this.id) {
|
|
@@ -634,13 +740,37 @@ class VaultFile {
|
|
|
634
740
|
return `vault://${this.id}`;
|
|
635
741
|
}
|
|
636
742
|
/**
|
|
637
|
-
* Fetches the metadata
|
|
638
|
-
* @param options - The options for the request
|
|
639
|
-
* @param options.signal - The signal to abort the request
|
|
743
|
+
* Fetches the complete metadata for this file from the vault server.
|
|
640
744
|
*
|
|
641
|
-
*
|
|
745
|
+
* Retrieves detailed information about the file including size, MIME type, creation date,
|
|
746
|
+
* workspace ID, and other metadata fields. Unlike {@link populateMetadata}, this method
|
|
747
|
+
* returns the metadata without modifying the VaultFile instance.
|
|
748
|
+
*
|
|
749
|
+
* @param options - Additional options for the request
|
|
750
|
+
* @param options.signal - AbortSignal to cancel the request
|
|
751
|
+
*
|
|
752
|
+
* @returns A Promise that resolves to the FileMetadata object
|
|
642
753
|
* @throws {Error} If the file ID is not set
|
|
643
754
|
* @throws {FetchError} If the metadata fetch fails
|
|
755
|
+
*
|
|
756
|
+
* @example
|
|
757
|
+
* ```ts
|
|
758
|
+
* const vaultFile = await VaultFile.fromVaultReference({
|
|
759
|
+
* reference: 'vault://file-id',
|
|
760
|
+
* config: { vaultUrl, authStrategy }
|
|
761
|
+
* })
|
|
762
|
+
* const metadata = await vaultFile.getFileMetadata()
|
|
763
|
+
* console.log('File size:', metadata.size)
|
|
764
|
+
* console.log('Created at:', metadata.createdAt)
|
|
765
|
+
* console.log('Workspace:', metadata.workspaceId)
|
|
766
|
+
* ```
|
|
767
|
+
*
|
|
768
|
+
* @example
|
|
769
|
+
* ```ts
|
|
770
|
+
* // Use with abort signal
|
|
771
|
+
* const controller = new AbortController()
|
|
772
|
+
* const metadata = await vaultFile.getFileMetadata({ signal: controller.signal })
|
|
773
|
+
* ```
|
|
644
774
|
*/
|
|
645
775
|
async getFileMetadata(options) {
|
|
646
776
|
if (!this.id) {
|
|
@@ -654,14 +784,41 @@ class VaultFile {
|
|
|
654
784
|
return response;
|
|
655
785
|
}
|
|
656
786
|
/**
|
|
657
|
-
*
|
|
658
|
-
*
|
|
659
|
-
*
|
|
660
|
-
*
|
|
787
|
+
* Retrieves a presigned upload URL for uploading file content to the vault.
|
|
788
|
+
*
|
|
789
|
+
* This method returns a temporary URL that can be used to upload the file content directly
|
|
790
|
+
* to cloud storage (e.g., S3). The URL is cached and reused if still valid. If the file
|
|
791
|
+
* doesn't exist yet, it will be created automatically.
|
|
661
792
|
*
|
|
662
|
-
* @
|
|
793
|
+
* @param options - Additional options for the request
|
|
794
|
+
* @param options.signal - AbortSignal to cancel the request
|
|
795
|
+
* @param options.expiresIn - Number of seconds the upload URL should be valid for (default: server-defined)
|
|
796
|
+
*
|
|
797
|
+
* @returns A Promise that resolves to a URL object for uploading the file
|
|
663
798
|
* @throws {Error} If the vault service returns an invalid response
|
|
664
799
|
* @throws {FetchError} If the upload URL fetch fails
|
|
800
|
+
*
|
|
801
|
+
* @example
|
|
802
|
+
* ```ts
|
|
803
|
+
* const vaultFile = await VaultFile.fromContent({
|
|
804
|
+
* name: 'document.txt',
|
|
805
|
+
* content: new Blob(['content']),
|
|
806
|
+
* config: { vaultUrl, authStrategy }
|
|
807
|
+
* })
|
|
808
|
+
* const uploadUrl = await vaultFile.getUploadUrl()
|
|
809
|
+
* // Use the URL for custom upload logic
|
|
810
|
+
* await fetch(uploadUrl, {
|
|
811
|
+
* method: 'PUT',
|
|
812
|
+
* body: file,
|
|
813
|
+
* headers: { 'Content-Type': 'text/plain' }
|
|
814
|
+
* })
|
|
815
|
+
* ```
|
|
816
|
+
*
|
|
817
|
+
* @example
|
|
818
|
+
* ```ts
|
|
819
|
+
* // Request a longer-lived upload URL
|
|
820
|
+
* const uploadUrl = await vaultFile.getUploadUrl({ expiresIn: 7200 }) // 2 hours
|
|
821
|
+
* ```
|
|
665
822
|
*/
|
|
666
823
|
async getUploadUrl(options) {
|
|
667
824
|
if (this.lastUploadUrl && this.lastUploadUrl.expiresAt > /* @__PURE__ */ new Date()) {
|
|
@@ -688,15 +845,38 @@ class VaultFile {
|
|
|
688
845
|
return this.lastUploadUrl.url;
|
|
689
846
|
}
|
|
690
847
|
/**
|
|
691
|
-
*
|
|
692
|
-
*
|
|
693
|
-
*
|
|
694
|
-
*
|
|
848
|
+
* Retrieves a presigned download URL for accessing the file content.
|
|
849
|
+
*
|
|
850
|
+
* This method returns a temporary URL that can be used to download the file content directly
|
|
851
|
+
* from cloud storage (e.g., S3). The URL is cached and reused if still valid. This is useful
|
|
852
|
+
* for generating shareable links or implementing custom download logic.
|
|
853
|
+
*
|
|
854
|
+
* @param options - Additional options for the request
|
|
855
|
+
* @param options.signal - AbortSignal to cancel the request
|
|
856
|
+
* @param options.expiresIn - Number of seconds the download URL should be valid for (default: server-defined)
|
|
695
857
|
*
|
|
696
|
-
* @returns
|
|
858
|
+
* @returns A Promise that resolves to a URL object for downloading the file
|
|
697
859
|
* @throws {Error} If the vault service returns an invalid response
|
|
698
|
-
* @throws {Error} If
|
|
860
|
+
* @throws {Error} If no file ID, name, or content is set
|
|
699
861
|
* @throws {FetchError} If the download URL fetch fails
|
|
862
|
+
*
|
|
863
|
+
* @example
|
|
864
|
+
* ```ts
|
|
865
|
+
* const vaultFile = await VaultFile.fromVaultReference({
|
|
866
|
+
* reference: 'vault://file-id',
|
|
867
|
+
* config: { vaultUrl, authStrategy }
|
|
868
|
+
* })
|
|
869
|
+
* const downloadUrl = await vaultFile.getDownloadUrl()
|
|
870
|
+
* // Use the URL to download the file
|
|
871
|
+
* window.location.href = downloadUrl.toString()
|
|
872
|
+
* ```
|
|
873
|
+
*
|
|
874
|
+
* @example
|
|
875
|
+
* ```ts
|
|
876
|
+
* // Request a longer-lived download URL
|
|
877
|
+
* const downloadUrl = await vaultFile.getDownloadUrl({ expiresIn: 3600 }) // 1 hour
|
|
878
|
+
* // Share this URL with others
|
|
879
|
+
* ```
|
|
700
880
|
*/
|
|
701
881
|
async getDownloadUrl(options) {
|
|
702
882
|
if (this.lastDownloadUrl && this.lastDownloadUrl.expiresAt > /* @__PURE__ */ new Date()) {
|
|
@@ -716,30 +896,51 @@ class VaultFile {
|
|
|
716
896
|
return this.lastDownloadUrl.url;
|
|
717
897
|
}
|
|
718
898
|
/**
|
|
719
|
-
* Uploads
|
|
899
|
+
* Uploads file content to the vault using a presigned URL.
|
|
900
|
+
*
|
|
901
|
+
* This method handles the actual file upload to cloud storage. If no file is provided,
|
|
902
|
+
* it uses the content from the VaultFile instance. If no upload URL is provided, one
|
|
903
|
+
* will be fetched automatically. The MIME type is detected automatically if not already set.
|
|
904
|
+
*
|
|
905
|
+
* @param file - The Blob or File to upload. If not provided, uses the instance's content property
|
|
906
|
+
* @param url - A presigned upload URL. If not provided, will be fetched via {@link getUploadUrl}
|
|
907
|
+
* @param options - Additional options for the request
|
|
908
|
+
* @param options.signal - AbortSignal to cancel the upload
|
|
909
|
+
*
|
|
910
|
+
* @throws {Error} If no file content is available (neither provided nor in the instance)
|
|
911
|
+
* @throws {FetchError} If the upload request fails
|
|
912
|
+
* @returns A Promise that resolves when the upload completes successfully
|
|
720
913
|
*
|
|
721
914
|
* @example
|
|
722
915
|
* ```ts
|
|
916
|
+
* // Simple upload using instance content
|
|
723
917
|
* const file = new File(['content'], 'document.txt')
|
|
724
918
|
* const vaultFile = await VaultFile.fromContent({
|
|
725
919
|
* name: 'document.txt',
|
|
726
920
|
* content: file,
|
|
727
|
-
* config: {
|
|
728
|
-
* vaultUrl,
|
|
729
|
-
* authStrategy,
|
|
730
|
-
* },
|
|
921
|
+
* config: { vaultUrl, authStrategy }
|
|
731
922
|
* })
|
|
732
|
-
* await vaultFile.upload(
|
|
923
|
+
* await vaultFile.upload()
|
|
733
924
|
* ```
|
|
734
925
|
*
|
|
735
|
-
* @
|
|
736
|
-
*
|
|
737
|
-
*
|
|
738
|
-
*
|
|
926
|
+
* @example
|
|
927
|
+
* ```ts
|
|
928
|
+
* // Upload different content than what's in the instance
|
|
929
|
+
* const vaultFile = await VaultFile.fromContent({
|
|
930
|
+
* name: 'document.txt',
|
|
931
|
+
* content: new Blob(['original']),
|
|
932
|
+
* config: { vaultUrl, authStrategy }
|
|
933
|
+
* })
|
|
934
|
+
* const newContent = new Blob(['updated content'])
|
|
935
|
+
* await vaultFile.upload(newContent)
|
|
936
|
+
* ```
|
|
739
937
|
*
|
|
740
|
-
* @
|
|
741
|
-
*
|
|
742
|
-
*
|
|
938
|
+
* @example
|
|
939
|
+
* ```ts
|
|
940
|
+
* // Upload with custom URL (advanced usage)
|
|
941
|
+
* const uploadUrl = await vaultFile.getUploadUrl({ expiresIn: 3600 })
|
|
942
|
+
* await vaultFile.upload(file, uploadUrl.toString())
|
|
943
|
+
* ```
|
|
743
944
|
*/
|
|
744
945
|
async upload(file, url, options) {
|
|
745
946
|
const content = file ?? this.content;
|
|
@@ -770,31 +971,60 @@ class VaultFile {
|
|
|
770
971
|
return await blobToBase64(blob);
|
|
771
972
|
}
|
|
772
973
|
/**
|
|
773
|
-
* Downloads
|
|
974
|
+
* Downloads the file as a ReadableStream for memory-efficient processing of large files.
|
|
774
975
|
*
|
|
775
|
-
*
|
|
776
|
-
*
|
|
976
|
+
* This method is ideal for handling large files without loading the entire content into memory.
|
|
977
|
+
* The stream can be processed chunk-by-chunk, piped to other streams, or saved incrementally.
|
|
978
|
+
* This is the recommended approach for files larger than a few megabytes.
|
|
979
|
+
*
|
|
980
|
+
* @param options - Additional options for the request
|
|
981
|
+
* @param options.signal - AbortSignal to cancel the download
|
|
777
982
|
*
|
|
778
|
-
* @returns A ReadableStream that yields chunks
|
|
983
|
+
* @returns A Promise resolving to a ReadableStream that yields Uint8Array chunks
|
|
984
|
+
* @throws {Error} If the response body is not readable
|
|
985
|
+
* @throws {FetchError} If the download fails
|
|
779
986
|
*
|
|
780
987
|
* @example
|
|
781
988
|
* ```ts
|
|
782
|
-
*
|
|
989
|
+
* // Process large file chunk by chunk
|
|
990
|
+
* const vaultFile = await VaultFile.fromVaultReference({
|
|
991
|
+
* reference: 'vault://large-video-id',
|
|
992
|
+
* config: { vaultUrl, authStrategy }
|
|
993
|
+
* })
|
|
783
994
|
* const stream = await vaultFile.downloadStream()
|
|
784
995
|
*
|
|
785
|
-
* // Process the stream chunk by chunk
|
|
786
996
|
* const reader = stream.getReader()
|
|
997
|
+
* let bytesReceived = 0
|
|
787
998
|
* try {
|
|
788
999
|
* while (true) {
|
|
789
1000
|
* const { done, value } = await reader.read()
|
|
790
1001
|
* if (done) break
|
|
791
|
-
*
|
|
792
|
-
* console.log(
|
|
1002
|
+
* bytesReceived += value.length
|
|
1003
|
+
* console.log(`Downloaded ${bytesReceived} bytes...`)
|
|
1004
|
+
* // Process chunk (value is Uint8Array)
|
|
793
1005
|
* }
|
|
794
1006
|
* } finally {
|
|
795
1007
|
* reader.releaseLock()
|
|
796
1008
|
* }
|
|
797
1009
|
* ```
|
|
1010
|
+
*
|
|
1011
|
+
* @example
|
|
1012
|
+
* ```ts
|
|
1013
|
+
* // Pipe stream to a writable destination
|
|
1014
|
+
* const stream = await vaultFile.downloadStream()
|
|
1015
|
+
* const fileHandle = await navigator.storage.getDirectory()
|
|
1016
|
+
* .then(dir => dir.getFileHandle('output.dat', { create: true }))
|
|
1017
|
+
* const writable = await fileHandle.createWritable()
|
|
1018
|
+
* await stream.pipeTo(writable)
|
|
1019
|
+
* ```
|
|
1020
|
+
*
|
|
1021
|
+
* @example
|
|
1022
|
+
* ```ts
|
|
1023
|
+
* // Use with abort signal
|
|
1024
|
+
* const controller = new AbortController()
|
|
1025
|
+
* const stream = await vaultFile.downloadStream({ signal: controller.signal })
|
|
1026
|
+
* // Later: controller.abort()
|
|
1027
|
+
* ```
|
|
798
1028
|
*/
|
|
799
1029
|
async downloadStream(options) {
|
|
800
1030
|
const downloadUrl = await this.getDownloadUrl({ signal: options?.signal });
|
|
@@ -808,32 +1038,64 @@ class VaultFile {
|
|
|
808
1038
|
return response.body;
|
|
809
1039
|
}
|
|
810
1040
|
/**
|
|
811
|
-
* Uploads
|
|
1041
|
+
* Uploads file content using a ReadableStream for memory-efficient processing of large files.
|
|
812
1042
|
*
|
|
813
|
-
*
|
|
814
|
-
*
|
|
815
|
-
*
|
|
816
|
-
* @param options.contentLength - The total size of the content (required for S3 uploads)
|
|
817
|
-
* @param options.contentType - The MIME type of the content (will be detected if not provided)
|
|
1043
|
+
* This method is ideal for uploading large files without loading the entire content into memory.
|
|
1044
|
+
* The stream is sent directly to cloud storage, making it perfect for files larger than a few
|
|
1045
|
+
* megabytes. Note: When using Bun, the stream is buffered due to implementation limitations.
|
|
818
1046
|
*
|
|
819
|
-
* @
|
|
1047
|
+
* @param stream - A ReadableStream of Uint8Array chunks containing the file data
|
|
1048
|
+
* @param options - Required options for the upload
|
|
1049
|
+
* @param options.contentLength - The total size of the content in bytes (required for S3 uploads)
|
|
1050
|
+
* @param options.contentType - The MIME type of the content (auto-detected from filename if not provided)
|
|
1051
|
+
* @param options.signal - AbortSignal to cancel the upload
|
|
1052
|
+
*
|
|
1053
|
+
* @throws {Error} If contentLength is not provided or is negative
|
|
820
1054
|
* @throws {FetchError} If the upload fails
|
|
821
|
-
* @returns Promise that resolves when upload
|
|
1055
|
+
* @returns A Promise that resolves when the upload completes successfully
|
|
822
1056
|
*
|
|
823
1057
|
* @example
|
|
824
1058
|
* ```ts
|
|
825
|
-
*
|
|
826
|
-
* const
|
|
1059
|
+
* // Upload a large file using streaming
|
|
1060
|
+
* const file = new File(['large content'], 'video.mp4')
|
|
1061
|
+
* const vaultFile = await VaultFile.fromStream({
|
|
1062
|
+
* name: 'video.mp4',
|
|
1063
|
+
* contentLength: file.size,
|
|
827
1064
|
* contentType: file.type,
|
|
828
1065
|
* config: { vaultUrl, authStrategy }
|
|
829
1066
|
* })
|
|
830
1067
|
*
|
|
831
|
-
* // Upload using the stream directly
|
|
832
1068
|
* const stream = file.stream()
|
|
833
1069
|
* await vaultFile.uploadStream(stream, {
|
|
834
1070
|
* contentLength: file.size,
|
|
835
1071
|
* contentType: file.type
|
|
836
1072
|
* })
|
|
1073
|
+
* console.log('Upload complete!')
|
|
1074
|
+
* ```
|
|
1075
|
+
*
|
|
1076
|
+
* @example
|
|
1077
|
+
* ```ts
|
|
1078
|
+
* // Upload with progress tracking
|
|
1079
|
+
* const vaultFile = await VaultFile.fromStream({
|
|
1080
|
+
* name: 'document.pdf',
|
|
1081
|
+
* contentLength: fileSize,
|
|
1082
|
+
* config: { vaultUrl, authStrategy }
|
|
1083
|
+
* })
|
|
1084
|
+
*
|
|
1085
|
+
* // Create a transform stream to track progress
|
|
1086
|
+
* let uploaded = 0
|
|
1087
|
+
* const progressStream = new TransformStream({
|
|
1088
|
+
* transform(chunk, controller) {
|
|
1089
|
+
* uploaded += chunk.length
|
|
1090
|
+
* console.log(`Uploaded ${uploaded}/${fileSize} bytes`)
|
|
1091
|
+
* controller.enqueue(chunk)
|
|
1092
|
+
* }
|
|
1093
|
+
* })
|
|
1094
|
+
*
|
|
1095
|
+
* await vaultFile.uploadStream(
|
|
1096
|
+
* originalStream.pipeThrough(progressStream),
|
|
1097
|
+
* { contentLength: fileSize }
|
|
1098
|
+
* )
|
|
837
1099
|
* ```
|
|
838
1100
|
*/
|
|
839
1101
|
async uploadStream(stream, options) {
|
|
@@ -874,10 +1136,48 @@ class VaultFile {
|
|
|
874
1136
|
});
|
|
875
1137
|
}
|
|
876
1138
|
/**
|
|
877
|
-
*
|
|
878
|
-
*
|
|
879
|
-
*
|
|
1139
|
+
* Permanently deletes this file from the vault.
|
|
1140
|
+
*
|
|
1141
|
+
* This operation removes the file metadata and content from the vault. This action cannot be
|
|
1142
|
+
* undone. Any vault references or permalinks to this file will become invalid after deletion.
|
|
1143
|
+
* Note: This does not automatically delete child files in hierarchical relationships.
|
|
1144
|
+
*
|
|
1145
|
+
* @param options - Additional options for the request
|
|
1146
|
+
* @param options.signal - AbortSignal to cancel the request
|
|
1147
|
+
*
|
|
1148
|
+
* @throws {Error} If the file ID is not set
|
|
1149
|
+
* @throws {FetchError} If the deletion request fails
|
|
1150
|
+
* @returns A Promise that resolves when the deletion completes successfully
|
|
1151
|
+
*
|
|
1152
|
+
* @example
|
|
1153
|
+
* ```ts
|
|
1154
|
+
* // Delete a file
|
|
1155
|
+
* const vaultFile = await VaultFile.fromVaultReference({
|
|
1156
|
+
* reference: 'vault://file-id',
|
|
1157
|
+
* config: { vaultUrl, authStrategy }
|
|
1158
|
+
* })
|
|
1159
|
+
* await vaultFile.delete()
|
|
1160
|
+
* console.log('File deleted successfully')
|
|
1161
|
+
* ```
|
|
1162
|
+
*
|
|
1163
|
+
* @example
|
|
1164
|
+
* ```ts
|
|
1165
|
+
* // Delete with confirmation
|
|
1166
|
+
* const vaultFile = await VaultFile.fromVaultReference({
|
|
1167
|
+
* reference: 'vault://file-id',
|
|
1168
|
+
* config: { vaultUrl, authStrategy }
|
|
1169
|
+
* })
|
|
1170
|
+
* if (confirm('Are you sure you want to delete this file?')) {
|
|
1171
|
+
* await vaultFile.delete()
|
|
1172
|
+
* }
|
|
1173
|
+
* ```
|
|
880
1174
|
*
|
|
1175
|
+
* @example
|
|
1176
|
+
* ```ts
|
|
1177
|
+
* // Delete with abort signal
|
|
1178
|
+
* const controller = new AbortController()
|
|
1179
|
+
* await vaultFile.delete({ signal: controller.signal })
|
|
1180
|
+
* ```
|
|
881
1181
|
*/
|
|
882
1182
|
async delete(options) {
|
|
883
1183
|
if (!this.id) {
|
|
@@ -890,13 +1190,51 @@ class VaultFile {
|
|
|
890
1190
|
});
|
|
891
1191
|
}
|
|
892
1192
|
/**
|
|
893
|
-
* Creates a permalink for
|
|
894
|
-
*
|
|
895
|
-
*
|
|
896
|
-
*
|
|
897
|
-
*
|
|
1193
|
+
* Creates a new shareable permalink for this file.
|
|
1194
|
+
*
|
|
1195
|
+
* A permalink is a public URL that allows anyone with the link to access the file without
|
|
1196
|
+
* authentication. The permalink can optionally expire after a specified duration. This is
|
|
1197
|
+
* useful for sharing files with external users or embedding files in public content.
|
|
1198
|
+
*
|
|
1199
|
+
* @param params - Optional parameters for permalink creation
|
|
1200
|
+
* @param params.expiresIn - Number of seconds until the permalink expires (optional, defaults to server setting)
|
|
1201
|
+
* @param options - Additional options for the request
|
|
1202
|
+
* @param options.signal - AbortSignal to cancel the request
|
|
898
1203
|
*
|
|
899
|
-
* @
|
|
1204
|
+
* @throws {Error} If the file ID is not set
|
|
1205
|
+
* @throws {Error} If the workspace ID is not available (call {@link populateMetadata} first)
|
|
1206
|
+
* @throws {FetchError} If the permalink creation fails
|
|
1207
|
+
* @returns A Promise that resolves to a Permalink instance
|
|
1208
|
+
*
|
|
1209
|
+
* @example
|
|
1210
|
+
* ```ts
|
|
1211
|
+
* // Create a permanent permalink
|
|
1212
|
+
* const vaultFile = await VaultFile.fromVaultReference({
|
|
1213
|
+
* reference: 'vault://file-id',
|
|
1214
|
+
* config: { vaultUrl, authStrategy }
|
|
1215
|
+
* })
|
|
1216
|
+
* await vaultFile.populateMetadata() // Required to get workspace ID
|
|
1217
|
+
* const permalink = await vaultFile.createPermalink()
|
|
1218
|
+
* console.log('Share this link:', permalink.url)
|
|
1219
|
+
* ```
|
|
1220
|
+
*
|
|
1221
|
+
* @example
|
|
1222
|
+
* ```ts
|
|
1223
|
+
* // Create a permalink that expires in 24 hours
|
|
1224
|
+
* await vaultFile.populateMetadata()
|
|
1225
|
+
* const permalink = await vaultFile.createPermalink({
|
|
1226
|
+
* expiresIn: 24 * 60 * 60 // 24 hours in seconds
|
|
1227
|
+
* })
|
|
1228
|
+
* console.log('Link expires at:', permalink.expiresAt)
|
|
1229
|
+
* ```
|
|
1230
|
+
*
|
|
1231
|
+
* @example
|
|
1232
|
+
* ```ts
|
|
1233
|
+
* // Create a short-lived sharing link (1 hour)
|
|
1234
|
+
* await vaultFile.populateMetadata()
|
|
1235
|
+
* const permalink = await vaultFile.createPermalink({ expiresIn: 3600 })
|
|
1236
|
+
* // Send permalink.url to user
|
|
1237
|
+
* ```
|
|
900
1238
|
*/
|
|
901
1239
|
async createPermalink(params = {}, options) {
|
|
902
1240
|
if (!this.id) {
|
|
@@ -912,11 +1250,51 @@ class VaultFile {
|
|
|
912
1250
|
}, options);
|
|
913
1251
|
}
|
|
914
1252
|
/**
|
|
915
|
-
*
|
|
1253
|
+
* Retrieves all active permalinks associated with this file.
|
|
1254
|
+
*
|
|
1255
|
+
* This method fetches all permalinks that have been created for this file and are still
|
|
1256
|
+
* valid (not expired or deleted). Each permalink is returned as a Permalink instance
|
|
1257
|
+
* with full details including URL, expiration date, and other metadata.
|
|
1258
|
+
*
|
|
916
1259
|
* @param options - Additional options for the request
|
|
917
|
-
* @param options.signal -
|
|
1260
|
+
* @param options.signal - AbortSignal to cancel the request
|
|
918
1261
|
*
|
|
919
|
-
* @
|
|
1262
|
+
* @throws {Error} If the file ID is not set
|
|
1263
|
+
* @throws {FetchError} If the request to fetch permalinks fails
|
|
1264
|
+
* @returns A Promise that resolves to an array of Permalink instances
|
|
1265
|
+
*
|
|
1266
|
+
* @example
|
|
1267
|
+
* ```ts
|
|
1268
|
+
* // List all permalinks for a file
|
|
1269
|
+
* const vaultFile = await VaultFile.fromVaultReference({
|
|
1270
|
+
* reference: 'vault://file-id',
|
|
1271
|
+
* config: { vaultUrl, authStrategy }
|
|
1272
|
+
* })
|
|
1273
|
+
* const permalinks = await vaultFile.getPermalinks()
|
|
1274
|
+
* permalinks.forEach(permalink => {
|
|
1275
|
+
* console.log('URL:', permalink.url)
|
|
1276
|
+
* console.log('Expires:', permalink.expiresAt || 'Never')
|
|
1277
|
+
* })
|
|
1278
|
+
* ```
|
|
1279
|
+
*
|
|
1280
|
+
* @example
|
|
1281
|
+
* ```ts
|
|
1282
|
+
* // Check if any permalinks exist
|
|
1283
|
+
* const permalinks = await vaultFile.getPermalinks()
|
|
1284
|
+
* if (permalinks.length > 0) {
|
|
1285
|
+
* console.log(`This file has ${permalinks.length} active permalink(s)`)
|
|
1286
|
+
* } else {
|
|
1287
|
+
* console.log('No active permalinks')
|
|
1288
|
+
* }
|
|
1289
|
+
* ```
|
|
1290
|
+
*
|
|
1291
|
+
* @example
|
|
1292
|
+
* ```ts
|
|
1293
|
+
* // Find non-expiring permalinks
|
|
1294
|
+
* const permalinks = await vaultFile.getPermalinks()
|
|
1295
|
+
* const permanent = permalinks.filter(p => !p.expiresAt)
|
|
1296
|
+
* console.log(`Found ${permanent.length} permanent links`)
|
|
1297
|
+
* ```
|
|
920
1298
|
*/
|
|
921
1299
|
async getPermalinks(options) {
|
|
922
1300
|
if (!this.id) {
|
|
@@ -929,6 +1307,273 @@ class VaultFile {
|
|
|
929
1307
|
});
|
|
930
1308
|
return permalinks.map((data) => new Permalink(this.config, data));
|
|
931
1309
|
}
|
|
1310
|
+
/**
|
|
1311
|
+
* Retrieves all child files in the hierarchical file relationship.
|
|
1312
|
+
*
|
|
1313
|
+
* This method queries files that have this file set as their parent (via parentId).
|
|
1314
|
+
* Returns an empty array if the file has no children or if the file doesn't exist.
|
|
1315
|
+
* The returned children are VaultFile instances with populated metadata but no content.
|
|
1316
|
+
*
|
|
1317
|
+
* @param params - Optional parameters for filtering and request control
|
|
1318
|
+
* @param params.mimeType - Filter children by MIME type (e.g., 'image/png', 'application/pdf')
|
|
1319
|
+
* @param params.includeDeleted - Whether to include deleted child files (default: false)
|
|
1320
|
+
* @param params.limit - Maximum number of children to return (default: 100)
|
|
1321
|
+
* @param params.offset - Number of children to skip (default: 0)
|
|
1322
|
+
* @param options - Additional options for the request
|
|
1323
|
+
* @param options.signal - AbortSignal to cancel the request
|
|
1324
|
+
*
|
|
1325
|
+
* @returns An array of VaultFile instances representing the child files
|
|
1326
|
+
* @throws {Error} If the file ID is not set
|
|
1327
|
+
* @throws {FetchError} If the request to fetch children fails
|
|
1328
|
+
*
|
|
1329
|
+
* @example
|
|
1330
|
+
* ```ts
|
|
1331
|
+
* // Get all children of a file
|
|
1332
|
+
* const parent = await VaultFile.fromVaultReference({
|
|
1333
|
+
* reference: 'vault://parent-id',
|
|
1334
|
+
* config: { vaultUrl, authStrategy }
|
|
1335
|
+
* })
|
|
1336
|
+
* const children = await parent.getChildren()
|
|
1337
|
+
* console.log(`Found ${children.length} child files`)
|
|
1338
|
+
* ```
|
|
1339
|
+
*
|
|
1340
|
+
* @example
|
|
1341
|
+
* ```ts
|
|
1342
|
+
* // Get only image children
|
|
1343
|
+
* const parent = await VaultFile.fromVaultReference({
|
|
1344
|
+
* reference: 'vault://parent-id',
|
|
1345
|
+
* config: { vaultUrl, authStrategy }
|
|
1346
|
+
* })
|
|
1347
|
+
* const imageChildren = await parent.getChildren({ mimeType: 'image/png' })
|
|
1348
|
+
* ```
|
|
1349
|
+
*
|
|
1350
|
+
* @example
|
|
1351
|
+
* ```ts
|
|
1352
|
+
* // Get children with pagination
|
|
1353
|
+
* const parent = await VaultFile.fromVaultReference({
|
|
1354
|
+
* reference: 'vault://parent-id',
|
|
1355
|
+
* config: { vaultUrl, authStrategy }
|
|
1356
|
+
* })
|
|
1357
|
+
* const firstPage = await parent.getChildren({ limit: 10, offset: 0 })
|
|
1358
|
+
* const secondPage = await parent.getChildren({ limit: 10, offset: 10 })
|
|
1359
|
+
* ```
|
|
1360
|
+
*
|
|
1361
|
+
* @example
|
|
1362
|
+
* ```ts
|
|
1363
|
+
* // Use with abort signal for cancellable requests
|
|
1364
|
+
* const controller = new AbortController()
|
|
1365
|
+
* const children = await parent.getChildren({}, { signal: controller.signal })
|
|
1366
|
+
* // Later: controller.abort()
|
|
1367
|
+
* ```
|
|
1368
|
+
*/
|
|
1369
|
+
async getChildren(params = {}, options) {
|
|
1370
|
+
if (!this.id) {
|
|
1371
|
+
throw new Error("File ID is not set");
|
|
1372
|
+
}
|
|
1373
|
+
const query = {};
|
|
1374
|
+
if (params.mimeType) {
|
|
1375
|
+
query.mimeType = params.mimeType;
|
|
1376
|
+
}
|
|
1377
|
+
if (params.includeDeleted) {
|
|
1378
|
+
query.includeDeleted = params.includeDeleted ? "true" : "false";
|
|
1379
|
+
}
|
|
1380
|
+
if (params.limit !== void 0) {
|
|
1381
|
+
query.limit = params.limit.toString();
|
|
1382
|
+
}
|
|
1383
|
+
if (params.offset !== void 0) {
|
|
1384
|
+
query.offset = params.offset.toString();
|
|
1385
|
+
}
|
|
1386
|
+
const response = await this._fetch({
|
|
1387
|
+
method: "GET",
|
|
1388
|
+
path: `files/${this.id}/children`,
|
|
1389
|
+
signal: options?.signal,
|
|
1390
|
+
query
|
|
1391
|
+
});
|
|
1392
|
+
return response.files.map((data) => new VaultFile({
|
|
1393
|
+
config: this.config,
|
|
1394
|
+
id: data.id,
|
|
1395
|
+
name: data.originalFileName ?? void 0,
|
|
1396
|
+
metadata: data
|
|
1397
|
+
}));
|
|
1398
|
+
}
|
|
1399
|
+
/**
|
|
1400
|
+
* Iterates through all child files with automatic pagination.
|
|
1401
|
+
*
|
|
1402
|
+
* This method returns an async iterator that automatically fetches pages of children
|
|
1403
|
+
* as you iterate through them. This is useful when you have a large number of children
|
|
1404
|
+
* and want to process them without loading all of them into memory at once.
|
|
1405
|
+
*
|
|
1406
|
+
* @param params - Optional parameters for filtering and pagination
|
|
1407
|
+
* @param params.pageSize - Number of children to fetch per page (default: 100)
|
|
1408
|
+
* @param params.mimeType - Filter children by MIME type (e.g., 'image/png', 'application/pdf')
|
|
1409
|
+
* @param params.includeDeleted - Whether to include deleted child files (default: false)
|
|
1410
|
+
* @param options - Additional options for the request
|
|
1411
|
+
* @param options.signal - AbortSignal to cancel the iteration
|
|
1412
|
+
*
|
|
1413
|
+
* @returns An async iterator that yields VaultFile instances
|
|
1414
|
+
* @throws {Error} If the file ID is not set
|
|
1415
|
+
* @throws {FetchError} If the request to fetch children fails
|
|
1416
|
+
*
|
|
1417
|
+
* @example
|
|
1418
|
+
* ```ts
|
|
1419
|
+
* // Iterate through all children
|
|
1420
|
+
* const parent = await VaultFile.fromVaultReference({
|
|
1421
|
+
* reference: 'vault://parent-id',
|
|
1422
|
+
* config: { vaultUrl, authStrategy }
|
|
1423
|
+
* })
|
|
1424
|
+
*
|
|
1425
|
+
* for await (const child of parent.iterateChildren()) {
|
|
1426
|
+
* console.log(`Processing child: ${child.name}`)
|
|
1427
|
+
* }
|
|
1428
|
+
* ```
|
|
1429
|
+
*
|
|
1430
|
+
* @example
|
|
1431
|
+
* ```ts
|
|
1432
|
+
* // Iterate with filters and custom page size
|
|
1433
|
+
* for await (const child of parent.iterateChildren({
|
|
1434
|
+
* pageSize: 50,
|
|
1435
|
+
* mimeType: 'image/png'
|
|
1436
|
+
* })) {
|
|
1437
|
+
* console.log(`Processing image: ${child.name}`)
|
|
1438
|
+
* }
|
|
1439
|
+
* ```
|
|
1440
|
+
*
|
|
1441
|
+
* @example
|
|
1442
|
+
* ```ts
|
|
1443
|
+
* // Use with abort signal
|
|
1444
|
+
* const controller = new AbortController()
|
|
1445
|
+
* try {
|
|
1446
|
+
* for await (const child of parent.iterateChildren({}, { signal: controller.signal })) {
|
|
1447
|
+
* console.log(child.name)
|
|
1448
|
+
* // Can abort iteration at any time
|
|
1449
|
+
* if (someCondition) {
|
|
1450
|
+
* controller.abort()
|
|
1451
|
+
* }
|
|
1452
|
+
* }
|
|
1453
|
+
* } catch (error) {
|
|
1454
|
+
* if (error.name === 'AbortError') {
|
|
1455
|
+
* console.log('Iteration cancelled')
|
|
1456
|
+
* }
|
|
1457
|
+
* }
|
|
1458
|
+
* ```
|
|
1459
|
+
*/
|
|
1460
|
+
async *iterateChildren(params = {}, options) {
|
|
1461
|
+
if (!this.id) {
|
|
1462
|
+
throw new Error("File ID is not set");
|
|
1463
|
+
}
|
|
1464
|
+
const pageSize = params.pageSize ?? 100;
|
|
1465
|
+
let offset = 0;
|
|
1466
|
+
let hasMore = true;
|
|
1467
|
+
while (hasMore) {
|
|
1468
|
+
const children = await this.getChildren({
|
|
1469
|
+
limit: pageSize,
|
|
1470
|
+
offset,
|
|
1471
|
+
mimeType: params.mimeType,
|
|
1472
|
+
includeDeleted: params.includeDeleted
|
|
1473
|
+
}, options);
|
|
1474
|
+
for (const child of children) {
|
|
1475
|
+
yield child;
|
|
1476
|
+
}
|
|
1477
|
+
hasMore = children.length === pageSize;
|
|
1478
|
+
offset += children.length;
|
|
1479
|
+
if (children.length === 0) {
|
|
1480
|
+
hasMore = false;
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
/**
|
|
1485
|
+
* Creates a child file from content with this file as the parent.
|
|
1486
|
+
*
|
|
1487
|
+
* This is a convenience method that wraps {@link VaultFile.fromContent} and automatically
|
|
1488
|
+
* sets the current file as the parent. All parameters and behavior are identical to
|
|
1489
|
+
* {@link VaultFile.fromContent}, except parentId is automatically provided.
|
|
1490
|
+
*
|
|
1491
|
+
* @param params - Parameters for creating the child file (same as fromContent, minus parentId)
|
|
1492
|
+
* @param options - Additional options for the request
|
|
1493
|
+
*
|
|
1494
|
+
* @returns A new VaultFile instance representing the child file
|
|
1495
|
+
* @throws {Error} If the parent file ID is not set
|
|
1496
|
+
* @throws {FetchError} If the child file creation fails
|
|
1497
|
+
*
|
|
1498
|
+
* @example
|
|
1499
|
+
* ```ts
|
|
1500
|
+
* // Create a child file
|
|
1501
|
+
* const parent = await VaultFile.fromContent({
|
|
1502
|
+
* name: 'parent.txt',
|
|
1503
|
+
* content: new Blob(['parent content']),
|
|
1504
|
+
* config: { vaultUrl, authStrategy },
|
|
1505
|
+
* upload: true
|
|
1506
|
+
* })
|
|
1507
|
+
* const child = await parent.createChildFromContent({
|
|
1508
|
+
* name: 'child.txt',
|
|
1509
|
+
* content: new Blob(['child content']),
|
|
1510
|
+
* upload: true
|
|
1511
|
+
* })
|
|
1512
|
+
* console.log('Child created with parent:', child.metadata?.parentId)
|
|
1513
|
+
* ```
|
|
1514
|
+
*/
|
|
1515
|
+
async createChildFromContent(params, options) {
|
|
1516
|
+
if (!this.id) {
|
|
1517
|
+
throw new Error("Parent file ID is not set");
|
|
1518
|
+
}
|
|
1519
|
+
return VaultFile.fromContent(
|
|
1520
|
+
{
|
|
1521
|
+
...params,
|
|
1522
|
+
config: this.config,
|
|
1523
|
+
parentId: this.id
|
|
1524
|
+
},
|
|
1525
|
+
options
|
|
1526
|
+
);
|
|
1527
|
+
}
|
|
1528
|
+
/**
|
|
1529
|
+
* Creates a child file from a stream with this file as the parent.
|
|
1530
|
+
*
|
|
1531
|
+
* This is a convenience method that wraps {@link VaultFile.fromStream} and automatically
|
|
1532
|
+
* sets the current file as the parent. All parameters and behavior are identical to
|
|
1533
|
+
* {@link VaultFile.fromStream}, except parentId is automatically provided.
|
|
1534
|
+
*
|
|
1535
|
+
* @param params - Parameters for creating the child file (same as fromStream, minus parentId)
|
|
1536
|
+
* @param options - Additional options for the request
|
|
1537
|
+
*
|
|
1538
|
+
* @returns A new VaultFile instance ready for streaming upload as a child
|
|
1539
|
+
* @throws {Error} If the parent file ID is not set
|
|
1540
|
+
* @throws {FetchError} If the child file creation fails
|
|
1541
|
+
*
|
|
1542
|
+
* @example
|
|
1543
|
+
* ```ts
|
|
1544
|
+
* // Create a child file for streaming
|
|
1545
|
+
* const parent = await VaultFile.fromContent({
|
|
1546
|
+
* name: 'parent.txt',
|
|
1547
|
+
* content: new Blob(['parent']),
|
|
1548
|
+
* config: { vaultUrl, authStrategy },
|
|
1549
|
+
* upload: true
|
|
1550
|
+
* })
|
|
1551
|
+
* const child = await parent.createChildFromStream({
|
|
1552
|
+
* name: 'large-child.mp4',
|
|
1553
|
+
* contentLength: 100 * 1024 * 1024,
|
|
1554
|
+
* contentType: 'video/mp4'
|
|
1555
|
+
* })
|
|
1556
|
+
* // Upload the stream
|
|
1557
|
+
* const stream = file.stream()
|
|
1558
|
+
* await child.uploadStream(stream, {
|
|
1559
|
+
* contentLength: file.size,
|
|
1560
|
+
* contentType: file.type
|
|
1561
|
+
* })
|
|
1562
|
+
* ```
|
|
1563
|
+
*/
|
|
1564
|
+
async createChildFromStream(params, options) {
|
|
1565
|
+
if (!this.id) {
|
|
1566
|
+
throw new Error("Parent file ID is not set");
|
|
1567
|
+
}
|
|
1568
|
+
return VaultFile.fromStream(
|
|
1569
|
+
{
|
|
1570
|
+
...params,
|
|
1571
|
+
config: this.config,
|
|
1572
|
+
parentId: this.id
|
|
1573
|
+
},
|
|
1574
|
+
options
|
|
1575
|
+
);
|
|
1576
|
+
}
|
|
932
1577
|
}
|
|
933
1578
|
|
|
934
1579
|
function isS3UrlExpired(url) {
|
|
@@ -980,7 +1625,7 @@ const URL_STRATEGIES = [
|
|
|
980
1625
|
];
|
|
981
1626
|
function extractVaultFileIdFromS3Url(url) {
|
|
982
1627
|
if (isVaultReference(url))
|
|
983
|
-
return
|
|
1628
|
+
return vaultUtils__default.file.getFileIdFromVaultReference(url);
|
|
984
1629
|
try {
|
|
985
1630
|
if (!isVaultFileS3Url(url))
|
|
986
1631
|
return null;
|
|
@@ -1014,12 +1659,18 @@ function vaultClient(vaultConfig) {
|
|
|
1014
1659
|
const name2 = nameOrContent;
|
|
1015
1660
|
const content2 = contentOrNameOrOptions;
|
|
1016
1661
|
const signal2 = options?.signal;
|
|
1017
|
-
|
|
1662
|
+
const parentId2 = options?.parentId;
|
|
1663
|
+
const mimeType2 = options?.mimeType;
|
|
1664
|
+
const upload2 = options?.upload;
|
|
1665
|
+
return VaultFile.fromContent({ content: content2, name: name2, config, parentId: parentId2, mimeType: mimeType2, upload: upload2 }, { signal: signal2 });
|
|
1018
1666
|
}
|
|
1019
1667
|
const content = nameOrContent;
|
|
1020
1668
|
const name = typeof contentOrNameOrOptions === "string" ? contentOrNameOrOptions : void 0;
|
|
1021
1669
|
const signal = isOptionsObject(contentOrNameOrOptions) ? contentOrNameOrOptions.signal : options?.signal;
|
|
1022
|
-
|
|
1670
|
+
const parentId = isOptionsObject(contentOrNameOrOptions) ? contentOrNameOrOptions.parentId : options?.parentId;
|
|
1671
|
+
const mimeType = isOptionsObject(contentOrNameOrOptions) ? contentOrNameOrOptions.mimeType : options?.mimeType;
|
|
1672
|
+
const upload = isOptionsObject(contentOrNameOrOptions) ? contentOrNameOrOptions.upload : options?.upload;
|
|
1673
|
+
return VaultFile.fromContent({ content, name, config, parentId, mimeType, upload }, { signal });
|
|
1023
1674
|
}
|
|
1024
1675
|
function createFromReference(reference, options) {
|
|
1025
1676
|
return VaultFile.fromVaultReference({
|
|
@@ -1032,7 +1683,8 @@ function vaultClient(vaultConfig) {
|
|
|
1032
1683
|
name,
|
|
1033
1684
|
contentLength,
|
|
1034
1685
|
config,
|
|
1035
|
-
contentType: options?.contentType
|
|
1686
|
+
contentType: options?.contentType,
|
|
1687
|
+
parentId: options?.parentId
|
|
1036
1688
|
}, { signal: options?.signal });
|
|
1037
1689
|
}
|
|
1038
1690
|
return { createFromContent, createFromReference, createFromStream };
|