jsi-dev 0.0.8 → 0.0.9

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 (148) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +3 -4
  3. data/CHANGELOG.md +19 -0
  4. data/LICENSE.md +2 -3
  5. data/README.md +87 -43
  6. data/docs/{glossary.md → Glossary.md} +84 -52
  7. data/jsi.gemspec +1 -1
  8. data/lib/jsi/base/mutability.rb +48 -0
  9. data/lib/jsi/base/node.rb +66 -52
  10. data/lib/jsi/base.rb +592 -176
  11. data/lib/jsi/jsi_coder.rb +4 -2
  12. data/lib/jsi/metaschema_node/bootstrap_schema.rb +118 -59
  13. data/lib/jsi/metaschema_node.rb +244 -154
  14. data/lib/jsi/ptr.rb +45 -17
  15. data/lib/jsi/ref.rb +197 -0
  16. data/lib/jsi/registry.rb +311 -0
  17. data/lib/jsi/schema/cxt/child_application.rb +35 -0
  18. data/lib/jsi/schema/cxt/inplace_application.rb +37 -0
  19. data/lib/jsi/schema/cxt.rb +80 -0
  20. data/lib/jsi/schema/dialect.rb +137 -0
  21. data/lib/jsi/schema/draft04.rb +113 -5
  22. data/lib/jsi/schema/draft06.rb +123 -5
  23. data/lib/jsi/schema/draft07.rb +157 -5
  24. data/lib/jsi/schema/draft202012.rb +303 -0
  25. data/lib/jsi/schema/dynamic_anchor_map.rb +63 -0
  26. data/lib/jsi/schema/element.rb +69 -0
  27. data/lib/jsi/schema/elements/anchor.rb +13 -0
  28. data/lib/jsi/schema/elements/array_validation.rb +82 -0
  29. data/lib/jsi/schema/elements/comment.rb +10 -0
  30. data/lib/jsi/schema/{validation → elements}/const.rb +11 -7
  31. data/lib/jsi/schema/elements/contains.rb +59 -0
  32. data/lib/jsi/schema/elements/contains_minmax.rb +91 -0
  33. data/lib/jsi/schema/elements/content_encoding.rb +10 -0
  34. data/lib/jsi/schema/elements/content_media_type.rb +10 -0
  35. data/lib/jsi/schema/elements/content_schema.rb +16 -0
  36. data/lib/jsi/schema/elements/default.rb +11 -0
  37. data/lib/jsi/schema/elements/definitions.rb +19 -0
  38. data/lib/jsi/schema/elements/dependencies.rb +99 -0
  39. data/lib/jsi/schema/elements/dependent_required.rb +49 -0
  40. data/lib/jsi/schema/elements/dependent_schemas.rb +69 -0
  41. data/lib/jsi/schema/elements/dynamic_ref.rb +69 -0
  42. data/lib/jsi/schema/elements/enum.rb +26 -0
  43. data/lib/jsi/schema/elements/examples.rb +10 -0
  44. data/lib/jsi/schema/elements/format.rb +10 -0
  45. data/lib/jsi/schema/elements/id.rb +30 -0
  46. data/lib/jsi/schema/elements/if_then_else.rb +82 -0
  47. data/lib/jsi/schema/elements/info_bool.rb +10 -0
  48. data/lib/jsi/schema/elements/info_string.rb +10 -0
  49. data/lib/jsi/schema/elements/items.rb +93 -0
  50. data/lib/jsi/schema/elements/items_prefixed.rb +96 -0
  51. data/lib/jsi/schema/elements/not.rb +31 -0
  52. data/lib/jsi/schema/elements/numeric.rb +137 -0
  53. data/lib/jsi/schema/elements/numeric_draft04.rb +77 -0
  54. data/lib/jsi/schema/elements/object_validation.rb +55 -0
  55. data/lib/jsi/schema/elements/pattern.rb +35 -0
  56. data/lib/jsi/schema/elements/properties.rb +145 -0
  57. data/lib/jsi/schema/elements/property_names.rb +48 -0
  58. data/lib/jsi/schema/elements/ref.rb +62 -0
  59. data/lib/jsi/schema/elements/required.rb +34 -0
  60. data/lib/jsi/schema/elements/self.rb +24 -0
  61. data/lib/jsi/schema/elements/some_of.rb +180 -0
  62. data/lib/jsi/schema/elements/string_validation.rb +57 -0
  63. data/lib/jsi/schema/elements/type.rb +43 -0
  64. data/lib/jsi/schema/elements/unevaluated_items.rb +54 -0
  65. data/lib/jsi/schema/elements/unevaluated_properties.rb +54 -0
  66. data/lib/jsi/schema/elements/xschema.rb +10 -0
  67. data/lib/jsi/schema/elements/xvocabulary.rb +10 -0
  68. data/lib/jsi/schema/elements.rb +101 -0
  69. data/lib/jsi/schema/issue.rb +3 -4
  70. data/lib/jsi/schema/schema_ancestor_node.rb +105 -52
  71. data/lib/jsi/schema/vocabulary.rb +36 -0
  72. data/lib/jsi/schema.rb +598 -383
  73. data/lib/jsi/schema_classes.rb +195 -141
  74. data/lib/jsi/schema_set.rb +85 -128
  75. data/lib/jsi/set.rb +23 -0
  76. data/lib/jsi/simple_wrap.rb +14 -17
  77. data/lib/jsi/struct.rb +57 -0
  78. data/lib/jsi/uri.rb +40 -0
  79. data/lib/jsi/util/private/memo_map.rb +9 -13
  80. data/lib/jsi/util/private.rb +59 -31
  81. data/lib/jsi/util/typelike.rb +19 -60
  82. data/lib/jsi/util.rb +53 -34
  83. data/lib/jsi/validation/error.rb +45 -2
  84. data/lib/jsi/validation/result.rb +121 -90
  85. data/lib/jsi/validation.rb +1 -6
  86. data/lib/jsi/version.rb +1 -1
  87. data/lib/jsi.rb +170 -36
  88. data/lib/schemas/json-schema.org/draft/2020-12/schema.rb +62 -0
  89. data/lib/schemas/json-schema.org/draft-04/schema.rb +60 -109
  90. data/lib/schemas/json-schema.org/draft-06/schema.rb +53 -108
  91. data/lib/schemas/json-schema.org/draft-07/schema.rb +63 -127
  92. data/readme.rb +4 -4
  93. data/{resources}/schemas/2020-12_strict.json +19 -0
  94. data/{resources}/schemas/json-schema.org/draft/2020-12/meta/applicator.json +48 -0
  95. data/{resources}/schemas/json-schema.org/draft/2020-12/meta/content.json +17 -0
  96. data/{resources}/schemas/json-schema.org/draft/2020-12/meta/core.json +51 -0
  97. data/{resources}/schemas/json-schema.org/draft/2020-12/meta/format-annotation.json +14 -0
  98. data/{resources}/schemas/json-schema.org/draft/2020-12/meta/format-assertion.json +14 -0
  99. data/{resources}/schemas/json-schema.org/draft/2020-12/meta/meta-data.json +37 -0
  100. data/{resources}/schemas/json-schema.org/draft/2020-12/meta/unevaluated.json +15 -0
  101. data/{resources}/schemas/json-schema.org/draft/2020-12/meta/validation.json +98 -0
  102. data/{resources}/schemas/json-schema.org/draft/2020-12/schema.json +58 -0
  103. metadata +73 -52
  104. data/lib/jsi/metaschema.rb +0 -6
  105. data/lib/jsi/schema/application/child_application/contains.rb +0 -25
  106. data/lib/jsi/schema/application/child_application/draft04.rb +0 -21
  107. data/lib/jsi/schema/application/child_application/draft06.rb +0 -28
  108. data/lib/jsi/schema/application/child_application/draft07.rb +0 -28
  109. data/lib/jsi/schema/application/child_application/items.rb +0 -18
  110. data/lib/jsi/schema/application/child_application/properties.rb +0 -25
  111. data/lib/jsi/schema/application/child_application.rb +0 -13
  112. data/lib/jsi/schema/application/draft04.rb +0 -8
  113. data/lib/jsi/schema/application/draft06.rb +0 -8
  114. data/lib/jsi/schema/application/draft07.rb +0 -8
  115. data/lib/jsi/schema/application/inplace_application/dependencies.rb +0 -28
  116. data/lib/jsi/schema/application/inplace_application/draft04.rb +0 -25
  117. data/lib/jsi/schema/application/inplace_application/draft06.rb +0 -26
  118. data/lib/jsi/schema/application/inplace_application/draft07.rb +0 -32
  119. data/lib/jsi/schema/application/inplace_application/ifthenelse.rb +0 -20
  120. data/lib/jsi/schema/application/inplace_application/ref.rb +0 -18
  121. data/lib/jsi/schema/application/inplace_application/someof.rb +0 -44
  122. data/lib/jsi/schema/application/inplace_application.rb +0 -14
  123. data/lib/jsi/schema/application.rb +0 -12
  124. data/lib/jsi/schema/ref.rb +0 -183
  125. data/lib/jsi/schema/validation/array.rb +0 -69
  126. data/lib/jsi/schema/validation/contains.rb +0 -25
  127. data/lib/jsi/schema/validation/dependencies.rb +0 -49
  128. data/lib/jsi/schema/validation/draft04/minmax.rb +0 -91
  129. data/lib/jsi/schema/validation/draft04.rb +0 -110
  130. data/lib/jsi/schema/validation/draft06.rb +0 -120
  131. data/lib/jsi/schema/validation/draft07.rb +0 -157
  132. data/lib/jsi/schema/validation/enum.rb +0 -25
  133. data/lib/jsi/schema/validation/ifthenelse.rb +0 -46
  134. data/lib/jsi/schema/validation/items.rb +0 -54
  135. data/lib/jsi/schema/validation/not.rb +0 -20
  136. data/lib/jsi/schema/validation/numeric.rb +0 -121
  137. data/lib/jsi/schema/validation/object.rb +0 -45
  138. data/lib/jsi/schema/validation/pattern.rb +0 -34
  139. data/lib/jsi/schema/validation/properties.rb +0 -101
  140. data/lib/jsi/schema/validation/property_names.rb +0 -32
  141. data/lib/jsi/schema/validation/ref.rb +0 -40
  142. data/lib/jsi/schema/validation/required.rb +0 -27
  143. data/lib/jsi/schema/validation/someof.rb +0 -90
  144. data/lib/jsi/schema/validation/string.rb +0 -47
  145. data/lib/jsi/schema/validation/type.rb +0 -49
  146. data/lib/jsi/schema/validation.rb +0 -49
  147. data/lib/jsi/schema_registry.rb +0 -190
  148. data/lib/jsi/util/private/attr_struct.rb +0 -130
