From a85efaa78a0010c4ef4c06f81056429383f470b3 Mon Sep 17 00:00:00 2001 From: Gijs van Veen Date: Tue, 25 Jun 2024 12:47:25 +0200 Subject: [PATCH] Fixed Storage for JS --- .../gitlive/firebase/firestore/firestore.kt | 2 +- .../dev/gitlive/firebase/storage/storage.kt | 6 +- .../firebase/storage/externals/storage.kt | 83 ++++++++++++------- .../dev/gitlive/firebase/storage/storage.kt | 32 +++---- .../gitlive/firebase/storage/storage.js.kt | 6 +- 5 files changed, 77 insertions(+), 52 deletions(-) diff --git a/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt b/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt index 06aecd9a1..c6cce33b9 100644 --- a/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt +++ b/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt @@ -154,7 +154,7 @@ actual class DocumentChange(val js: JsDocumentChange) { actual val oldIndex: Int get() = js.oldIndex actual val type: ChangeType - get() = ChangeType.values().first { it.jsString == js.type } + get() = ChangeType.entries.first { it.jsString == js.type } } actual data class NativeDocumentSnapshot(val js: JsDocumentSnapshot) diff --git a/firebase-storage/src/commonTest/kotlin/dev/gitlive/firebase/storage/storage.kt b/firebase-storage/src/commonTest/kotlin/dev/gitlive/firebase/storage/storage.kt index c5c299d40..dcd147944 100644 --- a/firebase-storage/src/commonTest/kotlin/dev/gitlive/firebase/storage/storage.kt +++ b/firebase-storage/src/commonTest/kotlin/dev/gitlive/firebase/storage/storage.kt @@ -54,7 +54,7 @@ class FirebaseStorageTest { } @Test - fun testStorageNotNull() { + fun testStorageNotNull() = runTest { assertNotNull(storage) } @@ -79,7 +79,7 @@ class FirebaseStorageTest { assertNotNull(metadataResult) assertNotNull(metadataResult.contentType) - assertEquals(metadataResult.contentType, metadata.contentType) + assertEquals(metadata.contentType, metadataResult.contentType) } @Test @@ -95,7 +95,7 @@ class FirebaseStorageTest { val metadataResult = ref.getMetadata() assertNotNull(metadataResult) - assertEquals(metadataResult.customMetadata["key"], metadata.customMetadata["key"]) + assertEquals( metadata.customMetadata["key"], metadataResult.customMetadata["key"]) } } diff --git a/firebase-storage/src/jsMain/kotlin/dev/gitlive/firebase/storage/externals/storage.kt b/firebase-storage/src/jsMain/kotlin/dev/gitlive/firebase/storage/externals/storage.kt index 13c23ce61..b1a793d54 100644 --- a/firebase-storage/src/jsMain/kotlin/dev/gitlive/firebase/storage/externals/storage.kt +++ b/firebase-storage/src/jsMain/kotlin/dev/gitlive/firebase/storage/externals/storage.kt @@ -4,26 +4,29 @@ package dev.gitlive.firebase.storage.externals import dev.gitlive.firebase.externals.FirebaseApp +import kotlin.js.Json import kotlin.js.Promise +import kotlin.js.collections.JsMap -external fun getStorage(app: FirebaseApp? = definedExternally, url: String): FirebaseStorage +external fun getStorage(app: FirebaseApp? = definedExternally, bucketUrl: String): FirebaseStorage external fun getStorage(app: FirebaseApp? = definedExternally): FirebaseStorage external fun ref(storage: FirebaseStorage, url: String? = definedExternally): StorageReference -external fun ref(ref: StorageReference, url: String? = definedExternally): StorageReference +external fun ref(ref: StorageReference, path: String? = definedExternally): StorageReference external fun getDownloadURL(ref: StorageReference): Promise -external fun getMetadata(ref: StorageReference): Promise +external fun getMetadata(ref: StorageReference): Promise +external fun updateMetadata(ref: StorageReference, metadata: SettableMetadata): Promise -external fun uploadBytes(ref: StorageReference, file: dynamic, metadata: StorageMetadata?): Promise +external fun uploadBytes(ref: StorageReference, file: dynamic, metadata: Json?): Promise +external fun uploadBytesResumable(ref: StorageReference, data: dynamic, metadata: Json?): UploadTask -external fun uploadBytesResumable(ref: StorageReference, data: dynamic, metadata: StorageMetadata?): UploadTask +external fun deleteObject(ref: StorageReference): Promise -external fun deleteObject(ref: StorageReference): Promise; - -external fun listAll(ref: StorageReference): Promise; +external fun list(ref: StorageReference, options: ListOptions?): Promise +external fun listAll(ref: StorageReference): Promise external fun connectStorageEmulator( storage: FirebaseStorage, @@ -46,7 +49,12 @@ external interface StorageReference { val storage: FirebaseStorage } -external open class ListResult { +external interface ListOptions { + val maxResults: Double? + val pageToken: String? +} + +external interface ListResult { val items: Array val nextPageToken: String val prefixes: Array @@ -54,37 +62,50 @@ external open class ListResult { external interface StorageError -external interface UploadTaskSnapshot { - val bytesTransferred: Number - val ref: StorageReference - val state: String - val task: UploadTask - val totalBytes: Number +external interface SettableMetadata { + val cacheControl: String? + val contentDisposition: String? + val contentEncoding: String? + val contentLanguage: String? + val contentType: String? + val customMetadata: Json? } -external class StorageMetadata { - val bucket: String? - var cacheControl: String? - var contentDisposition: String? - var contentEncoding: String? - var contentLanguage: String? - var contentType: String? - var customMetadata: Map? - val fullPath: String? - val generation: String? +external interface UploadMetadata : SettableMetadata { val md5Hash: String? - val metageneration: String? - val name: String? - val size: Number? - val timeCreated: String? - val updated: String? +} +external interface FullMetadata : UploadMetadata { + val bucket: String + val downloadTokens: Array? + val fullPath: String + val generation: String + val metageneration: String + val name: String + val ref: StorageReference? + val size: Double + val timeCreated: String + val updated: String } -external class UploadTask : Promise { +external interface UploadResult { + val metadata: FullMetadata + val ref: StorageReference +} + +external interface UploadTask { fun cancel(): Boolean; fun on(event: String, next: (snapshot: UploadTaskSnapshot) -> Unit, error: (a: StorageError) -> Unit, complete: () -> Unit): () -> Unit fun pause(): Boolean; fun resume(): Boolean; + fun then(onFulfilled: ((UploadTaskSnapshot) -> Unit)?, onRejected: ((StorageError) -> Unit)?): Promise val snapshot: UploadTaskSnapshot } + +external interface UploadTaskSnapshot { + val bytesTransferred: Double + val ref: StorageReference + val state: String + val task: UploadTask + val totalBytes: Double +} \ No newline at end of file diff --git a/firebase-storage/src/jsMain/kotlin/dev/gitlive/firebase/storage/storage.kt b/firebase-storage/src/jsMain/kotlin/dev/gitlive/firebase/storage/storage.kt index 6cb2b34a6..18430ca9e 100644 --- a/firebase-storage/src/jsMain/kotlin/dev/gitlive/firebase/storage/storage.kt +++ b/firebase-storage/src/jsMain/kotlin/dev/gitlive/firebase/storage/storage.kt @@ -14,6 +14,8 @@ import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.FlowCollector import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.emitAll +import kotlin.js.Json +import kotlin.js.json actual val Firebase.storage get() = FirebaseStorage(getStorage()) @@ -134,7 +136,7 @@ internal fun errorToException(error: dynamic) = (error?.code ?: error?.message ? } -internal fun StorageMetadata.toFirebaseStorageMetadata(): FirebaseStorageMetadata { +internal fun UploadMetadata.toFirebaseStorageMetadata(): FirebaseStorageMetadata { val sdkMetadata = this return storageMetadata { md5Hash = sdkMetadata.md5Hash @@ -143,19 +145,21 @@ internal fun StorageMetadata.toFirebaseStorageMetadata(): FirebaseStorageMetadat contentEncoding = sdkMetadata.contentEncoding contentLanguage = sdkMetadata.contentLanguage contentType = sdkMetadata.contentType - sdkMetadata.customMetadata?.entries?.forEach { - setCustomMetadata(it.key, it.value) - } + customMetadata = sdkMetadata.customMetadata?.let { metadata -> + val objectKeys = js("Object.keys") + objectKeys(metadata).unsafeCast>().associateWith { key -> + metadata[key]?.toString().orEmpty() + } + }.orEmpty().toMutableMap() } } -internal fun FirebaseStorageMetadata.toStorageMetadata(): StorageMetadata { - val metadata = StorageMetadata() - metadata.cacheControl = cacheControl - metadata.contentDisposition = contentDisposition - metadata.contentEncoding = contentEncoding - metadata.contentLanguage = contentLanguage - metadata.contentType = contentType - metadata.customMetadata = customMetadata - return metadata -} \ No newline at end of file +internal fun FirebaseStorageMetadata.toStorageMetadata(): Json = json( + "cacheControl" to cacheControl, + "contentDisposition" to contentDisposition, + "contentEncoding" to contentEncoding, + "contentLanguage" to contentLanguage, + "contentType" to contentType, + "customMetadata" to json(*customMetadata.toList().toTypedArray()), + "md5Hash" to md5Hash +) \ No newline at end of file diff --git a/firebase-storage/src/jsTest/kotlin/dev/gitlive/firebase/storage/storage.js.kt b/firebase-storage/src/jsTest/kotlin/dev/gitlive/firebase/storage/storage.js.kt index 8a8c266b6..a3c6ff594 100644 --- a/firebase-storage/src/jsTest/kotlin/dev/gitlive/firebase/storage/storage.js.kt +++ b/firebase-storage/src/jsTest/kotlin/dev/gitlive/firebase/storage/storage.js.kt @@ -1,5 +1,5 @@ package dev.gitlive.firebase.storage -actual fun createTestData(): Data { - TODO("Not yet implemented") -} \ No newline at end of file +import org.khronos.webgl.Uint8Array + +actual fun createTestData(): Data = Data(Uint8Array("test".encodeToByteArray().toTypedArray())) \ No newline at end of file