Class: Cloudflare::R2Bucket

Inherits:
Object
  • Object
show all
Defined in:
lib/cloudflare_workers.rb

Instance Method Summary collapse

Constructor Details

#initialize(js) ⇒ R2Bucket

Returns a new instance of R2Bucket.



689
690
691
# File 'lib/cloudflare_workers.rb', line 689

def initialize(js)
  @js = js
end

Instance Method Details

#delete(key) ⇒ Object

Delete a key. Returns a JS Promise.



726
727
728
729
# File 'lib/cloudflare_workers.rb', line 726

def delete(key)
  js_bucket = @js
  `#{js_bucket}.delete(#{key})`
end

#get(key) ⇒ Object

R2 get. Returns a JS Promise resolving to a Ruby Hash (or nil).



694
695
696
697
698
# File 'lib/cloudflare_workers.rb', line 694

def get(key)
  js_bucket = @js
  fallback_key = key
  `#{js_bucket}.get(#{key}).then(async function(obj) { if (obj == null) return nil; var text = await obj.text(); var rb = new Map(); rb.set('body', text); rb.set('etag', obj.etag || ''); rb.set('size', obj.size || 0); rb.set('key', obj.key || #{fallback_key}); return rb; })`
end

#get_binary(key) ⇒ Object

R2 get_binary. Returns a JS Promise that resolves to a Cloudflare::BinaryBody (wrapping the R2 object’s ReadableStream) or nil. Use this for serving images and other binary content through Sinatra routes without byte-mangling.

get '/images/:key' do
  obj = bucket.get_binary(key).__await__
  halt 404 if obj.nil?
  obj  # BinaryBody flows through build_js_response as a stream
end

Returns a JS Promise resolving to a Cloudflare::BinaryBody or nil. BinaryBody wraps the R2 ReadableStream so build_js_response can pass it straight to ‘new Response(stream)` without mangling bytes.



713
714
715
716
717
# File 'lib/cloudflare_workers.rb', line 713

def get_binary(key)
  js_bucket = @js
  bb = Cloudflare::BinaryBody
  `#{js_bucket}.get(#{key}).then(function(obj) { if (obj == null) return nil; var ct = (obj.httpMetadata && obj.httpMetadata.contentType) || 'application/octet-stream'; return #{bb}.$new(obj.body, ct, 'public, max-age=86400'); })`
end

#list(prefix: nil, limit: 100, cursor: nil, include: %w[httpMetadata])) ⇒ Object

List objects under a prefix. Returns a JS Promise that resolves to a Ruby Array of Hashes, one per object. Each Hash carries the common R2 metadata fields so callers can render a gallery view (key / size / uploaded / httpMetadata).

bucket.list(prefix: 'phase11a/uploads/', limit: 50).__await__
  => [{ 'key' => 'phase11a/uploads/abc-cat.png',
        'size' => 31337, 'uploaded' => '2026-04-17T...',
        'content_type' => 'image/png' }, ...]

NOTE: R2’s ‘list()` returns bare objects by default — `httpMetadata` is ONLY populated when `include: [’httpMetadata’]‘ is passed in the options. Without it, every row would come back with a fallback `application/octet-stream` content-type even for real PNG uploads. Always requesting httpMetadata is the right default for a gallery UI; callers that need the bytes-only fast path can fall back to listing raw keys + `get()` on-demand.



748
749
750
751
752
753
754
755
756
757
758
759
760
# File 'lib/cloudflare_workers.rb', line 748

def list(prefix: nil, limit: 100, cursor: nil, include: %w[httpMetadata])
  js_bucket = @js
  opts = `({})`
  `#{opts}.prefix = #{prefix}` if prefix
  `#{opts}.limit  = #{limit.to_i}` if limit
  `#{opts}.cursor = #{cursor}` if cursor
  if include && !include.empty?
    js_include = `[]`
    include.each { |v| vs = v.to_s; `#{js_include}.push(#{vs})` }
    `#{opts}.include = #{js_include}`
  end
  `#{js_bucket}.list(#{opts}).then(function(res) { var rows = []; var arr = res && res.objects ? res.objects : []; for (var i = 0; i < arr.length; i++) { var o = arr[i]; var ct = (o.httpMetadata && o.httpMetadata.contentType) || 'application/octet-stream'; var h = new Map(); h.set('key', o.key); h.set('size', o.size|0); h.set('uploaded', o.uploaded ? o.uploaded.toISOString() : null); h.set('content_type', ct); rows.push(h); } return rows; })`
end

#put(key, body, content_type = 'application/octet-stream') ⇒ Object

Put a value. ‘body` may be a String. Returns a JS Promise.



720
721
722
723
# File 'lib/cloudflare_workers.rb', line 720

def put(key, body, content_type = 'application/octet-stream')
  js_bucket = @js
  `#{js_bucket}.put(#{key}, #{body}, { httpMetadata: { contentType: #{content_type} } })`
end