data/lib/jsi/jsi_coder.rb CHANGED
@@ -30,13 +30,15 @@ module JSI
30
30
  # @param array [Boolean] whether the dumped data represent one instance of the schema,
31
31
  # or an array of them. note that it may be preferable to simply use an array schema.
32
32
  # @param jsi_opt [Hash] keyword arguments to pass to {Schema#new_jsi} when loading
33
- def initialize(schema, array: false, jsi_opt: {})
33
+ # @param as_json_opt [Hash] keyword arguments to pass to `#as_json` when dumping
34
+ def initialize(schema, array: false, jsi_opt: Util::EMPTY_HASH, as_json_opt: Util::EMPTY_HASH)
34
35
  unless schema.respond_to?(:new_jsi)
35
36
  raise(ArgumentError, "schema param does not respond to #new_jsi: #{schema.inspect}")
36
37
  end
37
38
  @schema = schema
38
39
  @array = array
39
40
  @jsi_opt = jsi_opt
41
+ @as_json_opt = as_json_opt
40
42
  end
41
43
 
42
44
  # loads the database column to JSI instances of our schema
@@ -86,7 +88,7 @@ module JSI
86
88
  # @param object [JSI::Base, Object]
87
89
  # @return [Object]
88
90
  def dump_object(object)
89
- JSI::Util.as_json(object)
91
+ JSI::Util.as_json(object, **@as_json_opt)
90
92
  end
