fix: add @spec to all public functions across 24 modules (CSM-019)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-10 11:40:42 +02:00
parent 3f77488e33
commit b6f9cf58e1
24 changed files with 150 additions and 3 deletions

View File

@@ -1,8 +1,10 @@
defmodule BDS.Rendering.FileSystem do
@moduledoc false
@type t :: %__MODULE__{root_paths: [String.t()]}
defstruct [:root_paths]
@spec new([String.t()] | String.t()) :: t()
def new(root_paths) when is_list(root_paths) do
%__MODULE__{root_paths: Enum.uniq(root_paths)}
end
@@ -11,6 +13,7 @@ defmodule BDS.Rendering.FileSystem do
new([root_path])
end
@spec full_path(t(), String.t()) :: String.t()
def full_path(%__MODULE__{root_paths: root_paths}, template_path) do
normalized_path = to_string(template_path)

View File

@@ -5,6 +5,7 @@ defmodule BDS.Rendering.Filters do
alias BDS.Slug
@spec i18n(term(), String.t(), Liquex.Context.t()) :: String.t()
def i18n(value, language, _context) do
key = value |> to_string() |> String.trim()
@@ -15,6 +16,16 @@ defmodule BDS.Rendering.Filters do
end
end
@spec markdown(
term(),
term(),
term(),
map(),
map(),
String.t(),
term(),
Liquex.Context.t()
) :: String.t()
def markdown(
value,
_post_id,
@@ -28,6 +39,8 @@ defmodule BDS.Rendering.Filters do
render_markdown(value, canonical_post_paths, canonical_media_paths, language, context)
end
@spec render_markdown(term(), map() | nil, map() | nil, String.t(), Liquex.Context.t()) ::
String.t()
def render_markdown(value, canonical_post_paths, canonical_media_paths, language, context) do
value
|> to_string()
@@ -36,6 +49,7 @@ defmodule BDS.Rendering.Filters do
|> rewrite_rendered_html_urls(canonical_post_paths || %{}, canonical_media_paths || %{})
end
@spec slugify(term(), Liquex.Context.t()) :: String.t()
def slugify(value, _context) do
value
|> to_string()

View File

@@ -8,6 +8,7 @@ defmodule BDS.Rendering.Labels do
use Gettext, backend: BDS.Gettext
@spec for_language(String.t()) :: map()
def for_language(language) do
Gettext.with_locale(BDS.Gettext, language, fn ->
%{
@@ -34,6 +35,7 @@ defmodule BDS.Rendering.Labels do
end)
end
@spec month_name(integer() | nil, String.t()) :: String.t() | nil
def month_name(nil, _language), do: nil
def month_name(1, language) do

View File

@@ -9,6 +9,7 @@ defmodule BDS.Rendering.LinksAndLanguages do
alias BDS.Posts.Post
alias BDS.Repo
@spec canonical_post_path_by_slug(String.t(), String.t()) :: %{String.t() => String.t()}
def canonical_post_path_by_slug(project_id, main_language) do
posts =
Repo.all(
@@ -36,6 +37,7 @@ defmodule BDS.Rendering.LinksAndLanguages do
end)
end
@spec canonical_media_path_by_source_path(String.t()) :: %{String.t() => String.t()}
def canonical_media_path_by_source_path(project_id) do
Repo.all(from media in MediaAsset, where: media.project_id == ^project_id)
|> Enum.reduce(%{}, fn media, acc ->
@@ -54,6 +56,7 @@ defmodule BDS.Rendering.LinksAndLanguages do
end)
end
@spec post_path(map(), String.t() | nil) :: String.t()
def post_path(post, language_prefix)
when is_binary(language_prefix) and language_prefix != "" do
String.trim_trailing(language_prefix, "/") <> post_path(post, nil)
@@ -73,11 +76,15 @@ defmodule BDS.Rendering.LinksAndLanguages do
]) <> "/"
end
@spec post_path(map(), String.t() | nil, String.t()) :: String.t()
def post_path(post, language, main_language) do
prefix = language_prefix(language, main_language)
post_path(post, prefix)
end
@spec link_contexts(String.t() | nil, String.t() | nil, :incoming | :outgoing, String.t()) :: [
map()
]
def link_contexts(_project_id, nil, _direction, _main_language), do: []
def link_contexts(project_id, post_id, :incoming, main_language) do
@@ -113,10 +120,12 @@ defmodule BDS.Rendering.LinksAndLanguages do
end
end
@spec language_prefix(String.t() | nil, String.t()) :: String.t()
def language_prefix(language, main_language) when language == main_language, do: ""
def language_prefix(nil, _main_language), do: ""
def language_prefix(language, _main_language), do: "/#{language}"
@spec normalize_language(String.t() | nil, String.t()) :: String.t()
def normalize_language(nil, fallback), do: fallback
def normalize_language("", fallback), do: fallback

View File

@@ -10,6 +10,7 @@ defmodule BDS.Rendering.ListArchive do
alias BDS.Rendering.TemplateSelection
use Gettext, backend: BDS.Gettext
@spec list_assigns(String.t(), map()) :: map()
def list_assigns(project_id, assigns) do
metadata = RenderMetadata.project_metadata(project_id)
template_context = TemplateSelection.template_render_context(project_id)
@@ -114,6 +115,7 @@ defmodule BDS.Rendering.ListArchive do
}
end
@spec not_found_assigns(String.t(), map()) :: map()
def not_found_assigns(project_id, assigns) do
metadata = RenderMetadata.project_metadata(project_id)

