defmodule BDS.PreviewAssets do @moduledoc false @preview_root Application.app_dir(:bds, "priv/preview_assets") def response(pathname) when is_binary(pathname) do pathname |> request_path() |> case do {:ok, relative_path} -> case File.read(Path.join(@preview_root, relative_path)) do {:ok, body} -> {:ok, %{content_type: content_type(relative_path), body: body}} {:error, _reason} -> :error end :error -> :error end end def generated_outputs do ["assets", "images"] |> Enum.flat_map(fn directory -> @preview_root |> Path.join(directory) |> Path.join("**/*") |> Path.wildcard(match_dot: false) end) |> Enum.filter(&File.regular?/1) |> Enum.sort() |> Enum.flat_map(fn path -> case File.read(path) do {:ok, contents} -> [{Path.relative_to(path, @preview_root), contents}] {:error, _reason} -> [] end end) end def stylesheet_href(nil), do: "/assets/pico.min.css" def stylesheet_href(""), do: "/assets/pico.min.css" def stylesheet_href("default"), do: "/assets/pico.min.css" def stylesheet_href(theme), do: "/assets/pico.#{theme}.min.css" defp request_path(pathname) do normalized = pathname |> URI.parse() |> Map.get(:path, pathname) case String.split(normalized, "/", trim: true) do [directory, filename] when directory in ["assets", "images"] -> relative_path = Path.join(directory, filename) if File.regular?(Path.join(@preview_root, relative_path)) do {:ok, relative_path} else :error end _other -> :error end end defp content_type(path) do case Path.extname(path) do ".css" -> "text/css" ".js" -> "application/javascript" ".png" -> "image/png" ".gif" -> "image/gif" ".jpg" -> "image/jpeg" ".jpeg" -> "image/jpeg" _other -> "application/octet-stream" end end end