91
93
  end
92
94
  end
@@ -1,114 +1,166 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JSI
4
- # internal class to bootstrap a metaschema. represents a schema without the complexity of JSI::Base. the
4
+ # internal class to bootstrap a meta-schema. represents a schema without the complexity of JSI::Base. the
5
5
  # schema is represented but schemas describing the schema are not.
6
6
  #
7
7
  # this class is to only be instantiated on nodes in the document that are known to be schemas.
8
8
  # Schema#subschema and Schema#resource_root_subschema are the intended mechanisms to instantiate subschemas
9
9
  # and resolve references. #[] and #jsi_root_node are not implemented.
10
10
  #
11
- # schema implementation modules are included on generated subclasses of BootstrapSchema by
12
- # {SchemaClasses.bootstrap_schema_class}. that subclass is instantiated with a document and
13
- # pointer, representing a schema.
11
+ # BootstrapSchema does not support mutation; its document must be immutable.
14
12
  #
15
13
  # @api private
16
- class MetaschemaNode::BootstrapSchema
17
- include Util::FingerprintHash
14
+ class MetaSchemaNode::BootstrapSchema
15
+ include(Util::FingerprintHash::Immutable)
18
16
  include Schema::SchemaAncestorNode
19
17
  include Schema
20
-
21
- class << self
22
- def inspect
23
- if self == MetaschemaNode::BootstrapSchema
24
- name
25
- else
26
- -"#{name || MetaschemaNode::BootstrapSchema.name} (#{schema_implementation_modules.map(&:inspect).join(', ')})"
27
- end
28
- end
29
-
30
- alias_method :to_s, :inspect
31
- end
18
+ include(Util::Pretty)
32
19
 
