Changelog
ChangelogResources

Storage object metadata

Storage put now accepts object attributes, and get and head return them: content type, cache control, content disposition, custom key-value metadata, plus the provider's ETag and version. No more keeping a file's content type in a separate database next to the file:

const assets = storage("assets")

await assets.put("reports/q1.pdf", pdfBytes, {
  attributes: {
    contentType: "application/pdf",
    cacheControl: "public, max-age=3600",
    metadata: { quarter: "q1" },
  },
})

// Serve it back with the headers it was stored with
const { data, attributes } = await assets.get("reports/q1.pdf")
res.type(attributes.contentType!).send(data)

Reads also return the provider's ETag and version; a head is enough to answer an If-None-Match with a 304 without downloading the object. The same model works on S3, Google Cloud Storage, and Azure Blob, and writes a provider can't honor fail before any bytes land, so an object never exists with silently dropped attributes.

Read the docs →

Dan LilienblumItamar Zand
Dan & Itamar