summaryrefslogtreecommitdiff
path: root/lib/tasks/frontend
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tasks/frontend')
-rw-r--r--lib/tasks/frontend/routes.rake68
1 files changed, 68 insertions, 0 deletions
diff --git a/lib/tasks/frontend/routes.rake b/lib/tasks/frontend/routes.rake
new file mode 100644
index 00000000000..50669f00cc4
--- /dev/null
+++ b/lib/tasks/frontend/routes.rake
@@ -0,0 +1,68 @@
+Route = Struct.new(:name, :path, :has_params?) do
+ def <=> (other)
+ self.name <=> other.name
+ end
+end
+
+def placeholder_params_hash(params)
+ Hash[params.zip(params.map { |param| "${params.#{param.to_s.camelize(:lower)}}" })]
+end
+
+class InternalRouteGenerator
+ def self.path_for_route(route, params)
+ path = route.format(placeholder_params_hash(params))
+ path = path.gsub(/%7B(.+?)%7D/, '{\1}') # undo escaping of JavaScript placeholdes
+ path.gsub(/\.\$\{params.format\}$/, '') # we favor ?format=
+ end
+
+ def self.all
+ routes = Rails.application.routes.routes.named_routes
+ routes.map do |name, route|
+ params = route.parts
+ Route.new("#{name}_path", self.path_for_route(route, params), !params.empty?)
+ end
+ end
+end
+
+class ApiRouteGenerator
+ def self.path_for_route(route, params, api_version)
+ values = placeholder_params_hash(params).merge(version: api_version)
+ segments = route.path_segments_with_values(values).reject { |s| route.optional_segment?(s) }
+ '/' + segments.join('/')
+ end
+
+ def self.all
+ routes = Array(Grape::API.decorated_routes)
+ routes.flat_map do |route|
+ Array(route.route_options[:version]).map do |api_version|
+ params = route.route_options[:params].keys
+ name = route.path_helper_name({ version: api_version, format: route.extension })
+ Route.new(name, self.path_for_route(route, params, api_version), !params.empty?)
+ end
+ end
+ end
+end
+
+namespace :frontend do
+ task :routes do
+ def write_routes(file, routes)
+ routes.each do |route|
+ name = route.name.camelize(:lower)
+ path = "${baseUrl}#{route.path}"
+ if route.has_params?
+ file.puts "export const #{name} = params => `#{path}`;"
+ else
+ file.puts "export const #{name} = () => `#{path}`;"
+ end
+ end
+ end
+
+ all_routes = (InternalRouteGenerator.all + ApiRouteGenerator.all).uniq { |route| route.name }.sort
+ output_path = File.join(Rails.root, 'app', 'assets', 'javascripts', 'routes.js')
+ File.open(output_path, 'w') do |file|
+ file.puts '// This file was generated by bin/rake frontend:routes'
+ file.puts "const baseUrl = gon.relative_url_root || '';"
+ write_routes(file, all_routes)
+ end
+ end
+end