70 lines
1.7 KiB
Elixir
70 lines
1.7 KiB
Elixir
defmodule BDS.Scripts do
|
|
@moduledoc false
|
|
|
|
import Ecto.Query
|
|
|
|
alias BDS.Repo
|
|
alias BDS.Scripts.Script
|
|
alias BDS.Slug
|
|
|
|
def create_script(attrs) do
|
|
now = System.system_time(:second)
|
|
project_id = attr(attrs, :project_id)
|
|
title = attr(attrs, :title) || ""
|
|
kind = attr(attrs, :kind)
|
|
|
|
%Script{}
|
|
|> Script.changeset(%{
|
|
id: Ecto.UUID.generate(),
|
|
project_id: project_id,
|
|
slug: unique_slug(project_id, Slug.slugify(title), "script"),
|
|
title: title,
|
|
kind: kind,
|
|
entrypoint: attr(attrs, :entrypoint) || default_entrypoint(kind),
|
|
enabled: true,
|
|
version: 1,
|
|
file_path: "",
|
|
status: :draft,
|
|
content: attr(attrs, :content),
|
|
created_at: now,
|
|
updated_at: now
|
|
})
|
|
|> Repo.insert()
|
|
end
|
|
|
|
defp default_entrypoint(:macro), do: "render"
|
|
defp default_entrypoint(_kind), do: "main"
|
|
|
|
defp unique_slug(project_id, base_slug, fallback) do
|
|
normalized = if base_slug in [nil, ""], do: fallback, else: base_slug
|
|
|
|
if slug_available?(project_id, normalized) do
|
|
normalized
|
|
else
|
|
find_unique_slug(project_id, normalized, 2)
|
|
end
|
|
end
|
|
|
|
defp find_unique_slug(project_id, base_slug, suffix) do
|
|
candidate = "#{base_slug}-#{suffix}"
|
|
|
|
if slug_available?(project_id, candidate) do
|
|
candidate
|
|
else
|
|
find_unique_slug(project_id, base_slug, suffix + 1)
|
|
end
|
|
end
|
|
|
|
defp slug_available?(project_id, slug) do
|
|
not Repo.exists?(from script in Script, where: script.project_id == ^project_id and script.slug == ^slug)
|
|
end
|
|
|
|
defp attr(attrs, key) do
|
|
cond do
|
|
Map.has_key?(attrs, key) -> Map.get(attrs, key)
|
|
Map.has_key?(attrs, Atom.to_string(key)) -> Map.get(attrs, Atom.to_string(key))
|
|
true -> nil
|
|
end
|
|
end
|
|
end
|