dry-swagger 0.5.2 → 0.6.0

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: 7ed13f9dd94583c53a6397262cd798a8a8897b4ac7d7f1c4484116751ff37e5d
4
- data.tar.gz: 777014e503f1f3febde2662275cf858a423806671e0ee4a843be3af43287df10
3
+ metadata.gz: 81ebe584ca27d649b54274106892160bc2b093f99b478dffc06873da1d4e46a5
4
+ data.tar.gz: eaecf374689642228916df2b7abf02799aa6ac6f22c7d31cbc1786ba215527d1
5
5
  SHA512:
6
- metadata.gz: 16a4528fbed7c9dfaba78a4757f489f49e80ffef3801b8cf5a10a49c13951530789ffb2ef1e89daba94b618ef8c3348cb4d4790e4e26db420eef74548cc51664
7
- data.tar.gz: a3411261ed52732f5d85fa7402fe232fbd4596b0d4618e22316d8f7f37ee70715481340a9256969a81418ba6c99b2321bcd09570ca371a9ec9c27702c48b5f2b
6
+ metadata.gz: e29e1554ee459d668656ef0dfb9dba87dc531cd27d841a3b6dc77eb9d97eb5b40a7fee88fdc3cf968e4b87db65ba7ee4dec285d24e619ad4149b7ba012ba02b8
7
+ data.tar.gz: 61a89adcc627a3ee432cfdad4de2d1bafb1ee215046f46e4fa20188111e1676ff87507587c612474dc0441d207944e1c794c37246b851ff6428221f510c3f6fb
data/.gitignore CHANGED
@@ -10,3 +10,4 @@
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
12
  .idea/
13
+ config/
data/Gemfile CHANGED
@@ -7,3 +7,4 @@ gem "rake", "~> 12.0"
7
7
  gem "rspec", "~> 3.0"
8
8
  gem "dry-validation"
9
9
  gem "dry-struct"
