praxis 2.0.pre.28 → 2.0.pre.29

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: 516db7752a3c4d1e8aa48abe0967781c9f6b31a65155a18285febb30c058e823
4
- data.tar.gz: f404aaf78564a04b4835c70928584a82f3313b013c71f1d5e28e78f3e814296c
3
+ metadata.gz: e8f0514dd2a155733de0efe5586dd4b0409c70a9b385822b15e39934a7b83ea2
4
+ data.tar.gz: ff66561cdaadb84a9c97b83c044c423561b6506e10a31cf72d032dce73dcb50c
5
5
  SHA512:
6
- metadata.gz: 5b1eae94ededb45b3cd48fdfe2440c5ac41af66b5c251e3a682906709d67a15d02d7463c7dc2e384fb4c217a745b7cec438b0d919e614f5f4c4c499a94cb17a4
7
- data.tar.gz: fe8c7d881560b09702a4fe63680046f472efebb18aa1c09b01138b6dd9569727d29759bfc0e765095d52ec92df1c136e1de1419bf3fe282cc0b56e92cb3b1c9e
6
+ metadata.gz: 9bcb89e0426fb2e9e8ea51e7794a42f0a1ec6969fce436196da8c9d32697b232a02bddb0008400d51c6dc8b2d475e1122283da8644ed78bb448d759fbf4f2363
7
+ data.tar.gz: 5c0a71be2bb1043ccc4269ccfa258d01e93b66d4dfa2f69938f5a495d8a296a305d2b8051c84a6683343672a69cd01e20f717dc87f4bf5ca4049b587438a3194
data/CHANGELOG.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # Praxis Changelog
2
2
 
3
3
  ## next
4
+
5
+ ## 2.0.pre.29
6
+ * Assorted set of fixes to generate cleaner and more compliant OpenApi documents.
7
+ * Mostly in the area of multipart generation, and requirements and nullability for OpenApi 3.0
4
8
  ## 2.0.pre.28
5
9
  * Enhance the mapper's Resource property to allow for a couple more powerful options using the `as:` keyword:
6
10
  * `as: :self` will provide a way to map any further incoming fields on top of the already existing object. This is useful when we want to expose some properties for a resource, grouped within a sub structure, but that in reality they exist directly in the resource's underlying model (i.e., to organize the information of the model in a more structured/groupable way).
@@ -45,15 +45,22 @@ module Praxis
45
45
 
46
46
  if example_payload
47
47
  examples_by_content_type = {}
48
- rendered_payload = example_payload.dump
48
+ # We don't need to provide top-level examples for a multipart payload...each part
49
+ # will provide its own example (and assembling a proper structured example for the whole
50
+ # body isn't necessarily trivial based on the spec)
51
+ # If we need to, someday, we can create the rendered_paylod by calling MultipartArray.self.dump_for_openapi
52
+ # and properly complete that code to generate the appropriate thing, including the encoding etc...
53
+ unless type < Praxis::Types::MultipartArray
54
+ rendered_payload = example_payload.dump
49
55
 
50
- example_handlers.each do |spec|
51
- content_type, handler_name = spec.first
52
- handler = Praxis::Application.instance.handlers[handler_name]
53
- # ReDoc is not happy to display json generated outputs when served as JSON...wtf?
54
- generated = handler.generate(rendered_payload)
55
- final = handler_name == 'json' ? JSON.parse(generated) : generated
56
- examples_by_content_type[content_type] = final
56
+ example_handlers.each do |spec|
57
+ content_type, handler_name = spec.first
58
+ handler = Praxis::Application.instance.handlers[handler_name]
59
+ # ReDoc is not happy to display json generated outputs when served as JSON...wtf?
60
+ generated = handler.generate(rendered_payload)
61
+ final = handler_name == 'json' ? JSON.parse(generated) : generated
62
+ examples_by_content_type[content_type] = final
63
+ end
57
64
  end
58
65
  end
59
66
 
@@ -23,13 +23,14 @@ module Praxis
23
23
  # so we'll show all the supported MTs...but repeating the schema
24
24
  # dumped_schema = SchemaObject.new(info: attribute).dump_schema
25
25
 
26
- example_handlers = if attribute.type < Praxis::Types::MultipartArray
27
- ident = MediaTypeIdentifier.load('multipart/form-data')
28
- [{ ident.to_s => 'plain' }] # Multipart content type, but with the plain renderer (so there's no modification)
29
- else
30
- # TODO: We could run it through other handlers I guess...if they're registered
31
- [{ 'application/json' => 'json' }]
32
- end
26
+ example_handlers = \
27
+ if attribute.type < Praxis::Types::MultipartArray
28
+ ident = MediaTypeIdentifier.load('multipart/form-data')
29
+ [{ ident.to_s => 'json' }] # Multipart content type
30
+ else
31
+ # TODO: We could run it through other handlers I guess...if they're registered
32
+ [{ 'application/json' => 'json' }]
33
+ end
33
34
 
