blueprinter_schema 0.1.0 → 0.3.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: 69d6a80c2ce8e67eeaa8b45e3b1b0052b76752fc4f9f3d06692519983e521695
4
- data.tar.gz: e968b4d65653a2ff5cba85bb8b8717709f7d855963ff1b124eb65f9858fbdc76
3
+ metadata.gz: bc07f2ba27532688748d728cfdb6ee4ae6d0c92a66b17d753519384ee8538f5b
4
+ data.tar.gz: 2add634f63f55305245acb2fb7d64438f7017d8ce6bdce9bb7626f59f186b66a
5
5
  SHA512:
6
- metadata.gz: fd7f793f1df05e0e8fc536e246f1bcd172cdb17a7e0fc059315608c4fc4b0f2df09e52be59b6097ee6ce51eaccac8c317126594134ade72d512c3c01eb9af81c
7
- data.tar.gz: 94a8ff84818b9ddf2e8c29080becaaf0a5211ab00e7d3007f94b087a71b19c65aea9f7c5aedef0443eae00b0729abe0270eb9ab41e6d6bc566d440756808c73e
6
+ metadata.gz: 592881730764b7873f8ae95bc4de43942f3f8345c37327157b528b9b740706544c206b1ea84b3c41d430d8e6f389cd6699cf0a535797c07e4f2e82aa06c8aa33
7
+ data.tar.gz: 88163ad100fa9e310cb42c8b1dc9240b3aa09831b048e6215ddc6636cfea57ade49d452290ca01cd91a13f001e902fe8291ff17d8da63ad85a32d1abe470e7c4
data/.rubocop.yml CHANGED
@@ -1,8 +1,11 @@
1
+ plugins:
2
+ - rubocop-rake
3
+ - rubocop-rspec
4
+
1
5
  AllCops:
2
6
  TargetRubyVersion: 3.1
7
+ NewCops: enable
3
8
 
4
- Style/StringLiterals:
5
- EnforcedStyle: double_quotes
6
-
7
- Style/StringLiteralsInInterpolation:
8
- EnforcedStyle: double_quotes
9
+ # Do not enforce documentation
10
+ Style/Documentation:
11
+ Enabled: false
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # BlueprinterSchema
2
2
 
3
- ### Create JSON Schema from Blueprinter serializers and ActiveRecord Models.
3
+ ### Create JSON Schema from Blueprinter Serializers and ActiveRecord Models.
4
4
 
5
5
  ## Installation
6
6
 
@@ -12,6 +12,75 @@ gem "blueprinter_schema"
12
12
 
13
13
  ## Usage
14
14
 
15
+ With the folloing Models and Serializers:
16
+ ```rb
17
+ class Address < ApplicationRecord
18
+ belongs_to :user
19
+ end
20
+
21
+ class User < ApplicationRecord
22
+ has_many :addresses
23
+ end
24
+
25
+ class AddressSerializer < Blueprinter::Base
26
+ identifier :id
27
+
28
+ fields :address
29
+ end
30
+
31
+ class UserSerializer < Blueprinter::Base
32
+ identifier :id
33
+
34
+ fields :name, :email, :created_at
35
+ association :addresses, blueprint: AddressSerializer
36
+ end
37
+ ```
38
+
39
+ Generate JSON Schema:
40
+ ```rb
41
+ BlueprinterSchema.generate(UserSerializer, User)
42
+ ```
43
+
44
+ ```rb
45
+ {
46
+ "type" => "object",
47
+ "title" => "User",
48
+ "properties" => {
49
+ "id" => {
50
+ "type" => "integer"
51
+ },
52
+ "created_at" => {
53
+ "type" => "string", "format" => "date-time"
54
+ },
55
+ "email" => {
56
+ "type" => "string"
57
+ },
58
+ "name" => {
59
+ "type" => ["string", "null"]
60
+ },
61
+ "addresses" => {
62
+ "type" => "array",
63
+ "items" => {
64
+ "type" => "object",
65
+ "title" => "Address",
66
+ "properties" => {
67
+ "id" => {
68
+ "type" => "integer"
69
+ },
70
+ "address" => {
71
+ "type" => "string"
72
+ }
73
+ },
74
+ "required" => ["id", "address"],
75
+ "additionalProperties" => false
76
+ }
77
+ }
78
+ },
79
+ "required" => ["id", "created_at", "email", "name"],
80
+ "additionalProperties" => false
81
+ }
82
+ ```
83
+
15
84
  ## Development
