module JsFromRoutes

Public: Automatically generates JS for Rails routes with { export: true }. Generates one file per controller, and one function per route.

Public: Automatically generates JS for Rails routes with { export: true }. Generates one file per controller, and one function per route.

Constants

VERSION

Public: This library adheres to semantic versioning.

Public Class Methods

config() { |config| ... } click to toggle source

Public: Configuration of the code generator.

# File lib/js_from_routes/generator.rb, line 131
def config
  @config ||= OpenStruct.new(default_config(::Rails.root || Pathname.new(Dir.pwd)))
  yield(@config) if block_given?
  @config
end
generate!(app_or_routes = Rails.application) click to toggle source

Public: Generates code for the specified routes with { export: true }.

# File lib/js_from_routes/generator.rb, line 138
def generate!(app_or_routes = Rails.application)
  raise ArgumentError, "A Rails app must be defined, or you must specify a custom `output_folder`" if config.output_folder.blank?
  rails_routes = app_or_routes.is_a?(::Rails::Engine) ? app_or_routes.routes.routes : app_or_routes
  generate_files exported_routes_by_controller(rails_routes)
end

Private Class Methods

default_config(root) click to toggle source
# File lib/js_from_routes/generator.rb, line 172
def default_config(root)
  dir = %w[frontend packs javascript assets].find { |dir| root.join("app", dir).exist? }
  {
    all_helpers_file: true,
    client_library: "@js-from-routes/client",
    file_suffix: "Api.js",
    helper_mappings: {"index" => "list", "show" => "get"},
    output_folder: root.join("app", dir, "api"),
    template_path: File.expand_path("template.js.erb", __dir__),
    template_all_path: File.expand_path("template_all.js.erb", __dir__),
    template_index_path: File.expand_path("template_index.js.erb", __dir__),
  }
end
exported_routes_by_controller(routes) click to toggle source

Internal: Returns exported routes grouped by controller name.

# File lib/js_from_routes/generator.rb, line 187
def exported_routes_by_controller(routes)
  routes.select { |route|
    route.defaults.fetch(:export, false)
  }.group_by { |route|
    route.requirements.fetch(:controller)
  }
end
generate_file_for_all(routes) click to toggle source
# File lib/js_from_routes/generator.rb, line 155
def generate_file_for_all(routes)
  return unless config.all_helpers_file && !routes.empty?

  preferred_extension = File.extname(config.file_suffix)
  index_file = config.all_helpers_file == true ? "index#{preferred_extension}" : config.all_helpers_file

  Template.new(config.template_all_path).write_if_changed OpenStruct.new(
    cache_key: routes.map(&:import_filename).join + File.read(config.template_all_path),
    filename: config.output_folder.join("all#{preferred_extension}"),
    helpers: routes,
  )
  Template.new(config.template_index_path).write_if_changed OpenStruct.new(
    cache_key: File.read(config.template_index_path),
    filename: config.output_folder.join(index_file),
  )
end
generate_files(exported_routes) click to toggle source
# File lib/js_from_routes/generator.rb, line 146
def generate_files(exported_routes)
  template = Template.new(config.template_path)
  generate_file_for_all exported_routes.map { |controller, routes|
    ControllerRoutes.new(controller, routes, config).tap do |routes|
      template.write_if_changed routes
    end
  }
end