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
@@ -0,0 +1,303 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSI
4
+ module Schema::Draft202012
5
+ module Vocab end
6
+
7
+ # draft-bhutton-json-schema-01 8. The JSON Schema Core Vocabulary
8
+ #
9
+ # The current URI for the Core vocabulary is:
10
+ # https://json-schema.org/draft/2020-12/vocab/core
11
+ #
12
+ # The current URI for the corresponding meta-schema is:
13
+ # https://json-schema.org/draft/2020-12/meta/core
14
+ Vocab::CORE = Schema::Vocabulary.new(
15
+ id: "https://json-schema.org/draft/2020-12/vocab/core",
16
+ elements: [
17
+ Schema::Elements::SELF[],
18
+
19
+ # draft-bhutton-json-schema-01 8.1.1. The "$schema" Keyword
20
+ Schema::Elements::XSCHEMA[],
21
+
22
+ # draft-bhutton-json-schema-01 8.1.2. The "$vocabulary" Keyword
23
+ Schema::Elements::XVOCABULARY[],
24
+
25
+ # draft-bhutton-json-schema-01 8.2.1. The "$id" Keyword
26
+ Schema::Elements::ID[keyword: '$id', fragment_is_anchor: false],
27
+
28
+ # draft-bhutton-json-schema-01 8.2.2. Defining location-independent identifiers
29
+ Schema::Elements::ANCHOR[keyword: '$anchor', actions: [:anchor]],
30
+ Schema::Elements::ANCHOR[keyword: '$dynamicAnchor', actions: [:anchor, :dynamicAnchor]],
31
+
32
+ # draft-bhutton-json-schema-01 8.2.3. Schema References
33
+
34
+ # draft-bhutton-json-schema-01 8.2.3.1. Direct References with "$ref"
35
+ Schema::Elements::REF[exclusive: false],
36
+
37
+ # draft-bhutton-json-schema-01 8.2.3.2. Dynamic References with "$dynamicRef"
38
+ Schema::Elements::DYNAMIC_REF[],
39
+
40
+ # draft-bhutton-json-schema-01 8.2.4. Schema Re-Use With "$defs"
41
+ Schema::Elements::DEFINITIONS[keyword: '$defs'],
42
+
43
+ # draft-bhutton-json-schema-01 8.3. Comments With "$comment"
44
+ Schema::Elements::COMMENT[],
45
+ ],
46
+ )
47
+
48
+ # draft-bhutton-json-schema-01 10. A Vocabulary for Applying Subschemas
49
+ #
50
+ # The current URI for this vocabulary, known as the Applicator vocabulary, is:
51
+ # https://json-schema.org/draft/2020-12/vocab/applicator
52
+ #
53
+ # The current URI for the corresponding meta-schema is:
54
+ # https://json-schema.org/draft/2020-12/meta/applicator
55
+ Vocab::APPLICATOR = Schema::Vocabulary.new(
56
+ id: "https://json-schema.org/draft/2020-12/vocab/applicator",
57
+ elements: [
58
+ # draft-bhutton-json-schema-01 10.2. Keywords for Applying Subschemas in Place
59
+ # draft-bhutton-json-schema-01 10.2.1. Keywords for Applying Subschemas With Logic
60
+
61
+ # draft-bhutton-json-schema-01 10.2.1.1. allOf
62
+ Schema::Elements::ALL_OF[],
63
+
64
+ # draft-bhutton-json-schema-01 10.2.1.2. anyOf
65
+ Schema::Elements::ANY_OF[],
66
+
67
+ # draft-bhutton-json-schema-01 10.2.1.3. oneOf
68
+ Schema::Elements::ONE_OF[],
69
+
70
+ # draft-bhutton-json-schema-01 10.2.1.4. not
71
+ Schema::Elements::NOT[],
72
+
73
+ # draft-bhutton-json-schema-01 10.2.2. Keywords for Applying Subschemas Conditionally
74
+
75
+ # draft-bhutton-json-schema-01 10.2.2.1. if
76
+ # draft-bhutton-json-schema-01 10.2.2.2. then
77
+ # draft-bhutton-json-schema-01 10.2.2.3. else
78
+ Schema::Elements::IF_THEN_ELSE[],
79
+
80
+ # draft-bhutton-json-schema-01 10.2.2.4. dependentSchemas
81
+ Schema::Elements::DEPENDENT_SCHEMAS[],
82
+
83
+ # draft-bhutton-json-schema-01 10.3. Keywords for Applying Subschemas to Child Instances
84
+ # draft-bhutton-json-schema-01 10.3.1. Keywords for Applying Subschemas to Arrays
85
+
86
+ # draft-bhutton-json-schema-01 10.3.1.1. prefixItems
87
+ # draft-bhutton-json-schema-01 10.3.1.2. items
88
+ Schema::Elements::ITEMS_PREFIXED[],
89
+
90
+ # draft-bhutton-json-schema-01 10.3.1.3. contains
91
+ Schema::Elements::CONTAINS_MINMAX[],
92
+
93
+ # draft-bhutton-json-schema-01 10.3.2. Keywords for Applying Subschemas to Objects
94
+
95
+ # draft-bhutton-json-schema-01 10.3.2.1. properties
96
+ # draft-bhutton-json-schema-01 10.3.2.2. patternProperties
97
+ # draft-bhutton-json-schema-01 10.3.2.3. additionalProperties
98
+ Schema::Elements::PROPERTIES[],
99
+
100
+ # draft-bhutton-json-schema-01 10.3.2.4. propertyNames
101
+ Schema::Elements::PROPERTY_NAMES[],
102
+ ],
103
+ )
104
+
105
+ # draft-bhutton-json-schema-01 11. A Vocabulary for Unevaluated Locations
106
+ #
107
+ # The current URI for this vocabulary, known as the Unevaluated Applicator vocabulary, is:
108
+ # https://json-schema.org/draft/2020-12/vocab/unevaluated
109
+ #
110
+ # The current URI for the corresponding meta-schema is:
111
+ # https://json-schema.org/draft/2020-12/meta/unevaluated
112
+ Vocab::UNEVALUATED = Schema::Vocabulary.new(
113
+ id: "https://json-schema.org/draft/2020-12/vocab/unevaluated",
114
+ elements: [
115
+ # draft-bhutton-json-schema-01 11.2. unevaluatedItems
116
+ Schema::Elements::UNEVALUATED_ITEMS[],
117
+
118
+ # draft-bhutton-json-schema-01 11.3. unevaluatedProperties
119
+ Schema::Elements::UNEVALUATED_PROPERTIES[],
120
+ ],
121
+ )
122
+
123
+ # draft-bhutton-json-schema-validation-01 6. A Vocabulary for Structural Validation
124
+ #
125
+ # The current URI for this vocabulary, known as the Validation vocabulary, is:
126
+ # https://json-schema.org/draft/2020-12/vocab/validation
127
+ #
128
+ # The current URI for the corresponding meta-schema is:
129
+ # https://json-schema.org/draft/2020-12/meta/validation
130
+ Vocab::VALIDATION = Schema::Vocabulary.new(
131
+ id: "https://json-schema.org/draft/2020-12/vocab/validation",
132
+ elements: [
133
+ # draft-bhutton-json-schema-validation-01 6.1. Validation Keywords for Any Instance Type
134
+
135
+ # draft-bhutton-json-schema-validation-01 6.1.1. type
136
+ Schema::Elements::TYPE[],
137
+
138
+ # draft-bhutton-json-schema-validation-01 6.1.2. enum
139
+ Schema::Elements::ENUM[],
140
+
141
+ # draft-bhutton-json-schema-validation-01 6.1.3. const
142
+ Schema::Elements::CONST[],
143
+
144
+ # draft-bhutton-json-schema-validation-01 6.2. Validation Keywords for Numeric Instances (number and integer)
145
+
146
+ # draft-bhutton-json-schema-validation-01 6.2.1. multipleOf
147
+ Schema::Elements::MULTIPLE_OF[],
148
+
149
+ # draft-bhutton-json-schema-validation-01 6.2.2. maximum
150
+ Schema::Elements::MAXIMUM[],
151
+
152
+ # draft-bhutton-json-schema-validation-01 6.2.3. exclusiveMaximum
153
+ Schema::Elements::EXCLUSIVE_MAXIMUM[],
154
+
155
+ # draft-bhutton-json-schema-validation-01 6.2.4. minimum
156
+ Schema::Elements::MINIMUM[],
157
+
158
+ # draft-bhutton-json-schema-validation-01 6.2.5. exclusiveMinimum
159
+ Schema::Elements::EXCLUSIVE_MINIMUM[],
160
+
161
+ # draft-bhutton-json-schema-validation-01 6.3. Validation Keywords for Strings
162
+
163
+ # draft-bhutton-json-schema-validation-01 6.3.1. maxLength
164
+ Schema::Elements::MAX_LENGTH[],
165
+
166
+ # draft-bhutton-json-schema-validation-01 6.3.2. minLength
167
+ Schema::Elements::MIN_LENGTH[],
168
+
169
+ # draft-bhutton-json-schema-validation-01 6.3.3. pattern
170
+ Schema::Elements::PATTERN[],
171
+
172
+ # draft-bhutton-json-schema-validation-01 6.4. Validation Keywords for Arrays
173
+
174
+ # draft-bhutton-json-schema-validation-01 6.4.1. maxItems
175
+ Schema::Elements::MAX_ITEMS[],
176
+
177
+ # draft-bhutton-json-schema-validation-01 6.4.2. minItems
178
+ Schema::Elements::MIN_ITEMS[],
179
+
180
+ # draft-bhutton-json-schema-validation-01 6.4.3. uniqueItems
181
+ Schema::Elements::UNIQUE_ITEMS[],
182
+
183
+ # draft-bhutton-json-schema-validation-01 6.4.4. maxContains
184
+ # draft-bhutton-json-schema-validation-01 6.4.5. minContains
185
+ # (see Schema::Elements::CONTAINS_MINMAX[] - draft-bhutton-json-schema-01 10.3.1.3. contains)
186
+
187
+ # draft-bhutton-json-schema-validation-01 6.5. Validation Keywords for Objects
188
+
189
+ # draft-bhutton-json-schema-validation-01 6.5.1. maxProperties
190
+ Schema::Elements::MAX_PROPERTIES[],
191
+
192
+ # draft-bhutton-json-schema-validation-01 6.5.2. minProperties
193
+ Schema::Elements::MIN_PROPERTIES[],
194
+
195
+ # draft-bhutton-json-schema-validation-01 6.5.3. required
196
+ Schema::Elements::REQUIRED[],
197
+
198
+ # draft-bhutton-json-schema-validation-01 6.5.4. dependentRequired
199
+ Schema::Elements::DEPENDENT_REQUIRED[],
200
+ ],
201
+ )
202
+
203
+ # draft-bhutton-json-schema-validation-01 7. Vocabularies for Semantic Content With "format"
204
+ #
205
+ # The current URI for this vocabulary, known as the Format-Annotation vocabulary, is:
206
+ # https://json-schema.org/draft/2020-12/vocab/format-annotation
207
+ #
208
+ # The current URI for the corresponding meta-schema is:
209
+ # https://json-schema.org/draft/2020-12/meta/format-annotation
210
+ Vocab::FORMAT_ANNOTATION = Schema::Vocabulary.new(
211
+ id: "https://json-schema.org/draft/2020-12/vocab/format-annotation",
212
+ elements: [
213
+ # draft-bhutton-json-schema-validation-01 7.2.1. Format-Annotation Vocabulary
214
+ Schema::Elements::FORMAT[],
215
+ ],
216
+ )
217
+
218
+ # draft-bhutton-json-schema-validation-01 7. Vocabularies for Semantic Content With "format"
219
+ #
220
+ # The URI for the Format-Assertion vocabulary, is:
221
+ # https://json-schema.org/draft/2020-12/vocab/format-assertion
222
+ #
223
+ # The current URI for the corresponding meta-schema is:
224
+ # https://json-schema.org/draft/2020-12/meta/format-assertion
225
+ #
226
+ # (Vocab::FORMAT_ASSERTION not implemented)
227
+
228
+
229
+ # draft-bhutton-json-schema-validation-01 8. A Vocabulary for the Contents of String-Encoded Data
230
+ #
231
+ # The current URI for this vocabulary, known as the Content vocabulary, is:
232
+ # https://json-schema.org/draft/2020-12/vocab/content
233
+ #
234
+ # The current URI for the corresponding meta-schema is:
235
+ # https://json-schema.org/draft/2020-12/meta/content
236
+ Vocab::CONTENT = Schema::Vocabulary.new(
237
+ id: "https://json-schema.org/draft/2020-12/vocab/content",
238
+ elements: [
239
+ # draft-bhutton-json-schema-validation-01 8.3. contentEncoding
240
+ Schema::Elements::CONTENT_ENCODING[],
241
+
242
+ # draft-bhutton-json-schema-validation-01 8.4. contentMediaType
243
+ Schema::Elements::CONTENT_MEDIA_TYPE[],
244
+
245
+ # draft-bhutton-json-schema-validation-01 8.5. contentSchema
246
+ Schema::Elements::CONTENT_SCHEMA[],
247
+ ],
248
+ )
249
+
250
+ # draft-bhutton-json-schema-validation-01 9. A Vocabulary for Basic Meta-Data Annotations
251
+ #
252
+ # The current URI for this vocabulary, known as the Meta-Data vocabulary, is:
253
+ # https://json-schema.org/draft/2020-12/vocab/meta-data
254
+ #
255
+ # The current URI for the corresponding meta-schema is:
256
+ # https://json-schema.org/draft/2020-12/meta/meta-data
257
+ Vocab::METADATA = Schema::Vocabulary.new(
258
+ id: "https://json-schema.org/draft/2020-12/vocab/meta-data",
259
+ elements: [
260
+ # draft-bhutton-json-schema-validation-01 9.1. "title" and "description"
261
+ Schema::Elements::INFO_STRING[keyword: 'title'],
262
+ Schema::Elements::INFO_STRING[keyword: 'description'],
263
+
264
+ # draft-bhutton-json-schema-validation-01 9.2. "default"
265
+ Schema::Elements::DEFAULT[],
266
+
267
+ # draft-bhutton-json-schema-validation-01 9.3. "deprecated"
268
+ Schema::Elements::INFO_BOOL[keyword: 'deprecated'],
269
+
270
+ # draft-bhutton-json-schema-validation-01 9.4. "readOnly" and "writeOnly"
271
+ Schema::Elements::INFO_BOOL[keyword: 'readOnly'],
272
+ Schema::Elements::INFO_BOOL[keyword: 'writeOnly'],
273
+
274
+ # draft-bhutton-json-schema-validation-01 9.5. "examples"
275
+ Schema::Elements::EXAMPLES[],
276
+ ],
277
+ )
278
+
279
+ # Compatibility vocabulary: The specification doesn't specify these keywords,
280
+ # but the meta-schema describes them. The test suite considers them optional.
281
+ Vocab::COMPATIBILITY = Schema::Vocabulary.new(
282
+ elements: [
283
+ Schema::Elements::DEFINITIONS[keyword: 'definitions'],
284
+
285
+ Schema::Elements::DEPENDENCIES[],
286
+ ],
287
+ )
288
+
289
+ DIALECT = Schema::Dialect.new(
290
+ id: "https://json-schema.org/draft/2020-12/schema",
291
+ vocabularies: [
292
+ Vocab::CORE,
293
+ Vocab::APPLICATOR,
294
+ Vocab::UNEVALUATED,
295
+ Vocab::VALIDATION,
296
+ Vocab::FORMAT_ANNOTATION,
297
+ Vocab::CONTENT,
298
+ Vocab::METADATA,
299
+ Vocab::COMPATIBILITY,
300
+ ],
301
+ )
302
+ end
303
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSI
4
+ # A map of dynamic anchors to schemas.
5
+ #
6
+ # key: `anchor_name` [String] a `$dynamicAnchor` keyword value
7
+ #
8
+ # value: [Array] (2-tuple)
9
+ #
10
+ # - `anchor_root` [Schema]
11
+ #
12
+ # The resource root of the schema containing the `$dynamicAnchor` with `anchor_name`.
13
+ #
14
+ # The `#jsi_schema_dynamic_anchor_map` of anchor_root is expected to be empty.
15
+ # It should be replaced when the anchor schema is resolved.
16
+ #
17
+ # - `ptrs` [Array<{Ptr}>]
18
+ #
19
+ # Pointers passed to {Schema#subschema} from `anchor_root`, resulting in the schema containing the
20
+ # `$dynamicAnchor` with `anchor_name`.
21
+ #
22
+ # @api private
23
+ class Schema::DynamicAnchorMap < Hash
24
+ # In order to avoid instantiating a node with a dynamic_anchor_map that refers to that node itself
25
+ # (which results in its jsi_fingerprint circularly referring to itself)
26
+ # we remove such anchors from the dynamic_anchor_map it will be instantiated with.
27
+ # The node's #jsi_next_schema_dynamic_anchor_map will remap such anchors to the node again.
28
+ #
29
+ # If the indicated node is not a schema and a resource root, nothing will be removed.
30
+ # @return [Schema::DynamicAnchorMap]
31
+ def without_node(node, document: node.jsi_document, ptr: node.jsi_ptr, registry: node.jsi_registry)
32
+ dynamic_anchor_map = self
33
+ each do |anchor, (anchor_root, anchor_ptrs)|
34
+ # Determine whether this anchor maps to the indicated node.
35
+ # This should strictly use the same fields as the node's #jsi_fingerprint
36
+ # (which is different for Base, MetaSchemaNode, and MetaSchemaNode::BootstrapSchema).
37
+ # However, some fields of the fingerprint are fairly complicated to compute with neither
38
+ # the node being removed nor the anchor schema actually instantiated.
39
+ # Realistically document+ptr is sufficient and correct outside of implausible edge cases.
40
+ maps_to_node = anchor_root.jsi_document.equal?(document) &&
41
+ anchor_root.jsi_ptr == ptr &&
42
+ anchor_root.jsi_registry == registry
43
+ if maps_to_node
44
+ dynamic_anchor_map = dynamic_anchor_map.dup
45
+ dynamic_anchor_map.delete(anchor)
46
+ dynamic_anchor_map.freeze
47
+ end
48
+ end
49
+ dynamic_anchor_map.empty? ? EMPTY : dynamic_anchor_map
50
+ end
51
+
52
+ # @private
53
+ # @return [String]
54
+ def anchor_schemas_identifier
55
+ names = map do |anchor, (r, ptrs)|
56
+ -"#{anchor}→#{ptrs.inject(r, &:subschema).jsi_schema_identifier(required: true)}"
57
+ end
58
+ -"«#{names.join(", ")}»"
59
+ end
60
+
61
+ EMPTY = new.freeze
62
+ end
63
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSI
4
+ module Schema
5
+ class Element
6
+ # @yield [Schema::Element] self
7
+ def initialize(keyword: nil, keywords: Util::EMPTY_SET)
8
+ @keywords = keyword ? (keywords.empty? ? Set[keyword].freeze : raise(ArgumentError)) : Set.new(keywords).freeze
9
+ @actions = Hash.new(Util::EMPTY_ARY)
10
+ @required_before_element_selector = nil
11
+ @depends_on_element_selector = nil
12
+
13
+ yield(self)
14
+
15
+ @actions.freeze
16
+ freeze
17
+ end
18
+
19
+ # @return [Set]
20
+ attr_reader(:keywords)
21
+
22
+ # @return [Hash<Symbol, Array<Proc>>]
23
+ attr_reader(:actions)
24
+
25
+ # this element will be invoked before elements for which the result of the block is true-ish
26
+ # @yieldparam [Schema::Element]
27
+ # @yieldreturn [Boolean]
28
+ def required_before_elements(&block)
29
+ @required_before_element_selector = block
30
+ end
31
+
32
+ # this element will be invoked after elements for which the result of the block is true-ish
33
+ # @yieldparam [Schema::Element]
34
+ # @yieldreturn [Boolean]
35
+ def depends_on_elements(&block)
36
+ @depends_on_element_selector = block
37
+ end
38
+
39
+ # selects which of `elements` this element is required before
40
+ def select_elements_self_is_required_before(elements)
41
+ return(Util::EMPTY_ARY) unless @required_before_element_selector
42
+ elements.select { |e| e != self && @required_before_element_selector.call(e) }.freeze
43
+ end
44
+
45
+ # selects which of `elements` this element depends on
46
+ def select_elements_self_depends_on(elements)
47
+ return(Util::EMPTY_ARY) unless @depends_on_element_selector
48
+ elements.select { |e| e != self && @depends_on_element_selector.call(e) }.freeze
49
+ end
50
+
51
+ # @param name [Symbol]
52
+ # @yield perform the action
53
+ # @return [void]
54
+ def add_action(name, &block)
55
+ raise(TypeError) unless name.is_a?(Symbol)
56
+
57
+ @actions[name] = @actions[name].dup.push(block).freeze
58
+
59
+ nil
60
+ end
61
+
62
+ # @param action_name [Symbol]
63
+ # @return [Boolean]
64
+ def invokes?(action_name)
65
+ !@actions[action_name].empty?
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSI
4
+ module Schema::Elements
5
+ ANCHOR = element_map do |keyword: , actions: |
6
+ Schema::Element.new(keyword: keyword) do |element|
7
+ actions.each do |action|
8
+ element.add_action(action) { cxt_yield(schema_content[keyword]) if keyword_value_str?(keyword) }
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSI
4
+ module Schema::Elements
5
+ MAX_ITEMS = element_map do
6
+ Schema::Element.new(keyword: 'maxItems') do |element|
7
+ element.add_action(:validate) do
8
+ if keyword?('maxItems')
9
+ value = schema_content['maxItems']
10
+ # The value of this keyword MUST be a non-negative integer.
11
+ if internal_integer?(value) && value >= 0
12
+ if instance.respond_to?(:to_ary)
13
+ # An array instance is valid against "maxItems" if its size is less than, or equal to, the value of this keyword.
14
+ size = instance.to_ary.size
15
+ validate(
16
+ size <= value,
17
+ 'validation.keyword.maxItems.size_greater',
18
+ 'instance array size is greater than `maxItems` value',
19
+ keyword: 'maxItems',
20
+ instance_size: size,
21
+ )
22
+ end
23
+ end
24
+ end
25
+ end # element.add_action(:validate)
26
+ end # Schema::Element.new
27
+ end # MAX_ITEMS = element_map
28
+ end # module Schema::Elements
29
+
30
+ module Schema::Elements
31
+ MIN_ITEMS = element_map do
32
+ Schema::Element.new(keyword: 'minItems') do |element|
33
+ element.add_action(:validate) do
34
+ if keyword?('minItems')
35
+ value = schema_content['minItems']
36
+ # The value of this keyword MUST be a non-negative integer.
37
+ if internal_integer?(value) && value >= 0
38
+ if instance.respond_to?(:to_ary)
39
+ # An array instance is valid against "minItems" if its size is greater than, or equal to, the value of this keyword.
40
+ size = instance.to_ary.size
41
+ validate(
42
+ size >= value,
43
+ 'validation.keyword.minItems.size_less',
44
+ 'instance array size is less than `minItems` value',
45
+ keyword: 'minItems',
46
+ instance_size: size,
47
+ )
48
+ end
49
+ end
50
+ end
51
+ end # element.add_action(:validate)
52
+ end # Schema::Element.new
53
+ end # MIN_ITEMS = element_map
54
+ end # module Schema::Elements
55
+
56
+ module Schema::Elements
57
+ UNIQUE_ITEMS = element_map do
58
+ Schema::Element.new(keyword: 'uniqueItems') do |element|
59
+ element.add_action(:validate) do
60
+ if keyword?('uniqueItems')
61
+ value = schema_content['uniqueItems']
62
+ # The value of this keyword MUST be a boolean.
63
+ if value == true
64
+ if instance.respond_to?(:to_ary)
65
+ # If it has boolean value true, the instance validates successfully if all of its elements are unique.
66
+ # TODO instance.tally.select { |_, count| count > 1 }.keys.freeze when all supported Hash.method_defined?(:tally)
67
+ duplicate_items = instance.group_by(&:itself).select { |_, v| v.size > 1 }.keys.freeze
68
+ validate(
69
+ duplicate_items.empty?,
70
+ 'validation.keyword.uniqueItems.not_unique',
71
+ "instance array items are not unique with `uniqueItems` = true",
72
+ keyword: 'uniqueItems',
73
+ duplicate_items: duplicate_items,
74
+ )
75
+ end
76
+ end
77
+ end
78
+ end # element.add_action(:validate)
79
+ end # Schema::Element.new
80
+ end # UNIQUE_ITEMS = element_map
81
+ end # module Schema::Elements
82
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSI
4
+ module Schema::Elements
5
+ COMMENT = element_map do
6
+ Schema::Element.new(keyword: '$comment') do |element|
7
+ end # Schema::Element.new
8
+ end # CONTENT_ENCODING = element_map
9
+ end # module Schema::Elements
10
+ end
@@ -1,20 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JSI
4
- module Schema::Validation::Const
5
- # @private
6
- def internal_validate_const(result_builder)
4
+ module Schema::Elements
5
+ CONST = element_map do
6
+ Schema::Element.new(keyword: 'const') do |element|
7
+ element.add_action(:validate) do
7
8
  if keyword?('const')