33
20
  # @param jsi_ptr [JSI::Ptr] pointer to the schema in the document
34
21
  # @param jsi_document [#to_hash, #to_ary, Boolean, Object] document containing the schema
35
22
  def initialize(
36
- jsi_document,
23
+ dialect: ,
24
+ jsi_document: ,
37
25
  jsi_ptr: Ptr[],
38
- jsi_schema_base_uri: nil
26
+ jsi_base_uri: nil,
27
+ jsi_schema_resource_ancestors: Util::EMPTY_ARY,
28
+ jsi_schema_dynamic_anchor_map: Schema::DynamicAnchorMap::EMPTY,
29
+ jsi_registry: nil
39
30
  )
40
- raise(Bug, "no #schema_implementation_modules") unless respond_to?(:schema_implementation_modules)
31
+ @dialect = dialect
32
+ #chkbug fail(Bug) unless jsi_ptr.resolve_against(jsi_document).equal?(jsi_ptr)
33
+ @jsi_ptr = jsi_ptr
34
+ @jsi_document = jsi_document
35
+ self.jsi_base_uri = jsi_base_uri
36
+ self.jsi_schema_resource_ancestors = jsi_schema_resource_ancestors
37
+ self.jsi_schema_dynamic_anchor_map = jsi_schema_dynamic_anchor_map
38
+ @jsi_registry = jsi_registry
39
+
40
+ @memos = {}
41
+ @jsi_node_content = jsi_ptr.evaluate(jsi_document)
41
42
 
42
43
  super()
43
-
44
- self.jsi_ptr = jsi_ptr
45
- self.jsi_document = jsi_document
46
- self.jsi_schema_base_uri = jsi_schema_base_uri
47
- self.jsi_schema_resource_ancestors = Util::EMPTY_ARY
48
44
  end
