media_types-serialization 0.6.2 → 0.7.0.beta1

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: 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: