@@ -47,6 +47,11 @@ import {
47
47
type InstantRules ,
48
48
type UpdateParams ,
49
49
type LinkParams ,
50
+
51
+ // storage types
52
+ type FileOpts ,
53
+ type UploadFileResponse ,
54
+ type DeleteFileResponse ,
50
55
} from "@instantdb/core" ;
51
56
52
57
import version from "./version" ;
@@ -283,8 +288,8 @@ class InstantAdmin<
283
288
*/
284
289
query = <
285
290
Q extends Schema extends InstantGraph < any , any >
286
- ? InstaQLParams < Schema >
287
- : Exactly < Query , Q > ,
291
+ ? InstaQLParams < Schema >
292
+ : Exactly < Query , Q > ,
288
293
> (
289
294
query : Q ,
290
295
) : Promise < QueryResponse < Q , Schema , WithCardinalityInference > > => {
@@ -592,7 +597,6 @@ class Auth {
592
597
}
593
598
}
594
599
595
- type UploadMetadata = { contentType ?: string } & Record < string , any > ;
596
600
type StorageFile = {
597
601
key : string ;
598
602
name : string ;
@@ -601,6 +605,12 @@ type StorageFile = {
601
605
last_modified : number ;
602
606
} ;
603
607
608
+ type DeleteManyFileResponse = {
609
+ data : {
610
+ ids : string [ ] | null ;
611
+ } ;
612
+ } ;
613
+
604
614
/**
605
615
* Functions to manage file storage.
606
616
*/
@@ -617,12 +627,73 @@ class Storage {
617
627
* @see https://instantdb.com/docs/storage
618
628
* @example
619
629
* const buffer = fs.readFileSync('demo.png');
620
- * const isSuccess = await db.storage.upload('photos/demo.png', buffer);
630
+ * const isSuccess = await db.storage.uploadFile('photos/demo.png', buffer);
631
+ */
632
+ uploadFile = async (
633
+ path : string ,
634
+ file : Buffer ,
635
+ metadata : FileOpts = { } ,
636
+ ) : Promise < UploadFileResponse > => {
637
+ const headers = {
638
+ ...authorizedHeaders ( this . config ) ,
639
+ path,
640
+ "content-type" : metadata . contentType || "application/octet-stream" ,
641
+ } ;
642
+ if ( metadata . contentDisposition ) {
643
+ headers [ "content-disposition" ] = metadata . contentDisposition ;
644
+ }
645
+
646
+ const data = await jsonFetch ( `${ this . config . apiURI } /admin/storage/upload` , {
647
+ method : "PUT" ,
648
+ headers,
649
+ body : file ,
650
+ } ) ;
651
+
652
+ return data ;
653
+ } ;
654
+
655
+ /**
656
+ * Deletes a file by its path name (e.g. "photos/demo.png").
657
+ *
658
+ * @see https://instantdb.com/docs/storage
659
+ * @example
660
+ * await db.storage.delete("photos/demo.png");
661
+ */
662
+ delete = async ( pathname : string ) : Promise < DeleteFileResponse > => {
663
+ return jsonFetch (
664
+ `${ this . config . apiURI } /admin/storage/files?filename=${ encodeURIComponent (
665
+ pathname ,
666
+ ) } `,
667
+ {
668
+ method : "DELETE" ,
669
+ headers : authorizedHeaders ( this . config ) ,
670
+ } ,
671
+ ) ;
672
+ } ;
673
+
674
+ /**
675
+ * Deletes multiple files by their path names (e.g. "photos/demo.png", "essays/demo.txt").
676
+ *
677
+ * @see https://instantdb.com/docs/storage
678
+ * @example
679
+ * await db.storage.deleteMany(["images/1.png", "images/2.png", "images/3.png"]);
680
+ */
681
+ deleteMany = async ( pathnames : string [ ] ) : Promise < DeleteManyFileResponse > => {
682
+ return jsonFetch ( `${ this . config . apiURI } /admin/storage/files/delete` , {
683
+ method : "POST" ,
684
+ headers : authorizedHeaders ( this . config ) ,
685
+ body : JSON . stringify ( { filenames : pathnames } ) ,
686
+ } ) ;
687
+ } ;
688
+
689
+ /**
690
+ * @deprecated . This method will be removed in the future. Use `uploadFile`
691
+ * instead
621
692
*/
622
693
upload = async (
623
694
pathname : string ,
624
695
file : Buffer ,
625
- metadata : UploadMetadata = { } ,
696
+ metadata : FileOpts = { } ,
626
697
) : Promise < boolean > => {
627
698
const { data : presignedUrl } = await jsonFetch (
628
699
`${ this . config . apiURI } /admin/storage/signed-upload-url` ,
@@ -647,15 +718,13 @@ class Storage {
647
718
} ;
648
719
649
720
/**
650
- * Retrieves a download URL for the provided path.
651
- *
652
- * @see https://instantdb.com/docs/storage
721
+ * @deprecated . This method will be removed in the future. Use `query` instead
653
722
* @example
654
- * const url = await db.storage.getDownloadUrl('photos/demo.png');
723
+ * const files = await db.query({ $files: {}})
655
724
*/
656
- getDownloadUrl = async ( pathname : string ) : Promise < string > => {
725
+ list = async ( ) : Promise < StorageFile [ ] > => {
657
726
const { data } = await jsonFetch (
658
- `${ this . config . apiURI } /admin/storage/signed-download-url?app_id= ${ this . config . appId } &filename= ${ encodeURIComponent ( pathname ) } ` ,
727
+ `${ this . config . apiURI } /admin/storage/files ` ,
659
728
{
660
729
method : "GET" ,
661
730
headers : authorizedHeaders ( this . config ) ,
@@ -665,16 +734,24 @@ class Storage {
665
734
return data ;
666
735
} ;
667
736
737
+
668
738
/**
669
- * Retrieves a list of all the files that have been uploaded by this app.
670
- *
671
- * @see https://instantdb.com/docs/storage
672
- * @example
673
- * const files = await db.storage.list();
739
+ * @deprecated . getDownloadUrl will be removed in the future.
740
+ * Use `query` instead to query and fetch for valid urls
741
+ *
742
+ * db.useQuery({
743
+ * $files: {
744
+ * $: {
745
+ * where: {
746
+ * path: "moop.png"
747
+ * }
748
+ * }
749
+ * }
750
+ * })
674
751
*/
675
- list = async ( ) : Promise < StorageFile [ ] > => {
752
+ getDownloadUrl = async ( pathname : string ) : Promise < string > => {
676
753
const { data } = await jsonFetch (
677
- `${ this . config . apiURI } /admin/storage/files ` ,
754
+ `${ this . config . apiURI } /admin/storage/signed-download-url?app_id= ${ this . config . appId } &filename= ${ encodeURIComponent ( pathname ) } ` ,
678
755
{
679
756
method : "GET" ,
680
757
headers : authorizedHeaders ( this . config ) ,
@@ -683,38 +760,6 @@ class Storage {
683
760
684
761
return data ;
685
762
} ;
686
-
687
- /**
688
- * Deletes a file by its path name (e.g. "photos/demo.png").
689
- *
690
- * @see https://instantdb.com/docs/storage
691
- * @example
692
- * await db.storage.delete("photos/demo.png");
693
- */
694
- delete = async ( pathname : string ) : Promise < void > => {
695
- await jsonFetch (
696
- `${ this . config . apiURI } /admin/storage/files?filename=${ encodeURIComponent ( pathname ) } ` ,
697
- {
698
- method : "DELETE" ,
699
- headers : authorizedHeaders ( this . config ) ,
700
- } ,
701
- ) ;
702
- } ;
703
-
704
- /**
705
- * Deletes multiple files by their path names (e.g. "photos/demo.png", "essays/demo.txt").
706
- *
707
- * @see https://instantdb.com/docs/storage
708
- * @example
709
- * await db.storage.deleteMany(["images/1.png", "images/2.png", "images/3.png"]);
710
- */
711
- deleteMany = async ( pathnames : string [ ] ) : Promise < void > => {
712
- await jsonFetch ( `${ this . config . apiURI } /admin/storage/files/delete` , {
713
- method : "POST" ,
714
- headers : authorizedHeaders ( this . config ) ,
715
- body : JSON . stringify ( { filenames : pathnames } ) ,
716
- } ) ;
717
- } ;
718
763
}
719
764
720
765
/**
@@ -955,4 +1000,10 @@ export {
955
1000
type InstantRules ,
956
1001
type UpdateParams ,
957
1002
type LinkParams ,
1003
+
1004
+ // storage types
1005
+ type FileOpts ,
1006
+ type UploadFileResponse ,
1007
+ type DeleteFileResponse ,
1008
+ type DeleteManyFileResponse ,
958
1009
} ;
0 commit comments