media_types-serialization 1.4.0 → 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 -14
  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 -182
  16. data/CODE_OF_CONDUCT.md +74 -74
  17. data/Gemfile +4 -4
  18. data/LICENSE.txt +21 -21
  19. data/README.md +1048 -1048
  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 -135
  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 -111
  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 -675
  40. data/media_types-serialization.gemspec +48 -48
  41. metadata +9 -8
  42. data/Gemfile.lock +0 -167
@@ -1,193 +1,193 @@
1
-
2
- module MediaTypes
3
- module Serialization
4
- class Error < StandardError
5
- end
6
-
7
- class ControlFlowError < Error
8
- end
9
-
10
- class InputNotAcceptableError < ControlFlowError
11
- def initialize
12
- super('Content-Type provided in the request is not acceptable.')
13
- end
14
- end
15
-
16
- class RuntimeError < Error
17
- end
18
-
19
- class NoInputReceivedError < RuntimeError
20
- def initialize
21
- super('No Content-Type specified in request.')
22
- end
23
- end
24
-
25
- class InputValidationFailedError < RuntimeError
26
- def initialize(inner)
27
- @inner = inner
28
- super(inner.message)
29
- end
30
- end
31
-
32
- class OutputValidationFailedError < RuntimeError
33
- def initialize(inner)
34
- @inner = inner
35
- super(inner.message)
36
- end
37
- end
38
-
39
- class CollectionTypeError < RuntimeError
40
- def initialize(type)
41
- super("Unable to serialize the collection. Input was of type #{type} but I expected an Array.")
42
- end
43
- end
44
-
45
- class UnsupportedMediaTypeError < RuntimeError
46
- def initialize(available)
47
- super("The controller was unable to process your Content-Type. Please use one of: [#{available.join(', ')}]")
48
- end
49
- end
50
-
51
- class ConfigurationError < Error
52
- end
53
-
54
- class CannotDecodeOutputError < ConfigurationError
55
- def initialize
56
- super('Unable to call decode on an output registration.')
57
- end
58
- end
59
-
60
- class ValidatorNotSpecifiedError < ConfigurationError
61
- def initialize(inout)
62
- super("Serializer tried to define an #{inout} without first specifying a validator using either the validator function or unvalidated function. Please call one of those before defining #{inout}s.")
63
- end
64
- end
65
-
66
- class ValidatorNotDefinedError < ConfigurationError
67
- def initialize(identifier, inout)
68
- super("Serializer tried to define an #{inout} using the media type identifier #{identifier}, but no validation has been set up for that identifier. Please add it to the validator.")
69
- end
70
- end
71
-
72
- class UnbackedAliasDefinitionError < ConfigurationError
73
- def initialize(identifier, inout)
74
- super(
75
- "Serializer tried to define an #{inout}_alias that points to the media type identifier #{identifier} but no such #{inout} has been defined yet. Please move the #{inout} definition above the alias.\n\n" \
76
- "Move the #{inout} definition above the alias:\n" \
77
- "\n" \
78
- "class MySerializer < MediaTypes::Serialization::Base\n" \
79
- "#...\n" \
80
- "#{inout} do\n" \
81
- " # ...\n" \
82
- "end\n" \
83
- "\n" \
84
- "#{inout}_alias 'text/html'\n" \
85
- "# ^----- move here\n" \
86
- 'end'
87
- )
88
- end
89
- end
90
-
91
- class VersionedAliasDefinitionError < ConfigurationError
92
- def initialize(identifier, inout, prefix_match)
93
- super(
94
- "Serializer tried to define an #{inout}_alias that points to the media type identifier #{identifier} but no such #{inout} has been defined yet. An #{inout} named #{prefix_match} was found. Often this can be fixed by providing an #{inout} with a nil version."
95
- )
96
- end
97
- end
98
-
99
- class DuplicateDefinitionError < ConfigurationError
100
- def initialize(identifier, inout)
101
- super("Serializer tried to define an #{inout} using the media type identifier #{identifier}, but another #{inout} was already defined with that identifier. Please remove one of the two.")
102
- end
103
- end
104
-
105
- class DuplicateUsageError < ConfigurationError
106
- def initialize(identifier, inout, serializer1, serializer2)
107
- super("Controller tried to use two #{inout} serializers (#{serializer1}, #{serializer2}) that both have a non-optional #{inout} defined for the media type identifier #{identifier}. Please remove one of the two or filter them more specifically.")
108
- end
109
- end
110
-
111
- class UnregisteredMediaTypeUsageError < ConfigurationError
112
- def initialize(identifier, available)
113
- super("A serialization or deserialization method was called using a media type identifier '#{identifier}' but no such identifier has been registered yet. Available media types: [#{available.join ', '}]")
114
- end
115
- end
116
-
117
- class UnmatchedSerializerError < ConfigurationError
118
- def initialize(serializer)
119
- super("Called render_media with a resolved serializer that was not specified in the do block. Please add a 'serializer #{serializer.name}, <value>' entry.")
120
- end
121
- end
122
-
123
- class VersionsNotAnArrayError < ConfigurationError
124
- def initialize
125
- super('Tried to create an input or output with a versions: parameter that is set to something that is not an array. Please use the version: parameter or conver the current value to an array.')
126
- end
127
- end
128
- class ViewsNotAnArrayError < ConfigurationError
129
- def initialize
130
- super('Tried to create an input or output with a views: parameter that is set to something that is not an array. Please use the view: parameter or conver the current value to an array.')
131
- end
132
- end
133
-
134
- class NoValidatorSetError < ConfigurationError
135
- def initialize
136
- super("Unable to return validator as no validator has been set. Either someone tried to fetch the currently defined validator or someone tried to set the validator to 'nil'.")
137
- end
138
- end
139
-
140
- class NoSelfLinkProvidedError < ConfigurationError
141
- def initialize(media_type_identifier)
142
- super("Tried to render an index of '#{media_type_identifier}' elements but the serializer did not return a :self link for me to use. Please call 'link rel: :self, href: 'https://...' in the #{media_type_identifier} serializer.")
143
- end
144
- end
145
-
146
- class MultipleSelfLinksProvidedError < ConfigurationError
147
- def initialize(media_type_identifier)
148
- super("Tried to render an index of '#{media_type_identifier}' elements but the serializer returned more than one :self link. Please make sure to only call 'link rel: :self, ...' once in the #{media_type_identifier} serializer.")
149
- end
150
- end
151
-
152
- class ArrayInViewParameterError < ConfigurationError
153
- def initialize(function)
154
- super("Tried to call #{function} with an array in the view: parameter. Please use the views: parameter instead.")
155
- end
156
- end
157
-
158
- class SerializersNotFrozenError < ConfigurationError
159
- def initialize
160
- super("Unable to serialize or deserialize objects with unfrozen serializers. Please add 'freeze_io!' to the controller definition.")
161
- end
162
- end
163
-
164
- class SerializersAlreadyFrozenError < ConfigurationError
165
- def initialize
166
- super("Unable to add a serializer when they are already frozen. Please make sure to call 'freeze_io!' last.")
167
- end
168
- end
169
-
170
- class UnableToRefreezeError < ConfigurationError
171
- def initialize
172
- super("Freeze was called while the serializers are already frozen. Please make sure to only call 'freeze_io!' once.")
173
- end
174
- end
175
-
176
- class NoOutputSerializersDefinedError < ConfigurationError
177
- def intialize
178
- super("Called freeze_io! without any allowed output serializers. Users won't be able to make any requests. Please make sure to add at least one allow_output_serializer call to your controller.")
179
- end
180
- end
181
-
182
- class AddedEmptyOutputSerializer < ConfigurationError
183
- def initialize(name)
184
- super("A serializer with name '#{name}' was just added to the controller but it contained no output definitions. Usually this is due to using the wrong view parameter when adding it.")
185
- end
186
- end
187
- class AddedEmptyInputSerializer < ConfigurationError
188
- def initialize(name)
189
- super("A serializer with name '#{name}' was just added to the controller but it contained no input definitions. Usually this is due to using the wrong view parameter when adding it.")
190
- end
191
- end
192
- end
193
- end
1
+
2
+ module MediaTypes
3
+ module Serialization
4
+ class Error < StandardError
5
+ end
6
+
7
+ class ControlFlowError < Error
8
+ end
9
+
10
+ class InputNotAcceptableError < ControlFlowError
11
+ def initialize
12
+ super('Content-Type provided in the request is not acceptable.')
13
+ end
14
+ end
15
+
16
+ class RuntimeError < Error
17
+ end
18
+
19
+ class NoInputReceivedError < RuntimeError
20
+ def initialize
21
+ super('No Content-Type specified in request.')
22
+ end
23
+ end
24
+
25
+ class InputValidationFailedError < RuntimeError
26
+ def initialize(inner)
27
+ @inner = inner
28
+ super(inner.message)
29
+ end
30
+ end
31
+
32
+ class OutputValidationFailedError < RuntimeError
33
+ def initialize(inner)
34
+ @inner = inner
35
+ super(inner.message)
36
+ end
37
+ end
38
+
39
+ class CollectionTypeError < RuntimeError
40
+ def initialize(type)
41
+ super("Unable to serialize the collection. Input was of type #{type} but I expected an Array.")
42
+ end
43
+ end
44
+
45
+ class UnsupportedMediaTypeError < RuntimeError
46
+ def initialize(available)
47
+ super("The controller was unable to process your Content-Type. Please use one of: [#{available.join(', ')}]")
48
+ end
49
+ end
50
+
51
+ class ConfigurationError < Error
52
+ end
53
+
54
+ class CannotDecodeOutputError < ConfigurationError
55
+ def initialize
56
+ super('Unable to call decode on an output registration.')
57
+ end
58
+ end
59
+
60
+ class ValidatorNotSpecifiedError < ConfigurationError
61
+ def initialize(inout)
62
+ super("Serializer tried to define an #{inout} without first specifying a validator using either the validator function or unvalidated function. Please call one of those before defining #{inout}s.")
63
+ end
64
+ end
65
+
66
+ class ValidatorNotDefinedError < ConfigurationError
67
+ def initialize(identifier, inout)
68
+ super("Serializer tried to define an #{inout} using the media type identifier #{identifier}, but no validation has been set up for that identifier. Please add it to the validator.")
69
+ end
70
+ end
71
+
72
+ class UnbackedAliasDefinitionError < ConfigurationError
73
+ def initialize(identifier, inout)
74
+ super(
75
+ "Serializer tried to define an #{inout}_alias that points to the media type identifier #{identifier} but no such #{inout} has been defined yet. Please move the #{inout} definition above the alias.\n\n" \
76
+ "Move the #{inout} definition above the alias:\n" \
77
+ "\n" \
78
+ "class MySerializer < MediaTypes::Serialization::Base\n" \
79
+ "#...\n" \
80
+ "#{inout} do\n" \
81
+ " # ...\n" \
82
+ "end\n" \
83
+ "\n" \
84
+ "#{inout}_alias 'text/html'\n" \
85
+ "# ^----- move here\n" \
86
+ 'end'
87
+ )
88
+ end
89
+ end
90
+
91
+ class VersionedAliasDefinitionError < ConfigurationError
92
+ def initialize(identifier, inout, prefix_match)
93
+ super(
94
+ "Serializer tried to define an #{inout}_alias that points to the media type identifier #{identifier} but no such #{inout} has been defined yet. An #{inout} named #{prefix_match} was found. Often this can be fixed by providing an #{inout} with a nil version."
95
+ )
96
+ end
97
+ end
98
+
99
+ class DuplicateDefinitionError < ConfigurationError
100
+ def initialize(identifier, inout)
101
+ super("Serializer tried to define an #{inout} using the media type identifier #{identifier}, but another #{inout} was already defined with that identifier. Please remove one of the two.")
102
+ end
103
+ end
104
+
105
+ class DuplicateUsageError < ConfigurationError
106
+ def initialize(identifier, inout, serializer1, serializer2)
107
+ super("Controller tried to use two #{inout} serializers (#{serializer1}, #{serializer2}) that both have a non-optional #{inout} defined for the media type identifier #{identifier}. Please remove one of the two or filter them more specifically.")
108
+ end
109
+ end
110
+
111
+ class UnregisteredMediaTypeUsageError < ConfigurationError
112
+ def initialize(identifier, available)
113
+ super("A serialization or deserialization method was called using a media type identifier '#{identifier}' but no such identifier has been registered yet. Available media types: [#{available.join ', '}]")
114
+ end
115
+ end
116
+
117
+ class UnmatchedSerializerError < ConfigurationError
118
+ def initialize(serializer)
119
+ super("Called render_media with a resolved serializer that was not specified in the do block. Please add a 'serializer #{serializer.name}, <value>' entry.")
120
+ end
121
+ end
122
+
123
+ class VersionsNotAnArrayError < ConfigurationError
124
+ def initialize
125
+ super('Tried to create an input or output with a versions: parameter that is set to something that is not an array. Please use the version: parameter or conver the current value to an array.')
126
+ end
127
+ end
128
+ class ViewsNotAnArrayError < ConfigurationError
129
+ def initialize
130
+ super('Tried to create an input or output with a views: parameter that is set to something that is not an array. Please use the view: parameter or conver the current value to an array.')
131
+ end
132
+ end
133
+
134
+ class NoValidatorSetError < ConfigurationError
135
+ def initialize
136
+ super("Unable to return validator as no validator has been set. Either someone tried to fetch the currently defined validator or someone tried to set the validator to 'nil'.")
137
+ end
138
+ end
139
+
140
+ class NoSelfLinkProvidedError < ConfigurationError
141
+ def initialize(media_type_identifier)
142
+ super("Tried to render an index of '#{media_type_identifier}' elements but the serializer did not return a :self link for me to use. Please call 'link rel: :self, href: 'https://...' in the #{media_type_identifier} serializer.")
143
+ end
144
+ end
145
+
146
+ class MultipleSelfLinksProvidedError < ConfigurationError
147
+ def initialize(media_type_identifier)
148
+ super("Tried to render an index of '#{media_type_identifier}' elements but the serializer returned more than one :self link. Please make sure to only call 'link rel: :self, ...' once in the #{media_type_identifier} serializer.")
149
+ end
150
+ end
151
+
152
+ class ArrayInViewParameterError < ConfigurationError
153
+ def initialize(function)
154
+ super("Tried to call #{function} with an array in the view: parameter. Please use the views: parameter instead.")
155
+ end
156
+ end
157
+
158
+ class SerializersNotFrozenError < ConfigurationError
159
+ def initialize
160
+ super("Unable to serialize or deserialize objects with unfrozen serializers. Please add 'freeze_io!' to the controller definition.")
161
+ end
162
+ end
163
+
164
+ class SerializersAlreadyFrozenError < ConfigurationError
165
+ def initialize
166
+ super("Unable to add a serializer when they are already frozen. Please make sure to call 'freeze_io!' last.")
167
+ end
168
+ end
169
+
170
+ class UnableToRefreezeError < ConfigurationError
171
+ def initialize
172
+ super("Freeze was called while the serializers are already frozen. Please make sure to only call 'freeze_io!' once.")
173
+ end
174
+ end
175
+
176
+ class NoOutputSerializersDefinedError < ConfigurationError
177
+ def intialize
178
+ super("Called freeze_io! without any allowed output serializers. Users won't be able to make any requests. Please make sure to add at least one allow_output_serializer call to your controller.")
179
+ end
180
+ end
181
+
182
+ class AddedEmptyOutputSerializer < ConfigurationError
183
+ def initialize(name)
184
+ super("A serializer with name '#{name}' was just added to the controller but it contained no output definitions. Usually this is due to using the wrong view parameter when adding it.")
185
+ end
186
+ end
187
+ class AddedEmptyInputSerializer < ConfigurationError
188
+ def initialize(name)
189
+ super("A serializer with name '#{name}' was just added to the controller but it contained no input definitions. Usually this is due to using the wrong view parameter when adding it.")
190
+ end
191
+ end
192
+ end
193
+ end
@@ -1,53 +1,53 @@
1
-
2
- # Validator that accepts all input
3
- class FakeValidator
4
- def initialize(prefix, view = nil, version = nil, suffixes = {})
5
- self.prefix = prefix
6
- self.suffixes = suffixes
7
- self.internal_view = view
8
- self.internal_version = version
9
- end
10
-
11
- UNSET = Object.new
12
-
13
- def view(view = UNSET)
14
- return self.internal_view if view == UNSET
15
- FakeValidator.new(prefix, view, internal_version, suffixes)
16
- end
17
-
18
- def version(version = UNSET)
19
- return self.internal_version if version == UNSET
20
- FakeValidator.new(prefix, internal_view, version, suffixes)
21
- end
22
-
23
- def override_suffix(suffix)
24
- suffixes[[internal_view, internal_version]] = suffix
25
- FakeValidator.new(prefix, internal_view, version, suffixes)
26
- end
27
-
28
- def identifier
29
- suffix = suffixes[[internal_view, internal_version]] || ''
30
- result = prefix
31
- result += '.v' + internal_version.to_s unless internal_version.nil?
32
- result += '.' + internal_view.to_s unless internal_view.nil?
33
- result += '+' + suffix.to_s unless suffix.empty?
34
-
35
- result
36
- end
37
-
38
- def validatable?
39
- true
40
- end
41
-
42
- def validate!(_)
43
- true
44
- end
45
-
46
- attr_accessor :prefix
47
- attr_accessor :suffixes
48
-
49
- protected
50
-
51
- attr_accessor :internal_view
52
- attr_accessor :internal_version
53
- end
1
+
2
+ # Validator that accepts all input
3
+ class FakeValidator
4
+ def initialize(prefix, view = nil, version = nil, suffixes = {})
5
+ self.prefix = prefix
6
+ self.suffixes = suffixes
7
+ self.internal_view = view
8
+ self.internal_version = version
9
+ end
10
+
11
+ UNSET = Object.new
12
+
13
+ def view(view = UNSET)
14
+ return self.internal_view if view == UNSET
15
+ FakeValidator.new(prefix, view, internal_version, suffixes)
16
+ end
17
+
18
+ def version(version = UNSET)
19
+ return self.internal_version if version == UNSET
20
+ FakeValidator.new(prefix, internal_view, version, suffixes)
21
+ end
22
+
23
+ def override_suffix(suffix)
24
+ suffixes[[internal_view, internal_version]] = suffix
25
+ FakeValidator.new(prefix, internal_view, version, suffixes)
26
+ end
27
+
28
+ def identifier
29
+ suffix = suffixes[[internal_view, internal_version]] || ''
30
+ result = prefix
31
+ result += '.v' + internal_version.to_s unless internal_version.nil?
32
+ result += '.' + internal_view.to_s unless internal_view.nil?
33
+ result += '+' + suffix.to_s unless suffix.empty?
34
+
35
+ result
36
+ end
37
+
38
+ def validatable?
39
+ true
40
+ end
41
+
42
+ def validate!(_)
43
+ true
44
+ end
45
+
46
+ attr_accessor :prefix
47
+ attr_accessor :suffixes
48
+
49
+ protected
50
+
51
+ attr_accessor :internal_view
52
+ attr_accessor :internal_version
53
+ end