Packages

CKEditor 5 integration for Phoenix Framework

Retired package: Renamed - Moved to ckeditor5-phoenix

Current section

Files

Jump to
ckeditor5 lib cloud cloud.ex
Raw

lib/cloud/cloud.ex

defmodule CKEditor5.Cloud do
@moduledoc """
Represents the Cloud configuration for a CKEditor 5 preset.
"""
import Norm
alias CKEditor5.Cloud.CKBox
alias CKEditor5.{Errors, Helpers}
@default_editor_version Mix.Project.config()[:cke][:default_cloud_editor_version]
@derive Jason.Encoder
@type t :: %__MODULE__{
version: String.t(),
premium: boolean(),
translations: [String.t()],
ckbox: CKBox.t() | nil
}
defstruct version: @default_editor_version,
premium: false,
translations: [],
ckbox: nil
@doc """
Defines the schema for a raw Cloud configuration map.
"""
def s do
schema(%{
version: spec(is_binary() and (&Helpers.is_semver_version?/1)),
premium: spec(is_boolean()),
ckbox: spec(is_map() or is_nil()),
translations: coll_of(spec(is_binary))
})
end
@doc """
Returns default values for Cloud configuration.
"""
def defaults do
%{
version: @default_editor_version,
premium: false,
translations: [],
ckbox: nil
}
end
@doc """
Parses a map into a Cloud struct.
Returns {:ok, %Cloud{}} if valid, {:error, reason} if invalid.
"""
def parse(nil), do: {:ok, nil}
def parse(map) when is_map(map) do
with {:ok, _} <- conform(map, s()),
{:ok, parsed_map} <- parse_ckbox(map) do
{:ok, build_struct(parsed_map)}
else
{:error, errors} -> {:error, errors}
end
end
def parse(_), do: {:error, "Cloud configuration must be a map or nil"}
@doc """
Parses a map into a Cloud struct.
Returns %Cloud{} if valid, raises an error if invalid.
"""
def parse!(cloud_data) do
case parse(cloud_data) do
{:ok, cloud} -> cloud
{:error, reason} -> raise Errors.InvalidCloudConfiguration, reason: reason
end
end
@doc """
Builds a Cloud struct with default values, allowing for overrides.
"""
def build_struct(overrides \\ %{}) do
defaults = defaults()
%__MODULE__{
version: Map.get(overrides, :version, defaults.version),
premium: Map.get(overrides, :premium, defaults.premium),
translations: Map.get(overrides, :translations, defaults.translations),
ckbox: Map.get(overrides, :ckbox, defaults.ckbox)
}
end
@doc """
Merges the current Cloud configuration with the provided overrides.
"""
def merge(nil, overrides) when is_map(overrides) do
build_struct(overrides)
end
def merge(%__MODULE__{}, nil), do: nil
def merge(%__MODULE__{} = cloud, overrides) when is_map(overrides) do
merged_ckbox = CKBox.merge(cloud.ckbox, Map.get(overrides, :ckbox))
%__MODULE__{
version: Map.get(overrides, :version, cloud.version),
premium: Map.get(overrides, :premium, cloud.premium),
translations: [Map.get(overrides, :translations, []) | cloud.translations],
ckbox: merged_ckbox
}
end
# Parses the CKBox configuration from a map.
defp parse_ckbox(%{ckbox: nil} = map), do: {:ok, Map.put(map, :ckbox, nil)}
defp parse_ckbox(%{ckbox: ckbox_data} = map) do
case CKBox.parse(ckbox_data) do
{:ok, ckbox} -> {:ok, Map.put(map, :ckbox, ckbox)}
{:error, error} -> {:error, error}
end
end
defp parse_ckbox(map), do: {:ok, map}
end