media_types-serialization 0.6.2 → 0.7.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e372ca567cb0169a0f1b497cb3f287f8ad8d83aa6416eb5c6cfcdfe6d6ca3774
4
- data.tar.gz: ae99ee2759337f6f196014556e508859bc0fa942e16acd9b1b582a7637bd3938
3
+ metadata.gz: 9d865beb9427149817eab4cefff9778571c295259c1779351fd720d46276f312
4
+ data.tar.gz: c96c8372252d7f832028870ea74bfb1972a0f7c56325fa38492a81f21df17fab
5
5
  SHA512:
6
- metadata.gz: ba7aa0f87e556d4304ec040b1f875749ddf2ec580467458d19058294b3ac54816b5d24d5915a64303b0d0a275b2bb6d24fa5e195958267753c93cb7e2de6542a
7
- data.tar.gz: f0fbb8190ebbde45274b43336a631ac5c0f0ee38ff1f336c3a308efd75e35b927c754eebc49b019179b05076f293b03316895d2d1ac36b8ea5d4fc5b6f64dfe6
6
+ metadata.gz: 1204aaa35637f97fafca495a691d2f07524e2e85c7742ebcf94ae6869e38cea9b4a0fa152bca0274aa1db86a43dd377ef98b49036fedae4e2f1b964663e6c444
7
+ data.tar.gz: cca3b6cfe51cfa3a0785e3f1dbe3d13b5c442d845171408e2e735940eb22aba6bfdefb5769d791e2908878150cd790366f43fc24006d23fce072def4cf43254d
@@ -43,13 +43,14 @@
43
43
  <orderEntry type="library" scope="PROVIDED" name="crass (v1.0.4, ruby-2.5.3-p105) [gem]" level="application" />
44
44
  <orderEntry type="library" scope="PROVIDED" name="erubi (v1.8.0, ruby-2.5.3-p105) [gem]" level="application" />
45
45
  <orderEntry type="library" scope="PROVIDED" name="globalid (v0.4.2, ruby-2.5.3-p105) [gem]" level="application" />
46
+ <orderEntry type="library" scope="PROVIDED" name="http_headers-accept (v0.2.2, ruby-2.5.3-p105) [gem]" level="application" />
46
47
  <orderEntry type="library" scope="PROVIDED" name="http_headers-link (v0.2.1, ruby-2.5.3-p105) [gem]" level="application" />
47
48
  <orderEntry type="library" scope="PROVIDED" name="http_headers-utils (v0.2.0, ruby-2.5.3-p105) [gem]" level="application" />
48
49
  <orderEntry type="library" scope="PROVIDED" name="i18n (v1.6.0, ruby-2.5.3-p105) [gem]" level="application" />
49
50
  <orderEntry type="library" scope="PROVIDED" name="loofah (v2.2.3, ruby-2.5.3-p105) [gem]" level="application" />
50
51
  <orderEntry type="library" scope="PROVIDED" name="mail (v2.7.1, ruby-2.5.3-p105) [gem]" level="application" />
51
52
  <orderEntry type="library" scope="PROVIDED" name="marcel (v0.3.3, ruby-2.5.3-p105) [gem]" level="application" />
52
- <orderEntry type="library" scope="PROVIDED" name="media_types (v0.6.1, ruby-2.5.3-p105) [gem]" level="application" />
53
+ <orderEntry type="library" scope="PROVIDED" name="media_types (v0.6.2, ruby-2.5.3-p105) [gem]" level="application" />
53
54
  <orderEntry type="library" scope="PROVIDED" name="method_source (v0.9.2, ruby-2.5.3-p105) [gem]" level="application" />
54
55
  <orderEntry type="library" scope="PROVIDED" name="mimemagic (v0.3.3, ruby-2.5.3-p105) [gem]" level="application" />
55
56
  <orderEntry type="library" scope="PROVIDED" name="mini_mime (v1.0.1, ruby-2.5.3-p105) [gem]" level="application" />
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.7.0.beta1
4
+
5
+ - 🐛 Fix non-serializer media types replacing known serializers
6
+ - 🐛 Fix passed in media type for HTML as fallback (actual type instead of html)
7
+ - 🐛 Fix passed in media type for API Viewer (actual type instead of API Viewer)
8
+ - 🐛 Fix migrations failing on versioning text/html
9
+ - 🐛 Fix HTML non-overwrite logic (first one wins, unless there is an override)
10
+ - ✨ Add `api_viewer_media_type` param for api viewers to set the serialization type
11
+ - ✨ Add api viewer links in the api viewer:
12
+ - For representations: use `.api_viewer` unless it's `.html`
13
+ - For body links: use .api_viewer unless it already has a `.format`
14
+ - For HTTP links: leave them alone
15
+
3
16
  ## 0.6.2
