jsi 0.4.0 → 0.7.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.
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