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 +4 -4
- data/.rubocop.yml +8 -5
- data/README.md +70 -1
- data/Rakefile +3 -3
- data/lib/blueprinter_schema/version.rb +1 -1
- data/lib/blueprinter_schema.rb +89 -3
- 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: 2400ee7efced7c677ae75e475d55dfc183f90ab6975780ba760b4d5c15f9e1f5
|
4
|
+
data.tar.gz: ff2966e94b5c3b6c4ea153e44ab386eafe95afd70d30d7eb9f255ef2dae570c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
5
|
-
|
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
|
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
|
4
|
-
require
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rspec/core/rake_task'
|
5
5
|
|
6
6
|
RSpec::Core::RakeTask.new(:spec)
|
7
7
|
|
8
|
-
require
|
8
|
+
require 'rubocop/rake_task'
|
9
9
|
|
10
10
|
RuboCop::RakeTask.new
|
11
11
|
|
data/lib/blueprinter_schema.rb
CHANGED
@@ -1,8 +1,94 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative 'blueprinter_schema/version'
|
4
4
|
|
5
5
|
module BlueprinterSchema
|
6
|
-
class
|
7
|
-
|
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.
|
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
|