4
17
 
5
18
  - 🐛 Update `http_headers-accept`: 0.2.1 → 0.2.2
data/Gemfile.lock CHANGED
@@ -1,12 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- media_types-serialization (0.6.2)
4
+ media_types-serialization (0.7.0.beta1)
5
5
  actionpack (>= 4.0.0)
6
6
  activesupport (>= 4.0.0)
7
7
  http_headers-accept (>= 0.2.2, < 1.0.0)
8
8
  http_headers-link (< 1.0.0)
9
- media_types (>= 0.6.0)
9
+ media_types (>= 0.6.2)
10
10
  oj (>= 3.5.0)
11
11
 
12
12
  GEM
@@ -75,7 +75,7 @@ GEM
75
75
  mini_mime (>= 0.1.1)
76
76
  marcel (0.3.3)
77
77
  mimemagic (~> 0.3.2)
78
- media_types (0.6.1)
78
+ media_types (0.6.2)
79
79
  method_source (0.9.2)
80
80
  mimemagic (0.3.3)
81
81
  mini_mime (1.0.1)
@@ -9,7 +9,14 @@
9
9
  <%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
10
10
  <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
11
11
  </head>
12
-
12
+ <%
13
+ def replace_link(full_match)
14
+ href = full_match[9...-1]
15
+ '"href": "%s"' % link_to(href.gsub('%7B', '{').gsub('%7D', '}'), href).html_safe
16
+ rescue
17
+ full_match
18
+ end
19
+ %>
13
20
  <body class="container h-100" style="overflow: auto; justify-content: start">
14
21
 
15
22
  <%# Remove the # below to show a logo %>
@@ -65,10 +72,7 @@
65
72
  .gsub('<', '&lt;')
66
73
  .gsub('>', '&gt;')
67
74
  .gsub('\n', "<br>")%>
68
- <%= code.gsub(/"href": "(http(?:s?:\/\/.*?))"/) { |full_match|
69
- href = full_match[9...-1]
70
- '"href": "' + link_to(href.gsub('%7B', '{').gsub('%7D', '}'), href).html_safe + '"' rescue full_match
71
- }.html_safe %></code></pre>
75
+ <%= code.gsub(/"href": "(http(?:s?:\/\/.*?))"/, &method(:replace_link)).html_safe %></code></pre>
72
76
  </div>
73
77
  </article>
74
78
 
@@ -5,6 +5,7 @@ require 'action_controller/metal/mime_responds'
5
5
  require 'action_dispatch/http/mime_type'
6
6
  require 'active_support/concern'
7
7
  require 'active_support/core_ext/module/attribute_accessors'
8
+ require 'active_support/core_ext/object/blank'
8
9
 
9
10
  require 'http_headers/accept'
10
11
 
@@ -15,6 +16,22 @@ require 'media_types/serialization/wrapper/html_wrapper'
15
16
 
16
17
  require 'awesome_print'
17
18
 
19
+ require 'delegate'
20
+
21
+ class MediaTypeApiViewer < SimpleDelegator
22
+ def initialize(inner_media)
23
+ super inner_media
24
+ end
25
+
26
+ def to_s
27
+ 'application/vnd.xpbytes.api-viewer.v1'
28
+ end
29
+
30
+ def serialize_as
31
+ __getobj__
32
+ end
33
+ end
34
+
18
35
  module MediaTypes
19
36
  module Serialization
20
37
 
@@ -34,6 +51,9 @@ module MediaTypes
34
51
  ##
35
52
  # Accept serialization using the passed in +serializer+ for the given +view+
36
53
  #
54
+ # By default will also accept the first call to this as HTML
55
+ # By default will also accept the first call to this as Api Viewer
56
+ #
37
57
  # @see #freeze_accepted_media!
38
58
  #
39
59
  # @param serializer the serializer to use for serialization. Needs to respond to #to_body, but may respond to
@@ -55,21 +75,34 @@ module MediaTypes
55
75
  accept_api_viewer(serializer, view: view, overwrite: false, **filter_opts) if accept_api_viewer
56
76
  end
57
77
 
78
+ ##
79
+ # Accept serialization using the passed in +serializer+ for the given +view+ as text/html
80
+ #
81
+ # Always overwrites the current acceptor of text/html. The last call to this, for the giben +filter_opts+ will win
82
+ # the serialization.
83
+ #
58
84
  def accept_html(serializer, view: [nil], overwrite: true, **filter_opts)
59
85
  before_action(**filter_opts) do
60
- resolved_media_types(serializer, view: view) do |_, media_view, registered, register|
86
+ resolved_media_types(serializer, view: view) do |media_type, media_view, registered, register|
61
87
  break if registered.call(MEDIA_TYPE_HTML) && !overwrite
62
- register.call(MEDIA_TYPE_HTML, wrap_html(serializer, media_view: media_view, media_type: MEDIA_TYPE_HTML))
88
+ register.call(MEDIA_TYPE_HTML, wrap_html(serializer, media_view: media_view, media_type: media_type))
63
89
  end
64
90
  end
65
91
  end
66
92
 
93
+ ##
94
+ # Same as +accept_html+ but then for Api Viewer
95
+ #
67
96
  def accept_api_viewer(serializer, view: [nil], overwrite: true, **filter_opts)
68
97
  before_action(**filter_opts) do
69
- resolved_media_types(serializer, view: view) do |_, media_view, registered, register|
98
+ fixate_content_type = (params[:api_viewer_media_type] || '').gsub(' ', '+')
99
+ resolved_media_types(serializer, view: view) do |media_type, media_view, registered, register|
70
100
  break if registered.call(MEDIA_TYPE_API_VIEWER) && !overwrite
71
- register.call(MEDIA_TYPE_API_VIEWER, wrap_html(serializer, media_view: media_view, media_type: MEDIA_TYPE_API_VIEWER))
72
- break
101
+ if fixate_content_type == '' || fixate_content_type == media_type.to_s
102
+ wrapped_media_type = MediaTypeApiViewer.new(fixate_content_type.presence || media_type)
103
+ register.call(MEDIA_TYPE_API_VIEWER, wrap_html(serializer, media_view: media_view, media_type: wrapped_media_type))
104
+ break
105
+ end
73
106
  end
74
107
  end
75
108
  end
@@ -88,8 +121,10 @@ module MediaTypes
88
121
  #
89
122
  def accept_without_serialization(*mimes, **filter_opts)
90
123
  before_action(**filter_opts) do
91
- self.serializers = Array(mimes).each_with_object(Hash(serializers)) do |mime, res|
92
- res[(Mime::Type.lookup_by_extension(mime) || mime).to_s] = nil
124
+ self.serializers = Hash(serializers)
125
+ mimes.each do |mime|
126
+ media_type = Mime::Type.lookup_by_extension(mime) || mime
127
+ serializers[String(media_type)] = nil
93
128
  end
94
129
  end
95
130
  end
@@ -143,13 +178,21 @@ module MediaTypes
143
178
  def respond_to_accept(&block)
144
179
  respond_to do |format|
145
180
  serializers.each_key do |mime|
146
- format.custom(mime, &block)
181
+ result = yield mime: mime, format: format
182
+ next unless result
183
+ format.custom(mime) do
184
+ result.call
185
+ end
147
186
  end
148
187
 
149
188
  format.any { raise_no_accept_serializer }
150
189
  end
151
190
  end
152
191
 
192
+ # def respond_to_viewer(&block)
193
+ # TODO: special collector that matches on api_viewer_content_type matches too
194
+ # end
195
+
153
196
  def request_accept
154
197
  @request_accept ||= HttpHeaders::Accept.new(request.get_header(HEADER_ACCEPT) || '')
155
198
  end
@@ -168,11 +211,21 @@ module MediaTypes
168
211
  raise NoMediaTypeSerializers unless serializers
169
212
 
170
213
  # Rails negotiation
214
+ #
215
+ # The problem with rails negotiation is that it has its own logic for some of the handling that is not
216
+ # spec compliant. If there is an exact match, that's fine and we leave it like this;
217
+ #
171
218
  if serializers[request.format.to_s]
172
219
  return serializers[request.format.to_s]
173
220
  end
174
221
 
175
222
  # Ruby negotiation
223
+ #
224
+ # This is similar to the respond_to logic. It sorts the accept values and tries to match against each option.
225
+ # Currently does not allow for */* or type/*.
226
+ #
227
+ # respond_to_accept do ... end
228
+ #
176
229
  request.accepts.each do |mime_type|
177
230
  next unless serializers.key?(mime_type.to_s)
178
231
  # Override Rails selected format
@@ -186,7 +239,7 @@ module MediaTypes
186
239
  def resolved_media_types(serializer, view:)
187
240
  self.serializers = Hash(serializers)
188
241
 
189
- registered = serializers.method(:key)
242
+ registered = serializers.method(:key?)
190
243
  register = serializers.method(:[]=)
