media_types-serialization 2.0.4 → 2.1.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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +32 -32
  3. data/.github/workflows/publish-bookworm.yml +34 -34
  4. data/.github/workflows/publish-sid.yml +34 -34
  5. data/.gitignore +22 -22
  6. data/.idea/.rakeTasks +7 -7
  7. data/.idea/dictionaries/Derk_Jan.xml +6 -6
  8. data/.idea/encodings.xml +3 -3
  9. data/.idea/inspectionProfiles/Project_Default.xml +5 -5
  10. data/.idea/media_types-serialization.iml +76 -76
  11. data/.idea/misc.xml +6 -6
  12. data/.idea/modules.xml +7 -7
  13. data/.idea/runConfigurations/test.xml +19 -19
  14. data/.idea/vcs.xml +5 -5
  15. data/CHANGELOG.md +207 -200
  16. data/CODE_OF_CONDUCT.md +74 -74
  17. data/Gemfile +4 -4
  18. data/Gemfile.lock +176 -169
  19. data/LICENSE.txt +21 -21
  20. data/README.md +1058 -1048
  21. data/Rakefile +10 -10
  22. data/bin/console +14 -14
  23. data/bin/setup +8 -8
  24. data/lib/media_types/problem.rb +67 -67
  25. data/lib/media_types/serialization/base.rb +269 -269
  26. data/lib/media_types/serialization/error.rb +193 -193
  27. data/lib/media_types/serialization/fake_validator.rb +53 -53
  28. data/lib/media_types/serialization/serialization_dsl.rb +139 -135
  29. data/lib/media_types/serialization/serialization_registration.rb +245 -245
  30. data/lib/media_types/serialization/serializers/api_viewer.rb +383 -383
  31. data/lib/media_types/serialization/serializers/common_css.rb +212 -212
  32. data/lib/media_types/serialization/serializers/endpoint_description_serializer.rb +80 -80
  33. data/lib/media_types/serialization/serializers/fallback_not_acceptable_serializer.rb +85 -85
  34. data/lib/media_types/serialization/serializers/fallback_unsupported_media_type_serializer.rb +58 -58
  35. data/lib/media_types/serialization/serializers/input_validation_error_serializer.rb +95 -93
  36. data/lib/media_types/serialization/serializers/problem_serializer.rb +111 -111
  37. data/lib/media_types/serialization/utils/accept_header.rb +77 -77
  38. data/lib/media_types/serialization/utils/accept_language_header.rb +82 -82
  39. data/lib/media_types/serialization/version.rb +7 -7
  40. data/lib/media_types/serialization.rb +689 -689
  41. data/media_types-serialization.gemspec +48 -48
  42. metadata +3 -3
