blueprinter_schema 0.4.1 → 0.5.0

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: 64488524dcc942abdab6c3f96841d1619dc40abade8d3006c73c55ef035c29e1
4
- data.tar.gz: 7a49a1189f126209721e032e5e752f1fbd7e15a4c5c0f442293627d6525afa2c
3
+ metadata.gz: 03c37dc53060c99e65e98088279e4e635bcedd8b495c9c9d4b31c624c7b56488
4
+ data.tar.gz: 5c82b98494016b536ed9e9f360353834c5daaf28e692a4a16fa8c5e466924733
5
5
  SHA512:
6
- metadata.gz: '0654209ac2820114fb2807295a690787fee47b41671ddfc9ff4740939f59ef84bcb05b92d3277e553a44d99652b32d318371e00eedcd9995c9be265d49ddbb60'
7
- data.tar.gz: bc4c26c5039d90cb5950f697cc7b242092fc92d194dc16cbfe3d075292b240bf439573645920f1b462591c5ad5f4661adc407965ebac9f181d6ea4fb838c7b2f
6
+ metadata.gz: a118085debb64d40d46aae65e8c88ddc69c0e55e49949e580966618ea14b7573a05c02a0df47aa8cac4c09bb2872b50c002e7828b275954a045728fa56115d6e
7
+ data.tar.gz: b05ee47b64997f7dbc0d16b0f8bf440e76e61d810d82b79ff3295d46f07c051b8048076db67983fd8df940e78f69b30e5504a2e646590f429993dc97ef1be5dd
data/README.md CHANGED
@@ -91,7 +91,8 @@ BlueprinterSchema.generate(
91
91
  model,
92
92
  {
93
93
  include_conditional_fields: true, # Whether or not to include conditional fields from the serializer
94
- fallback_type: {} # Type when no DB column is found or type is unknown. E.g. { 'type' => 'object' }
94
+ fallback_type: {}, # Type when no DB column is found or type is unknown. E.g. { 'type' => 'object' }
95
+ view: :default # The Blueprint view to use
95
96
  }
96
97
  )
97
98
  ```
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BlueprinterSchema
4
+ class Generator
5
+ def initialize(serializer, model, options)
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[@options[:view]].fields
25
+ end
26
+
27
+ def associations
28
+ @associations ||= @serializer.reflections[@options[:view]].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] &&
49
+ (field.options[:if] || field.options[:unless] || field.options[:exclude_if_nil])
50
+ end
51
+
52
+ def build_required_fields
53
+ fields.reject { |_, field| skip_field?(field) }.keys.map(&:to_s)
54
+ end
55
+
56
+ def field_to_json_schema(field)
57
+ column = @model.columns_hash[field.name.to_s]
58
+
59
+ ar_column_to_json_schema(column) || @options[:fallback_type]
60
+ end
61
+
62
+ # rubocop:disable Metrics/MethodLength
63
+ # rubocop:disable Metrics/CyclomaticComplexity
64
+ def ar_column_to_json_schema(column)
65
+ case column&.type
66
+ when :string, :text
67
+ build_json_schema_type('string', column.null)
68
+ when :integer
69
+ build_json_schema_type('integer', column.null)
70
+ when :float, :decimal
71
+ build_json_schema_type('number', column.null)
72
+ when :boolean
73
+ build_json_schema_type('boolean', column.null)
74
+ when :date
75
+ build_json_schema_type('string', column.null, 'date')
76
+ when :datetime, :timestamp
77
+ build_json_schema_type('string', column.null, 'date-time')
78
+ when :uuid
79
+ build_json_schema_type('string', column.null, 'uuid')
80
+ end
81
+ end
82
+ # rubocop:enable Metrics/MethodLength
83
+ # rubocop:enable Metrics/CyclomaticComplexity
84
+
85
+ def build_json_schema_type(json_schema_type, nullable, format = nil)
86
+ type = { 'type' => nullable ? [json_schema_type, 'null'] : json_schema_type }
87
+ type['format'] = format if format
88
+ type
89
+ end
90
+
91
+ def association_to_json_schema(association)
92
+ blueprint_class = association.options[:blueprint]
93
+
94
+ return { 'type' => 'object' } unless blueprint_class
95
+
96
+ ar_association = @model.reflect_on_association(association.name)
97
+ is_collection = ar_association.collection?
98
+ association_model = ar_association.klass
99
+
100
+ associated_schema = BlueprinterSchema.generate(blueprint_class, association_model)
101
+
102
+ is_collection ? { 'type' => 'array', 'items' => associated_schema } : associated_schema
103
+ end
104
+ end
105
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BlueprinterSchema
4
- VERSION = '0.4.1'
4
+ VERSION = '0.5.0'
5
5
  end
@@ -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
- class << self
7
- def generate(serializer, model, options = { include_conditional_fields: true, fallback_type: {} })
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, options),
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, options)
44
- fields.reject { |_, field| skip_field?(field, options) }.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: {}, view: :default })
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.1
4
+ version: 0.5.0
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