View File

@@ -14,16 +14,19 @@ defmodule BDS.Rendering.Metadata do
alias BDS.Posts.Translation
alias BDS.Tags.Tag
@spec project_metadata(String.t()) :: map()
def project_metadata(project_id) do
{:ok, metadata} = ProjectMetadata.get_project_metadata(project_id)
metadata
end
@spec menu_items(String.t()) :: [map()]
def menu_items(project_id) do
{:ok, %{items: items}} = Menu.get_menu(project_id)
Enum.map(items, &to_template_menu_item/1)
end
@spec menu_items_from_raw([map()]) :: [map()]
def menu_items_from_raw(items) when is_list(items) do
Enum.map(items, &to_template_menu_item/1)
end
@@ -52,6 +55,7 @@ defmodule BDS.Rendering.Metadata do
defp menu_item_href(%{kind: :submenu}), do: "#"
defp menu_item_href(_item), do: "#"
@spec blog_languages(map(), String.t()) :: [map()]
def blog_languages(metadata, current_language) do
([metadata.main_language] ++ (metadata.blog_languages || []))
|> Enum.reject(&(&1 in [nil, ""]))
@@ -72,11 +76,13 @@ defmodule BDS.Rendering.Metadata do
end)
end
@spec tag_color_by_name(String.t()) :: %{String.t() => String.t() | nil}
def tag_color_by_name(project_id) do
Repo.all(from tag in Tag, where: tag.project_id == ^project_id, select: {tag.name, tag.color})
|> Enum.into(%{}, fn {name, color} -> {name, color} end)
end
@spec alternate_links(Post.t() | nil, String.t(), String.t()) :: [map()]
def alternate_links(nil, _project_id, _main_language), do: []
def alternate_links(%Post{} = post, project_id, main_language) do
@@ -104,22 +110,27 @@ defmodule BDS.Rendering.Metadata do
end)
end
@spec backlinks([map()]) :: [map()]
def backlinks(incoming_links) do
Enum.map(incoming_links, fn link ->
%{path: link.href, display_slug: link.display_slug, title: link.title}
end)
end
@spec default_pico_stylesheet_href(String.t() | nil) :: String.t()
def default_pico_stylesheet_href(theme), do: PreviewAssets.stylesheet_href(theme)
@spec href_for_language(String.t()) :: String.t()
def href_for_language(""), do: "/"
def href_for_language(prefix), do: String.trim_trailing(prefix, "/") <> "/"
@spec calendar_initial_year(map() | nil) :: integer() | nil
def calendar_initial_year(%{created_at: created_at}) when is_integer(created_at),
do: Persistence.from_unix_ms!(created_at).year
def calendar_initial_year(_post), do: nil
@spec calendar_initial_month(map() | nil) :: integer() | nil
def calendar_initial_month(%{created_at: created_at}) when is_integer(created_at),
do: Persistence.from_unix_ms!(created_at).month

View File

@@ -13,6 +13,7 @@ defmodule BDS.Rendering.PostRendering do
alias BDS.Posts.Translation
alias BDS.Repo
@spec post_assigns(String.t(), map()) :: map()
def post_assigns(project_id, assigns) do
metadata = RenderMetadata.project_metadata(project_id)
template_context = TemplateSelection.template_render_context(project_id)
@@ -180,6 +181,7 @@ defmodule BDS.Rendering.PostRendering do
end
end
@spec post_data_json_value(map()) :: String.t()
def post_data_json_value(post_context) do
case Jason.encode(%{
id: Map.get(post_context, :id),
@@ -238,6 +240,13 @@ defmodule BDS.Rendering.PostRendering do
}
end
@spec render_post_content(
String.t() | nil,
map(),
map(),
String.t(),
Liquex.Context.t()
) :: String.t()
def render_post_content(
content,
canonical_post_paths,

View File

@@ -11,6 +11,8 @@ defmodule BDS.Rendering.TemplateSelection do
alias BDS.StarterTemplates
alias BDS.Templates.Template
@spec load_template_source(String.t(), atom(), String.t() | nil) ::
{:ok, String.t()} | {:error, term()}
def load_template_source(project_id, kind, slug) do
project = Projects.get_project!(project_id)
@@ -88,6 +90,8 @@ defmodule BDS.Rendering.TemplateSelection do
end
end
@spec render_template(String.t(), String.t(), map()) ::
{:ok, String.t()} | {:error, String.t()}
def render_template(project_id, source, assigns) do
with {:ok, template_ast} <- Liquex.parse(source) do
project = Projects.get_project!(project_id)
@@ -145,6 +149,7 @@ defmodule BDS.Rendering.TemplateSelection do
defp bundled_template_slug(_kind, slug) when is_binary(slug) and slug != "", do: slug
defp bundled_template_slug(kind, _slug), do: StarterTemplates.default_slug(kind)
@spec template_render_context(String.t()) :: Liquex.Context.t()
def template_render_context(project_id) do
project = Projects.get_project!(project_id)