media_types-serialization 1.3.9 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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 +33 -0
  4. data/.github/workflows/publish-sid.yml +33 -0
  5. data/.gitignore +22 -12
  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 +190 -178
  16. data/CODE_OF_CONDUCT.md +74 -74
  17. data/Gemfile +4 -4
  18. data/LICENSE.txt +21 -21
  19. data/README.md +1048 -1035
  20. data/Rakefile +10 -10
  21. data/bin/console +14 -14
  22. data/bin/setup +8 -8
  23. data/lib/media_types/problem.rb +67 -67
  24. data/lib/media_types/serialization/base.rb +269 -216
  25. data/lib/media_types/serialization/error.rb +193 -193
  26. data/lib/media_types/serialization/fake_validator.rb +53 -53
  27. data/lib/media_types/serialization/serialization_dsl.rb +135 -117
  28. data/lib/media_types/serialization/serialization_registration.rb +245 -245
  29. data/lib/media_types/serialization/serializers/api_viewer.rb +383 -136
  30. data/lib/media_types/serialization/serializers/common_css.rb +212 -168
  31. data/lib/media_types/serialization/serializers/endpoint_description_serializer.rb +80 -80
  32. data/lib/media_types/serialization/serializers/fallback_not_acceptable_serializer.rb +85 -85
  33. data/lib/media_types/serialization/serializers/fallback_unsupported_media_type_serializer.rb +58 -58
  34. data/lib/media_types/serialization/serializers/input_validation_error_serializer.rb +93 -93
  35. data/lib/media_types/serialization/serializers/problem_serializer.rb +111 -104
  36. data/lib/media_types/serialization/utils/accept_header.rb +77 -77
  37. data/lib/media_types/serialization/utils/accept_language_header.rb +82 -82
  38. data/lib/media_types/serialization/version.rb +7 -7
  39. data/lib/media_types/serialization.rb +682 -671
  40. data/media_types-serialization.gemspec +48 -48
  41. metadata +17 -16
  42. data/Gemfile.lock +0 -137
