jsi 0.8.1 → 0.9.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 (146) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +3 -2
  3. data/CHANGELOG.md +9 -0
  4. data/LICENSE.md +2 -3
  5. data/README.md +68 -31
  6. data/docs/Glossary.md +313 -0
  7. data/jsi.gemspec +1 -0
  8. data/lib/jsi/base/mutability.rb +4 -0
  9. data/lib/jsi/base/node.rb +63 -24
  10. data/lib/jsi/base.rb +556 -173
  11. data/lib/jsi/metaschema_node/bootstrap_schema.rb +106 -56
  12. data/lib/jsi/metaschema_node.rb +227 -160
  13. data/lib/jsi/ptr.rb +32 -15
  14. data/lib/jsi/ref.rb +197 -0
  15. data/lib/jsi/registry.rb +311 -0
  16. data/lib/jsi/schema/cxt/child_application.rb +35 -0
  17. data/lib/jsi/schema/cxt/inplace_application.rb +37 -0
  18. data/lib/jsi/schema/cxt.rb +80 -0
  19. data/lib/jsi/schema/dialect.rb +137 -0
  20. data/lib/jsi/schema/draft04.rb +113 -5
  21. data/lib/jsi/schema/draft06.rb +123 -5
  22. data/lib/jsi/schema/draft07.rb +157 -5
  23. data/lib/jsi/schema/draft202012.rb +303 -0
  24. data/lib/jsi/schema/dynamic_anchor_map.rb +63 -0
  25. data/lib/jsi/schema/element.rb +69 -0
  26. data/lib/jsi/schema/elements/anchor.rb +13 -0
  27. data/lib/jsi/schema/elements/array_validation.rb +82 -0
  28. data/lib/jsi/schema/elements/comment.rb +10 -0
  29. data/lib/jsi/schema/{validation → elements}/const.rb +11 -7
  30. data/lib/jsi/schema/elements/contains.rb +59 -0
  31. data/lib/jsi/schema/elements/contains_minmax.rb +91 -0
  32. data/lib/jsi/schema/elements/content_encoding.rb +10 -0
  33. data/lib/jsi/schema/elements/content_media_type.rb +10 -0
  34. data/lib/jsi/schema/elements/content_schema.rb +16 -0
  35. data/lib/jsi/schema/elements/default.rb +11 -0
  36. data/lib/jsi/schema/elements/definitions.rb +19 -0
  37. data/lib/jsi/schema/elements/dependencies.rb +99 -0
  38. data/lib/jsi/schema/elements/dependent_required.rb +49 -0
  39. data/lib/jsi/schema/elements/dependent_schemas.rb +69 -0
  40. data/lib/jsi/schema/elements/dynamic_ref.rb +69 -0
  41. data/lib/jsi/schema/elements/enum.rb +26 -0
  42. data/lib/jsi/schema/elements/examples.rb +10 -0
  43. data/lib/jsi/schema/elements/format.rb +10 -0
  44. data/lib/jsi/schema/elements/id.rb +30 -0
  45. data/lib/jsi/schema/elements/if_then_else.rb +82 -0
  46. data/lib/jsi/schema/elements/info_bool.rb +10 -0
  47. data/lib/jsi/schema/elements/info_string.rb +10 -0
  48. data/lib/jsi/schema/elements/items.rb +93 -0
  49. data/lib/jsi/schema/elements/items_prefixed.rb +96 -0
  50. data/lib/jsi/schema/elements/not.rb +31 -0
  51. data/lib/jsi/schema/elements/numeric.rb +137 -0
  52. data/lib/jsi/schema/elements/numeric_draft04.rb +77 -0
  53. data/lib/jsi/schema/elements/object_validation.rb +55 -0
  54. data/lib/jsi/schema/elements/pattern.rb +35 -0
  55. data/lib/jsi/schema/elements/properties.rb +145 -0
  56. data/lib/jsi/schema/elements/property_names.rb +48 -0
  57. data/lib/jsi/schema/elements/ref.rb +62 -0
  58. data/lib/jsi/schema/elements/required.rb +34 -0
  59. data/lib/jsi/schema/elements/self.rb +24 -0
  60. data/lib/jsi/schema/elements/some_of.rb +180 -0
  61. data/lib/jsi/schema/elements/string_validation.rb +57 -0
  62. data/lib/jsi/schema/elements/type.rb +43 -0
  63. data/lib/jsi/schema/elements/unevaluated_items.rb +54 -0
  64. data/lib/jsi/schema/elements/unevaluated_properties.rb +54 -0
  65. data/lib/jsi/schema/elements/xschema.rb +10 -0
  66. data/lib/jsi/schema/elements/xvocabulary.rb +10 -0
  67. data/lib/jsi/schema/elements.rb +101 -0
  68. data/lib/jsi/schema/issue.rb +3 -4
  69. data/lib/jsi/schema/schema_ancestor_node.rb +103 -50
  70. data/lib/jsi/schema/vocabulary.rb +36 -0
  71. data/lib/jsi/schema.rb +520 -338
  72. data/lib/jsi/schema_classes.rb +168 -124
  73. data/lib/jsi/schema_set.rb +67 -126
  74. data/lib/jsi/set.rb +23 -0
  75. data/lib/jsi/simple_wrap.rb +13 -16
  76. data/lib/jsi/struct.rb +57 -0
  77. data/lib/jsi/uri.rb +40 -0
  78. data/lib/jsi/util/private/memo_map.rb +9 -13
  79. data/lib/jsi/util/private.rb +57 -12
  80. data/lib/jsi/util/typelike.rb +19 -64
  81. data/lib/jsi/util.rb +52 -34
  82. data/lib/jsi/validation/error.rb +41 -2
  83. data/lib/jsi/validation/result.rb +118 -71
  84. data/lib/jsi/validation.rb +1 -6
  85. data/lib/jsi/version.rb +1 -1
  86. data/lib/jsi.rb +158 -41
  87. data/lib/schemas/json-schema.org/draft/2020-12/schema.rb +67 -0
  88. data/lib/schemas/json-schema.org/draft-04/schema.rb +63 -106
  89. data/lib/schemas/json-schema.org/draft-06/schema.rb +56 -105
  90. data/lib/schemas/json-schema.org/draft-07/schema.rb +67 -124
  91. data/readme.rb +3 -3
  92. data/{resources}/schemas/2020-12_strict.json +19 -0
  93. data/{resources}/schemas/json-schema.org/draft/2020-12/meta/applicator.json +48 -0
  94. data/{resources}/schemas/json-schema.org/draft/2020-12/meta/content.json +17 -0
  95. data/{resources}/schemas/json-schema.org/draft/2020-12/meta/core.json +51 -0
  96. data/{resources}/schemas/json-schema.org/draft/2020-12/meta/format-annotation.json +14 -0
  97. data/{resources}/schemas/json-schema.org/draft/2020-12/meta/format-assertion.json +14 -0
  98. data/{resources}/schemas/json-schema.org/draft/2020-12/meta/meta-data.json +37 -0
  99. data/{resources}/schemas/json-schema.org/draft/2020-12/meta/unevaluated.json +15 -0
  100. data/{resources}/schemas/json-schema.org/draft/2020-12/meta/validation.json +98 -0
  101. data/{resources}/schemas/json-schema.org/draft/2020-12/schema.json +58 -0
  102. metadata +70 -48
  103. data/lib/jsi/schema/application/child_application/contains.rb +0 -25
  104. data/lib/jsi/schema/application/child_application/draft04.rb +0 -21
  105. data/lib/jsi/schema/application/child_application/draft06.rb +0 -28
  106. data/lib/jsi/schema/application/child_application/draft07.rb +0 -28
  107. data/lib/jsi/schema/application/child_application/items.rb +0 -18
  108. data/lib/jsi/schema/application/child_application/properties.rb +0 -25
  109. data/lib/jsi/schema/application/child_application.rb +0 -13
  110. data/lib/jsi/schema/application/draft04.rb +0 -8
  111. data/lib/jsi/schema/application/draft06.rb +0 -8
  112. data/lib/jsi/schema/application/draft07.rb +0 -8
  113. data/lib/jsi/schema/application/inplace_application/dependencies.rb +0 -28
  114. data/lib/jsi/schema/application/inplace_application/draft04.rb +0 -25
  115. data/lib/jsi/schema/application/inplace_application/draft06.rb +0 -26
  116. data/lib/jsi/schema/application/inplace_application/draft07.rb +0 -32
  117. data/lib/jsi/schema/application/inplace_application/ifthenelse.rb +0 -20
  118. data/lib/jsi/schema/application/inplace_application/ref.rb +0 -18
  119. data/lib/jsi/schema/application/inplace_application/someof.rb +0 -44
  120. data/lib/jsi/schema/application/inplace_application.rb +0 -14
  121. data/lib/jsi/schema/application.rb +0 -12
  122. data/lib/jsi/schema/ref.rb +0 -186
  123. data/lib/jsi/schema/validation/array.rb +0 -69
  124. data/lib/jsi/schema/validation/contains.rb +0 -25
  125. data/lib/jsi/schema/validation/dependencies.rb +0 -49
  126. data/lib/jsi/schema/validation/draft04/minmax.rb +0 -93
  127. data/lib/jsi/schema/validation/draft04.rb +0 -110
  128. data/lib/jsi/schema/validation/draft06.rb +0 -120
  129. data/lib/jsi/schema/validation/draft07.rb +0 -157
  130. data/lib/jsi/schema/validation/enum.rb +0 -25
  131. data/lib/jsi/schema/validation/ifthenelse.rb +0 -46
  132. data/lib/jsi/schema/validation/items.rb +0 -54
  133. data/lib/jsi/schema/validation/not.rb +0 -20
  134. data/lib/jsi/schema/validation/numeric.rb +0 -121
  135. data/lib/jsi/schema/validation/object.rb +0 -45
  136. data/lib/jsi/schema/validation/pattern.rb +0 -34
  137. data/lib/jsi/schema/validation/properties.rb +0 -101
  138. data/lib/jsi/schema/validation/property_names.rb +0 -32
  139. data/lib/jsi/schema/validation/ref.rb +0 -40
  140. data/lib/jsi/schema/validation/required.rb +0 -27
  141. data/lib/jsi/schema/validation/someof.rb +0 -90
  142. data/lib/jsi/schema/validation/string.rb +0 -47
  143. data/lib/jsi/schema/validation/type.rb +0 -49
  144. data/lib/jsi/schema/validation.rb +0 -49
  145. data/lib/jsi/schema_registry.rb +0 -200
  146. data/lib/jsi/util/private/attr_struct.rb +0 -141
