jsi 0.7.0 → 0.8.1
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/.yardopts +6 -1
- data/CHANGELOG.md +19 -0
- data/README.md +29 -20
- data/jsi.gemspec +2 -3
- data/lib/jsi/base/mutability.rb +44 -0
- data/lib/jsi/base/node.rb +199 -34
- data/lib/jsi/base.rb +412 -228
- data/lib/jsi/jsi_coder.rb +18 -16
- data/lib/jsi/metaschema_node/bootstrap_schema.rb +57 -23
- data/lib/jsi/metaschema_node.rb +138 -107
- data/lib/jsi/ptr.rb +59 -37
- data/lib/jsi/schema/application/child_application/draft04.rb +0 -1
- data/lib/jsi/schema/application/child_application/draft06.rb +0 -1
- data/lib/jsi/schema/application/child_application/draft07.rb +0 -1
- data/lib/jsi/schema/application/child_application.rb +0 -25
- data/lib/jsi/schema/application/inplace_application/draft04.rb +0 -1
- data/lib/jsi/schema/application/inplace_application/draft06.rb +0 -1
- data/lib/jsi/schema/application/inplace_application/draft07.rb +0 -1
- data/lib/jsi/schema/application/inplace_application/ref.rb +1 -1
- data/lib/jsi/schema/application/inplace_application/someof.rb +1 -1
- data/lib/jsi/schema/application/inplace_application.rb +0 -27
- data/lib/jsi/schema/draft04.rb +0 -1
- data/lib/jsi/schema/draft06.rb +0 -1
- data/lib/jsi/schema/draft07.rb +0 -1
- data/lib/jsi/schema/ref.rb +44 -18
- data/lib/jsi/schema/schema_ancestor_node.rb +65 -56
- data/lib/jsi/schema/validation/contains.rb +1 -1
- data/lib/jsi/schema/validation/draft04/minmax.rb +2 -0
- data/lib/jsi/schema/validation/draft04.rb +0 -2
- data/lib/jsi/schema/validation/draft06.rb +0 -2
- data/lib/jsi/schema/validation/draft07.rb +0 -2
- data/lib/jsi/schema/validation/items.rb +3 -3
- data/lib/jsi/schema/validation/pattern.rb +1 -1
- data/lib/jsi/schema/validation/properties.rb +4 -4
- data/lib/jsi/schema/validation/ref.rb +1 -1
- data/lib/jsi/schema/validation.rb +0 -2
- data/lib/jsi/schema.rb +408 -198
- data/lib/jsi/schema_classes.rb +196 -127
- data/lib/jsi/schema_registry.rb +66 -17
- data/lib/jsi/schema_set.rb +76 -30
- data/lib/jsi/simple_wrap.rb +2 -7
- data/lib/jsi/util/private/attr_struct.rb +28 -14
- data/lib/jsi/util/private/memo_map.rb +75 -0
- data/lib/jsi/util/private.rb +73 -92
- data/lib/jsi/util/typelike.rb +28 -28
- data/lib/jsi/util.rb +120 -36
- data/lib/jsi/validation/error.rb +4 -0
- data/lib/jsi/validation/result.rb +18 -32
- data/lib/jsi/version.rb +1 -1
- data/lib/jsi.rb +67 -25
- data/lib/schemas/json-schema.org/draft-04/schema.rb +159 -4
- data/lib/schemas/json-schema.org/draft-06/schema.rb +161 -4
- data/lib/schemas/json-schema.org/draft-07/schema.rb +188 -4
- data/readme.rb +1 -1
- metadata +19 -5
- data/lib/jsi/metaschema.rb +0 -6
- data/lib/jsi/schema/validation/core.rb +0 -39
data/lib/jsi/schema.rb
CHANGED
@@ -1,10 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module JSI
|
4
|
-
# JSI::Schema is a module which extends instances which represent JSON schemas.
|
4
|
+
# JSI::Schema is a module which extends {JSI::Base} instances which represent JSON schemas.
|
5
5
|
#
|
6
|
-
#
|
7
|
-
#
|
6
|
+
# This module is included on the {Schema#jsi_schema_module JSI Schema module} of any schema
|
7
|
+
# that describes other schemas, i.e. is a meta-schema (a {Schema::MetaSchema}).
|
8
|
+
# Therefore, any JSI instance described by a schema which is a {Schema::MetaSchema} is
|
9
|
+
# a schema and is extended by this module.
|
10
|
+
#
|
11
|
+
# The content of an instance which is a JSI::Schema (referred to in this context as schema_content) is
|
12
|
+
# typically a Hash (JSON object) or a boolean.
|
8
13
|
module Schema
|
9
14
|
autoload :Application, 'jsi/schema/application'
|
10
15
|
autoload :Validation, 'jsi/schema/validation'
|
@@ -62,7 +67,7 @@ module JSI
|
|
62
67
|
# @return [Addressable::URI, nil]
|
63
68
|
def id_without_fragment
|
64
69
|
if id
|
65
|
-
id_uri =
|
70
|
+
id_uri = Util.uri(id)
|
66
71
|
if id_uri.merge(fragment: nil).empty?
|
67
72
|
# fragment-only id is just an anchor
|
68
73
|
# e.g. #foo
|
@@ -74,7 +79,7 @@ module JSI
|
|
74
79
|
elsif id_uri.fragment == ''
|
75
80
|
# empty fragment
|
76
81
|
# e.g. http://json-schema.org/draft-07/schema#
|
77
|
-
id_uri.merge(fragment: nil)
|
82
|
+
id_uri.merge(fragment: nil).freeze
|
78
83
|
elsif jsi_schema_base_uri && jsi_schema_base_uri.join(id_uri).merge(fragment: nil) == jsi_schema_base_uri
|
79
84
|
# the id, resolved against the base uri, consists of the base uri plus an anchor fragment.
|
80
85
|
# so there's no non-fragment id.
|
@@ -83,7 +88,7 @@ module JSI
|
|
83
88
|
nil
|
84
89
|
else
|
85
90
|
# e.g. http://localhost:1234/bar#foo
|
86
|
-
id_uri.merge(fragment: nil)
|
91
|
+
id_uri.merge(fragment: nil).freeze
|
87
92
|
end
|
88
93
|
else
|
89
94
|
nil
|
@@ -94,7 +99,7 @@ module JSI
|
|
94
99
|
# @return [String]
|
95
100
|
def anchor
|
96
101
|
if id
|
97
|
-
id_uri =
|
102
|
+
id_uri = Util.uri(id)
|
98
103
|
if id_uri.fragment == ''
|
99
104
|
nil
|
100
105
|
else
|
@@ -128,139 +133,242 @@ module JSI
|
|
128
133
|
end
|
129
134
|
end
|
130
135
|
|
131
|
-
# JSI
|
132
|
-
# extends a JSI::Schema instance and indicates that JSIs which instantiate the schema
|
133
|
-
# are themselves also schemas.
|
136
|
+
# This module extends any JSI Schema that is a meta-schema, i.e. it describes schemas.
|
134
137
|
#
|
135
|
-
#
|
138
|
+
# Examples of a meta-schema include the JSON Schema meta-schemas and
|
136
139
|
# the OpenAPI schema definition which describes "A deterministic version of a JSON Schema object."
|
137
|
-
|
138
|
-
|
140
|
+
#
|
141
|
+
# Meta-schemas include {JSI::Schema} in their
|
142
|
+
# {Schema#jsi_schema_module JSI Schema module}, so for a schema which is an instance of
|
143
|
+
# JSI::Schema::MetaSchema, instances of that schema are instances of {JSI::Schema} and are schemas.
|
144
|
+
#
|
145
|
+
# A schema is indicated as describing other schemas using the {Schema#describes_schema!} method.
|
146
|
+
module MetaSchema
|
147
|
+
# @return [Set<Module>]
|
148
|
+
attr_reader(:schema_implementation_modules)
|
149
|
+
|
150
|
+
# Instantiates the given schema content as a JSI Schema.
|
151
|
+
#
|
152
|
+
# By default, the schema will be registered with the {JSI.schema_registry}.
|
153
|
+
# This can be controlled by params `register` and `schema_registry`.
|
154
|
+
#
|
155
|
+
# By default, the `schema_content` will have any Symbol keys of Hashes replaced with Strings
|
156
|
+
# (recursively through the document). This is controlled by the param `stringify_symbol_keys`.
|
157
|
+
#
|
158
|
+
# Schemas instantiated with `new_schema` are immutable, their content transformed using
|
159
|
+
# the `to_immutable` param.
|
139
160
|
#
|
140
|
-
#
|
141
|
-
#
|
142
|
-
#
|
161
|
+
# @param schema_content an object to be instantiated as a JSI Schema - typically a Hash
|
162
|
+
# @param uri [#to_str, Addressable::URI] The retrieval URI of the schema document.
|
163
|
+
# If specified, the root schema will be identified by this URI, in addition
|
164
|
+
# to any absolute URI declared with an id keyword, for resolution in the `schema_registry`.
|
143
165
|
#
|
144
|
-
#
|
166
|
+
# It is rare that this needs to be specified. Most schemas, if they use absolute URIs, will
|
167
|
+
# use the `$id` keyword (`id` in draft 4) to specify this. A different retrieval URI is useful
|
168
|
+
# in unusual cases:
|
145
169
|
#
|
146
|
-
#
|
147
|
-
#
|
148
|
-
#
|
149
|
-
#
|
150
|
-
#
|
151
|
-
#
|
170
|
+
# - A schema in the document uses relative URIs for `$id` or `$ref` without an absolute id in an
|
171
|
+
# ancestor schema - these will be resolved relative to this URI
|
172
|
+
# - Another schema refers with `$ref` to the schema being instantiated by this retrieval URI,
|
173
|
+
# rather than an id declared in the schema - the schema is resolvable by this URI in the
|
174
|
+
# `schema_registry`.
|
175
|
+
# @param register [Boolean] Whether the instantiated schema and any subschemas with absolute URIs
|
176
|
+
# will be registered in the schema registry indicated by param `schema_registry`.
|
177
|
+
# @param schema_registry [SchemaRegistry, nil] The registry this schema will use.
|
178
|
+
#
|
179
|
+
# - The schema and subschemas will be registered here with any declared URI,
|
180
|
+
# unless the `register` param is false.
|
181
|
+
# - References from within the schema (typically from `$ref` keywords) are resolved using this registry.
|
182
|
+
# @param stringify_symbol_keys [Boolean] Whether the schema content will have any Symbol keys of Hashes
|
183
|
+
# replaced with Strings (recursively through the document).
|
184
|
+
# Replacement is done on a copy; the given schema content is not modified.
|
185
|
+
# @param to_immutable (see SchemaSet#new_jsi)
|
186
|
+
# @yield If a block is given, it is evaluated in the context of the schema's JSI schema module
|
187
|
+
# using [Module#module_exec](https://ruby-doc.org/core/Module.html#method-i-module_exec).
|
188
|
+
# @return [JSI::Base subclass + JSI::Schema] a JSI which is a {JSI::Schema} whose content comes from
|
189
|
+
# the given `schema_content` and whose schemas are this schema's inplace applicators.
|
152
190
|
def new_schema(schema_content,
|
153
|
-
uri: nil
|
191
|
+
uri: nil,
|
192
|
+
register: true,
|
193
|
+
schema_registry: JSI.schema_registry,
|
194
|
+
stringify_symbol_keys: true,
|
195
|
+
to_immutable: DEFAULT_CONTENT_TO_IMMUTABLE,
|
196
|
+
&block
|
154
197
|
)
|
155
|
-
schema_jsi = new_jsi(
|
198
|
+
schema_jsi = new_jsi(schema_content,
|
156
199
|
uri: uri,
|
200
|
+
register: register,
|
201
|
+
schema_registry: schema_registry,
|
202
|
+
stringify_symbol_keys: stringify_symbol_keys,
|
203
|
+
to_immutable: to_immutable,
|
204
|
+
mutable: false,
|
157
205
|
)
|
158
|
-
|
206
|
+
|
207
|
+
schema_jsi.jsi_schema_module_exec(&block) if block
|
208
|
+
|
159
209
|
schema_jsi
|
160
210
|
end
|
161
211
|
|
162
|
-
#
|
163
|
-
#
|
164
|
-
# shortcut to chain {#new_schema} + {Schema#jsi_schema_module}.
|
212
|
+
# Instantiates the given schema content as a JSI Schema, passing all params to
|
213
|
+
# {Schema::MetaSchema#new_schema}, and returns its {Schema#jsi_schema_module JSI Schema Module}.
|
165
214
|
#
|
166
|
-
# @
|
167
|
-
|
168
|
-
|
169
|
-
new_schema(schema_content, **kw).jsi_schema_module
|
215
|
+
# @return [JSI::SchemaModule] the JSI Schema Module of the instantiated schema
|
216
|
+
def new_schema_module(schema_content, **kw, &block)
|
217
|
+
new_schema(schema_content, **kw, &block).jsi_schema_module
|
170
218
|
end
|
171
219
|
end
|
172
220
|
|
173
221
|
class << self
|
174
|
-
|
222
|
+
def extended(o)
|
223
|
+
super
|
224
|
+
o.send(:jsi_schema_initialize)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
class << self
|
230
|
+
# An application-wide default meta-schema set by {default_metaschema=}, used by {JSI.new_schema}
|
231
|
+
# to instantiate schemas that do not specify their meta-schema using a `$schema` property.
|
175
232
|
#
|
176
|
-
# @return [nil,
|
233
|
+
# @return [nil, Base + Schema + Schema::MetaSchema]
|
177
234
|
def default_metaschema
|
178
|
-
|
179
|
-
return nil
|
235
|
+
@default_metaschema
|
180
236
|
end
|
181
237
|
|
182
|
-
#
|
238
|
+
# Sets {default_metaschema} to a schema indicated by the given param.
|
239
|
+
#
|
240
|
+
# @param default_metaschema [Schema::MetaSchema, SchemaModule::MetaSchemaModule, #to_str, nil]
|
241
|
+
# Indicates the default meta-schema.
|
242
|
+
# This may be a meta-schema or a meta-schema's schema module (e.g. `JSI::JSONSchemaDraft07`),
|
243
|
+
# or a URI (as would be in a `$schema` keyword).
|
183
244
|
#
|
184
|
-
#
|
185
|
-
# metaschema's schema module (e.g. `JSI::JSONSchemaOrgDraft07`).
|
245
|
+
# `nil` to unset.
|
186
246
|
def default_metaschema=(default_metaschema)
|
187
|
-
|
188
|
-
raise(TypeError, "given default_metaschema does not respond to #new_schema")
|
189
|
-
end
|
190
|
-
@default_metaschema = default_metaschema
|
247
|
+
@default_metaschema = default_metaschema.nil? ? nil : ensure_metaschema(default_metaschema)
|
191
248
|
end
|
192
249
|
|
193
|
-
#
|
250
|
+
# Instantiates the given schema content as a JSI Schema.
|
251
|
+
#
|
252
|
+
# The meta-schema that describes the schema must be indicated:
|
194
253
|
#
|
195
|
-
#
|
254
|
+
# - If the schema object has a `$schema` property, that URI is resolved using the `schema_registry`
|
255
|
+
# param (by default {JSI.schema_registry}), and that meta-schema is used. For example:
|
256
|
+
#
|
257
|
+
# ```ruby
|
258
|
+
# JSI.new_schema({
|
259
|
+
# "$schema" => "http://json-schema.org/draft-07/schema#",
|
260
|
+
# "properties" => ...,
|
261
|
+
# })
|
262
|
+
# ```
|
196
263
|
#
|
197
|
-
# - if the schema object has a `$schema` property, that URI is resolved using the {JSI.schema_registry},
|
198
|
-
# and that metaschema is used.
|
199
264
|
# - if no `$schema` property is present, the `default_metaschema` param is used, if the caller
|
200
|
-
# specifies it.
|
265
|
+
# specifies it. For example:
|
266
|
+
#
|
267
|
+
# ```ruby
|
268
|
+
# JSI.new_schema({"properties" => ...}, default_metaschema: JSI::JSONSchemaDraft07)
|
269
|
+
# ```
|
270
|
+
#
|
201
271
|
# - if no `default_metaschema` param is specified, the application-wide default
|
202
|
-
# {JSI
|
203
|
-
# if the application has set it.
|
272
|
+
# {JSI.default_metaschema JSI.default_metaschema} is used,
|
273
|
+
# if the application has set it. For example:
|
204
274
|
#
|
205
|
-
#
|
275
|
+
# ```ruby
|
276
|
+
# JSI.default_metaschema = JSI::JSONSchemaDraft07
|
277
|
+
# JSI.new_schema({"properties" => ...})
|
278
|
+
# ```
|
206
279
|
#
|
207
|
-
#
|
208
|
-
# passing the `default_metaschema` param is to use `.new_schema` on the metaschema or its module, e.g.
|
209
|
-
# `JSI::JSONSchemaOrgDraft07.new_schema(my_schema_object)`
|
280
|
+
# An ArgumentError is raised if none of these indicates a meta-schema to use.
|
210
281
|
#
|
211
|
-
# if
|
212
|
-
#
|
213
|
-
# {Schema#
|
282
|
+
# Note that if you are instantiating a schema known to have no `$schema` property, an alternative to
|
283
|
+
# specifying a `default_metaschema` is to call `new_schema` on the
|
284
|
+
# {Schema::MetaSchema#new_schema meta-schema} or its
|
285
|
+
# {SchemaModule::MetaSchemaModule#new_schema schema module}, e.g.
|
286
|
+
# `JSI::JSONSchemaDraft07.new_schema(my_schema_content)`
|
214
287
|
#
|
215
|
-
#
|
216
|
-
#
|
217
|
-
#
|
218
|
-
# @param
|
219
|
-
#
|
220
|
-
#
|
221
|
-
#
|
222
|
-
#
|
223
|
-
|
288
|
+
# Schemas instantiated with `new_schema` are immutable, their content transformed using
|
289
|
+
# the `to_immutable` param.
|
290
|
+
#
|
291
|
+
# @param schema_content (see Schema::MetaSchema#new_schema)
|
292
|
+
# @param default_metaschema [Schema::MetaSchema, SchemaModule::MetaSchemaModule, #to_str]
|
293
|
+
# Indicates the meta-schema to use if the given `schema_content` does not have a `$schema` property.
|
294
|
+
# This may be a meta-schema or a meta-schema's schema module (e.g. `JSI::JSONSchemaDraft07`),
|
295
|
+
# or a URI (as would be in a `$schema` keyword).
|
296
|
+
# @param uri (see Schema::MetaSchema#new_schema)
|
297
|
+
# @param register (see Schema::MetaSchema#new_schema)
|
298
|
+
# @param schema_registry (see Schema::MetaSchema#new_schema)
|
299
|
+
# @param stringify_symbol_keys (see Schema::MetaSchema#new_schema)
|
300
|
+
# @param to_immutable (see Schema::DescribesSchema#new_schema)
|
301
|
+
# @yield (see Schema::MetaSchema#new_schema)
|
302
|
+
# @return [JSI::Base subclass + JSI::Schema] a JSI which is a {JSI::Schema} whose content comes from
|
303
|
+
# the given `schema_content` and whose schemas are inplace applicators of the indicated meta-schema
|
304
|
+
def new_schema(schema_content,
|
305
|
+
default_metaschema: nil,
|
306
|
+
# params of Schema::MetaSchema#new_schema have their default values repeated here. delegating in a splat
|
307
|
+
# would remove repetition, but yard doesn't display delegated defaults with its (see X) directive.
|
308
|
+
uri: nil,
|
309
|
+
register: true,
|
310
|
+
schema_registry: JSI.schema_registry,
|
311
|
+
stringify_symbol_keys: true,
|
312
|
+
to_immutable: DEFAULT_CONTENT_TO_IMMUTABLE,
|
313
|
+
&block
|
314
|
+
)
|
315
|
+
new_schema_params = {
|
316
|
+
uri: uri,
|
317
|
+
register: register,
|
318
|
+
schema_registry: schema_registry,
|
319
|
+
stringify_symbol_keys: stringify_symbol_keys,
|
320
|
+
to_immutable: to_immutable,
|
321
|
+
}
|
224
322
|
default_metaschema_new_schema = -> {
|
225
|
-
default_metaschema
|
226
|
-
|
323
|
+
default_metaschema = if default_metaschema
|
324
|
+
Schema.ensure_metaschema(default_metaschema, name: "default_metaschema")
|
325
|
+
elsif self.default_metaschema
|
326
|
+
self.default_metaschema
|
327
|
+
else
|
227
328
|
raise(ArgumentError, [
|
228
|
-
"
|
229
|
-
"
|
230
|
-
"JSI
|
231
|
-
"
|
232
|
-
"
|
329
|
+
"When instantiating a schema with no `$schema` property, you must specify its meta-schema by one of these methods:",
|
330
|
+
"- pass the `default_metaschema` param to this method",
|
331
|
+
" e.g.: JSI.new_schema(..., default_metaschema: JSI::JSONSchemaDraft07)",
|
332
|
+
"- invoke `new_schema` on the appropriate meta-schema or its schema module",
|
333
|
+
" e.g.: JSI::JSONSchemaDraft07.new_schema(...)",
|
334
|
+
"- set JSI.default_metaschema to an application-wide default meta-schema initially",
|
335
|
+
" e.g.: JSI.default_metaschema = JSI::JSONSchemaDraft07",
|
336
|
+
"instantiating schema_content: #{schema_content.pretty_inspect.chomp}",
|
233
337
|
].join("\n"))
|
234
338
|
end
|
235
|
-
|
236
|
-
raise(TypeError, "given default_metaschema does not respond to #new_schema: #{default_metaschema.pretty_inspect.chomp}")
|
237
|
-
end
|
238
|
-
default_metaschema.new_schema(schema_object, **kw)
|
339
|
+
default_metaschema.new_schema(schema_content, **new_schema_params, &block)
|
239
340
|
}
|
240
|
-
if
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
341
|
+
if schema_content.is_a?(Schema)
|
342
|
+
raise(TypeError, [
|
343
|
+
"Given schema_content is already a JSI::Schema. It cannot be instantiated as the content of a schema.",
|
344
|
+
"given: #{schema_content.pretty_inspect.chomp}",
|
345
|
+
].join("\n"))
|
346
|
+
elsif schema_content.is_a?(JSI::Base)
|
347
|
+
raise(TypeError, [
|
348
|
+
"Given schema_content is a JSI::Base. It cannot be instantiated as the content of a schema.",
|
349
|
+
"given: #{schema_content.pretty_inspect.chomp}",
|
350
|
+
].join("\n"))
|
351
|
+
elsif schema_content.respond_to?(:to_hash)
|
352
|
+
id = schema_content['$schema'] || stringify_symbol_keys && schema_content[:'$schema']
|
353
|
+
if id
|
354
|
+
unless id.respond_to?(:to_str)
|
355
|
+
raise(ArgumentError, "given schema_content keyword `$schema` is not a string")
|
248
356
|
end
|
249
|
-
metaschema = Schema
|
250
|
-
|
251
|
-
raise(Schema::ReferenceError, "given schema_object contains a $schema but the resource it identifies does not describe a schema")
|
252
|
-
end
|
253
|
-
metaschema.new_schema(schema_object, **kw)
|
357
|
+
metaschema = Schema.ensure_metaschema(id, name: '$schema', schema_registry: schema_registry)
|
358
|
+
metaschema.new_schema(schema_content, **new_schema_params, &block)
|
254
359
|
else
|
255
360
|
default_metaschema_new_schema.call
|
256
361
|
end
|
257
|
-
elsif [true, false].include?(schema_object)
|
258
|
-
default_metaschema_new_schema.call
|
259
362
|
else
|
260
|
-
|
363
|
+
default_metaschema_new_schema.call
|
261
364
|
end
|
262
365
|
end
|
366
|
+
end
|
263
367
|
|
368
|
+
self.default_metaschema = nil
|
369
|
+
|
370
|
+
module Schema
|
371
|
+
class << self
|
264
372
|
# ensure the given object is a JSI Schema
|
265
373
|
#
|
266
374
|
# @param schema [Object] the thing the caller wishes to ensure is a Schema
|
@@ -272,20 +380,25 @@ module JSI
|
|
272
380
|
if schema.is_a?(Schema)
|
273
381
|
schema
|
274
382
|
else
|
275
|
-
if reinstantiate_as
|
383
|
+
if reinstantiate_as && schema.is_a?(JSI::Base)
|
276
384
|
# TODO warn; behavior is undefined and I hate this implementation
|
277
385
|
|
278
|
-
|
386
|
+
result_schema_indicated_schemas = SchemaSet.new(schema.jsi_indicated_schemas + reinstantiate_as)
|
387
|
+
result_schema_applied_schemas = result_schema_indicated_schemas.inplace_applicator_schemas(schema.jsi_node_content)
|
279
388
|
|
280
|
-
result_schema_class = JSI::SchemaClasses.class_for_schemas(
|
281
|
-
includes: SchemaClasses.includes_for(schema.jsi_node_content)
|
389
|
+
result_schema_class = JSI::SchemaClasses.class_for_schemas(result_schema_applied_schemas,
|
390
|
+
includes: SchemaClasses.includes_for(schema.jsi_node_content),
|
391
|
+
mutable: schema.jsi_mutable?,
|
282
392
|
)
|
283
393
|
|
284
394
|
result_schema_class.new(schema.jsi_document,
|
285
395
|
jsi_ptr: schema.jsi_ptr,
|
286
|
-
|
396
|
+
jsi_indicated_schemas: result_schema_indicated_schemas,
|
287
397
|
jsi_schema_base_uri: schema.jsi_schema_base_uri,
|
288
398
|
jsi_schema_resource_ancestors: schema.jsi_schema_resource_ancestors,
|
399
|
+
jsi_schema_registry: schema.jsi_schema_registry,
|
400
|
+
jsi_content_to_immutable: schema.jsi_content_to_immutable,
|
401
|
+
jsi_root_node: schema.jsi_ptr.root? ? nil : schema.jsi_root_node, # bad
|
289
402
|
)
|
290
403
|
else
|
291
404
|
raise(NotASchemaError, [
|
@@ -295,6 +408,40 @@ module JSI
|
|
295
408
|
end
|
296
409
|
end
|
297
410
|
end
|
411
|
+
|
412
|
+
# Ensures the given param identifies a meta-schema and returns that meta-schema.
|
413
|
+
#
|
414
|
+
# @api private
|
415
|
+
# @param metaschema [Schema::MetaSchema, SchemaModule::MetaSchemaModule, #to_str]
|
416
|
+
# @raise [TypeError] if the param does not indicate a meta-schema
|
417
|
+
# @return [Base + Schema + Schema::MetaSchema]
|
418
|
+
def ensure_metaschema(metaschema, name: nil, schema_registry: JSI.schema_registry)
|
419
|
+
if metaschema.respond_to?(:to_str)
|
420
|
+
schema = Schema::Ref.new(metaschema, schema_registry: schema_registry).deref_schema
|
421
|
+
if !schema.describes_schema?
|
422
|
+
raise(TypeError, [name, "URI indicates a schema that is not a meta-schema: #{metaschema.pretty_inspect.chomp}"].compact.join(" "))
|
423
|
+
end
|
424
|
+
schema
|
425
|
+
elsif metaschema.is_a?(SchemaModule::MetaSchemaModule)
|
426
|
+
metaschema.schema
|
427
|
+
elsif metaschema.is_a?(Schema::MetaSchema)
|
428
|
+
metaschema
|
429
|
+
else
|
430
|
+
raise(TypeError, "#{name || "param"} does not indicate a meta-schema: #{metaschema.pretty_inspect.chomp}")
|
431
|
+
end
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
if Util::LAST_ARGUMENT_AS_KEYWORD_PARAMETERS
|
436
|
+
def initialize(*)
|
437
|
+
super
|
438
|
+
jsi_schema_initialize
|
439
|
+
end
|
440
|
+
else
|
441
|
+
def initialize(*, **)
|
442
|
+
super
|
443
|
+
jsi_schema_initialize
|
444
|
+
end
|
298
445
|
end
|
299
446
|
|
300
447
|
# the underlying JSON data used to instantiate this JSI::Schema.
|
@@ -316,7 +463,7 @@ module JSI
|
|
316
463
|
def schema_absolute_uri
|
317
464
|
if respond_to?(:id_without_fragment) && id_without_fragment
|
318
465
|
if jsi_schema_base_uri
|
319
|
-
jsi_schema_base_uri.join(id_without_fragment)
|
466
|
+
jsi_schema_base_uri.join(id_without_fragment).freeze
|
320
467
|
elsif id_without_fragment.absolute?
|
321
468
|
id_without_fragment
|
322
469
|
else
|
@@ -327,7 +474,7 @@ module JSI
|
|
327
474
|
end
|
328
475
|
|
329
476
|
# a nonrelative URI which refers to this schema.
|
330
|
-
# nil if no
|
477
|
+
# `nil` if no ancestor of this schema defines an id.
|
331
478
|
# see {#schema_uris} for all URIs known to refer to this schema.
|
332
479
|
# @return [Addressable::URI, nil]
|
333
480
|
def schema_uri
|
@@ -337,9 +484,11 @@ module JSI
|
|
337
484
|
# nonrelative URIs (that is, absolute, but possibly with a fragment) which refer to this schema
|
338
485
|
# @return [Array<Addressable::URI>]
|
339
486
|
def schema_uris
|
340
|
-
|
487
|
+
@schema_uris_map[]
|
488
|
+
end
|
489
|
+
|
490
|
+
private def schema_uris_compute(**_) # TODO remove **_ eventually (keyword argument compatibility)
|
341
491
|
each_schema_uri.to_a
|
342
|
-
end
|
343
492
|
end
|
344
493
|
|
345
494
|
# see {#schema_uris}
|
@@ -350,22 +499,22 @@ module JSI
|
|
350
499
|
|
351
500
|
yield schema_absolute_uri if schema_absolute_uri
|
352
501
|
|
353
|
-
|
502
|
+
ancestor_schemas = jsi_subschema_resource_ancestors.reverse_each.select do |resource|
|
354
503
|
resource.schema_absolute_uri
|
355
504
|
end
|
356
505
|
|
357
506
|
anchored = respond_to?(:anchor) ? anchor : nil
|
358
|
-
|
507
|
+
ancestor_schemas.each do |ancestor_schema|
|
359
508
|
if anchored
|
360
|
-
if
|
361
|
-
yield
|
509
|
+
if ancestor_schema.jsi_anchor_subschema(anchor) == self
|
510
|
+
yield(ancestor_schema.schema_absolute_uri.merge(fragment: anchor).freeze)
|
362
511
|
else
|
363
512
|
anchored = false
|
364
513
|
end
|
365
514
|
end
|
366
515
|
|
367
|
-
relative_ptr = jsi_ptr.relative_to(
|
368
|
-
yield
|
516
|
+
relative_ptr = jsi_ptr.relative_to(ancestor_schema.jsi_ptr)
|
517
|
+
yield(ancestor_schema.schema_absolute_uri.merge(fragment: relative_ptr.fragment).freeze)
|
369
518
|
end
|
370
519
|
|
371
520
|
nil
|
@@ -374,9 +523,6 @@ module JSI
|
|
374
523
|
# a module which extends all instances of this schema. this may be opened by the application to add
|
375
524
|
# methods to schema instances.
|
376
525
|
#
|
377
|
-
# this module includes accessor methods for object property names this schema
|
378
|
-
# describes (see {#described_object_property_names}). these accessors wrap {Base#[]} and {Base#[]=}.
|
379
|
-
#
|
380
526
|
# some functionality is also defined on the module itself (its singleton class, not for its instances):
|
381
527
|
#
|
382
528
|
# - the module is extended with {JSI::SchemaModule}, which defines .new_jsi to instantiate instances
|
@@ -386,7 +532,7 @@ module JSI
|
|
386
532
|
# as `schema.items.jsi_schema_module`.
|
387
533
|
# - method .schema which returns this schema.
|
388
534
|
#
|
389
|
-
# @return [
|
535
|
+
# @return [SchemaModule]
|
390
536
|
def jsi_schema_module
|
391
537
|
JSI::SchemaClasses.module_for_schema(self)
|
392
538
|
end
|
@@ -401,57 +547,47 @@ module JSI
|
|
401
547
|
jsi_schema_module.module_exec(*a, **kw, &block)
|
402
548
|
end
|
403
549
|
|
404
|
-
#
|
405
|
-
#
|
550
|
+
# Instantiates a new JSI whose content comes from the given `instance` param.
|
551
|
+
# This schema indicates the schemas of the JSI - its schemas are inplace
|
552
|
+
# applicators of this schema which apply to the given instance.
|
406
553
|
#
|
407
|
-
# @param
|
408
|
-
# @
|
409
|
-
#
|
410
|
-
# inplace applicator schemas matched from this schema.
|
554
|
+
# @param (see SchemaSet#new_jsi)
|
555
|
+
# @return [JSI::Base subclass] a JSI whose content comes from the given instance and whose schemas are
|
556
|
+
# inplace applicators of this schema.
|
411
557
|
def new_jsi(instance, **kw)
|
412
558
|
SchemaSet[self].new_jsi(instance, **kw)
|
413
559
|
end
|
414
560
|
|
415
|
-
#
|
416
|
-
# @return [
|
417
|
-
def
|
418
|
-
|
419
|
-
|
420
|
-
jsi_schema_instance_modules.any? { |m| m <= JSI::Schema }
|
561
|
+
# @param keyword schema keyword e.g. "$ref", "$schema"
|
562
|
+
# @return [Schema::Ref]
|
563
|
+
def schema_ref(keyword = "$ref")
|
564
|
+
raise(ArgumentError, "keyword not present: #{keyword}") unless keyword?(keyword)
|
565
|
+
@schema_ref_map[keyword: keyword, value: schema_content[keyword]]
|
421
566
|
end
|
422
567
|
|
423
|
-
#
|
424
|
-
#
|
425
|
-
|
426
|
-
|
427
|
-
def jsi_schema_instance_modules
|
428
|
-
return @jsi_schema_instance_modules if instance_variable_defined?(:@jsi_schema_instance_modules)
|
429
|
-
return Util::EMPTY_SET
|
568
|
+
# Does this schema itself describe a schema? I.e. is this schema a meta-schema?
|
569
|
+
# @return [Boolean]
|
570
|
+
def describes_schema?
|
571
|
+
jsi_schema_module <= JSI::Schema || false
|
430
572
|
end
|
431
573
|
|
432
|
-
#
|
433
|
-
#
|
434
|
-
|
435
|
-
|
436
|
-
def jsi_schema_instance_modules=(jsi_schema_instance_modules)
|
437
|
-
@jsi_schema_instance_modules = Util.ensure_module_set(jsi_schema_instance_modules)
|
574
|
+
# Is this a JSI Schema?
|
575
|
+
# @return [Boolean]
|
576
|
+
def jsi_is_schema?
|
577
|
+
true
|
438
578
|
end
|
439
579
|
|
440
|
-
#
|
441
|
-
# this schema is extended with {
|
442
|
-
# with {
|
580
|
+
# Indicates that this schema describes schemas, i.e. it is a meta-schema.
|
581
|
+
# this schema is extended with {Schema::MetaSchema} and its {#jsi_schema_module} is extended
|
582
|
+
# with {SchemaModule::MetaSchemaModule}, and the JSI Schema Module will include
|
583
|
+
# JSI::Schema and the given modules.
|
443
584
|
#
|
444
585
|
# @param schema_implementation_modules [Enumerable<Module>] modules which implement the functionality of
|
445
586
|
# the schema to extend schemas described by this schema.
|
446
|
-
# this must include JSI::Schema (usually indirectly).
|
447
587
|
# @return [void]
|
448
588
|
def describes_schema!(schema_implementation_modules)
|
449
589
|
schema_implementation_modules = Util.ensure_module_set(schema_implementation_modules)
|
450
590
|
|
451
|
-
unless schema_implementation_modules.any? { |mod| mod <= Schema }
|
452
|
-
raise(ArgumentError, "schema_implementation_modules for a schema must include #{Schema}")
|
453
|
-
end
|
454
|
-
|
455
591
|
if describes_schema?
|
456
592
|
# this schema, or one equal to it, has already had describes_schema! called on it.
|
457
593
|
# this is to be avoided, but is not particularly a problem.
|
@@ -460,29 +596,30 @@ module JSI
|
|
460
596
|
raise(ArgumentError, "this schema already describes a schema with different schema_implementation_modules")
|
461
597
|
end
|
462
598
|
else
|
599
|
+
jsi_schema_module.include(Schema)
|
463
600
|
schema_implementation_modules.each do |mod|
|
464
601
|
jsi_schema_module.include(mod)
|
465
602
|
end
|
466
|
-
jsi_schema_module.extend(
|
467
|
-
jsi_schema_module.instance_variable_set(:@schema_implementation_modules, schema_implementation_modules)
|
603
|
+
jsi_schema_module.extend(SchemaModule::MetaSchemaModule)
|
468
604
|
end
|
469
605
|
|
470
|
-
|
606
|
+
@schema_implementation_modules = schema_implementation_modules
|
607
|
+
extend(Schema::MetaSchema)
|
471
608
|
|
472
609
|
nil
|
473
610
|
end
|
474
611
|
|
475
612
|
# a resource containing this schema.
|
476
613
|
#
|
477
|
-
#
|
614
|
+
# If any ancestor, or this schema itself, is a schema with an absolute uri (see {#schema_absolute_uri}),
|
478
615
|
# the resource root is the closest schema with an absolute uri.
|
479
616
|
#
|
480
|
-
#
|
481
|
-
#
|
617
|
+
# If no ancestor schema has an absolute uri, the schema_resource_root is the {Base#jsi_root_node document's root node}.
|
618
|
+
# In this case, the resource root may or may not be a schema itself.
|
482
619
|
#
|
483
620
|
# @return [JSI::Base] resource containing this schema
|
484
621
|
def schema_resource_root
|
485
|
-
jsi_subschema_resource_ancestors.
|
622
|
+
jsi_subschema_resource_ancestors.last || jsi_root_node
|
486
623
|
end
|
487
624
|
|
488
625
|
# is this schema the root of a schema resource?
|
@@ -496,71 +633,89 @@ module JSI
|
|
496
633
|
# @param subptr [JSI::Ptr, #to_ary] a relative pointer, or array of tokens, pointing to the subschema
|
497
634
|
# @return [JSI::Schema] the subschema at the location indicated by subptr. self if subptr is empty.
|
498
635
|
def subschema(subptr)
|
499
|
-
|
500
|
-
end
|
501
|
-
|
502
|
-
private
|
503
|
-
|
504
|
-
def subschema_map
|
505
|
-
jsi_memomap(:subschema) do |subptr: |
|
506
|
-
if is_a?(MetaschemaNode::BootstrapSchema)
|
507
|
-
self.class.new(
|
508
|
-
jsi_document,
|
509
|
-
jsi_ptr: jsi_ptr + subptr,
|
510
|
-
jsi_schema_base_uri: jsi_resource_ancestor_uri,
|
511
|
-
)
|
512
|
-
else
|
636
|
+
subptr = Ptr.ary_ptr(subptr)
|
513
637
|
Schema.ensure_schema(jsi_descendent_node(subptr), msg: [
|
514
638
|
"subschema is not a schema at pointer: #{subptr.pointer}"
|
515
639
|
])
|
516
|
-
end
|
517
|
-
end
|
518
640
|
end
|
519
641
|
|
520
|
-
public
|
521
|
-
|
522
642
|
# a schema in the same schema resource as this one (see {#schema_resource_root}) at the given
|
523
643
|
# pointer relative to the root of the schema resource.
|
524
644
|
#
|
525
645
|
# @param ptr [JSI::Ptr, #to_ary] a pointer to a schema from our schema resource root
|
526
646
|
# @return [JSI::Schema] the schema pointed to by ptr
|
527
647
|
def resource_root_subschema(ptr)
|
528
|
-
|
529
|
-
end
|
530
|
-
|
531
|
-
private
|
532
|
-
|
533
|
-
def resource_root_subschema_map
|
534
|
-
jsi_memomap(:resource_root_subschema_map) do |ptr: |
|
535
|
-
if is_a?(MetaschemaNode::BootstrapSchema)
|
536
|
-
# BootstrapSchema does not track jsi_schema_resource_ancestors used by #schema_resource_root;
|
537
|
-
# resource_root_subschema is always relative to the document root.
|
538
|
-
# BootstrapSchema also does not implement jsi_root_node or #[]. we instantiate the ptr directly
|
539
|
-
# rather than as a subschema from the root.
|
540
|
-
self.class.new(
|
541
|
-
jsi_document,
|
542
|
-
jsi_ptr: ptr,
|
543
|
-
jsi_schema_base_uri: nil,
|
544
|
-
)
|
545
|
-
else
|
648
|
+
ptr = Ptr.ary_ptr(ptr)
|
546
649
|
Schema.ensure_schema(schema_resource_root.jsi_descendent_node(ptr),
|
547
|
-
msg: [
|
548
|
-
"subschema is not a schema at pointer: #{ptr.pointer}"
|
549
|
-
],
|
550
650
|
reinstantiate_as: jsi_schemas.select(&:describes_schema?)
|
551
651
|
)
|
552
|
-
|
652
|
+
end
|
653
|
+
|
654
|
+
# a set of inplace applicator schemas of this schema (from $ref, allOf, etc.) which apply to the
|
655
|
+
# given instance.
|
656
|
+
#
|
657
|
+
# the returned set will contain this schema itself, unless this schema contains a $ref keyword.
|
658
|
+
#
|
659
|
+
# @param instance [Object] the instance to check any applicators against
|
660
|
+
# @return [JSI::SchemaSet] matched applicator schemas
|
661
|
+
def inplace_applicator_schemas(instance)
|
662
|
+
SchemaSet.new(each_inplace_applicator_schema(instance))
|
663
|
+
end
|
664
|
+
|
665
|
+
# yields each inplace applicator schema which applies to the given instance.
|
666
|
+
#
|
667
|
+
# @param instance (see #inplace_applicator_schemas)
|
668
|
+
# @param visited_refs [Enumerable<JSI::Schema::Ref>]
|
669
|
+
# @yield [JSI::Schema]
|
670
|
+
# @return [nil, Enumerator] an Enumerator if invoked without a block; otherwise nil
|
671
|
+
def each_inplace_applicator_schema(
|
672
|
+
instance,
|
673
|
+
visited_refs: Util::EMPTY_ARY,
|
674
|
+
&block
|
675
|
+
)
|
676
|
+
return to_enum(__method__, instance, visited_refs: visited_refs) unless block
|
677
|
+
|
678
|
+
catch(:jsi_application_done) do
|
679
|
+
internal_inplace_applicate_keywords(instance, visited_refs, &block)
|
553
680
|
end
|
681
|
+
|
682
|
+
nil
|
554
683
|
end
|
555
684
|
|
556
|
-
|
685
|
+
# a set of child applicator subschemas of this schema which apply to the child of the given instance
|
686
|
+
# on the given token.
|
687
|
+
#
|
688
|
+
# @param token [Object] the array index or object property name for the child instance
|
689
|
+
# @param instance [Object] the instance to check any child applicators against
|
690
|
+
# @return [JSI::SchemaSet] child applicator subschemas of this schema for the given token
|
691
|
+
# of the instance
|
692
|
+
def child_applicator_schemas(token, instance)
|
693
|
+
SchemaSet.new(each_child_applicator_schema(token, instance))
|
694
|
+
end
|
695
|
+
|
696
|
+
# yields each child applicator subschema (from properties, items, etc.) which applies to the child of
|
697
|
+
# the given instance on the given token.
|
698
|
+
#
|
699
|
+
# @param (see #child_applicator_schemas)
|
700
|
+
# @yield [JSI::Schema]
|
701
|
+
# @return [nil, Enumerator] an Enumerator if invoked without a block; otherwise nil
|
702
|
+
def each_child_applicator_schema(token, instance, &block)
|
703
|
+
return to_enum(__method__, token, instance) unless block
|
704
|
+
|
705
|
+
internal_child_applicate_keywords(token, instance, &block)
|
706
|
+
|
707
|
+
nil
|
708
|
+
end
|
557
709
|
|
558
710
|
# any object property names this schema indicates may be present on its instances.
|
559
711
|
# this includes any keys of this schema's "properties" object and any entries of this schema's
|
560
712
|
# array of "required" property keys.
|
561
713
|
# @return [Set]
|
562
714
|
def described_object_property_names
|
563
|
-
|
715
|
+
@described_object_property_names_map[]
|
716
|
+
end
|
717
|
+
|
718
|
+
private def described_object_property_names_compute(**_) # TODO remove **_ eventually (keyword argument compatibility)
|
564
719
|
Set.new.tap do |property_names|
|
565
720
|
if schema_content.respond_to?(:to_hash) && schema_content['properties'].respond_to?(:to_hash)
|
566
721
|
property_names.merge(schema_content['properties'].keys)
|
@@ -569,7 +724,6 @@ module JSI
|
|
569
724
|
property_names.merge(schema_content['required'].to_ary)
|
570
725
|
end
|
571
726
|
end.freeze
|
572
|
-
end
|
573
727
|
end
|
574
728
|
|
575
729
|
# validates the given instance against this schema
|
@@ -577,7 +731,7 @@ module JSI
|
|
577
731
|
# @param instance [Object] the instance to validate against this schema
|
578
732
|
# @return [JSI::Validation::Result]
|
579
733
|
def instance_validate(instance)
|
580
|
-
if instance.is_a?(
|
734
|
+
if instance.is_a?(SchemaAncestorNode)
|
581
735
|
instance_ptr = instance.jsi_ptr
|
582
736
|
instance_document = instance.jsi_document
|
583
737
|
else
|
@@ -591,12 +745,58 @@ module JSI
|
|
591
745
|
# @param instance [Object] the instance to validate against this schema
|
592
746
|
# @return [Boolean]
|
593
747
|
def instance_valid?(instance)
|
594
|
-
if instance.is_a?(
|
748
|
+
if instance.is_a?(SchemaAncestorNode)
|
595
749
|
instance = instance.jsi_node_content
|
596
750
|
end
|
597
751
|
internal_validate_instance(Ptr[], instance, validate_only: true).valid?
|
598
752
|
end
|
599
753
|
|
754
|
+
# validates the given instance against this schema
|
755
|
+
#
|
756
|
+
# @private
|
757
|
+
# @param instance_ptr [JSI::Ptr] a pointer to the instance to validate against the schema, in the instance_document
|
758
|
+
# @param instance_document [#to_hash, #to_ary, Object] document containing the instance instance_ptr pointer points to
|
759
|
+
# @param validate_only [Boolean] whether to return a full schema validation result or a simple, validation-only result
|
760
|
+
# @param visited_refs [Enumerable<JSI::Schema::Ref>]
|
761
|
+
# @return [JSI::Validation::Result]
|
762
|
+
def internal_validate_instance(
|
763
|
+
instance_ptr,
|
764
|
+
instance_document,
|
765
|
+
visited_refs: Util::EMPTY_ARY,
|
766
|
+
validate_only: false
|
767
|
+
)
|
768
|
+
if validate_only
|
769
|
+
result = JSI::Validation::VALID
|
770
|
+
else
|
771
|
+
result = JSI::Validation::FullResult.new
|
772
|
+
end
|
773
|
+
result_builder = result.class::Builder.new(
|
774
|
+
result: result,
|
775
|
+
schema: self,
|
776
|
+
instance_ptr: instance_ptr,
|
777
|
+
instance_document: instance_document,
|
778
|
+
validate_only: validate_only,
|
779
|
+
visited_refs: visited_refs,
|
780
|
+
)
|
781
|
+
|
782
|
+
catch(:jsi_validation_result) do
|
783
|
+
# note: true/false are not valid as schemas in draft 4; they are only values of
|
784
|
+
# additionalProperties / additionalItems. since their behavior is undefined, though,
|
785
|
+
# it's fine for them to behave the same as boolean schemas in later drafts.
|
786
|
+
# I don't care about draft 4 to implement a different structuring for that.
|
787
|
+
if schema_content == true
|
788
|
+
# noop
|
789
|
+
elsif schema_content == false
|
790
|
+
result_builder.validate(false, 'instance is not valid against `false` schema')
|
791
|
+
elsif schema_content.respond_to?(:to_hash)
|
792
|
+
internal_validate_keywords(result_builder)
|
793
|
+
else
|
794
|
+
result_builder.schema_error('schema is not a boolean or a JSON object')
|
795
|
+
end
|
796
|
+
result
|
797
|
+
end.freeze
|
798
|
+
end
|
799
|
+
|
600
800
|
# schema resources which are ancestors of any subschemas below this schema.
|
601
801
|
# this may include this schema if this is a schema resource root.
|
602
802
|
# @api private
|
@@ -608,5 +808,15 @@ module JSI
|
|
608
808
|
jsi_schema_resource_ancestors
|
609
809
|
end
|
610
810
|
end
|
811
|
+
|
812
|
+
private
|
813
|
+
|
814
|
+
def jsi_schema_initialize
|
815
|
+
@schema_ref_map = jsi_memomap(key_by: proc { |i| i[:keyword] }) do |keyword: , value: |
|
816
|
+
Schema::Ref.new(value, ref_schema: self)
|
817
|
+
end
|
818
|
+
@schema_uris_map = jsi_memomap(&method(:schema_uris_compute))
|
819
|
+
@described_object_property_names_map = jsi_memomap(&method(:described_object_property_names_compute))
|
820
|
+
end
|
611
821
|
end
|
612
822
|
end
|