json_model_rb 0.1.18 → 0.1.20
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/lib/json_model/composeable.rb +35 -0
- data/lib/json_model/schema.rb +3 -5
- data/lib/json_model/type_spec.rb +11 -10
- data/lib/json_model/version.rb +1 -1
- data/lib/json_model.rb +1 -0
- data/spec/examples/user_spec.rb +21 -5
- 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: 98b0c57c0738f93582f7783f5de240050d0129e7015ee2e208101ee2fbf62228
|
|
4
|
+
data.tar.gz: 847d1567156289c42144329ca370250772bdd9fdfa1c4776482d354a51560ab5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a8eb301c456c28814b8b7eca3fbbe30a0d7c6e8e789bbc6bbfca73052e0f18934e277913a1cc7632a45fe56245781389bc96ed8d59b01781d63ec08f3c2f0f61
|
|
7
|
+
data.tar.gz: 9ae72f4ab9291f822ed7dcb632744c4b87c8689344fcb3bb68ea469ea605fa57945735af341c1671edcfe2d4b91a8a73ece88fa72c092b9027860f8d1da73d74
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JsonModel
|
|
4
|
+
module Composeable
|
|
5
|
+
extend(ActiveSupport::Concern)
|
|
6
|
+
|
|
7
|
+
class_methods do
|
|
8
|
+
# @return [Array]
|
|
9
|
+
def composed_types
|
|
10
|
+
@composed_types ||= []
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @param [Object] type
|
|
14
|
+
# @param [Symbol] ref_mode
|
|
15
|
+
def compose(type, ref_mode: RefMode::LOCAL)
|
|
16
|
+
composed_types << {
|
|
17
|
+
type: TypeSpec.resolve(type),
|
|
18
|
+
ref_mode: ref_mode,
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @return [Array<JsonModel::TypeSpec::Composition>]
|
|
23
|
+
def composed_type_defs
|
|
24
|
+
composed_types.select { |type| type[:ref_mode] == RefMode::LOCAL }.flat_map { |it| it[:type].referenced_schemas }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @return [Array<Hash>]
|
|
28
|
+
def composed_types_as_schema
|
|
29
|
+
composed_types.each_with_object({}) do |it, agg|
|
|
30
|
+
agg.deep_merge!(it[:type].as_schema(ref_mode: it[:ref_mode]))
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
data/lib/json_model/schema.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
module JsonModel
|
|
4
4
|
module Schema
|
|
5
5
|
extend(ActiveSupport::Concern)
|
|
6
|
+
include(Composeable)
|
|
6
7
|
include(Properties)
|
|
7
8
|
include(SchemaMeta)
|
|
8
9
|
|
|
@@ -61,6 +62,7 @@ module JsonModel
|
|
|
61
62
|
required: required_properties_as_schema,
|
|
62
63
|
'$defs': defs_as_schema,
|
|
63
64
|
)
|
|
65
|
+
.merge(**composed_types_as_schema)
|
|
64
66
|
.merge(type: 'object')
|
|
65
67
|
.compact
|
|
66
68
|
when RefMode::LOCAL
|
|
@@ -94,11 +96,7 @@ module JsonModel
|
|
|
94
96
|
end
|
|
95
97
|
|
|
96
98
|
def defs_as_schema
|
|
97
|
-
referenced_schemas = local_properties
|
|
98
|
-
.values
|
|
99
|
-
.flat_map(&:referenced_schemas)
|
|
100
|
-
.uniq
|
|
101
|
-
|
|
99
|
+
referenced_schemas = (composed_type_defs + local_properties.values.flat_map(&:referenced_schemas)).uniq
|
|
102
100
|
if referenced_schemas.any?
|
|
103
101
|
referenced_schemas.to_h { |type| [type.name.to_sym, type.as_schema] }
|
|
104
102
|
end
|
data/lib/json_model/type_spec.rb
CHANGED
|
@@ -49,17 +49,18 @@ module JsonModel
|
|
|
49
49
|
# @param [Object, Class] type
|
|
50
50
|
# @return [TypeSpec]
|
|
51
51
|
def resolve(type)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
if type.is_a?(TypeSpec)
|
|
53
|
+
return type
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
if TYPE_MAP.key?(type)
|
|
57
|
+
TYPE_MAP[type]
|
|
58
|
+
elsif type.respond_to?(:to_type_spec)
|
|
59
|
+
type.to_type_spec
|
|
60
|
+
elsif type.is_a?(Class) && type < Schema
|
|
61
|
+
TypeSpec::Object.new(type)
|
|
57
62
|
else
|
|
58
|
-
|
|
59
|
-
type.to_type_spec
|
|
60
|
-
else
|
|
61
|
-
raise(ArgumentError, "Unsupported type: #{type}")
|
|
62
|
-
end
|
|
63
|
+
raise(ArgumentError, "Unsupported type: #{type}")
|
|
63
64
|
end
|
|
64
65
|
end
|
|
65
66
|
|
data/lib/json_model/version.rb
CHANGED
data/lib/json_model.rb
CHANGED
|
@@ -5,6 +5,7 @@ require('active_support/concern')
|
|
|
5
5
|
require('active_support/core_ext/class/attribute')
|
|
6
6
|
require('active_support/descendants_tracker')
|
|
7
7
|
require('uri')
|
|
8
|
+
require('json_model/composeable')
|
|
8
9
|
require('json_model/config')
|
|
9
10
|
require('json_model/errors')
|
|
10
11
|
require('json_model/properties')
|
data/spec/examples/user_spec.rb
CHANGED
|
@@ -20,20 +20,35 @@ RSpec.describe('User schema') do
|
|
|
20
20
|
|
|
21
21
|
stub_const('Address', address_class)
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
person_class = Class.new do
|
|
24
24
|
include(JsonModel::Schema)
|
|
25
25
|
|
|
26
26
|
def self.name
|
|
27
|
-
'
|
|
27
|
+
'Person'
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
schema_id('person.schema.json')
|
|
30
31
|
property(:name, type: String)
|
|
31
32
|
property(:email, type: T::String[format: :email])
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
stub_const('Person', person_class)
|
|
36
|
+
|
|
37
|
+
user_class = Class.new do
|
|
38
|
+
include(JsonModel::Schema)
|
|
39
|
+
|
|
40
|
+
def self.name
|
|
41
|
+
'User'
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
compose(T::AllOf[Person], ref_mode: JsonModel::RefMode::EXTERNAL)
|
|
32
45
|
property(:age, type: T::Integer[minimum: 0, maximum: 120], optional: true)
|
|
33
46
|
property(:active, type: T::Boolean, default: true, optional: true)
|
|
34
47
|
property(:addresses, type: T::Array[Address], ref_mode: JsonModel::RefMode::LOCAL)
|
|
35
48
|
property(:tags, type: T::Array[String], optional: true)
|
|
36
49
|
property(:birthday, type: Date, optional: true)
|
|
50
|
+
property(:websites, type: T::Array[URI], optional: true)
|
|
51
|
+
property(:height, type: Float, optional: true)
|
|
37
52
|
end
|
|
38
53
|
|
|
39
54
|
stub_const('User', user_class)
|
|
@@ -45,9 +60,8 @@ RSpec.describe('User schema') do
|
|
|
45
60
|
eq(
|
|
46
61
|
{
|
|
47
62
|
type: 'object',
|
|
63
|
+
allOf: [{ '$ref': 'person.schema.json' }],
|
|
48
64
|
properties: {
|
|
49
|
-
name: { type: 'string' },
|
|
50
|
-
email: { type: 'string', format: 'email' },
|
|
51
65
|
age: { type: 'integer', minimum: 0, maximum: 120 },
|
|
52
66
|
active: { type: 'boolean', default: true },
|
|
53
67
|
addresses: {
|
|
@@ -56,8 +70,10 @@ RSpec.describe('User schema') do
|
|
|
56
70
|
},
|
|
57
71
|
tags: { type: 'array', items: { type: 'string' } },
|
|
58
72
|
birthday: { type: 'string', format: 'date' },
|
|
73
|
+
websites: { type: 'array', items: { type: 'string', format: 'uri' } },
|
|
74
|
+
height: { type: 'number' },
|
|
59
75
|
},
|
|
60
|
-
required: %i(addresses
|
|
76
|
+
required: %i(addresses),
|
|
61
77
|
'$defs': {
|
|
62
78
|
Address: {
|
|
63
79
|
type: 'object',
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: json_model_rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.20
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Paul Gillesberger
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-01-
|
|
10
|
+
date: 2026-01-19 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: rake
|
|
@@ -103,6 +103,7 @@ files:
|
|
|
103
103
|
- LICENSE
|
|
104
104
|
- README.md
|
|
105
105
|
- lib/json_model.rb
|
|
106
|
+
- lib/json_model/composeable.rb
|
|
106
107
|
- lib/json_model/config.rb
|
|
107
108
|
- lib/json_model/config/options.rb
|
|
108
109
|
- lib/json_model/errors.rb
|