Cloud Storage
Cloud Storage
Section titled “Cloud Storage”Access S3-compatible object storage. Upload, download, list, and manage files with presigned URL support.
For storage configuration, see Cloud Storage.
Loading
Section titled “Loading”local cloudstorage = require("cloudstorage")Acquiring Storage
Section titled “Acquiring Storage”Get a cloud storage resource by registry ID:
local storage, err = cloudstorage.get("app.infra:files")if err then return nil, errend
storage:upload_object("data/file.txt", "content")storage:release()| Parameter | Type | Description |
|---|---|---|
id | string | Storage resource ID |
Returns: Storage, error
Uploading Objects
Section titled “Uploading Objects”Upload content from string or file:
local storage = cloudstorage.get("app.infra:files")
-- Upload string contentlocal ok, err = storage:upload_object("reports/daily.json", json.encode({ date = "2024-01-15", total = 1234}))
-- Upload from filelocal fs = require("fs")local vol = fs.get("app:data")local file = vol:open("/large-file.bin", "r")
storage:upload_object("backups/large-file.bin", file)file:close()
storage:release()| Parameter | Type | Description |
|---|---|---|
key | string | Object key/path |
content | string or Reader | Content as string or file reader |
options | table | Optional metadata and conditional write options |
Returns: boolean, error
Upload Options
Section titled “Upload Options”Attach metadata or guard the write with an options table:
storage:upload_object("reports/daily.json", body, { content_type = "application/json", cache_control = "max-age=3600", metadata = { owner = "team-a", run_id = "1234" }, -- stored as x-amz-meta-* only_if_absent = true -- fail if the key already exists})| Option | Type | Description |
|---|---|---|
content_type | string | MIME type |
cache_control | string | Cache-Control header |
content_disposition | string | Content-Disposition header |
content_encoding | string | Content-Encoding header |
metadata | table | User metadata (string keys/values), stored as x-amz-meta-* |
headers | table | Additional request headers (string keys/values) |
if_match | string | Write only if the current object ETag matches |
if_none_match | string | Write only if no object matches the ETag ("*" means any) |
only_if_absent | boolean | Write only if the key does not exist (alias for if_none_match = "*") |
A conditional write that fails its precondition returns a precondition_failed error.
Downloading Objects
Section titled “Downloading Objects”Download an object to a file writer:
local storage = cloudstorage.get("app.infra:files")local fs = require("fs")local vol = fs.get("app:temp")
local file = vol:open("/downloaded.json", "w")local ok, err = storage:download_object("reports/daily.json", file)file:close()
-- Download partial content (first 1KB)local partial = vol:open("/partial.bin", "w")storage:download_object("backups/large-file.bin", partial, { range = "bytes=0-1023"})partial:close()
storage:release()| Parameter | Type | Description |
|---|---|---|
key | string | Object key to download |
writer | Writer | Destination file writer |
options.range | string | Byte range (e.g., “bytes=0-1023”) |
options.if_match | string | Download only if the object ETag matches |
options.if_none_match | string | Download only if the ETag does not match |
Returns: boolean, error
A failed precondition (if_match/if_none_match) returns a precondition_failed error.
Listing Objects
Section titled “Listing Objects”List objects with optional prefix filtering:
local storage = cloudstorage.get("app.infra:files")
local result, err = storage:list_objects({ prefix = "reports/2024/", max_keys = 100})
for _, obj in ipairs(result.objects) do print(obj.key, obj.size, obj.etag)end
-- Paginate through large resultslocal token = nilrepeat local result = storage:list_objects({ prefix = "logs/", max_keys = 1000, continuation_token = token }) for _, obj in ipairs(result.objects) do process(obj) end token = result.next_continuation_tokenuntil not result.is_truncated
storage:release()| Parameter | Type | Description |
|---|---|---|
options.prefix | string | Filter by key prefix |
options.max_keys | integer | Maximum objects to return |
options.continuation_token | string | Pagination token |
options.include_owner | boolean | Include each object’s owner (id, display_name) |
options.include_versions | boolean | List object versions; each item includes version_id |
Returns: table, error
Result contains objects, is_truncated, next_continuation_token. Each object has key, size, etag, storage_class, and optional last_modified, version_id, and owner.
content_type is always empty — S3 list operations do not return it. Use head_object to read an object's content type and metadata.
Object Metadata
Section titled “Object Metadata”Fetch a single object’s metadata without downloading its body:
local storage = cloudstorage.get("app.infra:files")
local meta, err = storage:head_object("reports/daily.json")if err then return nil, errend
print(meta.size, meta.etag, meta.content_type)for k, v in pairs(meta.metadata) do print("meta", k, v)end
storage:release()| Parameter | Type | Description |
|---|---|---|
key | string | Object key |
Returns: table, error
Result fields:
| Field | Type | Description |
|---|---|---|
size | integer | Object size in bytes |
etag | string | Entity tag |
content_type | string | MIME type |
cache_control | string | Cache-Control header |
content_disposition | string | Content-Disposition header |
content_encoding | string | Content-Encoding header |
storage_class | string | Storage class |
version_id | string | Version ID (present when versioning is enabled) |
last_modified | integer | Last modified time (Unix seconds) |
metadata | table | User metadata (x-amz-meta-*) |
headers | table | Raw response headers (lowercased keys) |
A missing object returns a not_found error.
Deleting Objects
Section titled “Deleting Objects”Remove multiple objects:
local storage = cloudstorage.get("app.infra:files")
storage:delete_objects({ "temp/file1.txt", "temp/file2.txt", "temp/file3.txt"})
storage:release()| Parameter | Type | Description |
|---|---|---|
keys | string[] | Array of object keys to delete |
Returns: boolean, error
Download URLs
Section titled “Download URLs”Create a temporary URL that allows downloading an object without credentials. Useful for sharing files with external users or serving content through your application.
local storage, err = cloudstorage.get("app.infra:files")if err then return nil, errend
local url, err = storage:presigned_get_url("reports/quarterly.pdf", { expiration = 3600})
storage:release()
if err then return nil, errend
-- Return URL to client for direct downloadreturn {download_url = url}| Parameter | Type | Description |
|---|---|---|
key | string | Object key |
options.expiration | integer | Seconds until URL expires (default: 3600) |
Returns: string, error
Upload URLs
Section titled “Upload URLs”Create a temporary URL that allows uploading an object without credentials. Enables clients to upload files directly to storage without proxying through your server.
local storage, err = cloudstorage.get("app.infra:files")if err then return nil, errend
local url, err = storage:presigned_put_url("uploads/user-123/avatar.jpg", { expiration = 600, content_type = "image/jpeg", content_length = 1024 * 1024})
storage:release()
if err then return nil, errend
-- Return URL to client for direct uploadreturn {upload_url = url}| Parameter | Type | Description |
|---|---|---|
key | string | Object key |
options.expiration | integer | Seconds until URL expires (default: 3600) |
options.content_type | string | Required content type for upload |
options.content_length | integer | Maximum upload size in bytes |
Returns: string, error
Storage Methods
Section titled “Storage Methods”| Method | Returns | Description |
|---|---|---|
upload_object(key, content, opts?) | boolean, error | Upload string or file content |
download_object(key, writer, opts?) | boolean, error | Download to file writer |
head_object(key) | table, error | Fetch object metadata |
list_objects(opts?) | table, error | List objects with prefix filter |
delete_objects(keys) | boolean, error | Delete multiple objects |
presigned_get_url(key, opts?) | string, error | Generate temporary download URL |
presigned_put_url(key, opts?) | string, error | Generate temporary upload URL |
release() | boolean | Release storage resource |
Permissions
Section titled “Permissions”Cloud storage operations are subject to security policy evaluation.
| Action | Resource | Description |
|---|---|---|
cloudstorage.get | Storage ID | Acquire a storage resource |
Errors
Section titled “Errors”| Condition | Kind | Retryable |
|---|---|---|
| Empty resource ID | errors.INVALID | no |
| Resource not found | errors.NOT_FOUND | no |
| Not a cloud storage resource | errors.INVALID | no |
| Storage released | errors.INVALID | no |
| Empty key | errors.INVALID | no |
| Content nil | errors.INVALID | no |
| Writer not valid | errors.INVALID | no |
| Object not found | errors.NOT_FOUND | no |
| Conditional precondition failed | errors.CONFLICT | no |
| Permission denied | errors.PERMISSION_DENIED | no |
| Operation failed | errors.INTERNAL | no |
See Error Handling for working with errors.