34
35
  h[:content] = MediaTypeObject.create_content_attribute_helper(type: attribute.type,
35
36
  example_payload: attribute.example(nil),
@@ -31,7 +31,7 @@ module Praxis
31
31
 
32
32
  def dump_schema(shallow: false, allow_ref: false)
33
33
  # We will dump schemas for mediatypes by simply creating a reference to the components' section
34
- if type < Attributor::Container
34
+ if type < Attributor::Container && ! (type < Praxis::Types::MultipartArray)
35
35
  if (type < Praxis::Blueprint || type < Attributor::Model) && allow_ref && !type.anonymous?
36
36
  # TODO: Do we even need a description?
37
37
  h = @attribute_options[:description] ? { 'description' => @attribute_options[:description] } : {}
@@ -47,10 +47,11 @@ module Praxis
47
47
  props = type.attributes.transform_values.with_index do |definition, index|
48
48
  # if type has an attribute in its requirements all, then it should be marked as required here
49
49
  field_name = type.attributes.keys[index]
50
- definition.options.merge!(required: true) if required_attributes.include?(field_name)
51
50
  OpenApi::SchemaObject.new(info: definition).dump_schema(allow_ref: true, shallow: shallow)
52
51
  end
53
- h = { type: :object, properties: props } # TODO: Example?
52
+ h = { type: :object}
53
+ h[:properties] = props if props.presence
54
+ h[:required] = required_attributes unless required_attributes.empty?
54
55
  end
55
56
  else
56
57
  # OpenApi::SchemaObject.new(info:target).dump_schema(allow_ref: allow_ref, shallow: shallow)
@@ -61,12 +62,8 @@ module Praxis
61
62
 
62
63
  # Tag on OpenAPI specific requirements that aren't already added in the underlying JSON schema model
63
64
  # Nullable: (it seems we need to ensure there is a null option to the enum, if there is one)
64
- if @attribute_options[:null]
65
- h[:nullable] = @attribute_options[:null]
66
- h[:enum] = h[:enum] + [nil] if h[:enum] && !h[:enum].include?(nil)
67
- end
68
- # Required: Mostly for request bodies
69
- h[:required] = true if @attribute_options[:required]
65
+ is_nullable = @attribute_options[:null]
66
+ h[:nullable] = true if is_nullable
70
67
  h
71
68
 
72
69
  # # TODO: FIXME: return a generic object type if the passed info was weird.
@@ -117,10 +117,10 @@ module Praxis
117
117
  openapi: '3.0.2',
118
118
  info: info_object.dump,
119
119
  servers: [server_object.dump],
120
- paths: paths_object.dump
120
+ paths: paths_object.dump,
121
+ security: [] # NOTE: No security definitions in Praxis. Leave it empty, to not anger linters
121
122
  # responses: {}, #TODO!! what do we get here? the templates?...need to transform to "Responses Definitions Object"
122
123
  # securityDefinitions: {}, # NOTE: No security definitions in Praxis
123
- # security: [], # NOTE: No security definitions in Praxis
124
124
  }
125
125
 
126
126
  # Create the top level tags by:
@@ -254,5 +254,10 @@ module Praxis
254
254
  ensure
255
255
  self.content_type = original_content_type
256
256
  end
257
+
258
+ def self.dump_for_openapi(example_part)
259
+ # TODO: This needs to be structured as OpenAPI requires it
260
+ raise "dumping a part for open api not implemented yet"
261
+ end
257
262
  end
258
263
  end
@@ -197,7 +197,7 @@ module Praxis
197
197
  encoding[key_to_use]['headers'] = headers_attribute.as_json_schema(example: part_example.headers)
198
198
  end
199
199
 
200
- hash[:properties] = props
200
+ hash[:properties] = props if props.presence
201
201
  hash[:encoding] = encoding unless encoding.empty?
202
202
  end
203
203
  hash
@@ -370,6 +370,10 @@ module Praxis
370
370
  all_entities = parts.join("\r\n--#{boundary}\r\n")
371
371
  "--#{boundary}\r\n#{all_entities}\r\n--#{boundary}--\r\n"
372
372
  end
373
+
374
+ def self.dump_for_openapi(example)
375
+ example.map {|part| MultipartPart.dump_for_openapi(part)}
376
+ end
373
377
  end
374
378
  end
375
379
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Praxis
4
- VERSION = '2.0.pre.28'
4
+ VERSION = '2.0.pre.29'
5
5
  end
data/praxis.gemspec CHANGED
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
23
23
  spec.executables << 'praxis'
24
24
 
25
25
  spec.add_dependency 'activesupport', '>= 3'
26
- spec.add_dependency 'attributor', '>= 6.4'
26
+ spec.add_dependency 'attributor', '>= 6.5'
27
27
  spec.add_dependency 'mime', '~> 0'
28
28
  spec.add_dependency 'mustermann', '>=1.1'
29
29
  spec.add_dependency 'rack', '>= 1'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: praxis
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.pre.28
4
+ version: 2.0.pre.29
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josep M. Blanquer
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-01-10 00:00:00.000000000 Z
12
+ date: 2023-01-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -31,14 +31,14 @@ dependencies:
31
31
  requirements:
32
32
  - - ">="
33
33
  - !ruby/object:Gem::Version
34
- version: '6.4'
34
+ version: '6.5'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - ">="
40
40
  - !ruby/object:Gem::Version
41
- version: '6.4'
41
+ version: '6.5'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: mime
44
44
  requirement: !ruby/object:Gem::Requirement