@@ -8,102 +8,148 @@ module JSI
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.
14
- #
15
11
  # BootstrapSchema does not support mutation; its document must be immutable.
16
12
  #
17
13
  # @api private
18
14
  class MetaSchemaNode::BootstrapSchema
19
- include Util::FingerprintHash
15
+ include(Util::FingerprintHash::Immutable)
20
16
  include Schema::SchemaAncestorNode
21
17
  include Schema
22
-
23
- class << self
24
- def inspect
25
- if self == MetaSchemaNode::BootstrapSchema
26
- name.freeze
27
- else
28
- -"#{name || MetaSchemaNode::BootstrapSchema.name} (#{schema_implementation_modules.map(&:inspect).join(', ')})"
29
- end
30
- end
31
-
32
- def to_s
33
- inspect
34
- end
35
- end
18
+ include(Util::Pretty)
36
19
 
37
20
  # @param jsi_ptr [JSI::Ptr] pointer to the schema in the document
38
21
  # @param jsi_document [#to_hash, #to_ary, Boolean, Object] document containing the schema
39
22
  def initialize(
40
- jsi_document,
23
+ dialect: ,
24
+ jsi_document: ,
41
25
  jsi_ptr: Ptr[],
42
- 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
43
30
  )
44
- raise(Bug, "no #schema_implementation_modules") unless respond_to?(:schema_implementation_modules)
45
-
46
- self.jsi_ptr = jsi_ptr
47
- self.jsi_document = jsi_document
48
- self.jsi_schema_base_uri = jsi_schema_base_uri
49
- self.jsi_schema_resource_ancestors = Util::EMPTY_ARY
50
-
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 = {}
51
41
  @jsi_node_content = jsi_ptr.evaluate(jsi_document)
