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

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.
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