scheming 0.5.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/.solargraph.yml +28 -0
- data/CHANGELOG.md +97 -1
- data/Gemfile +2 -1
- data/Gemfile.lock +47 -7
- data/README.md +10 -5
- data/Rakefile +6 -1
- data/lib/scheming/attribute/list.rb +1 -0
- data/lib/scheming/dsl/data_builder.rb +0 -1
- data/lib/scheming/dsl/tagging.rb +3 -3
- data/lib/scheming/dsl/type_specs.rb +14 -0
- data/lib/scheming/schema/json.rb +23 -1
- data/lib/scheming/type.rb +48 -1
- data/lib/scheming/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 670c2fce2ac13e3ae6d64790ef6fbcad0f0de413c06bb2fc3300e24686315495
|
4
|
+
data.tar.gz: 599cd2a5d28aed9215a011b896a7eb5a207f14f2a7ca55dcd9299abed4100e32
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb6bc063479d9b7fc4f3769d966102b0c9fccc971727bb5e72962186227dfb55d3921b40b3a26b5454defc36f1f48cf1afba680b6221ed4b84bee12ae16cce5f
|
7
|
+
data.tar.gz: 711e2a1f8b035ff4aa33dca7955f810cbd7e11774d221f7a2ad0da59623ce5424e4fc02a92fefac78117a1ed37b35fa3a24799547121e97daaebd523a722ef63
|
data/.rubocop.yml
CHANGED
data/.solargraph.yml
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
---
|
2
|
+
include:
|
3
|
+
- "**/*.rb"
|
4
|
+
exclude:
|
5
|
+
- spec/**/*
|
6
|
+
- test/**/*
|
7
|
+
- vendor/**/*
|
8
|
+
- ".bundle/**/*"
|
9
|
+
require: []
|
10
|
+
domains: []
|
11
|
+
reporters:
|
12
|
+
- rubocop
|
13
|
+
- require_not_found
|
14
|
+
- typecheck
|
15
|
+
formatter:
|
16
|
+
rubocop:
|
17
|
+
cops: safe
|
18
|
+
except: []
|
19
|
+
only: []
|
20
|
+
extra_args: []
|
21
|
+
require_paths: [
|
22
|
+
'factory_bot',
|
23
|
+
'json_schemer',
|
24
|
+
'pry',
|
25
|
+
'set'
|
26
|
+
]
|
27
|
+
plugins: []
|
28
|
+
max_files: 5000
|
data/CHANGELOG.md
CHANGED
@@ -1,12 +1,108 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.7.0] - 2024-05-10
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
- `Tuple` type added
|
8
|
+
|
9
|
+
#### Example
|
10
|
+
```ruby
|
11
|
+
EmailTemplate = Scheming.object do
|
12
|
+
attribute :id, Integer
|
13
|
+
attribute :data, Tuple(String, Array(String))
|
14
|
+
end
|
15
|
+
|
16
|
+
Scheming::Schema.json(EmailTemplate)
|
17
|
+
# =>
|
18
|
+
{
|
19
|
+
type: 'object',
|
20
|
+
additionalProperties: false,
|
21
|
+
required: %w[id data],
|
22
|
+
properties: {
|
23
|
+
id: { type: 'integer' },
|
24
|
+
data: {
|
25
|
+
type: 'array',
|
26
|
+
prefixItems: [
|
27
|
+
{ type: 'string' },
|
28
|
+
{
|
29
|
+
type: 'array',
|
30
|
+
items: { type: 'string' }
|
31
|
+
}
|
32
|
+
]
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
```
|
37
|
+
|
38
|
+
### Enhancement
|
39
|
+
|
40
|
+
- Added `solorgraph` to the development process and added
|
41
|
+
it's typecheck to the default `rake` task.
|
42
|
+
|
43
|
+
- Reduced string allocations when generating required field
|
44
|
+
names for objects with the JSON schema format.
|
45
|
+
|
46
|
+
### Bugfix
|
47
|
+
|
48
|
+
- Incorrect type syntax corrected as reported by `solargraph`.
|
49
|
+
|
50
|
+
## [0.6.0] - 2024-05-04
|
51
|
+
|
52
|
+
### Added
|
53
|
+
|
54
|
+
- `Union` type added
|
55
|
+
|
56
|
+
#### Example
|
57
|
+
```ruby
|
58
|
+
Order = Scheming.object do
|
59
|
+
attribute :id, Union(String, Integer)
|
60
|
+
end
|
61
|
+
|
62
|
+
Scheming::Schema.json(Order)
|
63
|
+
# =>
|
64
|
+
{
|
65
|
+
type: 'object',
|
66
|
+
additionalProperties: false,
|
67
|
+
required: %w[id],
|
68
|
+
properties: {
|
69
|
+
id: {
|
70
|
+
oneOf: [
|
71
|
+
{ type: 'string' },
|
72
|
+
{ type: 'integer' }
|
73
|
+
]
|
74
|
+
}
|
75
|
+
}
|
76
|
+
}
|
77
|
+
```
|
78
|
+
|
79
|
+
### Fixed
|
80
|
+
|
81
|
+
- Incorrect YARD comment tags and syntax.
|
82
|
+
|
83
|
+
### Breaking Change
|
84
|
+
|
85
|
+
- Switch from `json-schema` to `json_schemer`
|
86
|
+
|
87
|
+
> TL;DR
|
88
|
+
required object properties for the JSON schema
|
89
|
+
are now strings instead of symbols
|
90
|
+
|
91
|
+
After doing to research I've found that `json_schemer` is
|
92
|
+
more maintained than what was currently being used. It has
|
93
|
+
a smaller footprint and is much faster at validation.
|
94
|
+
|
95
|
+
As a consequence the `required` properties needed to be
|
96
|
+
changed from symbols to strings in the generated JSON schema.
|
97
|
+
|
98
|
+
|
3
99
|
## [0.5.0] - 2024-05-02
|
4
100
|
|
5
101
|
### Added
|
6
102
|
|
7
103
|
- Support for `generic` definitions
|
8
104
|
|
9
|
-
|
105
|
+
#### Example
|
10
106
|
```ruby
|
11
107
|
Point = Scheming.generic do |(type)|
|
12
108
|
Object(x: type, y: type)
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
scheming (0.
|
4
|
+
scheming (0.7.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
@@ -16,27 +16,40 @@ GEM
|
|
16
16
|
minitest (>= 5.1)
|
17
17
|
mutex_m
|
18
18
|
tzinfo (~> 2.0)
|
19
|
-
addressable (2.8.6)
|
20
|
-
public_suffix (>= 2.0.2, < 6.0)
|
21
19
|
ast (2.4.2)
|
20
|
+
backport (1.2.0)
|
22
21
|
base64 (0.2.0)
|
22
|
+
benchmark (0.3.0)
|
23
23
|
bigdecimal (3.1.7)
|
24
24
|
coderay (1.1.3)
|
25
25
|
concurrent-ruby (1.2.3)
|
26
26
|
connection_pool (2.4.1)
|
27
27
|
diff-lcs (1.5.1)
|
28
28
|
drb (2.2.1)
|
29
|
+
e2mmap (0.1.0)
|
29
30
|
factory_bot (6.4.6)
|
30
31
|
activesupport (>= 5.0.0)
|
32
|
+
hana (1.3.7)
|
31
33
|
i18n (1.14.4)
|
32
34
|
concurrent-ruby (~> 1.0)
|
35
|
+
jaro_winkler (1.5.6)
|
33
36
|
json (2.7.2)
|
34
|
-
|
35
|
-
|
37
|
+
json_schemer (2.2.1)
|
38
|
+
base64
|
39
|
+
bigdecimal
|
40
|
+
hana (~> 1.3)
|
41
|
+
regexp_parser (~> 2.0)
|
42
|
+
simpleidn (~> 0.2)
|
43
|
+
kramdown (2.4.0)
|
44
|
+
rexml
|
45
|
+
kramdown-parser-gfm (1.1.0)
|
46
|
+
kramdown (~> 2.0)
|
36
47
|
language_server-protocol (3.17.0.3)
|
37
48
|
method_source (1.1.0)
|
38
49
|
minitest (5.22.3)
|
39
50
|
mutex_m (0.2.0)
|
51
|
+
nokogiri (1.16.4-x86_64-linux)
|
52
|
+
racc (~> 1.4)
|
40
53
|
parallel (1.24.0)
|
41
54
|
parser (3.3.1.0)
|
42
55
|
ast (~> 2.4.1)
|
@@ -44,11 +57,13 @@ GEM
|
|
44
57
|
pry (0.14.2)
|
45
58
|
coderay (~> 1.1)
|
46
59
|
method_source (~> 1.0)
|
47
|
-
public_suffix (5.0.5)
|
48
60
|
racc (1.7.3)
|
49
61
|
rainbow (3.1.1)
|
50
62
|
rake (13.2.1)
|
63
|
+
rbs (2.8.4)
|
51
64
|
regexp_parser (2.9.0)
|
65
|
+
reverse_markdown (2.1.1)
|
66
|
+
nokogiri
|
52
67
|
rexml (3.2.6)
|
53
68
|
rspec (3.13.0)
|
54
69
|
rspec-core (~> 3.13.0)
|
@@ -77,21 +92,46 @@ GEM
|
|
77
92
|
rubocop-ast (1.31.2)
|
78
93
|
parser (>= 3.3.0.4)
|
79
94
|
ruby-progressbar (1.13.0)
|
95
|
+
simpleidn (0.2.2)
|
96
|
+
unf (~> 0.1.4)
|
97
|
+
solargraph (0.50.0)
|
98
|
+
backport (~> 1.2)
|
99
|
+
benchmark
|
100
|
+
bundler (~> 2.0)
|
101
|
+
diff-lcs (~> 1.4)
|
102
|
+
e2mmap
|
103
|
+
jaro_winkler (~> 1.5)
|
104
|
+
kramdown (~> 2.3)
|
105
|
+
kramdown-parser-gfm (~> 1.1)
|
106
|
+
parser (~> 3.0)
|
107
|
+
rbs (~> 2.0)
|
108
|
+
reverse_markdown (~> 2.0)
|
109
|
+
rubocop (~> 1.38)
|
110
|
+
thor (~> 1.0)
|
111
|
+
tilt (~> 2.0)
|
112
|
+
yard (~> 0.9, >= 0.9.24)
|
113
|
+
thor (1.3.1)
|
114
|
+
tilt (2.3.0)
|
80
115
|
tzinfo (2.0.6)
|
81
116
|
concurrent-ruby (~> 1.0)
|
117
|
+
unf (0.1.4)
|
118
|
+
unf_ext
|
119
|
+
unf_ext (0.0.9.1)
|
82
120
|
unicode-display_width (2.5.0)
|
121
|
+
yard (0.9.36)
|
83
122
|
|
84
123
|
PLATFORMS
|
85
124
|
x86_64-linux
|
86
125
|
|
87
126
|
DEPENDENCIES
|
88
127
|
factory_bot (~> 6.4)
|
89
|
-
|
128
|
+
json_schemer
|
90
129
|
pry (~> 0.14.2)
|
91
130
|
rake (~> 13.0)
|
92
131
|
rspec (~> 3.0)
|
93
132
|
rubocop (~> 1.21)
|
94
133
|
scheming!
|
134
|
+
solargraph
|
95
135
|
|
96
136
|
BUNDLED WITH
|
97
137
|
2.4.5
|
data/README.md
CHANGED
@@ -15,7 +15,7 @@ gem 'scheming'
|
|
15
15
|
Definition:
|
16
16
|
```ruby
|
17
17
|
LineItem = Scheming.object do
|
18
|
-
attribute :id, Integer
|
18
|
+
attribute :id, Union(Integer, String)
|
19
19
|
attribute :name, String
|
20
20
|
attribute :taxable, :bool
|
21
21
|
attribute :price, Float
|
@@ -45,16 +45,21 @@ Scheming::Schema.json(Receipt)
|
|
45
45
|
{
|
46
46
|
type: 'object',
|
47
47
|
additionalProperties: false,
|
48
|
-
required: %
|
48
|
+
required: %w[line_items total location],
|
49
49
|
properties: {
|
50
50
|
line_items: {
|
51
51
|
type: 'array',
|
52
52
|
items: {
|
53
53
|
type: 'object',
|
54
54
|
additionalProperties: false,
|
55
|
-
required: %
|
55
|
+
required: %w[id name taxable price],
|
56
56
|
properties: {
|
57
|
-
id: {
|
57
|
+
id: {
|
58
|
+
oneOf: [
|
59
|
+
{ type: 'integer' },
|
60
|
+
{ type: 'string' }
|
61
|
+
]
|
62
|
+
},
|
58
63
|
name: { type: 'string' },
|
59
64
|
taxable: { type: 'boolean' },
|
60
65
|
desc: {
|
@@ -75,7 +80,7 @@ Scheming::Schema.json(Receipt)
|
|
75
80
|
location: {
|
76
81
|
type: 'object',
|
77
82
|
additionalProperties: false,
|
78
|
-
required: %
|
83
|
+
required: %w[x y],
|
79
84
|
properties: {
|
80
85
|
x: { type: 'number' },
|
81
86
|
y: { type: 'number' }
|
data/Rakefile
CHANGED
data/lib/scheming/dsl/tagging.rb
CHANGED
@@ -9,8 +9,8 @@ class Scheming::DSL::Tagging
|
|
9
9
|
# creation of an [Scheming::Attribute]
|
10
10
|
#
|
11
11
|
class Tag
|
12
|
-
# @param name [
|
13
|
-
# @data [Hash<Symbol, Object>]
|
12
|
+
# @param name [Symbol]
|
13
|
+
# @param data [Hash<Symbol, Object>]
|
14
14
|
def initialize(name, data)
|
15
15
|
@name = name
|
16
16
|
@data = data
|
@@ -29,8 +29,8 @@ class Scheming::DSL::Tagging
|
|
29
29
|
nil
|
30
30
|
end
|
31
31
|
|
32
|
-
# @param taglist [Hash<Symbol, Object>]
|
33
32
|
# @param name [Symbol]
|
33
|
+
# @param data [Hash<Symbol, Object>]
|
34
34
|
# @return [Tag]
|
35
35
|
def tag!(name, data)
|
36
36
|
@tags[name] = Tag.new(name, data)
|
@@ -26,4 +26,18 @@ module Scheming::DSL::TypeSpecs
|
|
26
26
|
type = Scheming::DSL::TypeResolver.resolve(type_spec)
|
27
27
|
Scheming::Type::Nullable.new(type)
|
28
28
|
end
|
29
|
+
|
30
|
+
def Union(*type_specs) # rubocop:disable Naming/MethodName
|
31
|
+
types = type_specs.map do |type_spec|
|
32
|
+
Scheming::DSL::TypeResolver.resolve(type_spec)
|
33
|
+
end
|
34
|
+
Scheming::Type::Union.new(types)
|
35
|
+
end
|
36
|
+
|
37
|
+
def Tuple(*type_specs) # rubocop:disable Naming/MethodName
|
38
|
+
types = type_specs.map do |type_spec|
|
39
|
+
Scheming::DSL::TypeResolver.resolve(type_spec)
|
40
|
+
end
|
41
|
+
Scheming::Type::Tuple.new(types.freeze)
|
42
|
+
end
|
29
43
|
end
|
data/lib/scheming/schema/json.rb
CHANGED
@@ -29,7 +29,10 @@ module Scheming::Schema
|
|
29
29
|
private
|
30
30
|
|
31
31
|
def required
|
32
|
-
attributes
|
32
|
+
attributes
|
33
|
+
.required
|
34
|
+
.map! { |attr| attr.field_name.name }
|
35
|
+
.freeze
|
33
36
|
end
|
34
37
|
|
35
38
|
def properties
|
@@ -39,6 +42,25 @@ module Scheming::Schema
|
|
39
42
|
end
|
40
43
|
end
|
41
44
|
|
45
|
+
refine Scheming::Type::Union do
|
46
|
+
# @!attribute [r] types
|
47
|
+
# @return [Array<Scheming::Type::Base>]
|
48
|
+
|
49
|
+
def schema = { oneOf: types.map(&:schema).freeze }
|
50
|
+
end
|
51
|
+
|
52
|
+
refine Scheming::Type::Tuple do
|
53
|
+
# @!attribute [r] types
|
54
|
+
# @return [Array<Scheming::Type::Base>]
|
55
|
+
|
56
|
+
def schema
|
57
|
+
{
|
58
|
+
type: 'array',
|
59
|
+
prefixItems: types.map(&:schema).freeze
|
60
|
+
}.freeze
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
42
64
|
refine Scheming::Type::Nullable do
|
43
65
|
# @!attribute [r] type
|
44
66
|
# @return [Scheming::Type::Base]
|
data/lib/scheming/type.rb
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# This is a redundant require statement; however,
|
4
|
+
# for some reason Solargraph will not honor the
|
5
|
+
# path for `set` in it's config. For this reson
|
6
|
+
# we need to require it here to prevent typecheck
|
7
|
+
# errors.
|
8
|
+
require 'set' # rubocop:disable Lint/RedundantRequireStatement
|
9
|
+
|
3
10
|
# = Type
|
4
11
|
#
|
5
12
|
# Everything needed to describe and work
|
@@ -11,7 +18,11 @@ module Scheming::Type
|
|
11
18
|
# Any and all shared functionality comes from
|
12
19
|
# this base type definition.
|
13
20
|
#
|
14
|
-
Base
|
21
|
+
class Base
|
22
|
+
# This class left empty on purpose. Acts
|
23
|
+
# merely as a tag which all types inherit
|
24
|
+
# back to.
|
25
|
+
end
|
15
26
|
|
16
27
|
# = Object Type Definition
|
17
28
|
#
|
@@ -30,6 +41,25 @@ module Scheming::Type
|
|
30
41
|
end
|
31
42
|
end
|
32
43
|
|
44
|
+
# = Tuple Type Definition
|
45
|
+
#
|
46
|
+
# Specifies a type which specifies specific types
|
47
|
+
# in a fixed order. Another way to think of it is
|
48
|
+
# like an [Scheming::Type::Object] but without named
|
49
|
+
# attribute fields.
|
50
|
+
#
|
51
|
+
class Tuple < Base
|
52
|
+
# @return [Array<Scheming::Type::Base>]
|
53
|
+
attr_reader :types
|
54
|
+
|
55
|
+
# @param types [Array<Scheming::Type::Base>]
|
56
|
+
def initialize(types)
|
57
|
+
super()
|
58
|
+
@types = types
|
59
|
+
freeze
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
33
63
|
# = Nullable Type Definition
|
34
64
|
#
|
35
65
|
# Type wrapper that describes a type can be either
|
@@ -47,6 +77,23 @@ module Scheming::Type
|
|
47
77
|
end
|
48
78
|
end
|
49
79
|
|
80
|
+
# = Union Type Definition
|
81
|
+
#
|
82
|
+
# In cases where a value can be of many different
|
83
|
+
# types a union is how to describe this.
|
84
|
+
#
|
85
|
+
class Union < Base
|
86
|
+
# @return [Array<Scheming::Type::Base>]
|
87
|
+
attr_reader :types
|
88
|
+
|
89
|
+
# @param types [Array<Scheming::Type::Base>]
|
90
|
+
def initialize(types)
|
91
|
+
super()
|
92
|
+
@types = types
|
93
|
+
freeze
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
50
97
|
# = Enumeration Type Definition
|
51
98
|
#
|
52
99
|
# The wrapper that describes a type and holds
|
data/lib/scheming/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scheming
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Falk
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-05-
|
11
|
+
date: 2024-05-10 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Ergonomic Data Design for the Masses
|
14
14
|
email:
|
@@ -19,6 +19,7 @@ extra_rdoc_files: []
|
|
19
19
|
files:
|
20
20
|
- ".rspec"
|
21
21
|
- ".rubocop.yml"
|
22
|
+
- ".solargraph.yml"
|
22
23
|
- CHANGELOG.md
|
23
24
|
- Gemfile
|
24
25
|
- Gemfile.lock
|