52
- #chkbug raise(Bug, 'BootstrapSchema instance must be frozen') unless jsi_node_content.frozen?
53
42
 
54
43
  super()
55
44
  end
56
45
 
46
+ # @return [Schema::Dialect]
47
+ attr_reader(:dialect)
48
+
57
49
  # document containing the schema content
58
50
  attr_reader :jsi_document
59
51
 
60
52
  # JSI::Ptr pointing to this schema within the document
61
53
  attr_reader :jsi_ptr
62
54
 
55
+ # @return [nil]
56
+ def jsi_root_uri
57
+ end
58
+
59
+ # @return [Registry, nil]
60
+ attr_reader(:jsi_registry)
61
+
63
62
  attr_reader(:jsi_node_content)
64
63
 
65
64
  # overrides {Schema#subschema}
66
65
  def subschema(subptr)
67
- self.class.new(
68
- jsi_document,
66
+ subptr = Ptr.ary_ptr(subptr).resolve_against(jsi_node_content)
67
+ kw = {
68
+ jsi_document: jsi_document,
69
69
  jsi_ptr: jsi_ptr + subptr,
70
- 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,
71
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
72
87
  end
73
88
 
74
89
  # overrides {Schema#resource_root_subschema}
75
90
  def resource_root_subschema(ptr)
76
- # BootstrapSchema does not track jsi_schema_resource_ancestors used by Schema#schema_resource_root;
77
- # resource_root_subschema is always relative to the document root.
78
- # BootstrapSchema also does not implement jsi_root_node or #[]. we instantiate the ptr directly
79
- # rather than as a subschema from the root.
80
- self.class.new(
81
- jsi_document,
82
- jsi_ptr: Ptr.ary_ptr(ptr),
83
- 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,
84
121
  )
85
122
  end
86
123
 
87
- # @return [String]
88
- def inspect
89
- -"\#<#{jsi_object_group_text.join(' ')} #{schema_content.inspect}>"
90
- end
91
-
92
- def to_s
93
- 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
94
145
  end
95
146
 
96
147
  # pretty-prints a representation of self to the given printer
97
148
  # @return [void]
98
149
  def pretty_print(q)
99
- q.text '#<'
100
- q.text jsi_object_group_text.join(' ')
101
- q.group(2) {
102
- q.breakable ' '
150
+ jsi_pp_object_group(q, jsi_object_group_text) do
103
151
  q.pp schema_content
104
- }
105
- q.breakable ''
106
- q.text '>'
152
+ end
107
153
  end
108
154
 
109
155
  # @private
@@ -111,9 +157,10 @@ module JSI
111
157
  def jsi_object_group_text
112
158
  [
113
159
  self.class.name || MetaSchemaNode::BootstrapSchema.name,
114
- -"(#{schema_implementation_modules.map(&:inspect).join(', ')})",
160
+ dialect.id ? -"(#{dialect.id})" : nil,
161
+ !jsi_schema_dynamic_anchor_map.empty? ? jsi_schema_dynamic_anchor_map.anchor_schemas_identifier : nil,
115
162
  jsi_ptr.uri,
116
- ].freeze
163
+ ].compact.freeze
117
164
  end
118
165
 
119
166
  # see {Util::Private::FingerprintHash}
@@ -121,8 +168,11 @@ module JSI
121
168
  def jsi_fingerprint
122
169
  {
123
170
  class: self.class,
171
+ dialect: dialect,
124
172
  jsi_ptr: @jsi_ptr,
125
173
  jsi_document: @jsi_document,
174
+ jsi_schema_dynamic_anchor_map: jsi_schema_dynamic_anchor_map,
175
+ jsi_registry: jsi_registry,
126
176
  }.freeze
127
177
  end
128
178