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.