191
244
 
192
245
  Array(view).each do |media_view|
@@ -208,16 +261,22 @@ module MediaTypes
208
261
 
209
262
  def wrap_html(serializer, media_view:, media_type:)
210
263
  lambda do |*args, **opts|
264
+ inner_media_type = media_type.try(:serialize_as) || media_type
265
+
211
266
  media_serializer = wrap_media(
212
267
  serializer,
213
268
  media_view: media_view,
214
- media_type: media_type
269
+ media_type: inner_media_type
215
270
  ).call(*args, **opts)
216
271
 
272
+ override_mime_type = media_type.respond_to?(:serialize_as) ?
273
+ "#{media_type.to_s} (#{media_type.serialize_as})" :
274
+ media_type.to_s
275
+
217
276
  Wrapper::HtmlWrapper.new(
218
277
  media_serializer,
219
278
  view: media_view,
220
- mime_type: media_type.to_s,
279
+ mime_type: override_mime_type,
221
280
  representations: serializers.keys,
222
281
  url_context: request.original_fullpath.chomp(".#{request.format.symbol}")
223
282
  )
@@ -9,7 +9,7 @@ module MediaTypes
9
9
  end
10
10
 
11
11
  def call(result, mime_type, view)
12
- return result if matches_current_mime_type?(view: view, mime_type: mime_type)
12
+ return result if mime_type.is_a?(String) || matches_current_mime_type?(view: view, mime_type: mime_type)
13
13
 
14
14
  migrations.reduce(result) do |migrated, (version, migration)|
15
15
  migrated = migration.call(migrated)
@@ -24,8 +24,9 @@ module MediaTypes
24
24
  elsif Mime::Type.lookup(content_type) == Mime[:html] && obj.respond_to?(:to_html)
25
25
  obj.to_html
26
26
  elsif content_type === MEDIA_TYPE_API_VIEWER && obj.respond_to?(:to_api_viewer)
27
- self.content_type = 'text/html'
28
- obj.to_api_viewer
27
+ obj.to_api_viewer(content_type: options[:api_viewer_content_type]).tap do
28
+ self.content_type = 'text/html' # because the api viewer will not be seen as
29
+ end
29
30
  else
30
31
  obj.to_body(content_type: options.delete(:content_type) || content_type, **options)
31
32
  end
@@ -1,5 +1,5 @@
1
1
  module MediaTypes
2
2
  module Serialization
3
- VERSION = '0.6.2'
3
+ VERSION = '0.7.0.beta1'
4
4
  end
5
5
  end
@@ -24,12 +24,13 @@ module MediaTypes
24
24
  to_api_viewer(layout: ::MediaTypes::Serialization.html_wrapper_layout)
25
25
  end
26
26
 
27
- def to_api_viewer(layout: ::MediaTypes::Serialization.api_viewer_layout)
27
+ def to_api_viewer(content_type: nil, layout: ::MediaTypes::Serialization.api_viewer_layout)
28
28
  ActionController::Base.render(
29
29
  layout || 'serializers/wrapper/html_wrapper',
30
30
  assigns: {
31
31
  serializer: self,
32
32
  view: view,
33
+ content_type: content_type,
33
34
  **render_options
34
35
  }
35
36
  )
@@ -37,7 +37,7 @@ Gem::Specification.new do |spec|
37
37
 
38
38
  spec.add_dependency 'actionpack', '>= 4.0.0'
39
39
  spec.add_dependency 'activesupport', '>= 4.0.0'
40
- spec.add_dependency 'media_types', '>= 0.6.0'
40
+ spec.add_dependency 'media_types', '>= 0.6.2'
41
41
  spec.add_dependency 'oj', '>= 3.5.0'
42
42
  spec.add_dependency 'http_headers-accept', '>= 0.2.2', '< 1.0.0'
43
43
  spec.add_dependency 'http_headers-link', '< 1.0.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: media_types-serialization
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.7.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Derk-Jan Karrenbeld
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-05-02 00:00:00.000000000 Z
11
+ date: 2019-05-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 0.6.0
47
+ version: 0.6.2
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: 0.6.0
54
+ version: 0.6.2
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: oj
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -239,9 +239,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
239
239
  version: '0'
240
240
  required_rubygems_version: !ruby/object:Gem::Requirement
241
241
  requirements:
242
- - - ">="
242
+ - - ">"
243
243
  - !ruby/object:Gem::Version
244
- version: '0'
244
+ version: 1.3.1
245
245
  requirements: []
246
246
  rubygems_version: 3.0.3
247
247
  signing_key: