blueprinter_schema 0.4.0 → 0.4.2
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/lib/blueprinter_schema/generator.rb +104 -0
- data/lib/blueprinter_schema/version.rb +1 -1
- data/lib/blueprinter_schema.rb +3 -89
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a5c36ae7940be0f29d7fa96352756ac959c03dfb61d968d4080d1368a7eb29c
|
4
|
+
data.tar.gz: cf498e454ca5349f419ac3e2db8d1efe9ee686ae09d34570be8523757e983e42
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d5eaf5134861ca54d30c5e1380ba7e0afa15db73c692bc84591903a04b2d3a2190628e8221fd58506c0c328cf2da149f4df7813faeec29b92d2333910487cc93
|
7
|
+
data.tar.gz: 6259270843fd90b83c08d797d1cd81799072e5b5d0c4e2295353c9b963e6e06b8729dde7f45e41121d4416a709f11e8a1aa7ed0d2a977180de98424b4d493d3b
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BlueprinterSchema
|
4
|
+
class Generator
|
5
|
+
def initialize(serializer, model, options = { include_conditional_fields: true, fallback_type: {} })
|
6
|
+
@serializer = serializer
|
7
|
+
@model = model
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def generate
|
12
|
+
{
|
13
|
+
'type' => 'object',
|
14
|
+
'title' => @model.name,
|
15
|
+
'properties' => build_properties,
|
16
|
+
'required' => build_required_fields,
|
17
|
+
'additionalProperties' => false
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def fields
|
24
|
+
@fields ||= @serializer.reflections[:default].fields
|
25
|
+
end
|
26
|
+
|
27
|
+
def associations
|
28
|
+
@associations ||= @serializer.reflections[:default].associations
|
29
|
+
end
|
30
|
+
|
31
|
+
def build_properties
|
32
|
+
properties = {}
|
33
|
+
|
34
|
+
fields.each_value do |field|
|
35
|
+
next if skip_field?(field)
|
36
|
+
|
37
|
+
properties[field.display_name.to_s] = field_to_json_schema(field)
|
38
|
+
end
|
39
|
+
|
40
|
+
associations.each_value do |association|
|
41
|
+
properties[association.display_name.to_s] = association_to_json_schema(association)
|
42
|
+
end
|
43
|
+
|
44
|
+
properties
|
45
|
+
end
|
46
|
+
|
47
|
+
def skip_field?(field)
|
48
|
+
!@options[:include_conditional_fields] && (field.options[:if] || field.options[:unless])
|
49
|
+
end
|
50
|
+
|
51
|
+
def build_required_fields
|
52
|
+
fields.reject { |_, field| skip_field?(field) }.keys.map(&:to_s)
|
53
|
+
end
|
54
|
+
|
55
|
+
def field_to_json_schema(field)
|
56
|
+
column = @model.columns_hash[field.name.to_s]
|
57
|
+
|
58
|
+
ar_column_to_json_schema(column) || @options[:fallback_type]
|
59
|
+
end
|
60
|
+
|
61
|
+
# rubocop:disable Metrics/MethodLength
|
62
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
63
|
+
def ar_column_to_json_schema(column)
|
64
|
+
case column&.type
|
65
|
+
when :string, :text
|
66
|
+
build_json_schema_type('string', column.null)
|
67
|
+
when :integer
|
68
|
+
build_json_schema_type('integer', column.null)
|
69
|
+
when :float, :decimal
|
70
|
+
build_json_schema_type('number', column.null)
|
71
|
+
when :boolean
|
72
|
+
build_json_schema_type('boolean', column.null)
|
73
|
+
when :date
|
74
|
+
build_json_schema_type('string', column.null, 'date')
|
75
|
+
when :datetime, :timestamp
|
76
|
+
build_json_schema_type('string', column.null, 'date-time')
|
77
|
+
when :uuid
|
78
|
+
build_json_schema_type('string', column.null, 'uuid')
|
79
|
+
end
|
80
|
+
end
|
81
|
+
# rubocop:enable Metrics/MethodLength
|
82
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
83
|
+
|
84
|
+
def build_json_schema_type(json_schema_type, nullable, format = nil)
|
85
|
+
type = { 'type' => nullable ? [json_schema_type, 'null'] : json_schema_type }
|
86
|
+
type['format'] = format if format
|
87
|
+
type
|
88
|
+
end
|
89
|
+
|
90
|
+
def association_to_json_schema(association)
|
91
|
+
blueprint_class = association.options[:blueprint]
|
92
|
+
|
93
|
+
return { 'type' => 'object' } unless blueprint_class
|
94
|
+
|
95
|
+
ar_association = @model.reflect_on_association(association.name)
|
96
|
+
is_collection = ar_association.collection?
|
97
|
+
association_model = ar_association.klass
|
98
|
+
|
99
|
+
associated_schema = BlueprinterSchema.generate(blueprint_class, association_model)
|
100
|
+
|
101
|
+
is_collection ? { 'type' => 'array', 'items' => associated_schema } : associated_schema
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
data/lib/blueprinter_schema.rb
CHANGED
@@ -1,96 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'blueprinter_schema/version'
|
4
|
+
require_relative 'blueprinter_schema/generator'
|
4
5
|
|
5
6
|
module BlueprinterSchema
|
6
|
-
|
7
|
-
|
8
|
-
views = serializer.reflections
|
9
|
-
fields = views[:default].fields
|
10
|
-
associations = views[:default].associations
|
11
|
-
|
12
|
-
{
|
13
|
-
'type' => 'object',
|
14
|
-
'title' => model.name,
|
15
|
-
'properties' => build_properties(fields, associations, model, options),
|
16
|
-
'required' => build_required_fields(fields),
|
17
|
-
'additionalProperties' => false
|
18
|
-
}
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def build_properties(fields, associations, model, options)
|
24
|
-
properties = {}
|
25
|
-
|
26
|
-
fields.each_value do |field|
|
27
|
-
next if skip_field?(field, options)
|
28
|
-
|
29
|
-
properties[field.display_name.to_s] = field_to_json_schema(field, model, options)
|
30
|
-
end
|
31
|
-
|
32
|
-
associations.each_value do |association|
|
33
|
-
properties[association.display_name.to_s] = association_to_json_schema(association, model)
|
34
|
-
end
|
35
|
-
|
36
|
-
properties
|
37
|
-
end
|
38
|
-
|
39
|
-
def skip_field?(field, options)
|
40
|
-
!options[:include_conditional_fields] && (field.options[:if] || field.options[:unless])
|
41
|
-
end
|
42
|
-
|
43
|
-
def build_required_fields(fields)
|
44
|
-
fields.keys.map(&:to_s)
|
45
|
-
end
|
46
|
-
|
47
|
-
def field_to_json_schema(field, model, options)
|
48
|
-
column = model.columns_hash[field.name.to_s]
|
49
|
-
|
50
|
-
ar_column_to_json_schema(column) || options[:fallback_type]
|
51
|
-
end
|
52
|
-
|
53
|
-
# rubocop:disable Metrics/MethodLength
|
54
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
55
|
-
def ar_column_to_json_schema(column)
|
56
|
-
case column&.type
|
57
|
-
when :string, :text
|
58
|
-
build_json_schema_type('string', column.null)
|
59
|
-
when :integer
|
60
|
-
build_json_schema_type('integer', column.null)
|
61
|
-
when :float, :decimal
|
62
|
-
build_json_schema_type('number', column.null)
|
63
|
-
when :boolean
|
64
|
-
build_json_schema_type('boolean', column.null)
|
65
|
-
when :date
|
66
|
-
build_json_schema_type('string', column.null, 'date')
|
67
|
-
when :datetime, :timestamp
|
68
|
-
build_json_schema_type('string', column.null, 'date-time')
|
69
|
-
when :uuid
|
70
|
-
build_json_schema_type('string', column.null, 'uuid')
|
71
|
-
end
|
72
|
-
end
|
73
|
-
# rubocop:enable Metrics/MethodLength
|
74
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
75
|
-
|
76
|
-
def build_json_schema_type(json_schema_type, nullable, format = nil)
|
77
|
-
type = { 'type' => nullable ? [json_schema_type, 'null'] : json_schema_type }
|
78
|
-
type['format'] = format if format
|
79
|
-
type
|
80
|
-
end
|
81
|
-
|
82
|
-
def association_to_json_schema(association, model)
|
83
|
-
blueprint_class = association.options[:blueprint]
|
84
|
-
|
85
|
-
return { 'type' => 'object' } unless blueprint_class
|
86
|
-
|
87
|
-
ar_association = model.reflect_on_association(association.name)
|
88
|
-
is_collection = ar_association.collection?
|
89
|
-
association_model = ar_association.klass
|
90
|
-
|
91
|
-
associated_schema = generate(blueprint_class, association_model)
|
92
|
-
|
93
|
-
is_collection ? { 'type' => 'array', 'items' => associated_schema } : associated_schema
|
94
|
-
end
|
7
|
+
def self.generate(serializer, model, options = { include_conditional_fields: true, fallback_type: {} })
|
8
|
+
Generator.new(serializer, model, options).generate
|
95
9
|
end
|
96
10
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blueprinter_schema
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- thisismydesign
|
@@ -25,6 +25,7 @@ files:
|
|
25
25
|
- Rakefile
|
26
26
|
- docker-compose.yml
|
27
27
|
- lib/blueprinter_schema.rb
|
28
|
+
- lib/blueprinter_schema/generator.rb
|
28
29
|
- lib/blueprinter_schema/version.rb
|
29
30
|
- sig/blueprinter_schema.rbs
|
30
31
|
homepage: https://github.com/thisismydesign/blueprinter_schema
|