json_model_rb 0.1.19 → 0.1.22
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/README.md +156 -572
- data/lib/json_model/builder/alias_builder.rb +10 -0
- data/lib/json_model/builder/array_builder.rb +24 -0
- data/lib/json_model/builder/base_builder.rb +24 -0
- data/lib/json_model/builder/composition/any_of_builder.rb +16 -0
- data/lib/json_model/builder/composition/builder.rb +47 -0
- data/lib/json_model/builder/composition/intersection_builder.rb +16 -0
- data/lib/json_model/builder/composition/one_of_builder.rb +16 -0
- data/lib/json_model/builder/composition/sum_builder.rb +16 -0
- data/lib/json_model/builder/composition.rb +6 -0
- data/lib/json_model/builder/constrained_builder.rb +83 -0
- data/lib/json_model/builder/default_builder.rb +14 -0
- data/lib/json_model/builder/enum_builder.rb +16 -0
- data/lib/json_model/builder/format_builder.rb +47 -0
- data/lib/json_model/builder/key_builder.rb +30 -0
- data/lib/json_model/builder/nested_builder.rb +31 -0
- data/lib/json_model/builder/primitive/boolean_builder.rb +16 -0
- data/lib/json_model/builder/primitive/builder.rb +25 -0
- data/lib/json_model/builder/primitive/integer_builder.rb +16 -0
- data/lib/json_model/builder/primitive/null_builder.rb +16 -0
- data/lib/json_model/builder/primitive/number_builder.rb +16 -0
- data/lib/json_model/builder/primitive/string_builder.rb +16 -0
- data/lib/json_model/builder/primitive.rb +7 -0
- data/lib/json_model/builder/ref_builder.rb +35 -0
- data/lib/json_model/builder/schema_builder.rb +14 -0
- data/lib/json_model/builder.rb +65 -0
- data/lib/json_model/config/options.rb +5 -2
- data/lib/json_model/config.rb +0 -2
- data/lib/json_model/errors.rb +0 -3
- data/lib/json_model/logic/predicates/methods.rb +17 -0
- data/lib/json_model/predicates.rb +3 -0
- data/lib/json_model/schema.rb +41 -77
- data/lib/json_model/schema_meta.rb +7 -28
- data/lib/json_model/types/alias.rb +33 -0
- data/lib/json_model/types/any_of.rb +51 -20
- data/lib/json_model/types/one_of.rb +51 -20
- data/lib/json_model/types/ref.rb +32 -0
- data/lib/json_model/types.rb +47 -9
- data/lib/json_model/version.rb +1 -1
- data/lib/json_model.rb +3 -6
- data/spec/config_spec.rb +0 -14
- data/spec/examples/file_system_spec.rb +71 -31
- data/spec/examples/user_spec.rb +67 -26
- data/spec/schema_meta_spec.rb +0 -40
- data/spec/schema_spec.rb +43 -59
- metadata +84 -57
- data/lib/json_model/errors/invalid_ref_mode_error.rb +0 -12
- data/lib/json_model/errors/type_error.rb +0 -8
- data/lib/json_model/errors/unknown_attribute_error.rb +0 -13
- data/lib/json_model/properties.rb +0 -86
- data/lib/json_model/property.rb +0 -54
- data/lib/json_model/ref_mode.rb +0 -9
- data/lib/json_model/type_spec/array.rb +0 -72
- data/lib/json_model/type_spec/castable.rb +0 -34
- data/lib/json_model/type_spec/composition/all_of.rb +0 -29
- data/lib/json_model/type_spec/composition/any_of.rb +0 -34
- data/lib/json_model/type_spec/composition/one_of.rb +0 -38
- data/lib/json_model/type_spec/composition.rb +0 -79
- data/lib/json_model/type_spec/const.rb +0 -35
- data/lib/json_model/type_spec/enum.rb +0 -35
- data/lib/json_model/type_spec/object.rb +0 -32
- data/lib/json_model/type_spec/primitive/boolean.rb +0 -13
- data/lib/json_model/type_spec/primitive/integer.rb +0 -21
- data/lib/json_model/type_spec/primitive/null.rb +0 -13
- data/lib/json_model/type_spec/primitive/number.rb +0 -14
- data/lib/json_model/type_spec/primitive/numeric.rb +0 -85
- data/lib/json_model/type_spec/primitive/string.rb +0 -150
- data/lib/json_model/type_spec/primitive.rb +0 -40
- data/lib/json_model/type_spec.rb +0 -82
- data/lib/json_model/types/all_of.rb +0 -29
- data/lib/json_model/types/array.rb +0 -29
- data/lib/json_model/types/boolean.rb +0 -7
- data/lib/json_model/types/const.rb +0 -23
- data/lib/json_model/types/enum.rb +0 -23
- data/lib/json_model/types/integer.rb +0 -23
- data/lib/json_model/types/null.rb +0 -7
- data/lib/json_model/types/number.rb +0 -23
- data/lib/json_model/types/string.rb +0 -23
- data/spec/properties_spec.rb +0 -76
- data/spec/property_spec.rb +0 -86
- data/spec/type_spec/array_spec.rb +0 -206
- data/spec/type_spec/castable_spec.rb +0 -19
- data/spec/type_spec/composition/all_of_spec.rb +0 -57
- data/spec/type_spec/composition/any_of_spec.rb +0 -54
- data/spec/type_spec/composition/one_of_spec.rb +0 -59
- data/spec/type_spec/composition_spec.rb +0 -90
- data/spec/type_spec/const_spec.rb +0 -18
- data/spec/type_spec/enum_spec.rb +0 -84
- data/spec/type_spec/primitive/boolean_spec.rb +0 -12
- data/spec/type_spec/primitive/integer_spec.rb +0 -57
- data/spec/type_spec/primitive/null_spec.rb +0 -12
- data/spec/type_spec/primitive/number_spec.rb +0 -12
- data/spec/type_spec/primitive/numeric_spec.rb +0 -176
- data/spec/type_spec/primitive/string_spec.rb +0 -119
- data/spec/type_spec_spec.rb +0 -32
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative('nested_builder')
|
|
4
|
+
|
|
5
|
+
module JsonModel
|
|
6
|
+
module Builder
|
|
7
|
+
class ArrayBuilder < NestedBuilder
|
|
8
|
+
# @return [Hash]
|
|
9
|
+
def as_schema
|
|
10
|
+
{
|
|
11
|
+
type: 'array',
|
|
12
|
+
items: builder.as_schema,
|
|
13
|
+
}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
protected
|
|
17
|
+
|
|
18
|
+
# @return [Type]
|
|
19
|
+
def nested_type
|
|
20
|
+
type.member
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JsonModel
|
|
4
|
+
module Builder
|
|
5
|
+
class BaseBuilder
|
|
6
|
+
attr_reader(:type)
|
|
7
|
+
|
|
8
|
+
# @param [Dry::Types::Type] type
|
|
9
|
+
def initialize(type)
|
|
10
|
+
@type = type
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @return [Hash]
|
|
14
|
+
def as_schema
|
|
15
|
+
raise(NotImplementedError)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @return [Array<JsonModel::Builder::BaseBuilder>]
|
|
19
|
+
def referenced_schemas
|
|
20
|
+
[]
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative('builder')
|
|
4
|
+
|
|
5
|
+
module JsonModel
|
|
6
|
+
module Builder
|
|
7
|
+
module Composition
|
|
8
|
+
class AnyOfBuilder < Builder
|
|
9
|
+
# @param [Dry::Types::Intersection] type
|
|
10
|
+
def initialize(type)
|
|
11
|
+
super(type.type, :anyOf)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative('../base_builder')
|
|
4
|
+
|
|
5
|
+
module JsonModel
|
|
6
|
+
module Builder
|
|
7
|
+
module Composition
|
|
8
|
+
class Builder < BaseBuilder
|
|
9
|
+
# @param [Dry::Types::Type] type
|
|
10
|
+
# @param [Symbol] modifier
|
|
11
|
+
def initialize(type, modifier)
|
|
12
|
+
super(type)
|
|
13
|
+
@modifier = modifier
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @return [Hash]
|
|
17
|
+
def as_schema
|
|
18
|
+
{
|
|
19
|
+
@modifier => builders.map(&:as_schema).uniq,
|
|
20
|
+
}
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# @return [Array<JsonModel::Builder::BaseBuilder>]
|
|
24
|
+
def referenced_schemas
|
|
25
|
+
builders.flat_map(&:referenced_schemas).uniq
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
# @return [Array<JsonModel::Builder::BaseBuilder>]
|
|
31
|
+
def builders
|
|
32
|
+
@builders ||= types(type).uniq.map { |type| JsonModel::Builder.for(type) }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# @param [Dry::Types::Type] type
|
|
36
|
+
# @return [Array<Dry::Types::Type>]
|
|
37
|
+
def types(type)
|
|
38
|
+
if type.is_a?(Dry::Types::Composition)
|
|
39
|
+
types(type.left) + types(type.right)
|
|
40
|
+
else
|
|
41
|
+
[type]
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative('builder')
|
|
4
|
+
|
|
5
|
+
module JsonModel
|
|
6
|
+
module Builder
|
|
7
|
+
module Composition
|
|
8
|
+
class IntersectionBuilder < Builder
|
|
9
|
+
# @param [Dry::Types::Intersection] type
|
|
10
|
+
def initialize(type)
|
|
11
|
+
super(type, :allOf)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative('builder')
|
|
4
|
+
|
|
5
|
+
module JsonModel
|
|
6
|
+
module Builder
|
|
7
|
+
module Composition
|
|
8
|
+
class OneOfBuilder < Builder
|
|
9
|
+
# @param [Dry::Types::Sum] type
|
|
10
|
+
def initialize(type)
|
|
11
|
+
super(type.type, :oneOf)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative('builder')
|
|
4
|
+
|
|
5
|
+
module JsonModel
|
|
6
|
+
module Builder
|
|
7
|
+
module Composition
|
|
8
|
+
class SumBuilder < Builder
|
|
9
|
+
# @param [Dry::Types::Sum] type
|
|
10
|
+
def initialize(type)
|
|
11
|
+
super(type, :anyOf)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative('nested_builder')
|
|
4
|
+
|
|
5
|
+
module JsonModel
|
|
6
|
+
module Builder
|
|
7
|
+
class ConstrainedBuilder < NestedBuilder
|
|
8
|
+
CONSTRAINT_MAPPING = {
|
|
9
|
+
eql?: {
|
|
10
|
+
String => { key: :const },
|
|
11
|
+
},
|
|
12
|
+
format?: {
|
|
13
|
+
String => { key: :pattern, transform: lambda(&:source) },
|
|
14
|
+
},
|
|
15
|
+
gt?: {
|
|
16
|
+
Integer => { key: :exclusiveMinimum },
|
|
17
|
+
},
|
|
18
|
+
gteq?: {
|
|
19
|
+
Integer => { key: :minimum },
|
|
20
|
+
},
|
|
21
|
+
lt?: {
|
|
22
|
+
Integer => { key: :exclusiveMaximum },
|
|
23
|
+
},
|
|
24
|
+
lteq?: {
|
|
25
|
+
Integer => { key: :maximum },
|
|
26
|
+
},
|
|
27
|
+
max_size?: {
|
|
28
|
+
String => { key: :maxLength },
|
|
29
|
+
Array => { key: :maxItems },
|
|
30
|
+
},
|
|
31
|
+
min_size?: {
|
|
32
|
+
String => { key: :minLength },
|
|
33
|
+
Array => { key: :minItems },
|
|
34
|
+
},
|
|
35
|
+
unique?: {
|
|
36
|
+
Array => { key: :uniqueItems, transform: ->(_v) { true } },
|
|
37
|
+
},
|
|
38
|
+
}.freeze
|
|
39
|
+
|
|
40
|
+
# @return [Hash]
|
|
41
|
+
def as_schema
|
|
42
|
+
if type.meta[:format]
|
|
43
|
+
super
|
|
44
|
+
else
|
|
45
|
+
super.merge(*extract_constraints)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
# @return [Array<Hash>]
|
|
52
|
+
def extract_constraints
|
|
53
|
+
extract_rules(type.rule)
|
|
54
|
+
.map { |rule| extract_constraint(rule.to_ast) }
|
|
55
|
+
.compact
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# @param [Dry::Types::Rule] rule
|
|
59
|
+
# @return [Array<Dry::Types::Rule>]
|
|
60
|
+
def extract_rules(rule)
|
|
61
|
+
if rule.respond_to?(:rules)
|
|
62
|
+
rule.rules.flat_map { |rule| extract_rules(rule) }
|
|
63
|
+
else
|
|
64
|
+
[rule]
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# @param [Array] ast
|
|
69
|
+
# @return [Hash, nil]
|
|
70
|
+
def extract_constraint(ast)
|
|
71
|
+
predicate, args = ast.last
|
|
72
|
+
if CONSTRAINT_MAPPING.key?(predicate)
|
|
73
|
+
mapping = CONSTRAINT_MAPPING.dig(predicate, type.primitive) || CONSTRAINT_MAPPING[predicate].values.first
|
|
74
|
+
{
|
|
75
|
+
mapping[:key] => mapping
|
|
76
|
+
.fetch(:transform, ->(v) { v })
|
|
77
|
+
.call(args.first.last),
|
|
78
|
+
}
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative('base_builder')
|
|
4
|
+
|
|
5
|
+
module JsonModel
|
|
6
|
+
module Builder
|
|
7
|
+
class FormatBuilder < BaseBuilder
|
|
8
|
+
class << self
|
|
9
|
+
# @param [String] format
|
|
10
|
+
# @return [Factory]
|
|
11
|
+
def for(format)
|
|
12
|
+
Factory.new(format)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
class Factory
|
|
17
|
+
attr_reader(:format)
|
|
18
|
+
|
|
19
|
+
# @param [String] format
|
|
20
|
+
def initialize(format)
|
|
21
|
+
@format = format
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @param [Dry::Types::Type] type
|
|
25
|
+
# @return [FormatBuilder]
|
|
26
|
+
def new(type)
|
|
27
|
+
FormatBuilder.new(type, format)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @param [Dry::Types::Type] type
|
|
32
|
+
# @param [Symbol] format
|
|
33
|
+
def initialize(type, format)
|
|
34
|
+
super(type)
|
|
35
|
+
@format = format
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @return [Hash]
|
|
39
|
+
def as_schema
|
|
40
|
+
{
|
|
41
|
+
type: 'string',
|
|
42
|
+
format: @format,
|
|
43
|
+
}
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative('nested_builder')
|
|
4
|
+
|
|
5
|
+
module JsonModel
|
|
6
|
+
module Builder
|
|
7
|
+
class KeyBuilder < NestedBuilder
|
|
8
|
+
# @return [Hash]
|
|
9
|
+
def as_schema
|
|
10
|
+
{
|
|
11
|
+
self.alias => builder.as_schema,
|
|
12
|
+
}
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @return [FalseClass, TrueClass]
|
|
16
|
+
def optional?
|
|
17
|
+
type.optional?
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# @return [Symbol]
|
|
21
|
+
def alias
|
|
22
|
+
if type.respond_to?(:alias)
|
|
23
|
+
type.alias
|
|
24
|
+
else
|
|
25
|
+
JsonModel.config.property_naming_strategy.call(type.name)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative('base_builder')
|
|
4
|
+
|
|
5
|
+
module JsonModel
|
|
6
|
+
module Builder
|
|
7
|
+
class NestedBuilder < BaseBuilder
|
|
8
|
+
# @return [Hash]
|
|
9
|
+
def as_schema
|
|
10
|
+
builder.as_schema
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @return [Array<Type>]
|
|
14
|
+
def referenced_schemas
|
|
15
|
+
builder.referenced_schemas
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
protected
|
|
19
|
+
|
|
20
|
+
# @return [BaseBuilder]
|
|
21
|
+
def builder
|
|
22
|
+
@builder ||= Builder.for(nested_type)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @return [Type]
|
|
26
|
+
def nested_type
|
|
27
|
+
type.type
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative('builder')
|
|
4
|
+
|
|
5
|
+
module JsonModel
|
|
6
|
+
module Builder
|
|
7
|
+
module Primitive
|
|
8
|
+
class BooleanBuilder < Builder
|
|
9
|
+
# @param [Dry::Types::Type] type
|
|
10
|
+
def initialize(type)
|
|
11
|
+
super(type, 'boolean')
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative('../base_builder')
|
|
4
|
+
|
|
5
|
+
module JsonModel
|
|
6
|
+
module Builder
|
|
7
|
+
module Primitive
|
|
8
|
+
class Builder < BaseBuilder
|
|
9
|
+
# @param [Dry::Types::Type] type
|
|
10
|
+
# @param [String] schema_type
|
|
11
|
+
def initialize(type, schema_type)
|
|
12
|
+
super(type)
|
|
13
|
+
@schema_type = schema_type
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @return [Hash]
|
|
17
|
+
def as_schema
|
|
18
|
+
{
|
|
19
|
+
type: @schema_type,
|
|
20
|
+
}
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative('builder')
|
|
4
|
+
|
|
5
|
+
module JsonModel
|
|
6
|
+
module Builder
|
|
7
|
+
module Primitive
|
|
8
|
+
class IntegerBuilder < Builder
|
|
9
|
+
# @param [Dry::Types::Type] type
|
|
10
|
+
def initialize(type)
|
|
11
|
+
super(type, 'integer')
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative('builder')
|
|
4
|
+
|
|
5
|
+
module JsonModel
|
|
6
|
+
module Builder
|
|
7
|
+
module Primitive
|
|
8
|
+
class NullBuilder < Builder
|
|
9
|
+
# @param [Dry::Types::Type] type
|
|
10
|
+
def initialize(type)
|
|
11
|
+
super(type, 'null')
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative('builder')
|
|
4
|
+
|
|
5
|
+
module JsonModel
|
|
6
|
+
module Builder
|
|
7
|
+
module Primitive
|
|
8
|
+
class NumberBuilder < Builder
|
|
9
|
+
# @param [Dry::Types::Type] type
|
|
10
|
+
def initialize(type)
|
|
11
|
+
super(type, 'number')
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative('builder')
|
|
4
|
+
|
|
5
|
+
module JsonModel
|
|
6
|
+
module Builder
|
|
7
|
+
module Primitive
|
|
8
|
+
class StringBuilder < Builder
|
|
9
|
+
# @param [Dry::Types::Type] type
|
|
10
|
+
def initialize(type)
|
|
11
|
+
super(type, 'string')
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative('base_builder')
|
|
4
|
+
|
|
5
|
+
module JsonModel
|
|
6
|
+
module Builder
|
|
7
|
+
class RefBuilder < NestedBuilder
|
|
8
|
+
# @return [Hash]
|
|
9
|
+
def as_schema
|
|
10
|
+
case ref_mode
|
|
11
|
+
when :local
|
|
12
|
+
{ '$ref': "#/$defs/#{type.name}" }
|
|
13
|
+
when :external
|
|
14
|
+
{ '$ref': type.schema_id }
|
|
15
|
+
else
|
|
16
|
+
type.as_schema
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# @return [Array<Type>]
|
|
21
|
+
def referenced_schemas
|
|
22
|
+
if ref_mode == :local
|
|
23
|
+
[type]
|
|
24
|
+
else
|
|
25
|
+
super
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @return [Symbol]
|
|
30
|
+
def ref_mode
|
|
31
|
+
type.options[:mode]
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative('builder/alias_builder')
|
|
4
|
+
require_relative('builder/array_builder')
|
|
5
|
+
require_relative('builder/composition')
|
|
6
|
+
require_relative('builder/constrained_builder')
|
|
7
|
+
require_relative('builder/default_builder')
|
|
8
|
+
require_relative('builder/enum_builder')
|
|
9
|
+
require_relative('builder/format_builder')
|
|
10
|
+
require_relative('builder/key_builder')
|
|
11
|
+
require_relative('builder/primitive')
|
|
12
|
+
require_relative('builder/ref_builder')
|
|
13
|
+
require_relative('builder/schema_builder')
|
|
14
|
+
|
|
15
|
+
require_relative('types')
|
|
16
|
+
|
|
17
|
+
module JsonModel
|
|
18
|
+
module Builder
|
|
19
|
+
class << self
|
|
20
|
+
PRIMITIVE_TO_BUILDER = {
|
|
21
|
+
Array => Builder::ArrayBuilder,
|
|
22
|
+
FalseClass => Builder::Primitive::BooleanBuilder,
|
|
23
|
+
Float => Builder::Primitive::NumberBuilder,
|
|
24
|
+
Integer => Builder::Primitive::IntegerBuilder,
|
|
25
|
+
NilClass => Builder::Primitive::NullBuilder,
|
|
26
|
+
String => Builder::Primitive::StringBuilder,
|
|
27
|
+
TrueClass => Builder::Primitive::BooleanBuilder,
|
|
28
|
+
URI => Builder::FormatBuilder.for('uri'),
|
|
29
|
+
}.freeze
|
|
30
|
+
|
|
31
|
+
TYPE_TO_BUILDER = {
|
|
32
|
+
Dry::Struct::Sum => Builder::Composition::SumBuilder,
|
|
33
|
+
Dry::Types::Constrained => Builder::ConstrainedBuilder,
|
|
34
|
+
Dry::Types::Constructor => Builder::NestedBuilder,
|
|
35
|
+
Dry::Types::Default => Builder::DefaultBuilder,
|
|
36
|
+
Dry::Types::Enum => Builder::EnumBuilder,
|
|
37
|
+
Dry::Types::Intersection => Builder::Composition::IntersectionBuilder,
|
|
38
|
+
Dry::Types::Intersection::Constrained => Builder::Composition::IntersectionBuilder,
|
|
39
|
+
Dry::Types::Schema::Key => Builder::KeyBuilder,
|
|
40
|
+
Dry::Types::Sum => Builder::Composition::SumBuilder,
|
|
41
|
+
Dry::Types::Sum::Constrained => Builder::Composition::SumBuilder,
|
|
42
|
+
JsonModel::Types::Alias => Builder::AliasBuilder,
|
|
43
|
+
JsonModel::Types::AnyOf => Builder::Composition::AnyOfBuilder,
|
|
44
|
+
JsonModel::Types::OneOf => Builder::Composition::OneOfBuilder,
|
|
45
|
+
JsonModel::Types::Ref => Builder::RefBuilder,
|
|
46
|
+
}.freeze
|
|
47
|
+
|
|
48
|
+
# @param [Dry::Types::Type] type
|
|
49
|
+
# @return [Builder::BaseBuilder]
|
|
50
|
+
def for(type)
|
|
51
|
+
if TYPE_TO_BUILDER.key?(type.class)
|
|
52
|
+
TYPE_TO_BUILDER[type.class].new(type)
|
|
53
|
+
elsif type.respond_to?(:meta) && type.meta[:format]
|
|
54
|
+
Builder::FormatBuilder.for(type.meta[:format]).new(type)
|
|
55
|
+
elsif type.respond_to?(:primitive) && PRIMITIVE_TO_BUILDER.key?(type.primitive)
|
|
56
|
+
PRIMITIVE_TO_BUILDER[type.primitive].new(type)
|
|
57
|
+
elsif type.is_a?(Class) && type < Schema
|
|
58
|
+
SchemaBuilder.new(type)
|
|
59
|
+
else
|
|
60
|
+
raise("No builder available for type: #{type.inspect}")
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -13,15 +13,18 @@ module JsonModel
|
|
|
13
13
|
@settings ||= {}
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
# @param [Symbol] name
|
|
17
|
+
# @param [Object] default
|
|
18
|
+
# @param [Proc, nil] transformation
|
|
16
19
|
def option(name, default: nil, &transformation)
|
|
17
20
|
define_method(name) { settings[name] }
|
|
18
21
|
define_method("#{name}=") do |value|
|
|
19
|
-
settings[name] = transformation.
|
|
22
|
+
settings[name] = transformation.nil? ? value : transformation.call(value)
|
|
20
23
|
end
|
|
21
24
|
module_function(name)
|
|
22
25
|
module_function("#{name}=")
|
|
23
26
|
|
|
24
|
-
defaults[name] = transformation.
|
|
27
|
+
defaults[name] = transformation.nil? ? default : transformation.call(default)
|
|
25
28
|
settings[name] = defaults[name]
|
|
26
29
|
end
|
|
27
30
|
end
|