scheming 0.4.0 → 0.6.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/CHANGELOG.md +69 -2
- data/Gemfile +1 -1
- data/Gemfile.lock +14 -7
- data/README.md +25 -6
- data/lib/scheming/dsl/data_builder.rb +0 -1
- data/lib/scheming/dsl/tagging.rb +2 -2
- data/lib/scheming/dsl/type_specs.rb +7 -0
- data/lib/scheming/generic.rb +41 -0
- data/lib/scheming/schema/json.rb +11 -1
- data/lib/scheming/type.rb +17 -0
- data/lib/scheming/version.rb +1 -1
- data/lib/scheming.rb +4 -0
- 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: c861bcba1706b9ffe842a7d13cb55b047479d57a1c7e44a6e7fa7a934c83819a
|
4
|
+
data.tar.gz: 8837b76f3fa1c0c334387432a8c466085a96064482b4ff1dd00bbabc2b69c1ae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8d822270972cb4abc4837c89fa8084b78132af50acc829e7b610fe74cb5ce6bc517ea579528b489b774daa4aec17dd971704ad7f54c3113589d0fee225b22ed
|
7
|
+
data.tar.gz: 3c72a5b224d4d345ee050045d75f72ae74413e1bb78be6f1203795b4ed015f5327ca2e998a05712e086aef4b5d4925818c09c3afb98c5ffb1ac94ba1b6374296
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,72 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.6.0]
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
- `Union` type added
|
8
|
+
|
9
|
+
# Example
|
10
|
+
```ruby
|
11
|
+
Order = Scheming.object do
|
12
|
+
attribute :id, Union(String, Integer)
|
13
|
+
end
|
14
|
+
|
15
|
+
Scheming::Schema.json(Order)
|
16
|
+
# =>
|
17
|
+
{
|
18
|
+
oneOf: [
|
19
|
+
{ type: 'string' },
|
20
|
+
{ type: 'integer' }
|
21
|
+
]
|
22
|
+
}
|
23
|
+
```
|
24
|
+
|
25
|
+
### Fixed
|
26
|
+
|
27
|
+
- Incorrect YARD comment tags and syntax.
|
28
|
+
|
29
|
+
### Breaking Change
|
30
|
+
|
31
|
+
- Switch from `json-schema` to `json_schemer`
|
32
|
+
|
33
|
+
> TL;DR
|
34
|
+
required object properties for the JSON schema
|
35
|
+
are now strings instead of symbols
|
36
|
+
|
37
|
+
After doing to research I've found that `json_schemer` is
|
38
|
+
more maintained than what was currently being used. It has
|
39
|
+
a smaller footprint and is much faster at validation.
|
40
|
+
|
41
|
+
As a consequence the `required` properties needed to be
|
42
|
+
changed from symbols to strings in the generated JSON schema.
|
43
|
+
|
44
|
+
|
45
|
+
## [0.5.0] - 2024-05-02
|
46
|
+
|
47
|
+
### Added
|
48
|
+
|
49
|
+
- Support for `generic` definitions
|
50
|
+
|
51
|
+
# Example
|
52
|
+
```ruby
|
53
|
+
Point = Scheming.generic do |(type)|
|
54
|
+
Object(x: type, y: type)
|
55
|
+
end
|
56
|
+
|
57
|
+
Scheming::Schema.json(Point)
|
58
|
+
# =>
|
59
|
+
{
|
60
|
+
type: 'object',
|
61
|
+
additionalProperties: false,
|
62
|
+
required: %i[x y],
|
63
|
+
properties: {
|
64
|
+
x: { type: 'number' },
|
65
|
+
y: { type: 'number' }
|
66
|
+
}
|
67
|
+
}
|
68
|
+
```
|
69
|
+
|
3
70
|
## [0.4.0] - 2024-05-02
|
4
71
|
|
5
72
|
### Breaking Change
|
@@ -35,6 +102,8 @@
|
|
35
102
|
|
36
103
|
### Enhancement
|
37
104
|
|
105
|
+
- Ensure all types produce valid JSON Schema
|
106
|
+
|
38
107
|
## [0.2.0] - 2024-05-01
|
39
108
|
|
40
109
|
### Added
|
@@ -56,8 +125,6 @@
|
|
56
125
|
end
|
57
126
|
```
|
58
127
|
|
59
|
-
- Ensure all types produce valid JSON Schema
|
60
|
-
|
61
128
|
## [0.1.0] - 2024-04-26
|
62
129
|
|
63
130
|
- Initial release
|
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.6.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
@@ -16,8 +16,6 @@ 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)
|
22
20
|
base64 (0.2.0)
|
23
21
|
bigdecimal (3.1.7)
|
@@ -28,11 +26,16 @@ GEM
|
|
28
26
|
drb (2.2.1)
|
29
27
|
factory_bot (6.4.6)
|
30
28
|
activesupport (>= 5.0.0)
|
29
|
+
hana (1.3.7)
|
31
30
|
i18n (1.14.4)
|
32
31
|
concurrent-ruby (~> 1.0)
|
33
32
|
json (2.7.2)
|
34
|
-
|
35
|
-
|
33
|
+
json_schemer (2.2.1)
|
34
|
+
base64
|
35
|
+
bigdecimal
|
36
|
+
hana (~> 1.3)
|
37
|
+
regexp_parser (~> 2.0)
|
38
|
+
simpleidn (~> 0.2)
|
36
39
|
language_server-protocol (3.17.0.3)
|
37
40
|
method_source (1.1.0)
|
38
41
|
minitest (5.22.3)
|
@@ -44,7 +47,6 @@ GEM
|
|
44
47
|
pry (0.14.2)
|
45
48
|
coderay (~> 1.1)
|
46
49
|
method_source (~> 1.0)
|
47
|
-
public_suffix (5.0.5)
|
48
50
|
racc (1.7.3)
|
49
51
|
rainbow (3.1.1)
|
50
52
|
rake (13.2.1)
|
@@ -77,8 +79,13 @@ GEM
|
|
77
79
|
rubocop-ast (1.31.2)
|
78
80
|
parser (>= 3.3.0.4)
|
79
81
|
ruby-progressbar (1.13.0)
|
82
|
+
simpleidn (0.2.2)
|
83
|
+
unf (~> 0.1.4)
|
80
84
|
tzinfo (2.0.6)
|
81
85
|
concurrent-ruby (~> 1.0)
|
86
|
+
unf (0.1.4)
|
87
|
+
unf_ext
|
88
|
+
unf_ext (0.0.9.1)
|
82
89
|
unicode-display_width (2.5.0)
|
83
90
|
|
84
91
|
PLATFORMS
|
@@ -86,7 +93,7 @@ PLATFORMS
|
|
86
93
|
|
87
94
|
DEPENDENCIES
|
88
95
|
factory_bot (~> 6.4)
|
89
|
-
|
96
|
+
json_schemer
|
90
97
|
pry (~> 0.14.2)
|
91
98
|
rake (~> 13.0)
|
92
99
|
rspec (~> 3.0)
|
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
|
@@ -27,9 +27,14 @@ LineItem = Scheming.object do
|
|
27
27
|
attribute :item_type, Enum('entertainment', 'staple')
|
28
28
|
end
|
29
29
|
|
30
|
+
Point = Scheming.generic do |(type)|
|
31
|
+
Object(x: type, y: type)
|
32
|
+
end
|
33
|
+
|
30
34
|
Receipt = Scheming.object do
|
31
35
|
attribute :line_items, Array(LineItem)
|
32
36
|
attribute :total, Float
|
37
|
+
attribute :location, Point[Float]
|
33
38
|
end
|
34
39
|
```
|
35
40
|
|
@@ -40,16 +45,21 @@ Scheming::Schema.json(Receipt)
|
|
40
45
|
{
|
41
46
|
type: 'object',
|
42
47
|
additionalProperties: false,
|
43
|
-
required: %
|
48
|
+
required: %w[line_items total location],
|
44
49
|
properties: {
|
45
50
|
line_items: {
|
46
51
|
type: 'array',
|
47
52
|
items: {
|
48
53
|
type: 'object',
|
49
54
|
additionalProperties: false,
|
50
|
-
required: %
|
55
|
+
required: %w[id name taxable price],
|
51
56
|
properties: {
|
52
|
-
id: {
|
57
|
+
id: {
|
58
|
+
oneOf: [
|
59
|
+
{ type: 'integer' },
|
60
|
+
{ type: 'string' }
|
61
|
+
]
|
62
|
+
},
|
53
63
|
name: { type: 'string' },
|
54
64
|
taxable: { type: 'boolean' },
|
55
65
|
desc: {
|
@@ -61,12 +71,21 @@ Scheming::Schema.json(Receipt)
|
|
61
71
|
price: { type: 'number' },
|
62
72
|
item_type: {
|
63
73
|
type: 'string',
|
64
|
-
enum: [
|
74
|
+
enum: %w[entertainment staple]
|
65
75
|
}
|
66
76
|
}
|
67
77
|
}
|
68
78
|
},
|
69
|
-
total: { type: 'number' }
|
79
|
+
total: { type: 'number' },
|
80
|
+
location: {
|
81
|
+
type: 'object',
|
82
|
+
additionalProperties: false,
|
83
|
+
required: %w[x y],
|
84
|
+
properties: {
|
85
|
+
x: { type: 'number' },
|
86
|
+
y: { type: 'number' }
|
87
|
+
}
|
88
|
+
}
|
70
89
|
}
|
71
90
|
}
|
72
91
|
```
|
data/lib/scheming/dsl/tagging.rb
CHANGED
@@ -10,7 +10,7 @@ class Scheming::DSL::Tagging
|
|
10
10
|
#
|
11
11
|
class Tag
|
12
12
|
# @param name [Symbo]
|
13
|
-
# @data [Hash<Symbol, Object>]
|
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,11 @@ 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
|
29
36
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# = Generic
|
4
|
+
#
|
5
|
+
# Many types can be "templated" in a way where
|
6
|
+
# some types get swapped in and out. Perhaps
|
7
|
+
# the most common example for this is with a
|
8
|
+
# two dimensional `Point` structure. We could
|
9
|
+
# have a point with `Float` coordinates OR they
|
10
|
+
# could also be `Integer`:
|
11
|
+
#
|
12
|
+
# ```ruby
|
13
|
+
# Object(x: Float, y: Float)
|
14
|
+
# Object(x: Integer, y: Integer)
|
15
|
+
# ```
|
16
|
+
#
|
17
|
+
# Instead of having two defintions we can have
|
18
|
+
# a single generic that defins both:
|
19
|
+
#
|
20
|
+
# ```ruby
|
21
|
+
# Point = Scheming::Generic.new do |(t)|
|
22
|
+
# Object(x: t, y: t)
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# Point[Float]
|
26
|
+
#
|
27
|
+
# Point[Integer]
|
28
|
+
# ```
|
29
|
+
#
|
30
|
+
class Scheming::Generic
|
31
|
+
def initialize(&proto_type)
|
32
|
+
@proto_type = proto_type
|
33
|
+
end
|
34
|
+
|
35
|
+
# @param types [Scheming::Type::Base]
|
36
|
+
def [](*types)
|
37
|
+
Scheming::DSL::DataBuilder
|
38
|
+
.new
|
39
|
+
.instance_exec(types, &@proto_type)
|
40
|
+
end
|
41
|
+
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.to_s.freeze }
|
35
|
+
.freeze
|
33
36
|
end
|
34
37
|
|
35
38
|
def properties
|
@@ -39,6 +42,13 @@ 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
|
+
|
42
52
|
refine Scheming::Type::Nullable do
|
43
53
|
# @!attribute [r] type
|
44
54
|
# @return [Scheming::Type::Base]
|
data/lib/scheming/type.rb
CHANGED
@@ -47,6 +47,23 @@ module Scheming::Type
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
+
# = Union Type Definition
|
51
|
+
#
|
52
|
+
# In cases where a value can be of many different
|
53
|
+
# types a union is how to describe this.
|
54
|
+
#
|
55
|
+
class Union < Base
|
56
|
+
# @return [Array<Scheming::Type::Base>]
|
57
|
+
attr_reader :types
|
58
|
+
|
59
|
+
# @param types [Array<Scheming::Type::Base>]
|
60
|
+
def initialize(types)
|
61
|
+
super()
|
62
|
+
@types = types
|
63
|
+
freeze
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
50
67
|
# = Enumeration Type Definition
|
51
68
|
#
|
52
69
|
# The wrapper that describes a type and holds
|
data/lib/scheming/version.rb
CHANGED
data/lib/scheming.rb
CHANGED
@@ -10,6 +10,7 @@ module Scheming
|
|
10
10
|
require_relative 'scheming/attribute'
|
11
11
|
require_relative 'scheming/type'
|
12
12
|
require_relative 'scheming/schema'
|
13
|
+
require_relative 'scheming/generic'
|
13
14
|
require_relative 'scheming/dsl'
|
14
15
|
|
15
16
|
# @return [Class]
|
@@ -18,4 +19,7 @@ module Scheming
|
|
18
19
|
builder.instance_exec(&)
|
19
20
|
builder.build
|
20
21
|
end
|
22
|
+
|
23
|
+
# @return [Scheming::Generic]
|
24
|
+
def self.generic(&) = Scheming::Generic.new(&)
|
21
25
|
end
|
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.6.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-04 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Ergonomic Data Design for the Masses
|
14
14
|
email:
|
@@ -35,6 +35,7 @@ files:
|
|
35
35
|
- lib/scheming/dsl/tagging.rb
|
36
36
|
- lib/scheming/dsl/type_resolver.rb
|
37
37
|
- lib/scheming/dsl/type_specs.rb
|
38
|
+
- lib/scheming/generic.rb
|
38
39
|
- lib/scheming/schema.rb
|
39
40
|
- lib/scheming/schema/json.rb
|
40
41
|
- lib/scheming/type.rb
|