16
85
 
17
86
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/Rakefile CHANGED
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "bundler/gem_tasks"
4
- require "rspec/core/rake_task"
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
5
 
6
6
  RSpec::Core::RakeTask.new(:spec)
7
7
 
8
- require "rubocop/rake_task"
8
+ require 'rubocop/rake_task'
9
9
 
10
10
  RuboCop::RakeTask.new
11
11
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BlueprinterSchema
4
- VERSION = "0.1.0"
4
+ VERSION = '0.3.0'
5
5
  end
@@ -1,8 +1,98 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "blueprinter_schema/version"
3
+ require_relative 'blueprinter_schema/version'
4
4
 
5
5
  module BlueprinterSchema
6
- class Error < StandardError; end
7
- # Your code goes here...
6
+ class << self
7
+ def generate(serializer, model)
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),
16
+ 'required' => build_required_fields(fields),
17
+ 'additionalProperties' => false
18
+ }
19
+ end
20
+
21
+ private
22
+
23
+ def build_properties(fields, associations, model)
24
+ properties = {}
25
+
26
+ fields.each_value do |field|
27
+ properties[field.display_name.to_s] = field_to_json_schema(field, model)
28
+ end
29
+
30
+ associations.each_value do |association|
31
+ properties[association.display_name.to_s] = association_to_json_schema(association, model)
32
+ end
33
+
34
+ properties
35
+ end
36
+
37
+ def build_required_fields(fields)
38
+ fields.keys.map(&:to_s)
39
+ end
40
+
41
+ def field_to_json_schema(field, model)
42
+ column = model.columns_hash[field.name.to_s]
43
+
44
+ if column
45
+ ar_column_to_json_schema(column)
46
+ else
47
+ # Non-database (e.g. computed) field, we don't know the schema type
48
+ {}
49
+ end
50
+ end
51
+
52
+ # rubocop:disable Metrics/MethodLength
53
+ # rubocop:disable Metrics/CyclomaticComplexity
54
+ def ar_column_to_json_schema(column)
55
+ case column.type
56
+ when :string, :text
57
+ build_json_schema_type('string', column.null)
58
+ when :integer
59
+ build_json_schema_type('integer', column.null)
60
+ when :float, :decimal
61
+ build_json_schema_type('number', column.null)
62
+ when :boolean
63
+ build_json_schema_type('boolean', column.null)
64
+ when :date
65
+ build_json_schema_type('string', column.null, 'date')
66
+ when :datetime, :timestamp
67
+ build_json_schema_type('string', column.null, 'date-time')
68
+ when :uuid
69
+ build_json_schema_type('string', column.null, 'uuid')
70
+ else
71
+ # Unknown column type, we don't know the schema type
72
+ {}
73
+ end
74
+ end
75
+ # rubocop:enable Metrics/MethodLength
76
+ # rubocop:enable Metrics/CyclomaticComplexity
77
+
78
+ def build_json_schema_type(json_schema_type, nullable, format = nil)
79
+ type = { 'type' => nullable ? [json_schema_type, 'null'] : json_schema_type }
80
+ type['format'] = format if format
81
+ type
82
+ end
83
+
84
+ def association_to_json_schema(association, model)
85
+ blueprint_class = association.options[:blueprint]
86
+
87
+ return { 'type' => 'object' } unless blueprint_class
88
+
89
+ ar_association = model.reflect_on_association(association.name)
90
+ is_collection = ar_association.collection?
91
+ association_model = ar_association.klass
92
+
93
+ associated_schema = generate(blueprint_class, association_model)
94
+
95
+ is_collection ? { 'type' => 'array', 'items' => associated_schema } : associated_schema
96
+ end
97
+ end
8
98
  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.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - thisismydesign
@@ -33,6 +33,7 @@ licenses:
33
33
  metadata:
34
34
  homepage_uri: https://github.com/thisismydesign/blueprinter_schema
35
35
  source_code_uri: https://github.com/thisismydesign/blueprinter_schema
36
+ rubygems_mfa_required: 'true'
36
37
  rdoc_options: []
37
38
  require_paths:
38
39
  - lib