rest_framework 0.3.7 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dfa62b5fb49a4c30fabee7308e785d495f244b8aec21be6d5fc99bf0f2f8a3aa
4
- data.tar.gz: 65e70b6fd5eb3b1d06d54da6044035f1ca418f440b666e81bc7fee7d89ff0e7b
3
+ metadata.gz: bd9117c7f8ec6e09424fd35946ede97fe1173cc010d77ef5da97328f1f5a555a
4
+ data.tar.gz: cd79a9d89862fdb60f14d6a17c03f9447d639ff794b0869e4cb8149c84755d4d
5
5
  SHA512:
6
- metadata.gz: 2e92adef73b6fe78b9381480015c950b20e8a14e91a49f24b655e4f58a7ba1870e4d7d5b33a1983be514e50215a6c1a8e2197e1008faf4eae4b2da16072ddde0
7
- data.tar.gz: 27bc294410be0d235db8fccd20bc48b013a9814a0ac3b26fc01f5f7f46905738f6a65dd3fcdf4d54946b70cdeb9eb11c60b33139b169bd83ff8d4cbad76aaf60
6
+ metadata.gz: d3958f44f171649a7f2d4a92aa8d21b8375bb18532ca53af723cb64cc6f3bdbe0842784fc4dcb5a3ac715327731f030437c37cec7cb10604a8f44b5f260f49c7
7
+ data.tar.gz: 7fda99d8ef74d689091b0ab971d1256bcef1c745f696a7a2af0a93c37aaebfd05abbfd111ec676d6d2c9ee104764d83cf3c994b7fa33f5a2411d57f181c5a121
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.7
1
+ 0.4.0
@@ -29,14 +29,14 @@
29
29
  <ul class="nav nav-tabs">
30
30
  <% if @json_payload %>
31
31
  <li class="nav-item">
32
- <a class="nav-link active" href="#tab-json" data-toggle="tab" role="tab">
32
+ <a class="nav-link active" href="#tab-json" data-bs-toggle="tab" role="tab">
33
33
  .json
34
34
  </a>
35
35
  </li>
36
36
  <% end %>
37
37
  <% if @xml_payload %>
38
38
  <li class="nav-item">
39
- <a class="nav-link" href="#tab-xml" data-toggle="tab" role="tab">
39
+ <a class="nav-link" href="#tab-xml" data-bs-toggle="tab" role="tab">
40
40
  .xml
41
41
  </a>
42
42
  </li>
@@ -57,7 +57,7 @@
57
57
  </div>
58
58
  </div>
59
59
  <% end %>
60
- <% unless @routes.blank? %>
60
+ <% unless @route_groups.blank? %>
61
61
  <div class="row">
62
62
  <h2>Routes</h2>
63
63
  <%= render partial: 'rest_framework/routes' %>
@@ -1,11 +1,12 @@
1
1
  <meta charset="utf-8">
2
- <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
2
+ <meta name="viewport" content="width=device-width, initial-scale=1">
3
3
  <%= csrf_meta_tags %>
4
4
  <%= csp_meta_tag rescue nil %>
5
5
 
6
- <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
7
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.2.0/styles/vs.min.css" integrity="sha512-aWjgJTbdG4imzxTxistV5TVNffcYGtIQQm2NBNahV6LmX14Xq9WwZTL1wPjaSglUuVzYgwrq+0EuI4+vKvQHHw==" crossorigin="anonymous" />
6
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
7
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.2.0/styles/vs.min.css" integrity="sha512-aWjgJTbdG4imzxTxistV5TVNffcYGtIQQm2NBNahV6LmX14Xq9WwZTL1wPjaSglUuVzYgwrq+0EuI4+vKvQHHw==" crossorigin="anonymous">
8
8
  <style>
9
+ /* Adjust headers to always take up their entire row, and tweak the sizing. */
9
10
  h1,h2,h3,h4,h5,h6 { width: 100%; font-weight: normal; }
10
11
  h1 { font-size: 2rem; }
11
12
  h2 { font-size: 1.7rem; }
@@ -13,11 +14,27 @@
13
14
  h4 { font-size: 1.3rem; }
14
15
  h5 { font-size: 1.1rem; }
15
16
  h6 { font-size: 1rem; }
