jsi 0.4.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -1
  3. data/CHANGELOG.md +33 -0
  4. data/LICENSE.md +1 -1
  5. data/README.md +114 -42
  6. data/jsi.gemspec +14 -12
  7. data/lib/jsi/base/node.rb +183 -0
  8. data/lib/jsi/base.rb +388 -220
  9. data/lib/jsi/jsi_coder.rb +8 -7
  10. data/lib/jsi/metaschema.rb +0 -1
  11. data/lib/jsi/metaschema_node/bootstrap_schema.rb +101 -0
  12. data/lib/jsi/metaschema_node.rb +159 -135
  13. data/lib/jsi/ptr.rb +303 -0
  14. data/lib/jsi/schema/application/child_application/contains.rb +25 -0
  15. data/lib/jsi/schema/application/child_application/draft04.rb +22 -0
  16. data/lib/jsi/schema/application/child_application/draft06.rb +29 -0
  17. data/lib/jsi/schema/application/child_application/draft07.rb +29 -0
  18. data/lib/jsi/schema/application/child_application/items.rb +18 -0
  19. data/lib/jsi/schema/application/child_application/properties.rb +25 -0
  20. data/lib/jsi/schema/application/child_application.rb +38 -0
  21. data/lib/jsi/schema/application/draft04.rb +8 -0
  22. data/lib/jsi/schema/application/draft06.rb +8 -0
  23. data/lib/jsi/schema/application/draft07.rb +8 -0
  24. data/lib/jsi/schema/application/inplace_application/dependencies.rb +28 -0
  25. data/lib/jsi/schema/application/inplace_application/draft04.rb +26 -0
  26. data/lib/jsi/schema/application/inplace_application/draft06.rb +27 -0
  27. data/lib/jsi/schema/application/inplace_application/draft07.rb +33 -0
  28. data/lib/jsi/schema/application/inplace_application/ifthenelse.rb +20 -0
  29. data/lib/jsi/schema/application/inplace_application/ref.rb +18 -0
  30. data/lib/jsi/schema/application/inplace_application/someof.rb +44 -0
  31. data/lib/jsi/schema/application/inplace_application.rb +41 -0
  32. data/lib/jsi/schema/application.rb +12 -0
  33. data/lib/jsi/schema/draft04.rb +14 -0
  34. data/lib/jsi/schema/draft06.rb +14 -0
  35. data/lib/jsi/schema/draft07.rb +14 -0
  36. data/lib/jsi/schema/issue.rb +36 -0
  37. data/lib/jsi/schema/ref.rb +160 -0
  38. data/lib/jsi/schema/schema_ancestor_node.rb +113 -0
  39. data/lib/jsi/schema/validation/array.rb +69 -0
  40. data/lib/jsi/schema/validation/const.rb +20 -0
  41. data/lib/jsi/schema/validation/contains.rb +25 -0
  42. data/lib/jsi/schema/validation/core.rb +39 -0
  43. data/lib/jsi/schema/validation/dependencies.rb +49 -0
  44. data/lib/jsi/schema/validation/draft04/minmax.rb +91 -0
  45. data/lib/jsi/schema/validation/draft04.rb +112 -0
  46. data/lib/jsi/schema/validation/draft06.rb +122 -0
  47. data/lib/jsi/schema/validation/draft07.rb +159 -0
  48. data/lib/jsi/schema/validation/enum.rb +25 -0
  49. data/lib/jsi/schema/validation/ifthenelse.rb +46 -0
  50. data/lib/jsi/schema/validation/items.rb +54 -0
  51. data/lib/jsi/schema/validation/not.rb +20 -0
  52. data/lib/jsi/schema/validation/numeric.rb +121 -0
  53. data/lib/jsi/schema/validation/object.rb +45 -0
  54. data/lib/jsi/schema/validation/pattern.rb +34 -0
  55. data/lib/jsi/schema/validation/properties.rb +101 -0
  56. data/lib/jsi/schema/validation/property_names.rb +32 -0
  57. data/lib/jsi/schema/validation/ref.rb +40 -0
  58. data/lib/jsi/schema/validation/required.rb +27 -0
  59. data/lib/jsi/schema/validation/someof.rb +90 -0
  60. data/lib/jsi/schema/validation/string.rb +47 -0
  61. data/lib/jsi/schema/validation/type.rb +49 -0
  62. data/lib/jsi/schema/validation.rb +51 -0
  63. data/lib/jsi/schema.rb +508 -149
  64. data/lib/jsi/schema_classes.rb +199 -59
  65. data/lib/jsi/schema_registry.rb +151 -0
  66. data/lib/jsi/schema_set.rb +181 -0
  67. data/lib/jsi/simple_wrap.rb +23 -4
  68. data/lib/jsi/util/private/attr_struct.rb +127 -0
  69. data/lib/jsi/util/private.rb +204 -0
  70. data/lib/jsi/util/typelike.rb +229 -0
  71. data/lib/jsi/util.rb +89 -53
  72. data/lib/jsi/validation/error.rb +34 -0
  73. data/lib/jsi/validation/result.rb +210 -0
  74. data/lib/jsi/validation.rb +15 -0
  75. data/lib/jsi/version.rb +3 -1
  76. data/lib/jsi.rb +44 -14
  77. data/lib/schemas/json-schema.org/draft-04/schema.rb +10 -3
  78. data/lib/schemas/json-schema.org/draft-06/schema.rb +10 -3
  79. data/lib/schemas/json-schema.org/draft-07/schema.rb +14 -0
  80. data/readme.rb +138 -0
  81. data/{resources}/schemas/json-schema.org/draft-04/schema.json +149 -0
  82. data/{resources}/schemas/json-schema.org/draft-06/schema.json +154 -0
  83. data/{resources}/schemas/json-schema.org/draft-07/schema.json +168 -0
  84. metadata +75 -122
  85. data/.simplecov +0 -3
  86. data/Rakefile.rb +0 -9
  87. data/lib/jsi/base/to_rb.rb +0 -128
  88. data/lib/jsi/json/node.rb +0 -203
  89. data/lib/jsi/json/pointer.rb +0 -419
  90. data/lib/jsi/json-schema-fragments.rb +0 -61
  91. data/lib/jsi/json.rb +0 -10
  92. data/lib/jsi/pathed_node.rb +0 -118
  93. data/lib/jsi/typelike_modules.rb +0 -240
  94. data/resources/icons/AGPL-3.0.png +0 -0
  95. data/test/base_array_test.rb +0 -323
  96. data/test/base_hash_test.rb +0 -337
  97. data/test/base_test.rb +0 -486
  98. data/test/jsi_coder_test.rb +0 -85
  99. data/test/jsi_json_arraynode_test.rb +0 -150
  100. data/test/jsi_json_hashnode_test.rb +0 -132
  101. data/test/jsi_json_node_test.rb +0 -257
  102. data/test/jsi_json_pointer_test.rb +0 -102
  103. data/test/jsi_test.rb +0 -11
  104. data/test/jsi_typelike_as_json_test.rb +0 -53
  105. data/test/metaschema_node_test.rb +0 -19
  106. data/test/schema_module_test.rb +0 -21
  107. data/test/schema_test.rb +0 -208
  108. data/test/spreedly_openapi_test.rb +0 -8
  109. data/test/test_helper.rb +0 -97
  110. data/test/util_test.rb +0 -62
