blueprinter_schema 0.1.0 → 0.2.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: 2400ee7efced7c677ae75e475d55dfc183f90ab6975780ba760b4d5c15f9e1f5
4
+ data.tar.gz: ff2966e94b5c3b6c4ea153e44ab386eafe95afd70d30d7eb9f255ef2dae570c2
5
5
  SHA512:
6
- metadata.gz: fd7f793f1df05e0e8fc536e246f1bcd172cdb17a7e0fc059315608c4fc4b0f2df09e52be59b6097ee6ce51eaccac8c317126594134ade72d512c3c01eb9af81c
7
- data.tar.gz: 94a8ff84818b9ddf2e8c29080becaaf0a5211ab00e7d3007f94b087a71b19c65aea9f7c5aedef0443eae00b0729abe0270eb9ab41e6d6bc566d440756808c73e
6
+ metadata.gz: a2479a8f99bf5b0bf2ba0662ad244999c2e4316fdbd0185b481ba390fc249118a9a364cbd805957938e8af389f29d513e566d9533ed57e37f8172cef8755e190
7
+ data.tar.gz: ec7b9bcfa2f38a936d0a9600e01a3c0702e98db58468a9f10d0e2f5c80f658483ad5308c7ee582fad8ceeec6f6ab53d85245dc54331db327eb4c21ad487c941c
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.2.0'
5
5
  end
@@ -1,8 +1,94 @@
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
+ def ar_column_to_json_schema(column)
54
+ case column.type
55
+ when :string, :text
56
+ build_json_schema_type('string', column.null)
57
+ when :integer
58
+ build_json_schema_type('integer', column.null)
59
+ when :float, :decimal
60
+ build_json_schema_type('number', column.null)
61
+ when :boolean
62
+ build_json_schema_type('boolean', column.null)
63
+ when :date
64
+ build_json_schema_type('string', column.null, 'date')
65
+ when :datetime, :timestamp
66
+ build_json_schema_type('string', column.null, 'date-time')
67
+ else
68
+ # Unknown column type, we don't know the schema type
69
+ {}
70
+ end
71
+ end
72
+ # rubocop:enable Metrics/MethodLength
73
+
74
+ def build_json_schema_type(json_schema_type, nullable, format = nil)
75
+ type = { 'type' => nullable ? [json_schema_type, 'null'] : json_schema_type }
76
+ type['format'] = format if format
77
+ type
78
+ end
79
+
80
+ def association_to_json_schema(association, model)
81
+ blueprint_class = association.options[:blueprint]
82
+
83
+ return { 'type' => 'object' } unless blueprint_class
84
+
85
+ ar_association = model.reflect_on_association(association.name)
86
+ is_collection = ar_association.collection?
87
+ association_model = ar_association.klass
88
+
89
+ associated_schema = generate(blueprint_class, association_model)
90
+
91
+ is_collection ? { 'type' => 'array', 'items' => associated_schema } : associated_schema
92
+ end
93
+ end
8
94
  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.2.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