17
+
18
+ /* Make route group expansion obvious to the user. */
19
+ .rrf-routes .rrf-route-group-header {
20
+ background-color: #f8f8f8;
21
+ }
22
+ .rrf-routes .rrf-route-group-header:hover {
23
+ background-color: #f0f0f0;
24
+ }
25
+ .rrf-routes .rrf-route-group-header td {
26
+ cursor: pointer;
27
+ }
28
+
29
+ /* Disable bootstrap's collapsing animation because in tables it causes delayed jerkiness. */
30
+ .rrf-routes .collapsing {
31
+ -webkit-transition: none;
32
+ transition: none;
33
+ display: none;
34
+ }
16
35
  </style>
17
36
 
18
- <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
19
- <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
20
- <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
37
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ" crossorigin="anonymous"></script>
21
38
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.2.0/highlight.min.js" integrity="sha512-TDKKr+IvoqZnPzc3l35hdjpHD0m+b2EC2SrLEgKDRWpxf2rFCxemkgvJ5kfU48ip+Y+m2XVKyOCD85ybtlZDmw==" crossorigin="anonymous"></script>
22
39
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.2.0/languages/json.min.js" integrity="sha512-FoN8JE+WWCdIGXAIT8KQXwpiavz0Mvjtfk7Rku3MDUNO0BDCiRMXAsSX+e+COFyZTcDb9HDgP+pM2RX12d4j+A==" crossorigin="anonymous"></script>
23
40
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.2.0/languages/xml.min.js" integrity="sha512-dICltIgnUP+QSJrnYGCV8943p3qSDgvcg2NU4W8IcOZP4tdrvxlXjbhIznhtVQEcXow0mOjLM0Q6/NvZsmUH4g==" crossorigin="anonymous"></script>
@@ -1,18 +1,36 @@
1
- <table class="table">
2
- <thead>
3
- <tr>
4
- <th scope="col">Verb</th>
5
- <th scope="col">Path</th>
6
- <th scope="col">Action</th>
7
- </tr>
8
- </thead>
9
- <tbody>
10
- <% @routes.each do |r| %>
11
- <tr>
12
- <td><%= r[:verb] %></td>
13
- <td><%= r[:path] %></td>
14
- <td><%= r[:action] %></td>
15
- </tr>
1
+ <div class="table-responsive">
2
+ <table class="table table-responsive rrf-routes">
3
+ <thead>
4
+ <tr>
5
+ <th scope="col">Path</th>
6
+ <th scope="col">Verb</th>
7
+ <th scope="col">Controller#Action</th>
8
+ </tr>
9
+ </thead>
10
+ <%# Render first group of routes directly. %>
11
+ <tbody>
12
+ <% @route_groups.values[0].each do |route| %>
13
+ <tr>
14
+ <td><%= route[:path] %></td>
15
+ <td><%= route[:verb] %></td>
16
+ <td><%= route[:controller] %>#<%= route[:action] %></td>
17
+ </tr>
18
+ <% end %>
19
+ </tbody>
20
+ <%# Render any other groups under dropdowns. %>
21
+ <% @route_groups.drop(1).each_with_index do |(name, route_group), index| %>
22
+ <tr data-bs-toggle="collapse" data-bs-target="#route-group-<%= index %>" class="rrf-route-group-header">
23
+ <td colspan="3" class="text-center user-select-none"><%= name %></td>
24
+ </tr>
25
+ <tbody id="route-group-<%= index %>" class="collapse" style="padding: 0">
26
+ <% route_group.each do |route| %>
27
+ <tr>
28
+ <td><%= route[:path] %></td>
29
+ <td><%= route[:verb] %></td>
30
+ <td><%= route[:controller] %>#<%= route[:action] %></td>
31
+ </tr>
32
+ <% end %>
33
+ </tbody>
16
34
  <% end %>
17
- </tbody>
18
- </table>
35
+ </table>
36
+ </div>
@@ -1,5 +1,6 @@
1
1
  require_relative '../errors'
2
2
  require_relative '../serializers'
3
+ require_relative '../utils'
3
4
 
4
5
 
5
6
  # This module provides the common functionality for any controller mixins, a `root` action, and
@@ -121,22 +122,6 @@ module RESTFramework::BaseControllerMixin
121
122
  }, status: 406)
122
123
  end
123
124
 