@@ -1,85 +1,85 @@
1
- # frozen_string_literal: true
2
-
3
- require 'media_types/serialization/base'
4
-
5
- module MediaTypes
6
- module Serialization
7
- module Serializers
8
- # The serializer used when no serializer has been configured.
9
- class FallbackNotAcceptableSerializer < MediaTypes::Serialization::Base
10
- unvalidated 'text/html'
11
-
12
- output_raw do |obj, version, context|
13
-
14
- available_types = []
15
- begin
16
- original_uri = URI.parse(context.request.original_url)
17
- stripped_original = original_uri.dup
18
- query_parts = stripped_original.query&.split('&') || []
19
- query_parts = query_parts.select { |q| !q.start_with? 'api_viewer=' }
20
-
21
- available_types = obj[:registrations].registrations.keys.map do |identifier|
22
- stripped_original.query = (query_parts + ["api_viewer=#{identifier}"]).join('&')
23
- {
24
- identifier: identifier,
25
- url: stripped_original.to_s,
26
- }
27
- end
28
- rescue URI::InvalidURIError
29
- available_types = obj[:registrations].registrations.keys.map do |identifier|
30
- {
31
- identifier: identifier,
32
- url: context.request.original_url,
33
- }
34
- end
35
- end
36
-
37
- input = OpenStruct.new(
38
- media_types: available_types,
39
- has_viewer: obj[:has_viewer],
40
- css: CommonCSS.css,
41
- acceptable_types: obj[:request].headers["Accept"] || "<none>",
42
- )
43
-
44
- template = ERB.new <<-TEMPLATE
45
- <html lang="en">
46
- <head>
47
- <title>Unable to provide requested media types</title>
48
- <style>
49
- <%= css.split("\n").join("\n ") %>
50
- </style>
51
- </head>
52
- <body>
53
- <header>
54
- <div id="logo"></div>
55
- <h1>Not acceptable</h1>
56
- </header>
57
- <section id="content">
58
- <nav>
59
- <section id="representations">
60
- <h2>Please choose one of the following types:</h2>
61
- <p>This endpoint tried really hard to show you the information you requested. Unfortunately you specified in your <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept">Accept header</a> that you only wanted to see the following types: <code><%= CGI::escapeHTML(acceptable_types) %></code>.
62
- <p>Please add one of the following types to your Accept header to see the content or error message:
63
- <hr>
64
- </section>
65
- </nav>
66
- <main>
67
- <% media_types.each do |m| %>
68
- <li>
69
- <a href="<%= m[:url] %>">
70
- <%= CGI::escapeHTML(m[:identifier]) %>
71
- </a>
72
- </li>
73
- <% end %>
74
- </main>
75
- </section>
76
- <!-- API viewer made with ❤ by: https://delftsolutions.com -->
77
- </body>
78
- </html>
79
- TEMPLATE
80
- template.result(input.instance_eval { binding })
81
- end
82
- end
83
- end
84
- end
85
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'media_types/serialization/base'
4
+
5
+ module MediaTypes
6
+ module Serialization
7
+ module Serializers
8
+ # The serializer used when no serializer has been configured.
9
+ class FallbackNotAcceptableSerializer < MediaTypes::Serialization::Base
10
+ unvalidated 'text/html'
11
+
12
+ output_raw do |obj, version, context|
13
+
14
+ available_types = []
15
+ begin
16
+ original_uri = URI.parse(context.request.original_url)
17
+ stripped_original = original_uri.dup
18
+ query_parts = stripped_original.query&.split('&') || []
19
+ query_parts = query_parts.select { |q| !q.start_with? 'api_viewer=' }
20
+
21
+ available_types = obj[:registrations].registrations.keys.map do |identifier|
22
+ stripped_original.query = (query_parts + ["api_viewer=#{identifier}"]).join('&')
23
+ {
24
+ identifier: identifier,
25
+ url: stripped_original.to_s,
26
+ }
27
+ end
28
+ rescue URI::InvalidURIError
29
+ available_types = obj[:registrations].registrations.keys.map do |identifier|
30
+ {
31
+ identifier: identifier,
32
+ url: context.request.original_url,
33
+ }
34
+ end
35
+ end
36
+
37
+ input = OpenStruct.new(
38
+ media_types: available_types,
39
+ has_viewer: obj[:has_viewer],
40
+ css: CommonCSS.css,
41
+ acceptable_types: obj[:request].headers["Accept"] || "<none>",
42
+ )
43
+
44
+ template = ERB.new <<-TEMPLATE
45
+ <html lang="en">
46
+ <head>
47
+ <title>Unable to provide requested media types</title>
48
+ <style>
49
+ <%= css.split("\n").join("\n ") %>
50
+ </style>
51
+ </head>
52
+ <body>
53
+ <header>
54
+ <div id="logo"></div>
55
+ <h1>Not acceptable</h1>
56
+ </header>
57
+ <section id="content">
58
+ <nav>
59
+ <section id="representations">
60
+ <h2>Please choose one of the following types:</h2>
61
+ <p>This endpoint tried really hard to show you the information you requested. Unfortunately you specified in your <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept">Accept header</a> that you only wanted to see the following types: <code><%= CGI::escapeHTML(acceptable_types) %></code>.
62
+ <p>Please add one of the following types to your Accept header to see the content or error message:
63
+ <hr>
64
+ </section>
65
+ </nav>
66
+ <main>
67
+ <% media_types.each do |m| %>
68
+ <li>
69
+ <a href="<%= m[:url] %>">
70
+ <%= CGI::escapeHTML(m[:identifier]) %>
71
+ </a>
72
+ </li>
73
+ <% end %>
74
+ </main>
75
+ </section>
76
+ <!-- API viewer made with ❤ by: https://delftsolutions.com -->
77
+ </body>
78
+ </html>
79
+ TEMPLATE
80
+ template.result(input.instance_eval { binding })
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -1,58 +1,58 @@
1
- # frozen_string_literal: true
2
-
3
- require 'media_types/serialization/base'
4
-
5
- module MediaTypes
6
- module Serialization
7
- module Serializers
8
- # The serializer used when no serializer has been configured.
9
- class FallbackUnsupportedMediaTypeSerializer < MediaTypes::Serialization::Base
10
- unvalidated 'text/html'
11
-
12
- output_raw do |obj, version, context|
13
-
14
- available_types = obj[:registrations].registrations.keys
15
-
16
- input = OpenStruct.new(
17
- media_types: available_types,
18
- css: CommonCSS.css
19
- )
20
-
21
- template = ERB.new <<-TEMPLATE
22
- <html lang="en">
23
- <head>
24
- <title>Unsupported Media Type</title>
25
- <style>
26
- <%= css.split("\n").join("\n ") %>
27
- </style>
28
- </head>
29
- <body>
30
- <header>
31
- <div id="logo"></div>
32
- <h1>Unsupported Media Type</h1>
33
- </header>
34
- <section id="content">
35
- <nav>
36
- <section id="representations">
37
- <h2>Please use one of the following <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type">Content-Types</a> when making your request:</h2>
38
- <hr>
39
- </section>
40
- </nav>
41
- <main>
42
- <% media_types.each do |m| %>
43
- <li>
44
- <%= CGI::escapeHTML(m) %>
45
- </li>
46
- <% end %>
47
- </main>
48
- </section>
49
- <!-- API viewer made with ❤ by: https://delftsolutions.com -->
50
- </body>
51
- </html>
52
- TEMPLATE
53
- template.result(input.instance_eval { binding })
54
- end
55
- end
56
- end
57
- end
58
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'media_types/serialization/base'
4
+
5
+ module MediaTypes
6
+ module Serialization
7
+ module Serializers
8
+ # The serializer used when no serializer has been configured.
9
+ class FallbackUnsupportedMediaTypeSerializer < MediaTypes::Serialization::Base
10
+ unvalidated 'text/html'
11
+
12
+ output_raw do |obj, version, context|
13
+
14
+ available_types = obj[:registrations].registrations.keys
15
+
16
+ input = OpenStruct.new(
17
+ media_types: available_types,
18
+ css: CommonCSS.css
19
+ )
20
+
21
+ template = ERB.new <<-TEMPLATE
22
+ <html lang="en">
23
+ <head>
24
+ <title>Unsupported Media Type</title>
25
+ <style>
26
+ <%= css.split("\n").join("\n ") %>
27
+ </style>
28
+ </head>
29
+ <body>
30
+ <header>
31
+ <div id="logo"></div>
32
+ <h1>Unsupported Media Type</h1>
33
+ </header>
34
+ <section id="content">
35
+ <nav>
36
+ <section id="representations">
37
+ <h2>Please use one of the following <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type">Content-Types</a> when making your request:</h2>
38
+ <hr>
39
+ </section>
40
+ </nav>
41
+ <main>
42
+ <% media_types.each do |m| %>
43
+ <li>
44
+ <%= CGI::escapeHTML(m) %>
45
+ </li>
46
+ <% end %>
47
+ </main>
48
+ </section>
49
+ <!-- API viewer made with ❤ by: https://delftsolutions.com -->
50
+ </body>
51
+ </html>
52
+ TEMPLATE
53
+ template.result(input.instance_eval { binding })
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -1,93 +1,95 @@
1
- # frozen_string_literal: true
2
-
3
- require 'media_types/serialization/base'
4
- require 'erb'
5
- require 'cgi'
6
-
7
- module MediaTypes
8
- module Serialization
9
- module Serializers
10
- class InputValidationErrorSerializer < MediaTypes::Serialization::Base
11
- unvalidated 'text/html'
12
-
13
- def self.escape_text(text)
14
- text
15
- .split("\n")
16
- .map { |l| CGI.escapeHTML(l).gsub(/ (?= )/, '&nbsp;') }
17
- .map do |l|
18
- l.gsub(/\bhttps?:\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;{}]*[-A-Z0-9+@#\/%=}~_|](?![a-z]*;)/i) do |m|
19
- converted = m
20
- invalid = false
21
- begin
22
- converted = viewerify(m, context.request.host)
23
- rescue URI::InvalidURIError
24
- invalid = true
25
- end
26
- style = ''
27
- style = ' style="color: red"' if invalid
28
- "<a#{style} href=\"#{converted}\">#{m}</a>"
29
- end
30
- end
31
- .join("<br>\n")
32
- end
33
-
34
- output_raw do |obj, version, context|
35
- input_identifier = obj[:identifier]
36
- original_input = obj[:input]
37
- error = obj[:error]
38
-
39
- escaped_error = escape_text(error.message)
40
- escaped_input = escape_text(original_input)
41
-
42
- input = OpenStruct.new(
43
- original_identifier: input_identifier,
44
- escaped_error: escaped_error,
45
- escaped_input: escaped_input,
46
- css: CommonCSS.css,
47
- )
48
-
49
- template = ERB.new <<-TEMPLATE
50
- <html lang="en">
51
- <head>
52
- <meta content="width=device-width, initial-scale=1" name="viewport">
53
- <title>Invalid input detected</title>
54
- <style>
55
- <%= css.split("\n").join("\n ") %>
56
- </style>
57
- </head>
58
- <body>
59
- <header>
60
- <div id="logo"></div>
61
- <h1>Invalid input detected</h1>
62
- </header>
63
- <section id="content">
64
- <nav>
65
- <section id="representations">
66
- <h2>While trying to process the <%= CGI::escapeHTML(original_identifier) %> input you sent; I encountered the following error:</h2>
67
- <hr>
68
- </section>
69
- </nav>
70
- <main>
71
- <section id="error">
72
- <code id="error">
73
- <%= escaped_error %>
74
- </code>
75
- </section>
76
- <section id="input">
77
- <h2>Original input:</h2>
78
- <code id="input">
79
- <%= escaped_input %>
80
- </code>
81
- </section>
82
- </main>
83
- </section>
84
- <!-- API viewer made with ❤ by: https://delftsolutions.com -->
85
- </body>
86
- </html>
87
- TEMPLATE
88
- template.result(input.instance_eval { binding })
89
- end
90
- end
91
- end
92
- end
93
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'media_types/serialization/base'
4
+ require 'erb'
5
+ require 'cgi'
6
+
7
+ module MediaTypes
8
+ module Serialization
9
+ module Serializers
10
+ class InputValidationErrorSerializer < MediaTypes::Serialization::Base
11
+ unvalidated 'text/html'
12
+
13
+ def self.escape_text(text, context)
14
+ result = text
15
+ .split("\n")
16
+ .map { |l| CGI.escapeHTML(l).gsub(/ (?= )/, '&nbsp;') }
17
+ .map do |l|
18
+ l.gsub(/\bhttps?:\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;{}]*[-A-Z0-9+@#\/%=}~_|](?![a-z]*;)/i) do |m|
19
+ converted = m
20
+ invalid = false
21
+ begin
22
+ converted = ApiViewer.viewerify(m, context.request.host)
23
+ rescue URI::InvalidURIError
24
+ invalid = true
25
+ end
26
+ style = ''
27
+ style = ' style="color: red"' if invalid
28
+ "<a#{style} href=\"#{converted}\">#{m}</a>"
29
+ end
30
+ end
31
+ .join("<br>\n")
32
+ result.html_safe
33
+ result
34
+ end
35
+
36
+ output_raw do |obj, version, context|
37
+ input_identifier = obj[:identifier]
38
+ original_input = obj[:input]
39
+ error = obj[:error]
40
+
41
+ escaped_error = escape_text(error.message, context)
42
+ escaped_input = escape_text(original_input, context)
43
+
44
+ input = OpenStruct.new(
45
+ original_identifier: input_identifier,
46
+ escaped_error: escaped_error,
47
+ escaped_input: escaped_input,
48
+ css: CommonCSS.css,
49
+ )
50
+
51
+ template = ERB.new <<-TEMPLATE
52
+ <html lang="en">
53
+ <head>
54
+ <meta content="width=device-width, initial-scale=1" name="viewport">
55
+ <title>Invalid input detected</title>
56
+ <style>
57
+ <%= css.split("\n").join("\n ") %>
58
+ </style>
59
+ </head>
60
+ <body>
61
+ <header>
62
+ <div id="logo"></div>
63
+ <h1>Invalid input detected</h1>
64
+ </header>
65
+ <section id="content">
66
+ <nav>
67
+ <section id="representations">
68
+ <h2>While trying to process the <%= CGI::escapeHTML(original_identifier) %> input you sent; I encountered the following error:</h2>
69
+ <hr>
70
+ </section>
71
+ </nav>
72
+ <main>
73
+ <section id="error">
74
+ <code id="error">
75
+ <%= escaped_error %>
76
+ </code>
77
+ </section>
78
+ <section id="input">
79
+ <h2>Original input:</h2>
80
+ <code id="input">
81
+ <%= escaped_input %>
82
+ </code>
83
+ </section>
84
+ </main>
85
+ </section>
86
+ <!-- API viewer made with ❤ by: https://delftsolutions.com -->
87
+ </body>
88
+ </html>
89
+ TEMPLATE
90
+ template.result(input.instance_eval { binding })
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end