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 +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/praxis/docs/open_api/media_type_object.rb +15 -8
- data/lib/praxis/docs/open_api/request_body_object.rb +8 -7
- data/lib/praxis/docs/open_api/schema_object.rb +6 -9
- data/lib/praxis/docs/open_api_generator.rb +2 -2
- data/lib/praxis/multipart/part.rb +5 -0
- data/lib/praxis/types/multipart_array.rb +5 -1
- data/lib/praxis/version.rb +1 -1
- data/praxis.gemspec +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e8f0514dd2a155733de0efe5586dd4b0409c70a9b385822b15e39934a7b83ea2
|
|
4
|
+
data.tar.gz: ff66561cdaadb84a9c97b83c044c423561b6506e10a31cf72d032dce73dcb50c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
-
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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 =
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
|
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
|
-
|
|
65
|
-
|
|
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
|
data/lib/praxis/version.rb
CHANGED
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.
|
|
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.
|
|
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-
|
|
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.
|
|
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.
|
|
41
|
+
version: '6.5'
|
|
42
42
|
- !ruby/object:Gem::Dependency
|
|
43
43
|
name: mime
|
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|