124
- # Helper for showing routes under a controller action, used for the browsable API.
125
- def _get_routes
126
- begin
127
- formatter = ActionDispatch::Routing::ConsoleFormatter::Sheet
128
- rescue NameError
129
- # :nocov:
130
- formatter = ActionDispatch::Routing::ConsoleFormatter
131
- # :nocov:
132
- end
133
- return ActionDispatch::Routing::RoutesInspector.new(Rails.application.routes.routes).format(
134
- formatter.new
135
- ).lines.drop(1).map { |r| r.split.last(3) }.map { |r|
136
- {verb: r[0], path: r[1], action: r[2]}
137
- }.select { |r| r[:path].start_with?(request.path) }
138
- end
139
-
140
125
  # Helper to render a browsable API for `html` format, along with basic `json`/`xml` formats, and
141
126
  # with support or passing custom `kwargs` to the underlying `render` calls.
142
127
  def api_response(payload, html_kwargs: nil, **kwargs)
@@ -178,7 +163,7 @@ module RESTFramework::BaseControllerMixin
178
163
  end
179
164
  @template_logo_text ||= "Rails REST Framework"
180
165
  @title ||= self.controller_name.camelize
181
- @routes ||= self._get_routes
166
+ @route_groups ||= RESTFramework::Utils::get_routes(Rails.application.routes, request)
182
167
  hkwargs = kwargs.merge(html_kwargs)
183
168
  begin
184
169
  render(**hkwargs)
@@ -1,43 +1,8 @@
1
1
  require 'action_dispatch/routing/mapper'
2
-
2
+ require_relative 'utils'
3
3
 
4
4
  module ActionDispatch::Routing
5
5
  class Mapper
6
- # Internal helper to take extra_actions hash and convert to a consistent format.
7
- protected def _parse_extra_actions(extra_actions)
8
- return (extra_actions || {}).map do |k,v|
9
- kwargs = {action: k}
10
- path = k
11
-
12
- # Convert structure to path/methods/kwargs.
13
- if v.is_a?(Hash) # allow kwargs
14
- v = v.symbolize_keys
15
-
16
- # Ensure methods is an array.
17
- if v[:methods].is_a?(String) || v[:methods].is_a?(Symbol)
18
- methods = [v.delete(:methods)]
19
- else
20
- methods = v.delete(:methods)
21
- end
22
-
23
- # Override path if it's provided.
24
- if v.key?(:path)
25
- path = v.delete(:path)
26
- end
27
-
28
- # Pass any further kwargs to the underlying Rails interface.
29
- kwargs = kwargs.merge(v)
30
- elsif v.is_a?(Symbol) || v.is_a?(String)
31
- methods = [v]
32
- else
33
- methods = v
34
- end
35
-
36
- # Return a hash with keys: :path, :methods, :kwargs.
37
- {path: path, methods: methods, kwargs: kwargs}
38
- end
39
- end
40
-
41
6
  # Internal interface to get the controller class from the name and current scope.
42
7
  protected def _get_controller_class(name, pluralize: true, fallback_reverse_pluralization: true)
43
8
  # get class name
@@ -92,13 +57,13 @@ module ActionDispatch::Routing
92
57
  if controller.is_a?(Class)
93
58
  controller_class = controller
94
59
  else
95
- controller_class = _get_controller_class(controller, pluralize: !default_singular)
60
+ controller_class = self._get_controller_class(controller, pluralize: !default_singular)
96
61
  end
97
62
 
98
63
  # Set controller if it's not explicitly set.
99
64
  kwargs[:controller] = name unless kwargs[:controller]
100
65
 
101
- # determine plural/singular resource
66
+ # Determine plural/singular resource.
102
67
  force_singular = kwargs.delete(:force_singular)
103
68
  force_plural = kwargs.delete(:force_plural)
104
69
  if force_singular
@@ -118,14 +83,16 @@ module ActionDispatch::Routing
118
83
  public_send(resource_method, name, except: skip, **kwargs) do
119
84
  if controller_class.respond_to?(:extra_member_actions)
120
85
  member do
121
- actions = self._parse_extra_actions(controller_class.extra_member_actions)
122
- _route_extra_actions(actions)
86
+ actions = RESTFramework::Utils::parse_extra_actions(
87
+ controller_class.extra_member_actions
88
+ )
89
+ self._route_extra_actions(actions)
123
90
  end