data/lib/jsi/util.rb CHANGED
@@ -1,13 +1,74 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JSI
4
- # JSI::Util classes, modules, constants, and methods are INTERNAL and will be added and removed without warning.
5
- # do not rely on them.
4
+ # JSI::Util contains public utilities
6
5
  module Util
7
- # a proc which does nothing
8
- NOOP = -> (*_) { }
6
+ autoload :Private, 'jsi/util/private'
9
7
 
10
- # returns a version of the given hash, in which any symbol keys are
8
+ include Private
9
+
10
+ autoload :Arraylike, 'jsi/util/typelike'
11
+ autoload :Hashlike, 'jsi/util/typelike'
12
+
13
+ # yields the content of the given param `object`. for objects which have a #jsi_modified_copy
14
+ # method of their own (JSI::Base, JSI::MetaschemaNode) that method is invoked with the given
15
+ # block. otherwise the given object itself is yielded.
16
+ #
17
+ # the given block must result in a modified copy of its block parameter
18
+ # (not destructively modifying the yielded content).
19
+ #
20
+ # @yield [Object] the content of the given object. the block should result
21
+ # in a (nondestructively) modified copy of this.
22
+ # @return [object.class] modified copy of the given object
23
+ def modified_copy(object, &block)
24
+ if object.respond_to?(:jsi_modified_copy)
25
+ object.jsi_modified_copy(&block)
26
+ else
27
+ return yield(object)
28
+ end
29
+ end
30
+
31
+ # recursive method to express the given argument object in json-compatible
32
+ # types of Hash, Array, and basic types of String/boolean/numeric/nil. this
33
+ # will raise TypeError if an object is given that is not a type that seems
34
+ # to be expressable as json.
35
+ #
36
+ # similar effect could be achieved by requiring 'json/add/core' and using #as_json,
37
+ # but I don't much care for how it represents classes that are
38
+ # not naturally expressable in JSON, and prefer not to load its
39
+ # monkey-patching.
40
+ #
41
+ # @param object [Object] the object to be converted to jsonifiability
42
+ # @return [Array, Hash, String, Boolean, NilClass, Numeric] jsonifiable
43
+ # expression of param object
44
+ # @raise [TypeError] when the object (or an object nested with a hash or
45
+ # array of object) cannot be expressed as json
46
+ def as_json(object, *opt)
47
+ if object.is_a?(JSI::Base)
48
+ as_json(object.jsi_node_content, *opt)
49
+ elsif object.respond_to?(:to_hash)
50
+ (object.respond_to?(:map) ? object : object.to_hash).map do |k, v|
51
+ unless k.is_a?(Symbol) || k.respond_to?(:to_str)
52
+ raise(TypeError, "json object (hash) cannot be keyed with: #{k.pretty_inspect.chomp}")
53
+ end
54
+ {k.to_s => as_json(v, *opt)}
55
+ end.inject({}, &:update)
56
+ elsif object.respond_to?(:to_ary)
57
+ (object.respond_to?(:map) ? object : object.to_ary).map { |e| as_json(e, *opt) }
58
+ elsif [String, TrueClass, FalseClass, NilClass, Numeric].any? { |c| object.is_a?(c) }
59
+ object
60
+ elsif object.is_a?(Symbol)
61
+ object.to_s
62
+ elsif object.is_a?(Set)
63
+ as_json(object.to_a, *opt)
64
+ elsif object.respond_to?(:as_json)
65
+ as_json(object.as_json(*opt), *opt)
66
+ else
67
+ raise(TypeError, "cannot express object as json: #{object.pretty_inspect.chomp}")
68
+ end
69
+ end
70
+
71
+ # a hash copied from the given hashlike, in which any symbol keys are
11
72
  # converted to strings. behavior on collisions is undefined (but in the
12
73
  # future could take a block like
13
74
  # ActiveSupport::HashWithIndifferentAccess#update)
@@ -25,7 +86,7 @@ module JSI
25
86
  unless hashlike.respond_to?(:to_hash)
26
87
  raise(ArgumentError, "expected argument to be a hash; got #{hashlike.class.inspect}: #{hashlike.pretty_inspect.chomp}")
27
88
  end
28
- JSI::Typelike.modified_copy(hashlike) do |hash|
89
+ JSI::Util.modified_copy(hashlike) do |hash|
29
90
  out = {}
30
91
  hash.each do |k, v|
31
92
  out[k.is_a?(Symbol) ? k.to_s : k] = v
@@ -36,7 +97,7 @@ module JSI
36
97
 
37
98
  def deep_stringify_symbol_keys(object)
38
99
  if object.respond_to?(:to_hash)
39
- JSI::Typelike.modified_copy(object) do |hash|
100
+ JSI::Util.modified_copy(object) do |hash|
40
101
  out = {}
41
102
  (hash.respond_to?(:each) ? hash : hash.to_hash).each do |k, v|
42
103
  out[k.is_a?(Symbol) ? k.to_s : deep_stringify_symbol_keys(k)] = deep_stringify_symbol_keys(v)
@@ -44,7 +105,7 @@ module JSI
44
105
  out
45
106
  end
46
107
  elsif object.respond_to?(:to_ary)
47
- JSI::Typelike.modified_copy(object) do |ary|
108
+ JSI::Util.modified_copy(object) do |ary|
48
109
  (ary.respond_to?(:each) ? ary : ary.to_ary).map do |e|
49
110
  deep_stringify_symbol_keys(e)
50
111
  end
@@ -54,55 +115,30 @@ module JSI
54
115
  end
55
116
  end
56
117
 
57
- # this is the Y-combinator, which allows anonymous recursive functions. for a simple example,
58
- # to define a recursive function to return the length of an array:
59
- #
60
- # length = ycomb do |len|
61
- # proc { |list| list == [] ? 0 : 1 + len.call(list[1..-1]) }
62
- # end
118
+ # ensures the given param becomes a frozen Set of Modules.
119
+ # returns the param if it is already that, otherwise initializes and freezes such a Set.
63
120
  #
64
- # see https://secure.wikimedia.org/wikipedia/en/wiki/Fixed_point_combinator#Y_combinator
65
- # and chapter 9 of the little schemer, available as the sample chapter at http://www.ccs.neu.edu/home/matthias/BTLS/
66
- def ycomb
67
- proc { |f| f.call(f) }.call(proc { |f| yield proc { |*x| f.call(f).call(*x) } })
68
- end
69
- module_function :ycomb
70
-
71
- module FingerprintHash
72
- # overrides BasicObject#==
73
- def ==(other)
74
- object_id == other.object_id || (other.respond_to?(:jsi_fingerprint) && other.jsi_fingerprint == self.jsi_fingerprint)
121
+ # @param modules [Set, Enumerable] the object to ensure becomes a frozen Set of Modules
122
+ # @return [Set] frozen Set containing the given modules
123
+ # @raise [ArgumentError] when the modules param is not an Enumerable
124
+ # @raise [Schema::NotASchemaError] when the modules param contains objects which are not Schemas
125
+ def ensure_module_set(modules)
126
+ if modules.is_a?(Set) && modules.frozen?
127
+ set = modules
128
+ else
129
+ set = Set.new(modules).freeze
75
130
  end
76
-
77
- alias_method :eql?, :==
78
-
79
- # overrides Kernel#hash
80
- def hash
81
- jsi_fingerprint.hash
131
+ not_modules = set.reject { |s| s.is_a?(Module) }
132
+ if !not_modules.empty?
133
+ raise(TypeError, [
134
+ "ensure_module_set given non-Module objects:",
135
+ *not_modules.map { |ns| ns.pretty_inspect.chomp },
136
+ ].join("\n"))
82
137
  end
83
- end
84
138
 
85
- module Memoize
86
- def jsi_memoize(key, *args_)
87
- @jsi_memos ||= {}
88
- @jsi_memos[key] ||= Hash.new do |h, args|
89
- h[args] = yield(*args)
90
- end
91
- @jsi_memos[key][args_]
92
- end
93
-
94
- def jsi_clear_memo(key, *args)
95
- @jsi_memos ||= {}
96
- if @jsi_memos[key]
97
- if args.empty?
98
- @jsi_memos[key].clear
99
- else
100
- @jsi_memos[key].delete(args)
101
- end
102
- end
103
- end
139
+ set
104
140
  end
141
+
142
+ extend self
105
143
  end
106
- public
107
- extend Util
108
144
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSI
4
+ module Validation
5
+ Error = Util::AttrStruct[*%w(
6
+ message
7
+ keyword
8
+ schema
9
+ instance_ptr
10
+ instance_document
11
+ )]
12
+
13
+ # a validation error of a schema instance against a schema
14
+ #
15
+ # @!attribute message
16
+ # a message describing the error
17
+ # @return [String]
18
+ # @!attribute keyword
19
+ # the keyword of the schema which failed to validate.
20
+ # this may be absent if the error is not from a schema keyword (i.e, `false` schema).
21
+ # @return [String]
22
+ # @!attribute schema
23
+ # the schema against which the instance failed to validate
24
+ # @return [JSI::Schema]
25
+ # @!attribute instance_ptr
26
+ # pointer to the instance in instance_document
27
+ # @return [JSI::Ptr]
28
+ # @!attribute instance_document
29
+ # document containing the instance at instance_ptr
30
+ # @return [Object]
31
+ class Error
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,210 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSI
4
+ module Validation
5
+ # a result of validating an instance against schemas which describe it.
6
+ # virtual base class.
7
+ class Result
8
+ include Util::Virtual
9
+
10
+ Builder = Util::AttrStruct[*%w(
11
+ result
12
+ schema
13
+ instance_ptr
14
+ instance_document
15
+ validate_only
16
+ visited_refs
17
+ )]
18
+
19
+ # @private
20
+ # a structure used to build a Result. virtual base class.
21
+ class Builder
22
+ def instance
23
+ instance_ptr.evaluate(instance_document)
24
+ end
25
+
26
+ def schema_issue(*_)
27
+ virtual_method
28
+ end
29
+
30
+ def schema_error(message, keyword = nil)
31
+ schema_issue(:error, message, keyword)
32
+ end
33
+
34
+ def schema_warning(message, keyword = nil)
35
+ schema_issue(:warning, message, keyword)
36
+ end
37
+
38
+ # @param subschema_ptr [JSI::Ptr, #to_ary]
39
+ # @return [JSI::Validation::Result]
40
+ def inplace_subschema_validate(subschema_ptr)
41
+ subresult = schema.subschema(subschema_ptr).internal_validate_instance(
42
+ instance_ptr,
43
+ instance_document,
44
+ validate_only: validate_only,
45
+ visited_refs: visited_refs,
46
+ )
47
+ merge_schema_issues(subresult)
48
+ subresult
49
+ end
50
+
51
+ # @param subschema_ptr [JSI::Ptr, #to_ary]
52
+ # @param subinstance_ptr [JSI::Ptr, #to_ary]
53
+ # @return [JSI::Validation::Result]
54
+ def child_subschema_validate(subschema_ptr, subinstance_ptr)
55
+ subresult = schema.subschema(subschema_ptr).internal_validate_instance(
56
+ instance_ptr + subinstance_ptr,
57
+ instance_document,
58
+ validate_only: validate_only,
59
+ )
60
+ merge_schema_issues(subresult)
61
+ subresult
62
+ end
63
+
64
+ # @param other_result [JSI::Validation::Result]
65
+ # @return [void]
66
+ def merge_schema_issues(other_result)
67
+ unless validate_only
68
+ # schema_issues are always merged from subschema results (not depending on validation results)
69
+ result.schema_issues.merge(other_result.schema_issues)
70
+ end
71
+ nil
72
+ end
73
+ end
74
+
75
+ def builder(schema, instance_ptr, instance_document, validate_only, visited_refs)
76
+ self.class::Builder.new(
77
+ result: self,
78
+ schema: schema,
79
+ instance_ptr: instance_ptr,
80
+ instance_document: instance_document,
81
+ validate_only: validate_only,
82
+ visited_refs: visited_refs,
83
+ )
84
+ end
85
+
86
+ # is the instance valid against its schemas?
87
+ # @return [Boolean]
88
+ def valid?
89
+ # :nocov:
90
+ virtual_method
91
+ # :nocov:
92
+ end
93
+
94
+ include Util::FingerprintHash
95
+ end
96
+
97
+ # a full result of validating an instance against its schemas, with each validation error
98
+ class FullResult < Result
99
+ # @private
100
+ class Builder < Result::Builder
101
+ def validate(
102
+ valid,
103
+ message,
104
+ keyword: nil,
105
+ results: []
106
+ )
107
+ results.each { |res| result.schema_issues.merge(res.schema_issues) }
108
+ if !valid
109
+ results.each { |res| result.validation_errors.merge(res.validation_errors) }
110
+ result.validation_errors << Validation::Error.new({
111
+ message: message,
112
+ keyword: keyword,
113
+ schema: schema,
114
+ instance_ptr: instance_ptr,
115
+ instance_document: instance_document,
116
+ })
117
+ end
118
+ end
119
+
120
+ def schema_issue(level, message, keyword = nil)
121
+ result.schema_issues << Schema::Issue.new({
122
+ level: level,
123
+ message: message,
124
+ keyword: keyword,
125
+ schema: schema,
126
+ })
127
+ end
128
+ end
129
+
130
+ def initialize
131
+ @validation_errors = Set.new
132
+ @schema_issues = Set.new
133
+ end
134
+
135
+ attr_reader :validation_errors
136
+ attr_reader :schema_issues
137
+
138
+ def valid?
139
+ validation_errors.empty?
140
+ end
141
+
142
+ def freeze
143
+ @validation_errors.each(&:freeze)
144
+ @schema_issues.each(&:freeze)
145
+ @validation_errors.freeze
146
+ @schema_issues.freeze
147
+ super
148
+ end
149
+
150
+ def merge(result)
151
+ unless result.is_a?(FullResult)
152
+ raise(TypeError, "not a #{FullResult.name}: #{result.pretty_inspect.chomp}")
153
+ end
154
+ validation_errors.merge(result.validation_errors)
155
+ schema_issues.merge(result.schema_issues)
156
+ self
157
+ end
158
+
159
+ def +(result)
160
+ FullResult.new.merge(self).merge(result)
161
+ end
162
+
163
+ # @private
164
+ def jsi_fingerprint
165
+ {
166
+ class: self.class,
167
+ validation_errors: validation_errors,
168
+ schema_issues: schema_issues,
169
+ }
170
+ end
171
+ end
172
+
173
+ # a result indicating only whether an instance is valid against its schemas
174
+ class ValidityResult < Result
175
+ # @private
176
+ class Builder < Result::Builder
177
+ def validate(
178
+ valid,
179
+ message,
180
+ keyword: nil,
181
+ results: []
182
+ )
183
+ if !valid
184
+ throw(:jsi_validation_result, INVALID)
185
+ end
186
+ end
187
+
188
+ def schema_issue(*_)
189
+ # noop
190
+ end
191
+ end
192
+
193
+ def initialize(valid)
194
+ @valid = valid
195
+ end
196
+
197
+ def valid?
198
+ @valid
199
+ end
200
+
201
+ # @private
202
+ def jsi_fingerprint
203
+ {
204
+ class: self.class,
205
+ valid: valid?,
206
+ }
207
+ end
208
+ end
209
+ end
210
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSI
4
+ module Validation
5
+ autoload :Error, 'jsi/validation/error'
6
+
7
+ autoload :Result, 'jsi/validation/result'
8
+ autoload :FullResult, 'jsi/validation/result'
9
+ autoload :ValidityResult, 'jsi/validation/result'
10
+
11
+ VALID = ValidityResult.new(true).freeze
12
+
13
+ INVALID = ValidityResult.new(false).freeze
14
+ end
15
+ end
data/lib/jsi/version.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JSI
2
- VERSION = "0.4.0".freeze
4
+ VERSION = "0.7.0".freeze
3
5
  end
data/lib/jsi.rb CHANGED
@@ -5,12 +5,10 @@ require "pp"
5
5
  require "set"
6
6
  require "json"
7
7
  require "pathname"
8
+ require "bigdecimal"
8
9
  require "addressable/uri"
9
10
 
10
- require "jsi/json-schema-fragments"
11
-
12
11
  require "jsi/util"
13
- require "jsi/typelike_modules"
14
12
 
15
13
  module JSI
16
14
  # generally put in code paths that are not expected to be valid control flow paths.
@@ -21,30 +19,62 @@ module JSI
21
19
  class Bug < NotImplementedError
22
20
  end
23
21
 
22
+ # @private
24
23
  ROOT_PATH = Pathname.new(__FILE__).dirname.parent.expand_path
25
- RESOURCES_PATH = ROOT_PATH.join('resources')
26
24
 
27
- autoload :JSON, 'jsi/json'
28
- autoload :PathedNode, 'jsi/pathed_node'
29
- autoload :Typelike, 'jsi/typelike_modules'
30
- autoload :Hashlike, 'jsi/typelike_modules'
31
- autoload :Arraylike, 'jsi/typelike_modules'
25
+ # @private
26
+ RESOURCES_PATH = ROOT_PATH.join('{resources}')
27
+
28
+ # @private
29
+ SCHEMAS_PATH = RESOURCES_PATH.join('schemas')
30
+
31
+ autoload :Ptr, 'jsi/ptr'
32
+ autoload :Typelike, 'jsi/util/typelike'
32
33
  autoload :Schema, 'jsi/schema'
34
+ autoload :SchemaSet, 'jsi/schema_set'
33
35
  autoload :Base, 'jsi/base'
34
36
  autoload :Metaschema, 'jsi/metaschema'
35
37
  autoload :MetaschemaNode, 'jsi/metaschema_node'
36
38
  autoload :SchemaClasses, 'jsi/schema_classes'
39
+ autoload :SchemaRegistry, 'jsi/schema_registry'
40
+ autoload :Validation, 'jsi/validation'
37
41
  autoload :JSICoder, 'jsi/jsi_coder'
38
42
 
39
43
  autoload :JSONSchemaOrgDraft04, 'schemas/json-schema.org/draft-04/schema'
40
44
  autoload :JSONSchemaOrgDraft06, 'schemas/json-schema.org/draft-06/schema'
45
+ autoload :JSONSchemaOrgDraft07, 'schemas/json-schema.org/draft-07/schema'
41
46
 
42
47
  autoload :SimpleWrap, 'jsi/simple_wrap'
43
48
 
44
- # @param schemas [Enumerable<JSI::Schema, #to_hash, Boolean>] schemas to represent with the class
45
- # @return [Class subclassing JSI::Base] a JSI class which represents the given schemas.
46
- # an instance of the class represents a JSON Schema instance described by all of the given schemas.
47
- def self.class_for_schemas(*schemas)
48
- SchemaClasses.class_for_schemas(*schemas)
49
+ # instantiates a given schema object as a JSI Schema.
50
+ #
51
+ # see {JSI::Schema.new_schema}
52
+ #
53
+ # @param (see JSI::Schema.new_schema)
54
+ # @return (see JSI::Schema.new_schema)
55
+ def self.new_schema(schema_object, **kw)
56
+ JSI::Schema.new_schema(schema_object, **kw)
57
+ end
58
+
59
+ # instantiates a given schema object as a JSI Schema and returns its JSI Schema Module.
60
+ #
61
+ # shortcut to chain {JSI::Schema.new_schema} + {Schema#jsi_schema_module}.
62
+ #
63
+ # @param (see JSI::Schema.new_schema)
64
+ # @return [Module, JSI::SchemaModule] the JSI Schema Module of the schema
65
+ def self.new_schema_module(schema_object, **kw)
66
+ JSI::Schema.new_schema(schema_object, **kw).jsi_schema_module
67
+ end
68
+
69
+ # `JSI.schema_registry` is the {JSI::SchemaRegistry} in which schemas are registered.
70
+ #
71
+ # @return [JSI::SchemaRegistry]
72
+ def self.schema_registry
73
+ return @schema_registry if instance_variable_defined?(:@schema_registry)
74
+ @schema_registry = SchemaRegistry.new
49
75
  end
50
76
  end
77
+
78
+ JSI.schema_registry.autoload_uri("http://json-schema.org/draft-04/schema") { JSI::JSONSchemaOrgDraft04.schema }
79
+ JSI.schema_registry.autoload_uri("http://json-schema.org/draft-06/schema") { JSI::JSONSchemaOrgDraft06.schema }
80
+ JSI.schema_registry.autoload_uri("http://json-schema.org/draft-07/schema") { JSI::JSONSchemaOrgDraft07.schema }
@@ -1,7 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JSI
4
- schema_id = 'http://json-schema.org/draft-04/schema'
5
- schema_content = ::JSON.parse(File.read(::JSON::Validator.validators[schema_id].metaschema))
6
- JSONSchemaOrgDraft04 = MetaschemaNode.new(schema_content).jsi_schema_module
4
+ metaschema_document = ::JSON.parse(SCHEMAS_PATH.join('json-schema.org/draft-04/schema.json').read)
5
+ JSONSchemaOrgDraft04 = MetaschemaNode.new(metaschema_document,
6
+ schema_implementation_modules: [JSI::Schema::Draft04],
7
+ ).jsi_schema_module
8
+
9
+ # the JSI schema module for `http://json-schema.org/draft-04/schema`
10
+ module JSONSchemaOrgDraft04
11
+ # @!parse extend JSI::DescribesSchemaModule
12
+ # @!parse include JSI::Schema::Draft04
13
+ end
7
14
  end
@@ -1,7 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JSI
4
- schema_id = 'http://json-schema.org/draft/schema' # I don't know why this is not http://json-schema.org/draft-06/schema
5
- schema_content = ::JSON.parse(File.read(::JSON::Validator.validators[schema_id].metaschema))
6
- JSONSchemaOrgDraft06 = MetaschemaNode.new(schema_content).jsi_schema_module
4
+ metaschema_document = ::JSON.parse(SCHEMAS_PATH.join('json-schema.org/draft-06/schema.json').read)
5
+ JSONSchemaOrgDraft06 = MetaschemaNode.new(metaschema_document,
6
+ schema_implementation_modules: [JSI::Schema::Draft06],
7
+ ).jsi_schema_module
8
+
9
+ # the JSI schema module for `http://json-schema.org/draft-06/schema`
10
+ module JSONSchemaOrgDraft06
11
+ # @!parse extend JSI::DescribesSchemaModule
12
+ # @!parse include JSI::Schema::Draft06
13
+ end
7
14
  end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSI
4
+ metaschema_document = ::JSON.parse(SCHEMAS_PATH.join('json-schema.org/draft-07/schema.json').read)
5
+ JSONSchemaOrgDraft07 = MetaschemaNode.new(metaschema_document,
6
+ schema_implementation_modules: [JSI::Schema::Draft07],
7
+ ).jsi_schema_module
8
+
9
+ # the JSI schema module for `http://json-schema.org/draft-07/schema`
10
+ module JSONSchemaOrgDraft07
11
+ # @!parse extend JSI::DescribesSchemaModule
12
+ # @!parse include JSI::Schema::Draft07
13
+ end
14
+ end