defmodule Supabase.Storage.Bucket do
@moduledoc """
Represents a Bucket on Supabase Storage.
This module defines the structure and operations related to a storage bucket on Supabase.
## Structure
A `Bucket` consists of:
- `id`: The unique identifier for the bucket.
- `name`: The display name of the bucket.
- `owner`: The owner of the bucket.
- `file_size_limit`: The maximum file size allowed in the bucket (in bytes). Can be `nil` for no limit.
- `allowed_mime_types`: List of MIME types permitted in this bucket. Can be `nil` for no restrictions.
- `created_at`: Timestamp indicating when the bucket was created.
- `updated_at`: Timestamp indicating the last update to the bucket.
- `public`: Boolean flag determining if the bucket is publicly accessible or not.
## Functions
- `parse!/1`: Parses and returns a bucket structure.
- `create_changeset/1`: Generates a changeset for creating a bucket.
- `update_changeset/2`: Generates a changeset for updating an existing bucket.
## Examples
### Parsing a bucket
bucket_attrs = %{
id: "bucket_id",
name: "My Bucket",
...
}
Supabase.Storage.Bucket.parse!(bucket_attrs)
### Creating a bucket changeset
new_bucket_attrs = %{
id: "new_bucket_id",
...
}
Supabase.Storage.Bucket.create_changeset(new_bucket_attrs)
### Updating a bucket
existing_bucket = %Supabase.Storage.Bucket{
id: "existing_bucket_id",
...
}
updated_attrs = %{
public: true
}
Supabase.Storage.Bucket.update_changeset(existing_bucket, updated_attrs)
"""
use Ecto.Schema
import Ecto.Changeset
@type t :: %__MODULE__{
id: String.t(),
name: String.t(),
owner: String.t(),
file_size_limit: integer | nil,
allowed_mime_types: list(String.t()) | nil,
created_at: NaiveDateTime.t(),
updated_at: NaiveDateTime.t(),
public: boolean
}
@fields ~w(id name created_at updated_at file_size_limit allowed_mime_types public owner)a
@create_fields ~w(id name file_size_limit allowed_mime_types public)a
@update_fields ~w(file_size_limit allowed_mime_types public)a
@primary_key false
embedded_schema do
field(:id, :string)
field(:name, :string)
field(:owner, :string)
field(:file_size_limit, :integer)
field(:allowed_mime_types, {:array, :string})
field(:created_at, :naive_datetime)
field(:updated_at, :naive_datetime)
field(:public, :boolean, default: false)
end
@spec parse!(map) :: t
def parse!(attrs) do
%__MODULE__{}
|> cast(attrs, @fields)
|> apply_action!(:parse)
end
@spec create_changeset(map) :: {:ok, map} | {:error, Ecto.Changeset.t()}
def create_changeset(attrs) do
%__MODULE__{}
|> cast(attrs, @create_fields)
|> validate_required([:id])
|> maybe_put_name()
|> apply_action(:create)
|> case do
{:ok, data} -> {:ok, Map.take(data, @create_fields)}
err -> err
end
end
defp maybe_put_name(changeset) do
if get_change(changeset, :name) do
changeset
else
id = get_change(changeset, :id)
put_change(changeset, :name, id)
end
end
@spec update_changeset(t, map) :: {:ok, map} | {:error, Ecto.Changeset.t()}
def update_changeset(%__MODULE__{} = bucket, attrs) do
bucket
|> cast(attrs, @update_fields)
|> apply_action(:update)
|> case do
{:ok, data} -> {:ok, Map.take(data, @update_fields)}
err -> err
end
end
end