124
91
  end
125
92
 
126
93
  collection do
127
- actions = self._parse_extra_actions(controller_class.extra_actions)
128
- _route_extra_actions(actions)
94
+ actions = RESTFramework::Utils::parse_extra_actions(controller_class.extra_actions)
95
+ self._route_extra_actions(actions)
129
96
  end
130
97
 
131
98
  yield if block_given?
@@ -160,14 +127,14 @@ module ActionDispatch::Routing
160
127
  kwargs[:controller] = name unless kwargs[:controller]
161
128
 
162
129
  # Route actions using the resourceful router, but skip all builtin actions.
163
- actions = self._parse_extra_actions(controller_class.extra_actions)
130
+ actions = RESTFramework::Utils::parse_extra_actions(controller_class.extra_actions)
164
131
  public_send(:resource, name, only: [], **kwargs) do
165
132
  # Route a root for this resource.
166
133
  if route_root_to
167
134
  get '', action: route_root_to
168
135
  end
169
136
 
170
- _route_extra_actions(actions, &block)
137
+ self._route_extra_actions(actions, &block)
171
138
  end
172
139
  end
173
140
 
@@ -0,0 +1,63 @@
1
+ module RESTFramework::Utils
2
+ # Helper to take extra_actions hash and convert to a consistent format:
3
+ # `{paths:, methods:, kwargs:}`.
4
+ def self.parse_extra_actions(extra_actions)
5
+ return (extra_actions || {}).map do |k,v|
6
+ kwargs = {action: k}
7
+ path = k
8
+
9
+ # Convert structure to path/methods/kwargs.
10
+ if v.is_a?(Hash) # allow kwargs
11
+ v = v.symbolize_keys
12
+
13
+ # Ensure methods is an array.
14
+ if v[:methods].is_a?(String) || v[:methods].is_a?(Symbol)
15
+ methods = [v.delete(:methods)]
16
+ else
17
+ methods = v.delete(:methods)
18
+ end
19
+
20
+ # Override path if it's provided.
21
+ if v.key?(:path)
22
+ path = v.delete(:path)
23
+ end
24
+
25
+ # Pass any further kwargs to the underlying Rails interface.
26
+ kwargs = kwargs.merge(v)
27
+ elsif v.is_a?(Symbol) || v.is_a?(String)
28
+ methods = [v]
29
+ else
30
+ methods = v
31
+ end
32
+
33
+ # Return a hash with keys: :path, :methods, :kwargs.
34
+ {path: path, methods: methods, kwargs: kwargs}
35
+ end
36
+ end
37
+
38
+ # Helper to get the current route pattern, stripped of the `(:format)` segment.
39
+ def self.get_route_pattern(application_routes, request)
40
+ application_routes.router.recognize(request) do |route, _, _|
41
+ return route.path.spec.to_s.gsub(/\(\.:format\)$/, '')
42
+ end
43
+ end
44
+
45
+ # Helper for showing routes under a controller action, used for the browsable API.
46
+ def self.get_routes(application_routes, request)
47
+ current_pattern = self.get_route_pattern(application_routes, request)
48
+ current_subdomain = request.subdomain.presence
49
+
50
+ # Return routes that match our current route subdomain/pattern, grouped by controller.
51
+ return application_routes.routes.map { |r|
52
+ {
53
+ verb: r.verb,
54
+ path: r.path.spec.to_s,
55
+ action: r.defaults[:action],
56
+ controller: r.defaults[:controller],
57
+ subdomain: r.defaults[:subdomain],
58
+ }
59
+ }.select { |r|
60
+ r[:subdomain] == current_subdomain && r[:path].start_with?(current_pattern)
61
+ }.group_by { |r| r[:controller] }
62
+ end
63
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rest_framework
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.7
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gregory N. Schmit
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-25 00:00:00.000000000 Z
11
+ date: 2021-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -49,6 +49,7 @@ files:
49
49
  - lib/rest_framework/paginators.rb
50
50
  - lib/rest_framework/routers.rb
51
51
  - lib/rest_framework/serializers.rb
52
+ - lib/rest_framework/utils.rb
52
53
  - lib/rest_framework/version.rb
53
54
  homepage: https://rails-rest-framework.com
54
55
  licenses: