// Cloudflare R2 Bucket bindings
///|
#external
pub type R2Bucket
///|
pub fn R2Bucket::as_any(self : R2Bucket) -> @core.Any = "%identity"
///|
/// Get an object from R2
pub async fn R2Bucket::get(
self : Self,
key : String,
onlyIf? : R2Conditional,
range? : R2Range,
) -> R2Object? {
let promise : @js_async.Promise[@core.Any] = if onlyIf is None &&
range is None {
self.as_any()._call("get", [@core.any(key)]).cast()
} else {
let onlyIf_js : @core.Any? = match onlyIf {
Some(cond) => {
let entries : Array[(String, @core.Any)] = []
if cond.etagMatches is Some(v) {
entries.push(("etagMatches", @core.any(v)))
}
if cond.etagDoesNotMatch is Some(v) {
entries.push(("etagDoesNotMatch", @core.any(v)))
}
if cond.uploadedBefore is Some(v) {
entries.push(("uploadedBefore", @core.identity(v)))
}
if cond.uploadedAfter is Some(v) {
entries.push(("uploadedAfter", @core.identity(v)))
}
Some(@core.from_entries(entries))
}
None => None
}
let range_js : @core.Any? = match range {
Some(r) => {
let entries : Array[(String, @core.Any)] = []
if r.offset is Some(v) {
entries.push(("offset", @core.any(v)))
}
if r.length is Some(v) {
entries.push(("length", @core.any(v)))
}
if r.suffix is Some(v) {
entries.push(("suffix", @core.any(v)))
}
Some(@core.from_entries(entries))
}
None => None
}
let entries : Array[(String, @core.Any)] = []
if onlyIf_js is Some(v) {
entries.push(("onlyIf", @core.any(v)))
}
if range_js is Some(v) {
entries.push(("range", @core.any(v)))
}
let opts = @core.from_entries(entries)
self.as_any()._call("get", [@core.any(key), opts]).cast()
}
let result = promise.wait()
if @core.is_null(result) || @core.typeof_(result) == "undefined" {
None
} else {
Some(result.cast())
}
}
///|
/// Get object metadata without body
pub async fn R2Bucket::head(self : Self, key : String) -> R2Object? {
let promise : @js_async.Promise[@core.Any] = self
.as_any()
._call("head", [@core.any(key)])
.cast()
let result = promise.wait()
if @core.is_null(result) || @core.typeof_(result) == "undefined" {
None
} else {
Some(result.cast())
}
}
///|
/// Put an object into R2
pub async fn R2Bucket::put(
self : Self,
key : String,
value : @core.Any,
httpMetadata? : R2HttpMetadata,
customMetadata? : @core.Any,
md5? : String,
sha1? : String,
sha256? : String,
sha384? : String,
sha512? : String,
) -> R2Object {
let promise : @js_async.Promise[R2Object] = if httpMetadata is None &&
customMetadata is None &&
md5 is None &&
sha1 is None &&
sha256 is None &&
sha384 is None &&
sha512 is None {
self.as_any()._call("put", [@core.any(key), @core.any(value)]).cast()
} else {
let httpMetadata_js : @core.Any? = match httpMetadata {
Some(meta) => Some(@core.any(meta.as_any()))
None => None
}
let customMetadata_js : @core.Any? = customMetadata.map(fn(x) {
@core.any(x)
})
let entries : Array[(String, @core.Any)] = []
if httpMetadata_js is Some(v) {
entries.push(("httpMetadata", v))
}
if customMetadata_js is Some(v) {
entries.push(("customMetadata", v))
}
if md5 is Some(v) {
entries.push(("md5", @core.any(v)))
}
if sha1 is Some(v) {
entries.push(("sha1", @core.any(v)))
}
if sha256 is Some(v) {
entries.push(("sha256", @core.any(v)))
}
if sha384 is Some(v) {
entries.push(("sha384", @core.any(v)))
}
if sha512 is Some(v) {
entries.push(("sha512", @core.any(v)))
}
let opts = @core.from_entries(entries)
self.as_any()._call("put", [@core.any(key), @core.any(value), opts]).cast()
}
promise.wait()
}
///|
/// Delete an object from R2
pub async fn R2Bucket::delete(self : Self, key : String) -> Unit {
let promise : @js_async.Promise[Unit] = self
.as_any()
._call("delete", [@core.any(key)])
.cast()
promise.wait()
}
///|
/// Delete multiple objects from R2
pub async fn R2Bucket::delete_multiple(
self : Self,
keys : Array[String],
) -> Unit {
let keys_js = @core.new_array()
let mut i = 0
while i < keys.length() {
@core.any(keys_js)._call("push", [@core.any(keys[i])]) |> ignore
i = i + 1
}
let promise : @js_async.Promise[Unit] = self
.as_any()
._call("delete", [@core.any(keys_js)])
.cast()
promise.wait()
}
///|
/// List objects in the bucket
pub async fn R2Bucket::list(
self : Self,
limit? : Int,
prefix? : String,
cursor? : String,
delimiter? : String,
startAfter? : String,
include_? : Array[String],
) -> R2Objects {
let promise : @js_async.Promise[R2Objects] = if limit is None &&
prefix is None &&
cursor is None &&
delimiter is None &&
startAfter is None &&
include_ is None {
self.as_any()._call("list", []).cast()
} else {
let include_js : @core.Any? = match include_ {
Some(inc) => Some(@core.any(@core.any(inc)))
None => None
}
let entries : Array[(String, @core.Any)] = []
if limit is Some(v) {
entries.push(("limit", @core.any(v)))
}
if prefix is Some(v) {
entries.push(("prefix", @core.any(v)))
}
if cursor is Some(v) {
entries.push(("cursor", @core.any(v)))
}
if delimiter is Some(v) {
entries.push(("delimiter", @core.any(v)))
}
if startAfter is Some(v) {
entries.push(("startAfter", @core.any(v)))
}
if include_js is Some(v) {
entries.push(("include", v))
}
let opts = @core.from_entries(entries)
self.as_any()._call("list", [opts]).cast()
}
promise.wait()
}
///|
/// Create a multipart upload
pub async fn R2Bucket::create_multipart_upload(
self : Self,
key : String,
httpMetadata? : R2HttpMetadata,
customMetadata? : @core.Any,
md5? : String,
sha1? : String,
sha256? : String,
sha384? : String,
sha512? : String,
) -> R2MultipartUpload {
let promise : @js_async.Promise[R2MultipartUpload] = if httpMetadata is None &&
customMetadata is None &&
md5 is None &&
sha1 is None &&
sha256 is None &&
sha384 is None &&
sha512 is None {
self.as_any()._call("createMultipartUpload", [@core.any(key)]).cast()
} else {
let httpMetadata_js : @core.Any? = match httpMetadata {
Some(meta) => Some(@core.any(meta.as_any()))
None => None
}
let customMetadata_js : @core.Any? = customMetadata.map(fn(x) {
@core.any(x)
})
let entries : Array[(String, @core.Any)] = []
if httpMetadata_js is Some(v) {
entries.push(("httpMetadata", v))
}
if customMetadata_js is Some(v) {
entries.push(("customMetadata", v))
}
if md5 is Some(v) {
entries.push(("md5", @core.any(v)))
}
if sha1 is Some(v) {
entries.push(("sha1", @core.any(v)))
}
if sha256 is Some(v) {
entries.push(("sha256", @core.any(v)))
}
if sha384 is Some(v) {
entries.push(("sha384", @core.any(v)))
}
if sha512 is Some(v) {
entries.push(("sha512", @core.any(v)))
}
let opts = @core.from_entries(entries)
self.as_any()._call("createMultipartUpload", [@core.any(key), opts]).cast()
}
promise.wait()
}
///|
/// Resume a multipart upload
pub fn R2Bucket::resume_multipart_upload(
self : Self,
key : String,
upload_id : String,
) -> R2MultipartUpload {
self
.as_any()
._call("resumeMultipartUpload", [@core.any(key), @core.any(upload_id)])
.cast()
}
///|
/// Conditional options for R2 operations
pub(all) struct R2Conditional {
etagMatches : String?
etagDoesNotMatch : String?
uploadedBefore : @date.Date?
uploadedAfter : @date.Date?
}
///|
/// Range options for R2 get operations
pub(all) struct R2Range {
offset : Int?
length : Int?
suffix : Int?
}
///|
/// HTTP metadata for R2 objects
pub(all) struct R2HttpMetadata {
contentType : String?
contentLanguage : String?
contentDisposition : String?
contentEncoding : String?
cacheControl : String?
cacheExpiry : @date.Date?
}
///|
pub fn R2HttpMetadata::as_any(self : R2HttpMetadata) -> @core.Any {
let entries : Array[(String, @core.Any)] = []
if self.contentType is Some(v) {
entries.push(("contentType", @core.any(v)))
}
if self.contentLanguage is Some(v) {
entries.push(("contentLanguage", @core.any(v)))
}
if self.contentDisposition is Some(v) {
entries.push(("contentDisposition", @core.any(v)))
}
if self.contentEncoding is Some(v) {
entries.push(("contentEncoding", @core.any(v)))
}
if self.cacheControl is Some(v) {
entries.push(("cacheControl", @core.any(v)))
}
if self.cacheExpiry is Some(v) {
entries.push(("cacheExpiry", @core.identity(v)))
}
@core.from_entries(entries)
}
///|
/// R2 Object type
#external
pub type R2Object
///|
pub fn R2Object::as_any(self : R2Object) -> @core.Any = "%identity"
///|
/// Get object key
pub fn R2Object::key(self : Self) -> String {
self.as_any()["key"].cast()
}
///|
/// Get object version
pub fn R2Object::version(self : Self) -> String {
self.as_any()["version"].cast()
}
///|
/// Get object size
pub fn R2Object::size(self : Self) -> Int {
self.as_any()["size"].cast()
}
///|
/// Get object etag
pub fn R2Object::etag(self : Self) -> String {
self.as_any()["etag"].cast()
}
///|
/// Get object HTTP metadata
pub fn R2Object::http_metadata(self : Self) -> @core.Any {
self.as_any()["httpMetadata"].cast()
}
///|
/// Get object custom metadata
pub fn R2Object::custom_metadata(self : Self) -> @core.Any {
self.as_any()["customMetadata"].cast()
}
///|
/// Get object uploaded time
pub fn R2Object::uploaded(self : Self) -> @core.Any {
self.as_any()["uploaded"].cast()
}
///|
/// Get object body as ArrayBuffer
pub async fn R2Object::array_buffer(self : Self) -> @arraybuffer.ArrayBuffer {
let promise : @js_async.Promise[@arraybuffer.ArrayBuffer] = self
.as_any()
._call("arrayBuffer", [])
.cast()
promise.wait()
}
///|
/// Get object body as text
pub async fn R2Object::text(self : Self) -> String {
let promise : @js_async.Promise[String] = self
.as_any()
._call("text", [])
.cast()
promise.wait()
}
///|
/// Get object body as JSON
pub async fn R2Object::json(self : Self) -> @core.Any {
let promise : @js_async.Promise[@core.Any] = self
.as_any()
._call("json", [])
.cast()
promise.wait()
}
///|
/// Get object body as blob
pub async fn R2Object::blob(self : Self) -> @blob.Blob {
let promise : @js_async.Promise[@blob.Blob] = self
.as_any()
._call("blob", [])
.cast()
promise.wait()
}
///|
/// Get object body as ReadableStream
pub fn R2Object::body(self : Self) -> @streams.ReadableStream {
self.as_any()["body"].cast()
}
///|
/// Get object body used status
pub fn R2Object::body_used(self : Self) -> Bool {
self.as_any()["bodyUsed"].cast()
}
///|
/// Write object to a writable stream
pub fn R2Object::write_http_metadata(self : Self, headers : @core.Any) -> Unit {
self.as_any()._call("writeHttpMetadata", [@core.any(headers)]).cast()
}
///|
/// Result of list operation (external type to properly handle JS object properties)
#external
pub type R2Objects
///|
pub fn R2Objects::as_any(self : R2Objects) -> @core.Any = "%identity"
///|
/// Get the objects array
pub fn R2Objects::objects(self : R2Objects) -> Array[R2Object] {
self.as_any()["objects"].cast()
}
///|
/// Check if the list is truncated
pub fn R2Objects::truncated(self : R2Objects) -> Bool {
self.as_any()["truncated"].cast()
}
///|
/// Get the cursor for pagination
pub fn R2Objects::cursor(self : R2Objects) -> String? {
let c = self.as_any()["cursor"]
if @core.typeof_(c) == "undefined" || @core.is_null(c) {
None
} else {
Some(c.cast())
}
}
///|
/// Get the delimited prefixes
pub fn R2Objects::delimited_prefixes(self : R2Objects) -> Array[String] {
let dp = self.as_any()["delimitedPrefixes"]
if @core.typeof_(dp) == "undefined" || @core.is_null(dp) {
[]
} else {
dp.cast()
}
}
///|
/// R2 Multipart Upload
#external
pub type R2MultipartUpload
///|
pub fn R2MultipartUpload::as_any(self : R2MultipartUpload) -> @core.Any = "%identity"
///|
/// Get upload key
pub fn R2MultipartUpload::key(self : Self) -> String {
self.as_any()["key"].cast()
}
///|
/// Get upload ID
pub fn R2MultipartUpload::uploadId(self : Self) -> String {
self.as_any()["uploadId"].cast()
}
///|
/// Upload a part
pub async fn R2MultipartUpload::upload_part(
self : Self,
part_number : Int,
value : @core.Any,
) -> R2UploadedPart {
let promise : @js_async.Promise[R2UploadedPart] = self
.as_any()
._call("uploadPart", [@core.any(part_number), @core.any(value)])
.cast()
promise.wait()
}
///|
/// Abort the multipart upload
pub async fn R2MultipartUpload::abort(self : Self) -> Unit {
let promise : @js_async.Promise[Unit] = self
.as_any()
._call("abort", [])
.cast()
promise.wait()
}
///|
/// Complete the multipart upload
pub async fn R2MultipartUpload::complete(
self : Self,
parts : Array[R2UploadedPart],
) -> R2Object {
let parts_js = @core.new_array()
let mut i = 0
while i < parts.length() {
@core.any(parts_js)._call("push", [@core.any(parts[i].as_any())]) |> ignore
i = i + 1
}
let promise : @js_async.Promise[R2Object] = self
.as_any()
._call("complete", [@core.any(parts_js)])
.cast()
promise.wait()
}
///|
/// Uploaded part information
pub(all) struct R2UploadedPart {
partNumber : Int
etag : String
}
///|
pub fn R2UploadedPart::as_any(self : R2UploadedPart) -> @core.Any {
@core.from_entries([
("partNumber", @core.any(self.partNumber)),
("etag", @core.any(self.etag)),
])
}