Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ import kotlinx.serialization.Serializable
import org.khronos.webgl.ArrayBuffer
import org.khronos.webgl.Uint8Array
import org.khronos.webgl.get
import org.khronos.webgl.set
import org.w3c.files.Blob
import org.w3c.files.FilePropertyBag
import org.w3c.files.FileReader
import kotlin.collections.forEachIndexed
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.js.ExperimentalWasmJsInterop
Expand All @@ -31,7 +35,22 @@ public actual data class PlatformFile(
) {
public actual override fun toString(): String = path

public actual companion object
public actual companion object {
/**
* Creates a [PlatformFile] from a browser [Blob].
*
* Since a browser [File] is a subtype of [Blob], it can also be passed directly.
*/
@OptIn(ExperimentalWasmJsInterop::class)
public operator fun invoke(blob: Blob, name: String): PlatformFile {
val file = BrowserFile(
fileBits = listOf(blob.unsafeCast<JsAny>()).toJsArray(),
fileName = name,
options = FilePropertyBag(type = blob.type),
)
return PlatformFile(webFile = WebFile.FileWrapper(file = file))
}
}
}

public actual val PlatformFile.name: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import io.github.vinceglb.filekit.exceptions.FileKitException
import io.github.vinceglb.filekit.mimeType.MimeType
import io.github.vinceglb.filekit.utils.createTestFile
import kotlinx.coroutines.test.runTest
import org.w3c.files.Blob
import org.w3c.files.BlobPropertyBag
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
Expand Down Expand Up @@ -189,6 +191,50 @@ class PlatformFileWebTest {
)
}

@OptIn(ExperimentalWasmJsInterop::class)
@Test
fun testPlatformFileFromBlob() = runTest {
val blob = Blob(
blobParts = listOf("Hello, World!".toJsString()).toJsArray(),
options = BlobPropertyBag(type = "text/plain"),
)

val file = PlatformFile(blob = blob, name = platformFile.name)

assertEquals(platformFile.name, file.name)
assertEquals(platformFile.extension, file.extension)
assertEquals(platformFile.nameWithoutExtension, file.nameWithoutExtension)
assertEquals(platformFile.size(), file.size())

assertEquals(
platformFile.readBytes().decodeToString(),
file.readBytes().decodeToString(),
)
assertEquals(
platformFile.readBytes().toList(),
file.readBytes().toList(),
)
assertEquals(platformFile.mimeType(), file.mimeType())
assertTrue(file.isRegularFile())
assertFalse(file.isDirectory())
}

@OptIn(ExperimentalWasmJsInterop::class)
@Test
fun testPlatformFileFromEmptyBlob() = runTest {
val blob = Blob(
blobParts = emptyList<JsAny?>().toJsArray(),
options = BlobPropertyBag(type = "application/octet-stream"),
)
val file = PlatformFile(blob = blob, name = "empty.bin")

assertEquals("empty.bin", file.name)
assertEquals(0L, file.size())
assertTrue(file.readBytes().isEmpty())
assertTrue(file.isRegularFile())
assertFalse(file.isDirectory())
}

private fun PlatformFile.webFileWrapper(): WebFile.FileWrapper =
assertIs<WebFile.FileWrapper>(webFile)
}
Loading