Current section

Files

Jump to
supabase_potion lib supabase client storage hostname.ex
Raw

lib/supabase/client/storage/hostname.ex

defmodule Supabase.Client.Storage.Hostname do
@moduledoc """
Handles hostname transformation for storage subdomain routing.
This module transforms official Supabase domain URLs to use the storage-specific
subdomain, which is optimized for large file uploads (>50GB) and provides better
streaming performance.
## Transformation Rules
- Official Supabase domains (`.supabase.co`, `.supabase.in`, `.supabase.red`) are
transformed to use the `storage.supabase.*` subdomain
- URLs already containing `storage.supabase.` are left unchanged
- Custom domains (non-Supabase) are left untouched
- Localhost and IP addresses are left unchanged
## Examples
iex> Supabase.Client.Storage.Hostname.transform_storage_url("https://abc123.supabase.co/storage/v1")
"https://abc123.storage.supabase.co/storage/v1"
iex> Supabase.Client.Storage.Hostname.transform_storage_url("https://abc123.supabase.in/storage/v1")
"https://abc123.storage.supabase.in/storage/v1"
iex> Supabase.Client.Storage.Hostname.transform_storage_url("https://abc123.storage.supabase.co/storage/v1")
"https://abc123.storage.supabase.co/storage/v1"
iex> Supabase.Client.Storage.Hostname.transform_storage_url("https://custom-domain.com/storage/v1")
"https://custom-domain.com/storage/v1"
iex> Supabase.Client.Storage.Hostname.transform_storage_url("http://localhost:54321/storage/v1")
"http://localhost:54321/storage/v1"
"""
@supabase_domain_regex ~r/\.supabase\.(co|in|red)$/
@storage_subdomain_regex ~r/storage\.supabase\./
@doc """
Transforms a storage URL to use the storage subdomain if applicable.
This function only transforms official Supabase domains that don't already
have the storage subdomain. Custom domains and non-Supabase URLs are returned
unchanged.
## Parameters
- `storage_url` - The storage URL to transform (string)
## Returns
The transformed URL as a string. If transformation is not applicable,
returns the original URL unchanged.
## Examples
iex> Supabase.Client.Storage.Hostname.transform_storage_url("https://project.supabase.co/storage/v1")
"https://project.storage.supabase.co/storage/v1"
iex> Supabase.Client.Storage.Hostname.transform_storage_url("https://project.storage.supabase.co/storage/v1")
"https://project.storage.supabase.co/storage/v1"
iex> Supabase.Client.Storage.Hostname.transform_storage_url("https://custom.example.com/storage/v1")
"https://custom.example.com/storage/v1"
iex> Supabase.Client.Storage.Hostname.transform_storage_url(nil)
nil
"""
@spec transform_storage_url(String.t() | nil) :: String.t() | nil
def transform_storage_url(nil), do: nil
def transform_storage_url(""), do: ""
def transform_storage_url(storage_url) when is_binary(storage_url) do
uri = URI.parse(storage_url)
if should_transform?(uri) do
new_host = transform_hostname(uri.host)
%{uri | host: new_host} |> URI.to_string()
else
storage_url
end
end
# Private helper functions
defp should_transform?(%URI{host: host}) when is_binary(host) do
supabase_domain?(host) and not has_storage_subdomain?(host)
end
defp should_transform?(_), do: false
defp supabase_domain?(hostname) when is_binary(hostname) do
Regex.match?(@supabase_domain_regex, hostname)
end
defp has_storage_subdomain?(hostname) when is_binary(hostname) do
Regex.match?(@storage_subdomain_regex, hostname)
end
defp transform_hostname(hostname) when is_binary(hostname) do
String.replace(hostname, "supabase.", "storage.supabase.", global: false)
end
end