8
9
  value = schema_content['const']
9
10
  # The value of this keyword MAY be of any type, including null.
10
11
  # An instance validates successfully against this keyword if its value is equal to the value of
11
12
  # the keyword.
12
- result_builder.validate(
13
- result_builder.instance == value,
13
+ validate(
14
+ instance == value,
15
+ 'validation.keyword.const.not_equal',
14
16
  'instance is not equal to `const` value',
15
17
  keyword: 'const',
16
18
  )
17
19
  end
18
- end
19
- end
20
+ end # element.add_action(:validate)
21
+ end # Schema::Element.new
22
+ end # CONST = element_map
23
+ end # module Schema::Elements
20
24
  end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSI
4
+ module Schema::Elements
5
+ CONTAINS = element_map do
6
+ Schema::Element.new(keyword: 'contains') do |element|
7
+ element.add_action(:subschema) do
8
+ if keyword?('contains')
9
+ #> The value of this keyword MUST be a valid JSON Schema.
10
+ cxt_yield(['contains'])
11
+ end
12
+ end # element.add_action(:subschema)
13
+
14
+ element.add_action(:child_applicate) do
15
+ if instance.respond_to?(:to_ary)
16
+ if keyword?('contains')
17
+ contains_schema = subschema(['contains'])
18
+
19
+ child_idx_valid = Hash.new { |h, i| h[i] = contains_schema.instance_valid?(instance[i]) }
20
+
21
+ if child_idx_valid[token]
22
+ child_schema_applicate(contains_schema)
23
+ else
24
+ instance_valid = instance.each_index.any? { |i| child_idx_valid[i] }
25
+
26
+ unless instance_valid
27
+ # invalid application: if contains_schema does not validate against any child, it applies to every child
28
+ child_schema_applicate(contains_schema)
29
+ end
30
+ end
31
+ end
32
+ end # if instance.respond_to?(:to_ary)
33
+ end # element.add_action(:child_applicate)
34
+
35
+ element.add_action(:validate) do
36
+ if keyword?('contains')
37
+ # An array instance is valid against "contains" if at least one of its elements is valid against
38
+ # the given schema.
39
+ if instance.respond_to?(:to_ary)
40
+ results = {}
41
+ instance.each_index do |i|
42
+ results[i] = child_subschema_validate(i, ['contains'])
43
+ end
44
+ child_results_validate(
45
+ results.each_value.any?(&:valid?),
46
+ 'validation.keyword.contains.none',
47
+ "instance array does not contain any items valid against `contains` schema",
48
+ keyword: 'contains',
49
+ child_results: results,
50
+ # when invalid these are all false, but included for consistency with `contains` with min/max
51
+ instance_indexes_valid: results.inject({}) { |h, (i, r)| h.update({i => r.valid?}) }.freeze,
52
+ )
53
+ end
54
+ end
55
+ end # element.add_action(:validate)
56
+ end # Schema::Element.new
57
+ end # CONTAINS = element_map
58
+ end # module Schema::Elements
59
+ end