49
45
 
46
+ # @return [Schema::Dialect]
47
+ attr_reader(:dialect)
48
+
50
49
  # document containing the schema content
51
50
  attr_reader :jsi_document
52
51
 
53
52
  # JSI::Ptr pointing to this schema within the document
54
53
  attr_reader :jsi_ptr
55
54
 
56
- def jsi_node_content
57
- jsi_ptr.evaluate(jsi_document)
55
+ # @return [nil]
56
+ def jsi_root_uri
58
57
  end
59
58
 
59
+ # @return [Registry, nil]
60
+ attr_reader(:jsi_registry)
61
+
62
+ attr_reader(:jsi_node_content)
63
+
60
64
  # overrides {Schema#subschema}
61
65
  def subschema(subptr)
62
- self.class.new(
63
- jsi_document,
66
+ subptr = Ptr.ary_ptr(subptr).resolve_against(jsi_node_content)
67
+ kw = {
68
+ jsi_document: jsi_document,
64
69
  jsi_ptr: jsi_ptr + subptr,
65
- jsi_schema_base_uri: jsi_resource_ancestor_uri,
70
+ jsi_base_uri: jsi_next_base_uri,
71
+ jsi_schema_resource_ancestors: jsi_subschema_resource_ancestors,
72
+ jsi_registry: jsi_registry,
73
+ }
74
+ # determine if subschema is a resource root here, for dynamic_anchor_map.
75
+ # done in the same manner as Base#jsi_child_dynamic_anchor_map, when child is a schema - a bootstrap schema is instantiated
76
+ # to check #jsi_is_resource_root?. here, though, that bootstrap schema is usually the returned subschema.
77
+ subschema = dialect.bootstrap_schema(**kw,
78
+ jsi_schema_dynamic_anchor_map: jsi_schema_dynamic_anchor_map,
66
79
  )
80
+ if subschema.jsi_is_resource_root?
81
+ # if subschema is a resource root, it should have our jsi_next_schema_dynamic_anchor_map
82
+ subschema = dialect.bootstrap_schema(**kw,
83
+ jsi_schema_dynamic_anchor_map: jsi_next_schema_dynamic_anchor_map.without_node(self, ptr: jsi_ptr + subptr),
84
+ )
85
+ end
86
+ subschema
67
87
  end
68
88
 
69
89
  # overrides {Schema#resource_root_subschema}
70
90
  def resource_root_subschema(ptr)
71
- # BootstrapSchema does not track jsi_schema_resource_ancestors used by Schema#schema_resource_root;
72
- # resource_root_subschema is always relative to the document root.
73
- # BootstrapSchema also does not implement jsi_root_node or #[]. we instantiate the ptr directly
74
- # rather than as a subschema from the root.
75
- self.class.new(
76
- jsi_document,
77
- jsi_ptr: Ptr.ary_ptr(ptr),
78
- jsi_schema_base_uri: nil,
91
+ ptr = Ptr.ary_ptr(ptr)
92
+ if jsi_resource_root
93
+ curschema = jsi_resource_root
94
+ remptr = ptr.resolve_against(jsi_resource_root.jsi_node_content)
95
+ found = true
96
+ while found
97
+ return(curschema) if remptr.empty?
98
+ found = false
99
+ curschema.each_immediate_subschema_ptr do |subptr|
100
+ if subptr.ancestor_of?(remptr)
101
+ curschema = curschema.subschema(subptr)
102
+ remptr = remptr.relative_to(subptr)
103
+ found = true
104
+ break
105
+ end
106
+ end
107
+ end
108
+ # ptr indicates a location where no element indicates a subschema.
109
+ # TODO rm support (along with reinstantiate_as) and raise(NotASchemaError) here.
110
+ return(curschema.subschema(remptr))
111
+ end
112
+ # no jsi_resource_root means the root is not a schema and no parent schema has an absolute uri.
113
+ # result schema is instantiated relative to document root.
114
+ dialect.bootstrap_schema(
115
+ jsi_document: jsi_document,
116
+ jsi_ptr: ptr.resolve_against(jsi_document),
117
+ jsi_base_uri: nil,
118
+ jsi_schema_resource_ancestors: Util::EMPTY_ARY,
119
+ jsi_schema_dynamic_anchor_map: jsi_schema_dynamic_anchor_map,
120
+ jsi_registry: jsi_registry,
79
121
  )
80
122
  end
81
123
 
82
- # @return [String]
83
- def inspect
84
- -"\#<#{jsi_object_group_text.join(' ')} #{schema_content.inspect}>"
124
+ # @param dynamic_anchor_map [Schema::DynamicAnchorMap]
125
+ # @return [MetaSchemaNode::BootstrapSchema]
126
+ private def jsi_dynamic_root_descendent(dynamic_anchor_map)
127
+ resource_root = jsi_resource_root
128
+ if resource_root
129
+ dialect.bootstrap_schema(
130
+ jsi_document: resource_root.jsi_document,
131
+ jsi_ptr: resource_root.jsi_ptr,
132
+ jsi_base_uri: resource_root.jsi_base_uri,
133
+ #jsi_schema_resource_ancestors: none (new root) (though that is not significant for bootstrap),
134
+ jsi_schema_dynamic_anchor_map: dynamic_anchor_map,
135
+ jsi_registry: resource_root.jsi_registry,
136
+ ).resource_root_subschema(jsi_ptr.relative_to(resource_root.jsi_ptr))
137
+ else
138
+ dialect.bootstrap_schema(
139
+ jsi_document: jsi_document,
140
+ jsi_ptr: jsi_ptr,
141
+ jsi_schema_dynamic_anchor_map: dynamic_anchor_map,
142
+ jsi_registry: jsi_registry,
143
+ )
144
+ end
85
145
  end
86
146
 
87
- alias_method :to_s, :inspect
88
-
89
147
  # pretty-prints a representation of self to the given printer
90
148
  # @return [void]
91
149
  def pretty_print(q)
92
- q.text '#<'
93
- q.text jsi_object_group_text.join(' ')
94
- q.group_sub {
95
- q.nest(2) {
96
- q.breakable ' '
150
+ jsi_pp_object_group(q, jsi_object_group_text) do
97
151
  q.pp schema_content
98
- }
99
- }
100
- q.breakable ''
101
- q.text '>'
152
+ end
102
153
  end
103
154
 
104
155
  # @private
105
156
  # @return [Array<String>]
106
157
  def jsi_object_group_text
107
158
  [
108
- self.class.name || MetaschemaNode::BootstrapSchema.name,
109
- -"(#{schema_implementation_modules.map(&:inspect).join(', ')})",
159
+ self.class.name || MetaSchemaNode::BootstrapSchema.name,
160
+ dialect.id ? -"(#{dialect.id})" : nil,
161
+ !jsi_schema_dynamic_anchor_map.empty? ? jsi_schema_dynamic_anchor_map.anchor_schemas_identifier : nil,
110
162
  jsi_ptr.uri,
111
- ]
163
+ ].compact.freeze
112
164
  end
113
165
 
114
166
  # see {Util::Private::FingerprintHash}
@@ -116,11 +168,18 @@ module JSI
116
168
  def jsi_fingerprint
117
169
  {
118
170
  class: self.class,
171
+ dialect: dialect,
119
172
  jsi_ptr: @jsi_ptr,
120
173
  jsi_document: @jsi_document,
121
- jsi_schema_base_uri: jsi_schema_base_uri,
122
- schema_implementation_modules: schema_implementation_modules,
123
- }
174
+ jsi_schema_dynamic_anchor_map: jsi_schema_dynamic_anchor_map,
175
+ jsi_registry: jsi_registry,
176
+ }.freeze
177
+ end
178
+
179
+ private
180
+
181
+ def jsi_memomap_class
182
+ Util::MemoMap::Immutable
124
183
  end
125
184
  end
126
185
  end