json_model_rb 0.1.20 → 0.1.23
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 +54 -78
- 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 -7
- data/spec/config_spec.rb +0 -14
- data/spec/examples/file_system_spec.rb +71 -31
- data/spec/examples/user_spec.rb +69 -40
- data/spec/schema_meta_spec.rb +0 -40
- data/spec/schema_spec.rb +43 -59
- metadata +84 -58
- data/lib/json_model/composeable.rb +0 -35
- 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
|