defmodule OeditusCredo.Check.Warning.MissingThrottle do use Credo.Check, base_priority: :low, category: :warning, explanations: [ check: """ Form inputs with phx-change, phx-keyup, or phx-input should include phx-debounce or phx-throttle. This prevents excessive server events and improves performance. Bad: Good: """, params: [] ] @trigger_events ["phx-change", "phx-keyup", "phx-input"] @throttle_attrs ["phx-debounce", "phx-throttle"] @doc false @impl true def run(%SourceFile{} = source_file, params) do issue_meta = IssueMeta.for(source_file, params) if heex_file?(source_file) do source_file |> Credo.Code.to_lines() |> check_for_missing_throttle(issue_meta) else [] end end defp heex_file?(%SourceFile{filename: filename}) do String.ends_with?(filename, [".heex", ".leex"]) end defp check_for_missing_throttle(lines, issue_meta) do lines |> Enum.with_index(1) |> Enum.flat_map(fn {{_, line}, line_no} -> if has_trigger_event?(line) and not has_throttle?(line) do [issue_for(issue_meta, line_no)] else [] end end) end defp has_trigger_event?(line) do Enum.any?(@trigger_events, &String.contains?(line, &1)) end defp has_throttle?(line) do Enum.any?(@throttle_attrs, &String.contains?(line, &1)) end defp issue_for(issue_meta, line_no) do format_issue( issue_meta, message: "Add phx-debounce or phx-throttle to prevent excessive server events", trigger: "phx-change", line_no: line_no ) end end