10
+ gem 'i18n'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dry-swagger (0.5.2)
4
+ dry-swagger (0.6.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -46,6 +46,8 @@ GEM
46
46
  dry-equalizer (~> 0.2)
47
47
  dry-initializer (~> 3.0)
48
48
  dry-schema (~> 1.5, >= 1.5.2)
49
+ i18n (1.8.10)
50
+ concurrent-ruby (~> 1.0)
49
51
  ice_nine (0.11.2)
50
52
  rake (12.3.3)
51
53
  rspec (3.10.0)
@@ -69,6 +71,7 @@ DEPENDENCIES
69
71
  dry-struct
70
72
  dry-swagger!
71
73
  dry-validation
74
+ i18n
72
75
  rake (~> 12.0)
73
76
  rspec (~> 3.0)
74
77
 
data/README.md CHANGED
@@ -15,269 +15,269 @@ And then execute:
15
15
 
16
16
  bundle install
17
17
 
18
- Or install it yourself as:
19
-
20
- gem install dry-swagger
21
-
22
- ## Usage
23
- ## Dry::Validation::Contract
24
- class Contract < Dry::Validation::Contract
25
- json do
26
- required(:required_field).value(:str?)
27
- required(:required_nullable_field).maybe(:str?)
28
- required(:required_filled_field).filled(:str?)
29
-
30
- optional(:optional_field).value(:str?)
31
- optional(:optional_nullable_field).maybe(:str?)
32
- optional(:optional_filled_field).filled(:str?)
33
- end
34
- end
18
+ After installing, execute the following command:
35
19
 
36
- Dry::Swagger::ContractParser.new.call(Contract).to_swagger
37
- => {
38
- "type": "object",
39
- "properties": {
40
- "required_field": {
41
- "type": "string",
42
- "nullable": false
43
- },
44
- "required_nullable_field": {
45
- "type": "string",
46
- "nullable": true
47
- },
48
- "required_filled_field": {
49
- "type": "string",
50
- "nullable": false
51
- },
52
- "optional_field": {
53
- "type": "string",
54
- "nullable": false
55
- },
56
- "optional_nullable_field": {
57
- "type": "string",
58
- "nullable": true
59
- },
60
- "optional_filled_field": {
61
- "type": "string",
62
- "nullable": false
63
- }
64
- },
65
- "required": [
66
- "required_field",
67
- "required_nullable_field",
68
- "required_filled_field"
69
- ]
70
- }
71
- #### With nested fields - hash or array
72
- class Contract < Dry::Validation::Contract
73
- json do
74
- required(:array_field).array(:int?)
75
- required(:array_of_hash).array(:hash) do
76
- required(:field).value(:str?)
77
- end
78
- required(:hash_field).hash do
79
- required(:field).value(:str?)
20
+ rake dry-swagger:install
21
+
22
+ This will generate configuration files in your project under `project/config`. See Configuration section for more details.
23
+
24
+ ##Usage
25
+
26
+ ####With Dry::Validation::Contract
27
+ Lets say we have the following Dry::Validation::Contract definition:
28
+
29
+ class TestContract < Dry::Validation::Contract
30
+ params do
31
+ required(:some_field).value(:str?, min_size?: 5, max_size?: 10)
32
+ required(:some_array_of_objects).array(:hash) do
33
+ required(:some_nested_attribute).value(:str?)
34
+ end
35
+ required(:some_array_of_integers).array(:int?)
36
+ required(:dto).value(:hash) do
37
+ optional(:some_nested_attribute).maybe(:str?)
38
+ end
80
39
  end
81
- end
82
40
  end
83
41
 
84
- Dry::Swagger::ContractParser.new.call(Contract).to_swagger
85
- => {
86
- "type": "object",
87
- "properties": {
88
- "array_field": {
89
- "type": "array",
90
- "items": {
91
- "type": "integer"
92
- }
93
- },
94
- "array_of_hash": {
95
- "type": "array",
96
- "items": {
97
- "type": "object",
98
- "properties": {
99
- "field": {
100
- "type": "string",
101
- "x-nullable": false
102
- }
103
- },
104
- "required": [
105
- "field"
106
- ]
107
- }
108
- },
109
- "hash_field": {
110
- "type": "object",
111
- "properties": {
112
- "field": {
113
- "type": "string",
114
- "x-nullable": false
115
- }
116
- },
117
- "required": [
118
- "field"
119
- ]
120
- }
121
- },
122
- "required": [
123
- "array_field",
124
- "array_of_hash",
125
- "hash_field"
126
- ]
127
- }
42
+ parser = Dry::Swagger::ContractParser.new
128
43
 
129
- ### With Dry::Struct
130
- class DTO < Dry::Struct
131
- attribute :required_string, Types::String
132
- attribute :required_nullable_string, Types::String.optional
133
- attribute :required_string_with_enum, Types::String.enum('enum1')
134
- attribute? :optional_string, Types::String
135
- attribute? :optional_nullable_string, Types::String.optional
136
- end
44
+ `parser.call(TestContract)` will set the `keys` of the `parser` object to:
137
45
 
138
- Dry::Swagger::StructParser.new.call(DTO).to_swagger
139
- => {
140
- "type": "object",
141
- "properties": {
142
- "required_string": {
143
- "type": "string",
144
- "x-nullable": false
145
- },
146
- "required_nullable_string": {
147
- "type": "string",
148
- "x-nullable": true
149
- },
150
- "required_string_with_enum": {
151
- "type": "string",
152
- "enum": [
153
- "enum1"
154
- ],
155
- "x-nullable": false
156
- },
157
- "optional_string": {
158
- "type": "string",
159
- "x-nullable": false
160
- },
161
- "optional_nullable_string": {
162
- "type": "string",
163
- "x-nullable": true
164
- }
46
+ {
47
+ :some_field => {
48
+ :required => true,
49
+ :type => "string",
50
+ :description => "Minimum size: 5, Maximum size: 10"
51
+ },
52
+ :some_array_of_objects => {
53
+ :required => true,
54
+ :array => true,
55
+ :type => "array",
56
+ :keys => {
57
+ :some_nested_attribute => {
58
+ :required=>true, :type=>"string"
59
+ }
60
+ }
165
61
  },
166
- "required": [
167
- "required_string",
168
- "required_nullable_string",
169
- "required_string_with_enum"
170
- ]
171
- }
172
- #### With nested fields
173
- class NestedDTO < Dry::Struct
174
- attribute :required_string, Types::String
175
- attribute :required_nullable_string, Types::String.optional
176
- attribute :required_string_with_enum, Types::String.enum('enum1')
177
- attribute? :optional_string, Types::String
178
- attribute? :optional_nullable_string, Types::String.optional
179
- end
180
-
181
- class DTO < Dry::Struct
182
- attribute :array_of_integer, Types::Array.of(Types::Integer)
183
- attribute :array_of_objects, Types::Array.of(NestedDTO)
184
- attribute :dto, NestedDTO
185
- end
62
+ :some_array_of_integers => {
63
+ :required=>true,
64
+ :array=>true,
65
+ :type=>"integer"
66
+ },
67
+ :dto => {
68
+ :required => true,
69
+ :type => "hash",
70
+ :keys => {
71
+ :some_nested_attribute => {
72
+ :required => false,
73
+ :"x-nullable"=>true,
74
+ :type=>"string"
75
+ }
76
+ }
77
+ }
78
+ }
79
+
80
+ As we can see, the `ContractParser` goes through all the params defined in the
81
+ schema and generates a hash. The hash is saved in the `keys` attribute of the parser,
82
+ so that we can call `to_swagger` later.
83
+
84
+ The required key in our result will be set to `true` if the field is defined as
85
+ `required(:field_name)`, and `false` if defined as `optional(:field_name)`.
86
+
87
+ The "x-nullable" key depends on whether we have defined the field as value, maybe or filled.
88
+
89
+ For nested objects like array of objects or hash, we add a keys field with a definition
90
+ for each field inside the nested hash.
91
+
92
+ If the field is an array of primitive type, the type field will equal to the primitive type, and a
93
+ array flag will be set on the field.
94
+
95
+ Calling `parser.to_swagger` will give the following result:
186
96
 
187
- Dry::Swagger::StructParser.new.call(DTO).to_swagger
188
- => {
97
+ {
189
98
  "type": "object",
190
99
  "properties": {
191
- "array_of_integer": {
192
- "type": "array",
193
- "items": {
194
- "type": "integer"
195
- },
100
+ "some_field": {
101
+ "type": "string",
102
+ "description": "Minimum size: 5, Maximum size: 10",
196
103
  "x-nullable": false
197
104
  },
198
- "array_of_objects": {
105
+ "some_array_of_objects": {
199
106
  "type": "array",
200
107
  "items": {
201
108
  "type": "object",
202
109
  "properties": {
203
- "required_string": {
204
- "type": "string",
205
- "x-nullable": false
206
- },
207
- "required_nullable_string": {
208
- "type": "string",
209
- "x-nullable": true
210
- },
211
- "required_string_with_enum": {
212
- "type": "string",
213
- "enum": [
214
- "enum1"
215
- ],
216
- "x-nullable": false
217
- },
218
- "optional_string": {
110
+ "some_nested_attribute": {
219
111
  "type": "string",
220
112
  "x-nullable": false
221
- },
222
- "optional_nullable_string": {
223
- "type": "string",
224
- "x-nullable": true
225
113
  }
226
114
  },
227
115
  "required": [
228
- "required_string",
229
- "required_nullable_string",
230
- "required_string_with_enum"
231
- ]
116
+ "some_nested_attribute"
117
+ ],
118
+ "x-nullable": false
119
+ },
120
+ "x-nullable": false
121
+ },
122
+ "some_array_of_integers": {
123
+ "type": "array",
124
+ "items": {
125
+ "type": "integer",
126
+ "x-nullable": false
232
127
  },
233
128
  "x-nullable": false
234
129
  },
235
130
  "dto": {
236
131
  "type": "object",
237
132
  "properties": {
238
- "required_string": {
239
- "type": "string",
240
- "x-nullable": false
241
- },
242
- "required_nullable_string": {
243
- "type": "string",
244
- "x-nullable": true
245
- },
246
- "required_string_with_enum": {
247
- "type": "string",
248
- "enum": [
249
- "enum1"
250
- ],
251
- "x-nullable": false
252
- },
253
- "optional_string": {
254
- "type": "string",
255
- "x-nullable": false
256
- },
257
- "optional_nullable_string": {
133
+ "some_nested_attribute": {
258
134
  "type": "string",
259
135
  "x-nullable": true
260
136
  }
261
137
  },
262
138
  "required": [
263
- "required_string",
264
- "required_nullable_string",
265
- "required_string_with_enum"
139
+
266
140
  ],
267
141
  "x-nullable": false
268
142
  }
269
143
  },
270
144
  "required": [
271
- "array_of_integer",
272
- "array_of_objects",
145
+ "some_field",
146
+ "some_array_of_objects",
147
+ "some_array_of_integers",
273
148
  "dto"
274
149
  ]
275
150
  }
276
- ## Overriding fields on run time
277
- You can also modify the fields during runtime by passing a block after the .call() method.
278
151
 
279
- For example:
152
+ ####With Dry::Struct
153
+ The `Dry::Swagger::StructParser` works the same as the contract parser.
154
+
155
+ The required key depends on whether we define the field as attribute or attribute?
156
+
157
+ The "x-nullable" key depends on whether we define the type as Type or Type.optional.
158
+
159
+ For more complex types, for example DTO1 | DTO2 or Types::Array.of(DTO1 | DTO2),
160
+ the parser converts the field value to an array of both schemas.
161
+
162
+ Example:
163
+
164
+ class DTO1 < Dry::Struct
165
+ attribute :dto1_field, Types::String
166
+ end
167
+
168
+ class DTO2 < Dry::Struct
169
+ attribute :dto2_field, Types::String
170
+ end
171
+
172
+ class DTO < Dry::Struct
173
+ attribute :dynamic_dto, DTO1 | DTO2
174
+ end
175
+ parser = Dry::Swagger::StructParser.new
176
+
177
+ parser.call(DTO)
178
+ => {
179
+ "dynamic_dto": [ # ARRAY
180
+ {
181
+ "type": "hash",
182
+ "required": true,
183
+ "x-nullable": false,
184
+ "keys": {
185
+ "dto1_field": {
186
+ "type": "string",
187
+ "required": true,
188
+ "x-nullable": false
189
+ }
190
+ }
191
+ },
192
+ {
193
+ "type": "hash",
194
+ "required": true,
195
+ "x-nullable": false,
196
+ "keys": {
197
+ "dto2_field": {
198
+ "type": "string",
199
+ "required": true,
200
+ "x-nullable": false
201
+ }
202
+ }
203
+ }
204
+ ]
205
+ }
206
+
207
+ Calling `parser.to_swagger` will give the following result:
280
208
 
209
+ {
210
+ "type": "object",
211
+ "properties": {
212
+ "dynamic_dto": {
213
+ "type": "object",
214
+ "properties": {
215
+ "definition_1": {
216
+ "type": "object",
217
+ "properties": {
218
+ "dto1_field": {
219
+ "type": "string",
220
+ "x-nullable": false
221
+ }
222
+ },
223
+ "required": [
224
+ "dto1_field"
225
+ ],
226
+ "x-nullable": false
227
+ },
228
+ "definition_2": {
229
+ "type": "object",
230
+ "properties": {
231
+ "dto2_field": {
232
+ "type": "string",
233
+ "x-nullable": false
234
+ }
235
+ },
236
+ "required": [
237
+ "dto2_field"
238
+ ],
239
+ "x-nullable": false
240
+ }
241
+ },
242
+ "example": "Dynamic Field. See Model Definitions",
243
+ "oneOf": [
244
+ {
245
+ "type": "object",
246
+ "properties": {
247
+ "dto1_field": {
248
+ "type": "string",
249
+ "x-nullable": false
250
+ }
251
+ },
252
+ "required": [
253
+ "dto1_field"
254
+ ],
255
+ "x-nullable": false
256
+ },
257
+ {
258
+ "type": "object",
259
+ "properties": {
260
+ "dto2_field": {
261
+ "type": "string",
262
+ "x-nullable": false
263
+ }
264
+ },
265
+ "required": [
266
+ "dto2_field"
267
+ ],
268
+ "x-nullable": false
269
+ }
270
+ ]
271
+ }
272
+ },
273
+ "required": [
274
+ "dynamic_dto"
275
+ ]
276
+ }
277
+
278
+ ## Overriding fields
279
+ You can also modify the fields by passing a block after the .call() method.
280
+
281
281
  Dry::Swagger::StructParser.new.call(DTO) do |it|
282
282
  # types = string/integer/hash/array
283
283
 
@@ -311,26 +311,12 @@ For example:
311
311
  }
312
312
 
313
313
  end.to_swagger()
314
- ## Custom Configuration For Your Project
315
- You can override default configurations by creating a file in config/initializers/dry-swagger.rb and changing the following values.
316
-
317
- Dry::Swagger::Config::StructConfiguration.configuration do |config|
318
- config.enable_required_validation = true / false
319
- config.enable_nullable_validation = true / false
320
- config.enable_enums = true / false
321
- config.enable_descriptions = true / false
322
- config.nullable_type = :"x-nullable" / :nullable
323
- end
324
314
 
325
- Dry::Swagger::Config::ContractConfiguration.configuration do |config|
326
- config.enable_required_validation = true / false
327
- config.enable_nullable_validation = true / false
328
- config.enable_enums = true / false
329
- config.enable_descriptions = true / false
330
- config.nullable_type = :"x-nullable" / :nullable
331
- end
332
-
333
- By default, all these settings are true, and nullable_type is :"x-nullable".
315
+ ##Custom Configuration For Your Project
316
+ You can override default configurations by changing the values in the `config/initializers/dry-swagger.rb` file generated from the rake command in the Installation section.
317
+
318
+ To modify the descriptions for the Contracts, modify the values in `config/locale/dry-swagger.yml`.
319
+
334
320
  ## Development
335
321
 
336
322
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/lib/dry/swagger.rb CHANGED
@@ -7,8 +7,10 @@ require 'dry/swagger/errors/missing_type_error'
7
7
  require 'dry/swagger/config/configuration'
8
8
  require 'dry/swagger/config/contract_configuration'
9
9
  require 'dry/swagger/config/struct_configuration'
10
+ require 'i18n'
10
11
 
11
12
  module Dry
12
13
  module Swagger
14
+ ::I18n.load_path << Dir[File.expand_path("config/locales") + "/*.yml"]
13
15
  end
14
16
  end
@@ -116,18 +116,8 @@ module Dry
116
116
  end
117
117
  end
118
118
 
119
- def predicate_description(name, validation)
120
- case name
121
- when 'eql?' then "Must be equal to #{validation}"
122
- when 'max_size?' then "Maximum size: #{validation}"
123
- when 'min_size?' then "Minimum size: #{validation}"
124
- when 'gteq?' then "Greater or equal #{validation}"
125
- when 'gt?' then "Greater than #{validation}"
126
- when 'lt?' then "Lower than #{validation}"
127
- when 'lteq?' then "Lower than or equal to #{validation}"
128
- else
129
- ''
130
- end
119
+ def predicate_description(name, value)
120
+ ::I18n.t("contract.descriptions.#{name}", value: value, default: '')
131
121
  end
132
122
 
133
123
  def to_swagger
@@ -17,83 +17,90 @@ module Dry
17
17
 
18
18
  def generate_documentation(fields)
19
19
  documentation = { properties: {}, required: [] }
20
- fields.each do |field_name, attributes_hash|
21
- documentation[:properties][field_name] = generate_field_properties(attributes_hash)
22
- if attributes_hash.is_a?(Hash)
23
- documentation[:required] << field_name if attributes_hash.fetch(:required, true) && @config.enable_required_validation
20
+ fields.each do |field_name, definition|
21
+ documentation[:properties][field_name] = generate_field_properties(definition)
22
+ if definition.is_a?(Hash)
23
+ documentation[:required] << field_name if definition.fetch(:required, true) && @config.enable_required_validation
24
24
  else
25
- documentation[:required] << field_name if attributes_hash[0].fetch(:required, true) && @config.enable_required_validation
25
+ documentation[:required] << field_name if definition[0].fetch(:required, true) && @config.enable_required_validation
26
26
  end
27
27
 
28
28
  rescue Errors::MissingTypeError => e
29
- raise StandardError.new e.message % { field_name: field_name, valid_types: SWAGGER_FIELD_TYPE_DEFINITIONS.keys, attributes_hash: attributes_hash }
29
+ raise StandardError.new e.message % { field_name: field_name, valid_types: SWAGGER_FIELD_TYPE_DEFINITIONS.keys, definition: definition }
30
30
  rescue Errors::MissingHashSchemaError => e
31
- raise StandardError.new e.message % { field_name: field_name, valid_types: SWAGGER_FIELD_TYPE_DEFINITIONS.keys, attributes_hash: attributes_hash }
31
+ raise StandardError.new e.message % { field_name: field_name, valid_types: SWAGGER_FIELD_TYPE_DEFINITIONS.keys, definition: definition }
32
32
  end
33
33
 
34
34
  { :type => :object, :properties => documentation[:properties], :required => documentation[:required] }
35
35
  end
36
36
 
37
- def generate_field_properties(attributes_hash)
38
- if attributes_hash.is_a?(Array)
39
- properties = {}
40
- attributes_hash.each_with_index do |_, index|
41
- properties["definition_#{index + 1}"] = generate_field_properties(attributes_hash[index])
42
- end
43
- if attributes_hash[0][:type] == 'array'
44
- attributes_hash.each { |definition| definition[:type] = 'hash'}
45
- {
46
- type: :array,
47
- items: {
48
- type: :object,
49
- properties: properties,
50
- oneOf: attributes_hash.map{ |it| generate_field_properties(it) },
51
- example: 'Dynamic Field. See Model Definitions'
52
- },
53
- }
54
- else
55
- {
56
- oneOf: attributes_hash.map{ |it| generate_field_properties(it) },
57
- type: :object,
58
- properties: properties,
59
- example: 'Dynamic Field. See Model Definitions'
60
- }
61
- end
62
- else
63
- if attributes_hash[:type] == 'array'
64
- items = generate_documentation(attributes_hash.fetch(:keys))
65
- items = @config.enable_nullable_validation ?
66
- items.merge(@config.nullable_type => attributes_hash.fetch(@config.nullable_type, false)) :
67
- items.merge(@config.nullable_type => true)
68
- documentation = { type: :array, items: items }
69
- elsif attributes_hash[:array] && attributes_hash.fetch(:type) != 'array'
70
- items = SWAGGER_FIELD_TYPE_DEFINITIONS.fetch(attributes_hash.fetch(:type))
71
- items = @config.enable_nullable_validation ?
72
- items.merge(@config.nullable_type => attributes_hash.fetch(@config.nullable_type, false)) :
73
- items.merge(@config.nullable_type => true)
74
- documentation = { type: :array, items: items }
75
- elsif attributes_hash[:type] == 'hash'
76
- raise Errors::MissingHashSchemaError.new unless attributes_hash[:keys]
77
- documentation = generate_documentation(attributes_hash.fetch(:keys))
78
- else
79
- documentation = SWAGGER_FIELD_TYPE_DEFINITIONS.fetch(attributes_hash.fetch(:type))
80
- if attributes_hash[:enum] && @config.enable_enums
81
- documentation = documentation.merge(enum: attributes_hash.fetch(:enum))
82
- end
83
-
84
- if attributes_hash[:description] && @config.enable_descriptions
85
- documentation = documentation.merge(description: attributes_hash.fetch(:description))
86
- end
87
- end
37
+ def generate_field_properties(definition)
38
+ return generate_for_sti_type(definition) if definition.is_a?(Array)
88
39
 
89
- @config.enable_nullable_validation ?
90
- documentation.merge(@config.nullable_type => attributes_hash.fetch(@config.nullable_type, false)) :
91
- documentation.merge(@config.nullable_type => true)
40
+ if definition[:type] == 'array' || definition[:array]
41
+ documentation = generate_for_array(definition)
42
+ elsif definition[:type] == 'hash'
43
+ documentation = generate_for_hash(definition)
44
+ else
45
+ documentation = generate_for_primitive_type(definition)
92
46
  end
47
+ @config.enable_nullable_validation ?
48
+ documentation.merge(@config.nullable_type => definition.fetch(@config.nullable_type, false)) :
49
+ documentation.merge(@config.nullable_type => true)
93
50
 
94
51
  rescue KeyError
95
52
  raise Errors::MissingTypeError.new
96
53
  end
54
+
55
+ def generate_for_sti_type(definition)
56
+ properties = {}
57
+
58
+ definition.each_with_index do |_, index|
59
+ properties["definition_#{index + 1}"] = generate_field_properties(definition[index])
60
+ end
61
+
62
+ documentation = {
63
+ type: :object,
64
+ properties: properties,
65
+ example: 'Dynamic Field. See Model Definitions'
66
+ }
67
+
68
+ if definition[0][:type] == 'array'
69
+ definition.each { |it| it[:type] = 'hash'}
70
+ documentation[:oneOf] = definition.map{ |it| generate_field_properties(it) }
71
+ { type: :array, items: documentation }
72
+ else
73
+ documentation[:oneOf] = definition.map{ |it| generate_field_properties(it) }
74
+ documentation
75
+ end
76
+ end
77
+
78
+ def generate_for_array(definition)
79
+ items = array_of_primitive_type?(definition) ?
80
+ SWAGGER_FIELD_TYPE_DEFINITIONS.fetch(definition.fetch(:type)) :
81
+ generate_documentation(definition.fetch(:keys))
82
+ items = @config.enable_nullable_validation ?
83
+ items.merge(@config.nullable_type => definition.fetch(@config.nullable_type, false)) :
84
+ items.merge(@config.nullable_type => true)
85
+ { type: :array, items: items }
86
+ end
87
+
88
+ def generate_for_hash(definition)
89
+ raise Errors::MissingHashSchemaError.new unless definition[:keys]
90
+ generate_documentation(definition.fetch(:keys))
91
+ end
92
+
93
+ def generate_for_primitive_type(definition)
94
+ documentation = SWAGGER_FIELD_TYPE_DEFINITIONS.fetch(definition.fetch(:type))
95
+ documentation = documentation.merge(enum: definition.fetch(:enum)) if definition[:enum] && @config.enable_enums
96
+ documentation = documentation.merge(description: definition.fetch(:description)) if definition[:description] &&
97
+ @config.enable_descriptions
98
+ documentation
99
+ end
100
+
101
+ def array_of_primitive_type?(definition)
102
+ definition[:array] && definition.fetch(:type) != 'array'
103
+ end
97
104
  end
98
105
  end
99
106
  end
@@ -6,7 +6,7 @@ module Dry
6
6
  "Could not generate documentation for field %{field_name}. The field is defined as hash,
7
7
  but the schema is not defined.
8
8
  Valid types are: %{valid_types}.
9
- The parser has generated the following definition for the field: %{field_name}: %{attributes_hash}
9
+ The parser has generated the following definition for the field: %{field_name}: %{definition}
10
10
  "
11
11
  end
12
12
  end
@@ -6,7 +6,7 @@ module Dry
6
6
  "Could not generate documentation for field %{field_name}. The field is missing a type.
7
7
  If the field you have defined is an array, you must specify the type of the elements in that array.
8
8
  Valid types are: %{valid_types}.
9
- The parser has generated the following definition for the field: %{field_name}: %{attributes_hash}.
9
+ The parser has generated the following definition for the field: %{field_name}: %{definition}.
10
10
  "
11
11
  end
12
12
  end
@@ -1,5 +1,5 @@
1
1
  module Dry
2
2
  module Swagger
3
- VERSION = "0.5.2"
3
+ VERSION = "0.6.0"
4
4
  end
5
5
  end
@@ -0,0 +1,49 @@
1
+ require 'fileutils'
2
+
3
+ namespace 'dry-swagger' do
4
+ desc 'Create a configuration file for Struct and Contract'
5
+ task :create_configuration_file do
6
+ FileUtils.mkdir_p "#{ Dir.pwd }/config/initializers/"
7
+ File.open("#{ Dir.pwd }/config/initializers/dry-swagger.rb", "w") { |file|
8
+ file.puts 'Dry::Swagger::Config::StructConfiguration.configuration do |config|
9
+ config.enable_required_validation = true
10
+ config.enable_nullable_validation = true
11
+ config.enable_enums = true
12
+ config.enable_descriptions = true
13
+ config.nullable_type = :"x-nullable" # or :nullable
14
+ end
15
+
16
+ Dry::Swagger::Config::ContractConfiguration.configuration do |config|
17
+ config.enable_required_validation = true
18
+ config.enable_nullable_validation = true
19
+ config.enable_enums = true
20
+ config.enable_descriptions = true
21
+ config.nullable_type = :"x-nullable" # or :nullable
22
+ end'
23
+ }
24
+ end
25
+
26
+ desc 'Create a YAML file for Contract swagger field descriptions'
27
+ task :create_contract_descriptions_yaml do
28
+ FileUtils.mkdir_p "#{ Dir.pwd }/config/locales/"
29
+ File.open("#{ Dir.pwd }/config/locales/dry-swagger.yml", "w") { |file|
30
+ file.puts 'en:
31
+ contract:
32
+ descriptions:
33
+ eql?: "Must be equal to %{value}"
34
+ max_size?: "Maximum size: %{value}"
35
+ min_size?: "Minimum size: %{value}"
36
+ gteq?: "Greater than or equal to %{value}"
37
+ gt?: "Greater than %{value}"
38
+ lt?: "Lower than %{value}"
39
+ lteq?: "Lower than or equal to %{value}"
40
+ '
41
+ }
42
+ end
43
+
44
+ desc 'Creates configuration files'
45
+ task :install do
46
+ Rake::Task['dry-swagger:create_configuration_file'].execute
47
+ Rake::Task['dry-swagger:create_contract_descriptions_yaml'].execute
48
+ end
49
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-swagger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jane-Terziev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-08-03 00:00:00.000000000 Z
11
+ date: 2021-08-06 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A parser which converts dry-validation or dry-struct into valid swagger
14
14
  documentation
@@ -42,6 +42,7 @@ files:
42
42
  - lib/dry/swagger/struct_parser.rb
43
43
  - lib/dry/swagger/types.rb
44
44
  - lib/dry/swagger/version.rb
45
+ - rakelib/configuration_generator.rake
45
46
  homepage: https://github.com/Jane-Terziev/dry-swagger
46
47
  licenses:
47
48
  - MIT