@@ -1,104 +1,111 @@
1
- # frozen_string_literal: true
2
-
3
- require 'erb'
4
- require 'media_types/serialization/base'
5
- require 'media_types/serialization/utils/accept_language_header'
6
-
7
- module MediaTypes
8
- module Serialization
9
- module Serializers
10
- class ProblemSerializer < MediaTypes::Serialization::Base
11
-
12
- unvalidated 'application/vnd.delftsolutions.problem'
13
- disable_wildcards
14
-
15
- output do |problem, _, context|
16
- raise 'No translations defined, add at least one title' unless problem.translations.keys.any?
17
-
18
- accept_language_header = Utils::AcceptLanguageHeader.new(
19
- context.request.get_header(HEADER_ACCEPT_LANGUAGE) || ''
20
- )
21
- translation_entry = accept_language_header.map do |locale|
22
- problem.translations.keys.find do |l|
23
- l.start_with? locale.locale
24
- end
25
- end.compact.first || problem.translations.keys.first
26
- translation = problem.translations[translation_entry]
27
-
28
- title = translation[:title]
29
- detail = translation[:detail] || problem.error.message
30
-
31
- problem.custom_attributes.each do |key, value|
32
- attribute key, value
33
- end
34
-
35
- attribute :type, problem.type
36
- attribute :title, title unless title.nil?
37
- attribute :detail, detail unless detail.nil?
38
- attribute :instance, problem.instance unless problem.instance.nil?
39
-
40
- emit
41
- end
42
- output_alias 'application/problem+json'
43
-
44
- output_raw view: :html do |problem, _, context|
45
- accept_language_header = Utils::AcceptLanguageHeader.new(
46
- context.request.get_header(HEADER_ACCEPT_LANGUAGE) || ''
47
- )
48
- translation_entry = accept_language_header.map do |locale|
49
- problem.translations.keys.find do |l|
50
- l.starts_with? locale.locale
51
- end
52
- end.compact.first || problem.translations.keys.first
53
- translation = problem.translations[translation_entry]
54
-
55
- title = translation[:title]
56
- detail = translation[:detail] || problem.error.message
57
-
58
- detail_lang = translation[:detail].nil? ? 'en' : translation_entry
59
-
60
- input = OpenStruct.new(
61
- title: title,
62
- detail: detail,
63
- help_url: problem.type,
64
- css: CommonCSS.css
65
- )
66
-
67
- template = ERB.new <<-TEMPLATE
68
- <html lang="en">
69
- <head>
70
- <meta content="width=device-width, initial-scale=1" name="viewport">
71
- <title>Error - <%= CGI::escapeHTML(title) %></title>
72
- <style>
73
- <%= css.split("\n").join("\n ") %>
74
- </style>
75
- </head>
76
- <body>
77
- <header>
78
- <div id="logo"></div>
79
- <h1>Error</h1>
80
- </header>
81
- <section id="content">
82
- <nav>
83
- <section id="description" lang="#{translation_entry}">
84
- <h2><a href="<%= help_url %>"><%= CGI::escapeHTML(title) %></a></h2>
85
- </section>
86
- </nav>
87
- <main lang="#{detail_lang}">
88
- <p><%= detail %>
89
- </main>
90
- </section>
91
- <!-- Made with by: https://delftsolutions.com -->
92
- </body>
93
- </html>
94
- TEMPLATE
95
- template.result(input.instance_eval { binding })
96
- end
97
-
98
- enable_wildcards
99
-
100
- output_alias_optional 'text/html', view: :html
101
- end
102
- end
103
- end
104
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'erb'
4
+ require 'media_types/serialization/base'
5
+ require 'media_types/serialization/utils/accept_language_header'
6
+
7
+ module MediaTypes
8
+ module Serialization
9
+ module Serializers
10
+ class ProblemSerializer < MediaTypes::Serialization::Base
11
+
12
+ unvalidated 'application/vnd.delftsolutions.problem'
13
+ disable_wildcards
14
+
15
+ output do |problem, _, context|
16
+ raise 'No translations defined, add at least one title' unless problem.translations.keys.any?
17
+
18
+ accept_language_header = Utils::AcceptLanguageHeader.new(
19
+ context.request.get_header(HEADER_ACCEPT_LANGUAGE) || ''
20
+ )
21
+ translation_entry = accept_language_header.map do |locale|
22
+ problem.translations.keys.find do |l|
23
+ l.start_with? locale.locale
24
+ end
25
+ end.compact.first || problem.translations.keys.first
26
+ translation = problem.translations[translation_entry]
27
+
28
+ title = translation[:title]
29
+ detail = translation[:detail] || problem.error.message
30
+
31
+ problem.custom_attributes.each do |key, value|
32
+ attribute key, value
33
+ end
34
+
35
+ hidden do
36
+ link :type, href: problem.type
37
+ end
38
+ attribute :type, problem.type
39
+ attribute :title, title unless title.nil?
40
+ attribute :detail, detail unless detail.nil?
41
+ attribute :instance, problem.instance unless problem.instance.nil?
42
+
43
+ emit
44
+ end
45
+ output_alias 'application/problem+json'
46
+
47
+ output_raw view: :html do |problem, _, context|
48
+ accept_language_header = Utils::AcceptLanguageHeader.new(
49
+ context.request.get_header(HEADER_ACCEPT_LANGUAGE) || ''
50
+ )
51
+ translation_entry = accept_language_header.map do |locale|
52
+ problem.translations.keys.find do |l|
53
+ l.starts_with? locale.locale
54
+ end
55
+ end.compact.first || problem.translations.keys.first
56
+ translation = problem.translations[translation_entry]
57
+
58
+ hidden do
59
+ link :type, href: problem.type
60
+ end
61
+
62
+ title = translation[:title]
63
+ detail = translation[:detail] || problem.error.message
64
+
65
+ detail_lang = translation[:detail].nil? ? 'en' : translation_entry
66
+
67
+ input = OpenStruct.new(
68
+ title: title,
69
+ detail: detail,
70
+ help_url: problem.type,
71
+ css: CommonCSS.css
72
+ )
73
+
74
+ template = ERB.new <<-TEMPLATE
75
+ <html lang="en">
76
+ <head>
77
+ <meta content="width=device-width, initial-scale=1" name="viewport">
78
+ <title>Error - <%= CGI::escapeHTML(title) %></title>
79
+ <style>
80
+ <%= css.split("\n").join("\n ") %>
81
+ </style>
82
+ </head>
83
+ <body>
84
+ <header>
85
+ <div id="logo"></div>
86
+ <h1>Error</h1>
87
+ </header>
88
+ <section id="content">
89
+ <nav>
90
+ <section id="description" lang="#{translation_entry}">
91
+ <h2><a href="<%= help_url %>"><%= CGI::escapeHTML(title) %></a></h2>
92
+ </section>
93
+ </nav>
94
+ <main lang="#{detail_lang}">
95
+ <p><%= detail %>
96
+ </main>
97
+ </section>
98
+ <!-- Made with ❤ by: https://delftsolutions.com -->
99
+ </body>
100
+ </html>
101
+ TEMPLATE
102
+ template.result(input.instance_eval { binding })
103
+ end
104
+
105
+ enable_wildcards
106
+
107
+ output_alias_optional 'text/html', view: :html
108
+ end
109
+ end
110
+ end
111
+ end
@@ -1,77 +1,77 @@
1
- =begin
2
- The MIT License (MIT)
3
-
4
- Copyright (c) 2019 Derk-Jan Karrenbeld
5
-
6
- Permission is hereby granted, free of charge, to any person obtaining a copy
7
- of this software and associated documentation files (the "Software"), to deal
8
- in the Software without restriction, including without limitation the rights
9
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
- copies of the Software, and to permit persons to whom the Software is
11
- furnished to do so, subject to the following conditions:
12
-
13
- The above copyright notice and this permission notice shall be included in
14
- all copies or substantial portions of the Software.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
- THE SOFTWARE.
23
- =end
24
-
25
- require 'media_types/serialization/utils/header_list'
26
-
27
- module MediaTypes
28
- module Serialization
29
- module Utils
30
- class AcceptHeader < DelegateClass(Array)
31
- def initialize(value)
32
- __setobj__ HeaderList.new(value, entry_klazz: AcceptHeader::Entry)
33
- end
34
-
35
- class Entry
36
- def initialize(media_type, index:, parameters:)
37
- self.media_type = media_type
38
- self.parameters = parameters
39
- self.index = index
40
-
41
- freeze
42
- end
43
-
44
- attr_reader :media_type
45
-
46
- # noinspection RubyInstanceMethodNamingConvention
47
- def q
48
- parameters.fetch(:q) { 1.0 }.to_f
49
- end
50
-
51
- def <=>(other)
52
- quality = other.q <=> q
53
- return quality unless quality.zero?
54
- index <=> other.send(:index)
55
- end
56
-
57
- def [](parameter)
58
- parameters.fetch(String(parameter).to_sym)
59
- end
60
-
61
- def to_header
62
- to_s
63
- end
64
-
65
- def to_s
66
- [media_type].concat(parameters.map { |k, v| "#{k}=#{v}" }).compact.reject(&:empty?).join('; ')
67
- end
68
-
69
- private
70
-
71
- attr_writer :media_type
72
- attr_accessor :parameters, :index
73
- end
74
- end
75
- end
76
- end
77
- end
1
+ =begin
2
+ The MIT License (MIT)
3
+
4
+ Copyright (c) 2019 Derk-Jan Karrenbeld
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
23
+ =end
24
+
25
+ require 'media_types/serialization/utils/header_list'
26
+
27
+ module MediaTypes
28
+ module Serialization
29
+ module Utils
30
+ class AcceptHeader < DelegateClass(Array)
31
+ def initialize(value)
32
+ __setobj__ HeaderList.new(value, entry_klazz: AcceptHeader::Entry)
33
+ end
34
+
35
+ class Entry
36
+ def initialize(media_type, index:, parameters:)
37
+ self.media_type = media_type
38
+ self.parameters = parameters
39
+ self.index = index
40
+
41
+ freeze
42
+ end
43
+
44
+ attr_reader :media_type
45
+
46
+ # noinspection RubyInstanceMethodNamingConvention
47
+ def q
48
+ parameters.fetch(:q) { 1.0 }.to_f
49
+ end
50
+
51
+ def <=>(other)
52
+ quality = other.q <=> q
53
+ return quality unless quality.zero?
54
+ index <=> other.send(:index)
55
+ end
56
+
57
+ def [](parameter)
58
+ parameters.fetch(String(parameter).to_sym)
59
+ end
60
+
61
+ def to_header
62
+ to_s
63
+ end
64
+
65
+ def to_s
66
+ [media_type].concat(parameters.map { |k, v| "#{k}=#{v}" }).compact.reject(&:empty?).join('; ')
67
+ end
68
+
69
+ private
70
+
71
+ attr_writer :media_type
72
+ attr_accessor :parameters, :index
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -1,82 +1,82 @@
1
- =begin
2
- The MIT License (MIT)
3
-
4
- Copyright (c) 2019 Derk-Jan Karrenbeld
5
-
6
- Permission is hereby granted, free of charge, to any person obtaining a copy
7
- of this software and associated documentation files (the "Software"), to deal
8
- in the Software without restriction, including without limitation the rights
9
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
- copies of the Software, and to permit persons to whom the Software is
11
- furnished to do so, subject to the following conditions:
12
-
13
- The above copyright notice and this permission notice shall be included in
14
- all copies or substantial portions of the Software.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
- THE SOFTWARE.
23
- =end
24
-
25
- require 'media_types/serialization/utils/header_list'
26
-
27
- module MediaTypes
28
- module Serialization
29
- module Utils
30
- class AcceptLanguageHeader < DelegateClass(Array)
31
- def initialize(value)
32
- __setobj__ HeaderList.new(value, entry_klazz: Entry)
33
- end
34
-
35
- class Entry
36
-
37
- DELIMITER = '-'
38
-
39
- attr_reader :locale, :region, :language
40
-
41
- def initialize(locale, index:, parameters:)
42
- self.locale = locale
43
- # TODO: support extlang correctly, maybe we don't even need this
44
- self.language, self.region = locale.split(DELIMITER)
45
- self.parameters = parameters
46
- self.index = index
47
-
48
- freeze
49
- end
50
-
51
- # noinspection RubyInstanceMethodNamingConvention
52
- def q
53
- parameters.fetch(:q) { 1.0 }.to_f
54
- end
55
-
56
- def <=>(other)
57
- quality = other.q <=> q
58
- return quality unless quality.zero?
59
- index <=> other.send(:index)
60
- end
61
-
62
- def [](parameter)
63
- parameters.fetch(String(parameter).to_sym)
64
- end
65
-
66
- def to_header
67
- to_s
68
- end
69
-
70
- def to_s
71
- [locale].concat(parameters.map { |k, v| "#{k}=#{v}" }).compact.reject(&:empty?).join('; ')
72
- end
73
-
74
- private
75
-
76
- attr_writer :locale, :region, :language
77
- attr_accessor :parameters, :index
78
- end
79
- end
80
- end
81
- end
82
- end
1
+ =begin
2
+ The MIT License (MIT)
3
+
4
+ Copyright (c) 2019 Derk-Jan Karrenbeld
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
23
+ =end
24
+
25
+ require 'media_types/serialization/utils/header_list'
26
+
27
+ module MediaTypes
28
+ module Serialization
29
+ module Utils
30
+ class AcceptLanguageHeader < DelegateClass(Array)
31
+ def initialize(value)
32
+ __setobj__ HeaderList.new(value, entry_klazz: Entry)
33
+ end
34
+
35
+ class Entry
36
+
37
+ DELIMITER = '-'
38
+
39
+ attr_reader :locale, :region, :language
40
+
41
+ def initialize(locale, index:, parameters:)
42
+ self.locale = locale
43
+ # TODO: support extlang correctly, maybe we don't even need this
44
+ self.language, self.region = locale.split(DELIMITER)
45
+ self.parameters = parameters
46
+ self.index = index
47
+
48
+ freeze
49
+ end
50
+
51
+ # noinspection RubyInstanceMethodNamingConvention
52
+ def q
53
+ parameters.fetch(:q) { 1.0 }.to_f
54
+ end
55
+
56
+ def <=>(other)
57
+ quality = other.q <=> q
58
+ return quality unless quality.zero?
59
+ index <=> other.send(:index)
60
+ end
61
+
62
+ def [](parameter)
63
+ parameters.fetch(String(parameter).to_sym)
64
+ end
65
+
66
+ def to_header
67
+ to_s
68
+ end
69
+
70
+ def to_s
71
+ [locale].concat(parameters.map { |k, v| "#{k}=#{v}" }).compact.reject(&:empty?).join('; ')
72
+ end
73
+
74
+ private
75
+
76
+ attr_writer :locale, :region, :language
77
+ attr_accessor :parameters, :index
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -1,7 +1,7 @@
1
- # frozen_string_literal: true
2
-
3
- module MediaTypes
4
- module Serialization
5
- VERSION = '1.3.9'
6
- end
7
- end
1
+ # frozen_string_literal: true
2
+
3
+ module MediaTypes
4
+ module Serialization
5
+ VERSION = '2.0.0'
6
+ end
7
+ end