Packages

A library to validate conflicting routes in Phoenix applications.

Retired package: Deprecated - Renamed to phoenix_routes_validator

Current section

Files

Jump to
phoenix_route_validator lib phoenix_route_validator.ex
Raw

lib/phoenix_route_validator.ex

defmodule PhoenixRouteValidator do
@moduledoc """
Documentation for `PhoenixRouteValidator`.
"""
@doc """
Take a list of routes and returns a list of conflicting routes
"""
@spec find_conflicts(list()) :: list()
def find_conflicts(routes) do
map =
routes
|> Enum.with_index()
|> Enum.filter(fn {{_, route}, _} -> String.contains?(route, ":") end)
|> Enum.into(%{}, fn {route, index} ->
{index, route}
end)
conflicts =
Enum.map(map, fn {key, {dynamic_route_method, dynamic_route}} ->
dynamic_route_segments = String.split(dynamic_route, "/")
remaining_dynamic_route =
find_dynamic_segment_indexes(dynamic_route_segments)
|> delete_dynamic_parts(dynamic_route_segments)
matched_routes =
routes
|> Enum.with_index()
|> Enum.filter(fn {{method, route}, index} ->
if index > key do
route_segments = String.split(route, "/")
if length(dynamic_route_segments) == length(route_segments) do
remaining_route =
find_dynamic_segment_indexes(route_segments)
|> delete_dynamic_parts(route_segments)
remaining_route =
if remaining_route == route_segments do
{_, rem} = List.pop_at(remaining_route, -1)
rem
else
remaining_route
end
remaining_dynamic_route == remaining_route && method == dynamic_route_method
end
end
end)
{key, matched_routes}
end)
Enum.filter(conflicts, fn {_, matches} -> length(matches) > 0 end)
end
@spec find_dynamic_segment_indexes(list()) :: [integer()]
def find_dynamic_segment_indexes(route_segments) do
Enum.with_index(route_segments)
|> Enum.filter(fn {segment, _} -> String.contains?(segment, ":") end)
|> Enum.map(fn {_, index} -> index end)
end
@spec delete_dynamic_parts([integer()], list()) :: list()
def delete_dynamic_parts(indexes_to_remove, route_segments) do
route_segments
|> Enum.with_index()
|> Enum.reject(fn {_, index} -> index in indexes_to_remove end)
|> Enum.map(fn {segment, _} ->
segment
end)
end
end