# frozen_string_literal: true module RailsDevtools module Routes class Collection def self.all new.all end def self.find(id) new.find(id) end def all return @all if defined?(@all) @all = [] @current_id = 0 add_routes(app_routes, engine_name: "Application") process_engine_routes(rails_routes) @all end def find(id) all.find { |route| route.id == id.to_i } end private def add_routes(routes, engine_name:) routes.each do |route| @current_id += 1 @all << Routes::RouteInfo.new(route, engine: engine_name, id: @current_id) end end def process_engine_routes(routes) routes.select { |r| r.app.engine? && r.app.app.name != "RailsDevtools::Engine" }.each do |engine_route| engine = engine_route.app.app process_single_engine(engine: engine) end end def process_single_engine(engine:) valid_engine_routes = engine.routes.routes.select { |r| valid_route?(r) } add_routes(valid_engine_routes, engine_name: engine.name) nested_routes = engine.routes.routes nested_routes.select { |r| r.app.respond_to?(:engine?) && r.app.engine? }.each do |nested_engine_route| nested_engine = nested_engine_route.app.app process_single_engine(engine: nested_engine) end end def app_routes rails_routes.select { |r| valid_route?(r) } end def valid_route?(route) wrapped_route = ActionDispatch::Routing::RouteWrapper.new(route) !rails_route?(wrapped_route) && !turbo_route?(wrapped_route) && !wrapped_route.internal? end def rails_routes @rails_routes ||= Rails.application.routes.routes end def rails_route?(route) return true if route.path.include?("rails/") route.name&.include?("rails") end def turbo_route?(route) route.name&.start_with?("turbo") end end end end