json_schemer 0.2.18 → 2.1.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/.github/workflows/ci.yml +3 -7
 - data/CHANGELOG.md +69 -0
 - data/Gemfile.lock +28 -10
 - data/README.md +379 -4
 - data/bin/hostname_character_classes +42 -0
 - data/bin/rake +29 -0
 - data/exe/json_schemer +62 -0
 - data/json_schemer.gemspec +6 -12
 - data/lib/json_schemer/cached_resolver.rb +16 -0
 - data/lib/json_schemer/content.rb +18 -0
 - data/lib/json_schemer/draft201909/meta.rb +320 -0
 - data/lib/json_schemer/draft201909/vocab/applicator.rb +104 -0
 - data/lib/json_schemer/draft201909/vocab/core.rb +45 -0
 - data/lib/json_schemer/draft201909/vocab.rb +31 -0
 - data/lib/json_schemer/draft202012/meta.rb +364 -0
 - data/lib/json_schemer/draft202012/vocab/applicator.rb +382 -0
 - data/lib/json_schemer/draft202012/vocab/content.rb +52 -0
 - data/lib/json_schemer/draft202012/vocab/core.rb +160 -0
 - data/lib/json_schemer/draft202012/vocab/format_annotation.rb +23 -0
 - data/lib/json_schemer/draft202012/vocab/format_assertion.rb +23 -0
 - data/lib/json_schemer/draft202012/vocab/meta_data.rb +30 -0
 - data/lib/json_schemer/draft202012/vocab/unevaluated.rb +94 -0
 - data/lib/json_schemer/draft202012/vocab/validation.rb +286 -0
 - data/lib/json_schemer/draft202012/vocab.rb +105 -0
 - data/lib/json_schemer/draft4/meta.rb +161 -0
 - data/lib/json_schemer/draft4/vocab/validation.rb +39 -0
 - data/lib/json_schemer/draft4/vocab.rb +18 -0
 - data/lib/json_schemer/draft6/meta.rb +172 -0
 - data/lib/json_schemer/draft6/vocab.rb +16 -0
 - data/lib/json_schemer/draft7/meta.rb +183 -0
 - data/lib/json_schemer/draft7/vocab/validation.rb +69 -0
 - data/lib/json_schemer/draft7/vocab.rb +30 -0
 - data/lib/json_schemer/ecma_regexp.rb +51 -0
 - data/lib/json_schemer/errors.rb +1 -0
 - data/lib/json_schemer/format/duration.rb +23 -0
 - data/lib/json_schemer/format/email.rb +56 -0
 - data/lib/json_schemer/format/hostname.rb +58 -0
 - data/lib/json_schemer/format/json_pointer.rb +18 -0
 - data/lib/json_schemer/format/uri_template.rb +34 -0
 - data/lib/json_schemer/format.rb +129 -109
 - data/lib/json_schemer/keyword.rb +53 -0
 - data/lib/json_schemer/location.rb +25 -0
 - data/lib/json_schemer/openapi.rb +40 -0
 - data/lib/json_schemer/openapi30/document.rb +1672 -0
 - data/lib/json_schemer/openapi30/meta.rb +32 -0
 - data/lib/json_schemer/openapi30/vocab/base.rb +18 -0
 - data/lib/json_schemer/openapi30/vocab.rb +12 -0
 - data/lib/json_schemer/openapi31/document.rb +1557 -0
 - data/lib/json_schemer/openapi31/meta.rb +136 -0
 - data/lib/json_schemer/openapi31/vocab/base.rb +127 -0
 - data/lib/json_schemer/openapi31/vocab.rb +18 -0
 - data/lib/json_schemer/output.rb +56 -0
 - data/lib/json_schemer/result.rb +229 -0
 - data/lib/json_schemer/schema.rb +423 -0
 - data/lib/json_schemer/version.rb +1 -1
 - data/lib/json_schemer.rb +218 -28
 - metadata +98 -25
 - data/lib/json_schemer/cached_ref_resolver.rb +0 -14
 - data/lib/json_schemer/schema/base.rb +0 -658
 - data/lib/json_schemer/schema/draft4.rb +0 -44
 - data/lib/json_schemer/schema/draft6.rb +0 -25
 - data/lib/json_schemer/schema/draft7.rb +0 -32
 
| 
         @@ -0,0 +1,18 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            module JSONSchemer
         
     | 
| 
      
 3 
     | 
    
         
            +
              module Draft4
         
     | 
| 
      
 4 
     | 
    
         
            +
                module Vocab
         
     | 
| 
      
 5 
     | 
    
         
            +
                  ALL = Draft6::Vocab::ALL.dup
         
     | 
| 
      
 6 
     | 
    
         
            +
                  ALL.transform_keys! { |key| key == '$id' ? 'id' : key }
         
     | 
| 
      
 7 
     | 
    
         
            +
                  ALL.delete('contains')
         
     | 
| 
      
 8 
     | 
    
         
            +
                  ALL.delete('propertyNames')
         
     | 
| 
      
 9 
     | 
    
         
            +
                  ALL.delete('const')
         
     | 
| 
      
 10 
     | 
    
         
            +
                  ALL.delete('examples')
         
     | 
| 
      
 11 
     | 
    
         
            +
                  ALL.merge!(
         
     | 
| 
      
 12 
     | 
    
         
            +
                    'type' => Validation::Type,
         
     | 
| 
      
 13 
     | 
    
         
            +
                    'exclusiveMaximum' => Validation::ExclusiveMaximum,
         
     | 
| 
      
 14 
     | 
    
         
            +
                    'exclusiveMinimum' => Validation::ExclusiveMinimum
         
     | 
| 
      
 15 
     | 
    
         
            +
                  )
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,172 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            module JSONSchemer
         
     | 
| 
      
 3 
     | 
    
         
            +
              module Draft6
         
     | 
| 
      
 4 
     | 
    
         
            +
                BASE_URI = URI('http://json-schema.org/draft-06/schema#')
         
     | 
| 
      
 5 
     | 
    
         
            +
                FORMATS = Draft7::FORMATS.dup
         
     | 
| 
      
 6 
     | 
    
         
            +
                FORMATS.delete('date')
         
     | 
| 
      
 7 
     | 
    
         
            +
                FORMATS.delete('time')
         
     | 
| 
      
 8 
     | 
    
         
            +
                FORMATS.delete('idn-email')
         
     | 
| 
      
 9 
     | 
    
         
            +
                FORMATS.delete('idn-hostname')
         
     | 
| 
      
 10 
     | 
    
         
            +
                FORMATS.delete('iri')
         
     | 
| 
      
 11 
     | 
    
         
            +
                FORMATS.delete('iri-reference')
         
     | 
| 
      
 12 
     | 
    
         
            +
                FORMATS.delete('relative-json-pointer')
         
     | 
| 
      
 13 
     | 
    
         
            +
                FORMATS.delete('regex')
         
     | 
| 
      
 14 
     | 
    
         
            +
                CONTENT_ENCODINGS = Draft7::CONTENT_ENCODINGS
         
     | 
| 
      
 15 
     | 
    
         
            +
                CONTENT_MEDIA_TYPES = Draft7::CONTENT_MEDIA_TYPES
         
     | 
| 
      
 16 
     | 
    
         
            +
                SCHEMA = {
         
     | 
| 
      
 17 
     | 
    
         
            +
                  '$schema' => 'http://json-schema.org/draft-06/schema#',
         
     | 
| 
      
 18 
     | 
    
         
            +
                  '$id' => 'http://json-schema.org/draft-06/schema#',
         
     | 
| 
      
 19 
     | 
    
         
            +
                  'title' => 'Core schema meta-schema',
         
     | 
| 
      
 20 
     | 
    
         
            +
                  'definitions' => {
         
     | 
| 
      
 21 
     | 
    
         
            +
                    'schemaArray' => {
         
     | 
| 
      
 22 
     | 
    
         
            +
                      'type' => 'array',
         
     | 
| 
      
 23 
     | 
    
         
            +
                      'minItems' => 1,
         
     | 
| 
      
 24 
     | 
    
         
            +
                      'items' => { '$ref' => '#' }
         
     | 
| 
      
 25 
     | 
    
         
            +
                    },
         
     | 
| 
      
 26 
     | 
    
         
            +
                    'nonNegativeInteger' => {
         
     | 
| 
      
 27 
     | 
    
         
            +
                      'type' => 'integer',
         
     | 
| 
      
 28 
     | 
    
         
            +
                      'minimum' => 0
         
     | 
| 
      
 29 
     | 
    
         
            +
                    },
         
     | 
| 
      
 30 
     | 
    
         
            +
                    'nonNegativeIntegerDefault0' => {
         
     | 
| 
      
 31 
     | 
    
         
            +
                      'allOf' => [
         
     | 
| 
      
 32 
     | 
    
         
            +
                        { '$ref' => '#/definitions/nonNegativeInteger' },
         
     | 
| 
      
 33 
     | 
    
         
            +
                        { 'default' => 0 }
         
     | 
| 
      
 34 
     | 
    
         
            +
                      ]
         
     | 
| 
      
 35 
     | 
    
         
            +
                    },
         
     | 
| 
      
 36 
     | 
    
         
            +
                    'simpleTypes' => {
         
     | 
| 
      
 37 
     | 
    
         
            +
                      'enum' => [
         
     | 
| 
      
 38 
     | 
    
         
            +
                        'array',
         
     | 
| 
      
 39 
     | 
    
         
            +
                        'boolean',
         
     | 
| 
      
 40 
     | 
    
         
            +
                        'integer',
         
     | 
| 
      
 41 
     | 
    
         
            +
                        'null',
         
     | 
| 
      
 42 
     | 
    
         
            +
                        'number',
         
     | 
| 
      
 43 
     | 
    
         
            +
                        'object',
         
     | 
| 
      
 44 
     | 
    
         
            +
                        'string'
         
     | 
| 
      
 45 
     | 
    
         
            +
                      ]
         
     | 
| 
      
 46 
     | 
    
         
            +
                    },
         
     | 
| 
      
 47 
     | 
    
         
            +
                    'stringArray' => {
         
     | 
| 
      
 48 
     | 
    
         
            +
                      'type' => 'array',
         
     | 
| 
      
 49 
     | 
    
         
            +
                      'items' => { 'type' => 'string' },
         
     | 
| 
      
 50 
     | 
    
         
            +
                      'uniqueItems' => true,
         
     | 
| 
      
 51 
     | 
    
         
            +
                      'default' => []
         
     | 
| 
      
 52 
     | 
    
         
            +
                    }
         
     | 
| 
      
 53 
     | 
    
         
            +
                  },
         
     | 
| 
      
 54 
     | 
    
         
            +
                  'type' => ['object', 'boolean'],
         
     | 
| 
      
 55 
     | 
    
         
            +
                  'properties' => {
         
     | 
| 
      
 56 
     | 
    
         
            +
                    '$id' => {
         
     | 
| 
      
 57 
     | 
    
         
            +
                      'type' => 'string',
         
     | 
| 
      
 58 
     | 
    
         
            +
                      'format' => 'uri-reference'
         
     | 
| 
      
 59 
     | 
    
         
            +
                    },
         
     | 
| 
      
 60 
     | 
    
         
            +
                    '$schema' => {
         
     | 
| 
      
 61 
     | 
    
         
            +
                      'type' => 'string',
         
     | 
| 
      
 62 
     | 
    
         
            +
                      'format' => 'uri'
         
     | 
| 
      
 63 
     | 
    
         
            +
                    },
         
     | 
| 
      
 64 
     | 
    
         
            +
                    '$ref' => {
         
     | 
| 
      
 65 
     | 
    
         
            +
                      'type' => 'string',
         
     | 
| 
      
 66 
     | 
    
         
            +
                      'format' => 'uri-reference'
         
     | 
| 
      
 67 
     | 
    
         
            +
                    },
         
     | 
| 
      
 68 
     | 
    
         
            +
                    'title' => {
         
     | 
| 
      
 69 
     | 
    
         
            +
                      'type' => 'string'
         
     | 
| 
      
 70 
     | 
    
         
            +
                    },
         
     | 
| 
      
 71 
     | 
    
         
            +
                    'description' => {
         
     | 
| 
      
 72 
     | 
    
         
            +
                      'type' => 'string'
         
     | 
| 
      
 73 
     | 
    
         
            +
                    },
         
     | 
| 
      
 74 
     | 
    
         
            +
                    'default' => {},
         
     | 
| 
      
 75 
     | 
    
         
            +
                    'examples' => {
         
     | 
| 
      
 76 
     | 
    
         
            +
                      'type' => 'array',
         
     | 
| 
      
 77 
     | 
    
         
            +
                      'items' => {}
         
     | 
| 
      
 78 
     | 
    
         
            +
                    },
         
     | 
| 
      
 79 
     | 
    
         
            +
                    'multipleOf' => {
         
     | 
| 
      
 80 
     | 
    
         
            +
                      'type' => 'number',
         
     | 
| 
      
 81 
     | 
    
         
            +
                      'exclusiveMinimum' => 0
         
     | 
| 
      
 82 
     | 
    
         
            +
                    },
         
     | 
| 
      
 83 
     | 
    
         
            +
                    'maximum' => {
         
     | 
| 
      
 84 
     | 
    
         
            +
                      'type' => 'number'
         
     | 
| 
      
 85 
     | 
    
         
            +
                    },
         
     | 
| 
      
 86 
     | 
    
         
            +
                    'exclusiveMaximum' => {
         
     | 
| 
      
 87 
     | 
    
         
            +
                      'type' => 'number'
         
     | 
| 
      
 88 
     | 
    
         
            +
                    },
         
     | 
| 
      
 89 
     | 
    
         
            +
                    'minimum' => {
         
     | 
| 
      
 90 
     | 
    
         
            +
                      'type' => 'number'
         
     | 
| 
      
 91 
     | 
    
         
            +
                    },
         
     | 
| 
      
 92 
     | 
    
         
            +
                    'exclusiveMinimum' => {
         
     | 
| 
      
 93 
     | 
    
         
            +
                      'type' => 'number'
         
     | 
| 
      
 94 
     | 
    
         
            +
                    },
         
     | 
| 
      
 95 
     | 
    
         
            +
                    'maxLength' => { '$ref' => '#/definitions/nonNegativeInteger' },
         
     | 
| 
      
 96 
     | 
    
         
            +
                    'minLength' => { '$ref' => '#/definitions/nonNegativeIntegerDefault0' },
         
     | 
| 
      
 97 
     | 
    
         
            +
                    'pattern' => {
         
     | 
| 
      
 98 
     | 
    
         
            +
                      'type' => 'string',
         
     | 
| 
      
 99 
     | 
    
         
            +
                      'format' => 'regex'
         
     | 
| 
      
 100 
     | 
    
         
            +
                    },
         
     | 
| 
      
 101 
     | 
    
         
            +
                    'additionalItems' => { '$ref' => '#' },
         
     | 
| 
      
 102 
     | 
    
         
            +
                    'items' => {
         
     | 
| 
      
 103 
     | 
    
         
            +
                      'anyOf' => [
         
     | 
| 
      
 104 
     | 
    
         
            +
                        { '$ref' => '#' },
         
     | 
| 
      
 105 
     | 
    
         
            +
                        { '$ref' => '#/definitions/schemaArray' }
         
     | 
| 
      
 106 
     | 
    
         
            +
                      ],
         
     | 
| 
      
 107 
     | 
    
         
            +
                      'default' => {}
         
     | 
| 
      
 108 
     | 
    
         
            +
                    },
         
     | 
| 
      
 109 
     | 
    
         
            +
                    'maxItems' => { '$ref' => '#/definitions/nonNegativeInteger' },
         
     | 
| 
      
 110 
     | 
    
         
            +
                    'minItems' => { '$ref' => '#/definitions/nonNegativeIntegerDefault0' },
         
     | 
| 
      
 111 
     | 
    
         
            +
                    'uniqueItems' => {
         
     | 
| 
      
 112 
     | 
    
         
            +
                      'type' => 'boolean',
         
     | 
| 
      
 113 
     | 
    
         
            +
                      'default' => false
         
     | 
| 
      
 114 
     | 
    
         
            +
                    },
         
     | 
| 
      
 115 
     | 
    
         
            +
                    'contains' => { '$ref' => '#' },
         
     | 
| 
      
 116 
     | 
    
         
            +
                    'maxProperties' => { '$ref' => '#/definitions/nonNegativeInteger' },
         
     | 
| 
      
 117 
     | 
    
         
            +
                    'minProperties' => { '$ref' => '#/definitions/nonNegativeIntegerDefault0' },
         
     | 
| 
      
 118 
     | 
    
         
            +
                    'required' => { '$ref' => '#/definitions/stringArray' },
         
     | 
| 
      
 119 
     | 
    
         
            +
                    'additionalProperties' => { '$ref' => '#' },
         
     | 
| 
      
 120 
     | 
    
         
            +
                    'definitions' => {
         
     | 
| 
      
 121 
     | 
    
         
            +
                      'type' => 'object',
         
     | 
| 
      
 122 
     | 
    
         
            +
                      'additionalProperties' => { '$ref' => '#' },
         
     | 
| 
      
 123 
     | 
    
         
            +
                      'default' => {}
         
     | 
| 
      
 124 
     | 
    
         
            +
                    },
         
     | 
| 
      
 125 
     | 
    
         
            +
                    'properties' => {
         
     | 
| 
      
 126 
     | 
    
         
            +
                      'type' => 'object',
         
     | 
| 
      
 127 
     | 
    
         
            +
                      'additionalProperties' => { '$ref' => '#' },
         
     | 
| 
      
 128 
     | 
    
         
            +
                      'default' => {}
         
     | 
| 
      
 129 
     | 
    
         
            +
                    },
         
     | 
| 
      
 130 
     | 
    
         
            +
                    'patternProperties' => {
         
     | 
| 
      
 131 
     | 
    
         
            +
                      'type' => 'object',
         
     | 
| 
      
 132 
     | 
    
         
            +
                      'additionalProperties' => { '$ref' => '#' },
         
     | 
| 
      
 133 
     | 
    
         
            +
                      'propertyNames' => { 'format' => 'regex' },
         
     | 
| 
      
 134 
     | 
    
         
            +
                      'default' => {}
         
     | 
| 
      
 135 
     | 
    
         
            +
                    },
         
     | 
| 
      
 136 
     | 
    
         
            +
                    'dependencies' => {
         
     | 
| 
      
 137 
     | 
    
         
            +
                      'type' => 'object',
         
     | 
| 
      
 138 
     | 
    
         
            +
                      'additionalProperties' => {
         
     | 
| 
      
 139 
     | 
    
         
            +
                        'anyOf' => [
         
     | 
| 
      
 140 
     | 
    
         
            +
                          { '$ref' => '#' },
         
     | 
| 
      
 141 
     | 
    
         
            +
                          { '$ref' => '#/definitions/stringArray' }
         
     | 
| 
      
 142 
     | 
    
         
            +
                        ]
         
     | 
| 
      
 143 
     | 
    
         
            +
                      }
         
     | 
| 
      
 144 
     | 
    
         
            +
                    },
         
     | 
| 
      
 145 
     | 
    
         
            +
                    'propertyNames' => { '$ref' => '#' },
         
     | 
| 
      
 146 
     | 
    
         
            +
                    'const' => {},
         
     | 
| 
      
 147 
     | 
    
         
            +
                    'enum' => {
         
     | 
| 
      
 148 
     | 
    
         
            +
                      'type' => 'array',
         
     | 
| 
      
 149 
     | 
    
         
            +
                      'minItems' => 1,
         
     | 
| 
      
 150 
     | 
    
         
            +
                      'uniqueItems' => true
         
     | 
| 
      
 151 
     | 
    
         
            +
                    },
         
     | 
| 
      
 152 
     | 
    
         
            +
                    'type' => {
         
     | 
| 
      
 153 
     | 
    
         
            +
                      'anyOf' => [
         
     | 
| 
      
 154 
     | 
    
         
            +
                        { '$ref' => '#/definitions/simpleTypes' },
         
     | 
| 
      
 155 
     | 
    
         
            +
                        {
         
     | 
| 
      
 156 
     | 
    
         
            +
                          'type' => 'array',
         
     | 
| 
      
 157 
     | 
    
         
            +
                          'items' => { '$ref' => '#/definitions/simpleTypes' },
         
     | 
| 
      
 158 
     | 
    
         
            +
                          'minItems' => 1,
         
     | 
| 
      
 159 
     | 
    
         
            +
                          'uniqueItems' => true
         
     | 
| 
      
 160 
     | 
    
         
            +
                        }
         
     | 
| 
      
 161 
     | 
    
         
            +
                      ]
         
     | 
| 
      
 162 
     | 
    
         
            +
                    },
         
     | 
| 
      
 163 
     | 
    
         
            +
                    'format' => { 'type' => 'string' },
         
     | 
| 
      
 164 
     | 
    
         
            +
                    'allOf' => { '$ref' => '#/definitions/schemaArray' },
         
     | 
| 
      
 165 
     | 
    
         
            +
                    'anyOf' => { '$ref' => '#/definitions/schemaArray' },
         
     | 
| 
      
 166 
     | 
    
         
            +
                    'oneOf' => { '$ref' => '#/definitions/schemaArray' },
         
     | 
| 
      
 167 
     | 
    
         
            +
                    'not' => { '$ref' => '#' }
         
     | 
| 
      
 168 
     | 
    
         
            +
                  },
         
     | 
| 
      
 169 
     | 
    
         
            +
                  'default' => {}
         
     | 
| 
      
 170 
     | 
    
         
            +
                }
         
     | 
| 
      
 171 
     | 
    
         
            +
              end
         
     | 
| 
      
 172 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,16 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            module JSONSchemer
         
     | 
| 
      
 3 
     | 
    
         
            +
              module Draft6
         
     | 
| 
      
 4 
     | 
    
         
            +
                module Vocab
         
     | 
| 
      
 5 
     | 
    
         
            +
                  ALL = Draft7::Vocab::ALL.dup
         
     | 
| 
      
 6 
     | 
    
         
            +
                  ALL.delete('$comment')
         
     | 
| 
      
 7 
     | 
    
         
            +
                  ALL.delete('if')
         
     | 
| 
      
 8 
     | 
    
         
            +
                  ALL.delete('then')
         
     | 
| 
      
 9 
     | 
    
         
            +
                  ALL.delete('else')
         
     | 
| 
      
 10 
     | 
    
         
            +
                  ALL.delete('readOnly')
         
     | 
| 
      
 11 
     | 
    
         
            +
                  ALL.delete('writeOnly')
         
     | 
| 
      
 12 
     | 
    
         
            +
                  ALL.delete('contentMediaType')
         
     | 
| 
      
 13 
     | 
    
         
            +
                  ALL.delete('contentEncoding')
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,183 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            module JSONSchemer
         
     | 
| 
      
 3 
     | 
    
         
            +
              module Draft7
         
     | 
| 
      
 4 
     | 
    
         
            +
                BASE_URI = URI('http://json-schema.org/draft-07/schema#')
         
     | 
| 
      
 5 
     | 
    
         
            +
                FORMATS = Draft201909::FORMATS.dup
         
     | 
| 
      
 6 
     | 
    
         
            +
                FORMATS.delete('duration')
         
     | 
| 
      
 7 
     | 
    
         
            +
                FORMATS.delete('uuid')
         
     | 
| 
      
 8 
     | 
    
         
            +
                CONTENT_ENCODINGS = Draft201909::CONTENT_ENCODINGS
         
     | 
| 
      
 9 
     | 
    
         
            +
                CONTENT_MEDIA_TYPES = Draft201909::CONTENT_MEDIA_TYPES
         
     | 
| 
      
 10 
     | 
    
         
            +
                SCHEMA = {
         
     | 
| 
      
 11 
     | 
    
         
            +
                  '$schema' => 'http://json-schema.org/draft-07/schema#',
         
     | 
| 
      
 12 
     | 
    
         
            +
                  '$id' => 'http://json-schema.org/draft-07/schema#',
         
     | 
| 
      
 13 
     | 
    
         
            +
                  'title' => 'Core schema meta-schema',
         
     | 
| 
      
 14 
     | 
    
         
            +
                  'definitions' => {
         
     | 
| 
      
 15 
     | 
    
         
            +
                    'schemaArray' => {
         
     | 
| 
      
 16 
     | 
    
         
            +
                      'type' => 'array',
         
     | 
| 
      
 17 
     | 
    
         
            +
                      'minItems' => 1,
         
     | 
| 
      
 18 
     | 
    
         
            +
                      'items' => { '$ref' => '#' }
         
     | 
| 
      
 19 
     | 
    
         
            +
                    },
         
     | 
| 
      
 20 
     | 
    
         
            +
                    'nonNegativeInteger' => {
         
     | 
| 
      
 21 
     | 
    
         
            +
                      'type' => 'integer',
         
     | 
| 
      
 22 
     | 
    
         
            +
                      'minimum' => 0
         
     | 
| 
      
 23 
     | 
    
         
            +
                    },
         
     | 
| 
      
 24 
     | 
    
         
            +
                    'nonNegativeIntegerDefault0' => {
         
     | 
| 
      
 25 
     | 
    
         
            +
                      'allOf' => [
         
     | 
| 
      
 26 
     | 
    
         
            +
                        { '$ref' => '#/definitions/nonNegativeInteger' },
         
     | 
| 
      
 27 
     | 
    
         
            +
                        { 'default' => 0 }
         
     | 
| 
      
 28 
     | 
    
         
            +
                      ]
         
     | 
| 
      
 29 
     | 
    
         
            +
                    },
         
     | 
| 
      
 30 
     | 
    
         
            +
                    'simpleTypes' => {
         
     | 
| 
      
 31 
     | 
    
         
            +
                      'enum' => [
         
     | 
| 
      
 32 
     | 
    
         
            +
                        'array',
         
     | 
| 
      
 33 
     | 
    
         
            +
                        'boolean',
         
     | 
| 
      
 34 
     | 
    
         
            +
                        'integer',
         
     | 
| 
      
 35 
     | 
    
         
            +
                        'null',
         
     | 
| 
      
 36 
     | 
    
         
            +
                        'number',
         
     | 
| 
      
 37 
     | 
    
         
            +
                        'object',
         
     | 
| 
      
 38 
     | 
    
         
            +
                        'string'
         
     | 
| 
      
 39 
     | 
    
         
            +
                      ]
         
     | 
| 
      
 40 
     | 
    
         
            +
                    },
         
     | 
| 
      
 41 
     | 
    
         
            +
                    'stringArray' => {
         
     | 
| 
      
 42 
     | 
    
         
            +
                      'type' => 'array',
         
     | 
| 
      
 43 
     | 
    
         
            +
                      'items' => { 'type' => 'string' },
         
     | 
| 
      
 44 
     | 
    
         
            +
                      'uniqueItems' => true,
         
     | 
| 
      
 45 
     | 
    
         
            +
                      'default' => []
         
     | 
| 
      
 46 
     | 
    
         
            +
                    }
         
     | 
| 
      
 47 
     | 
    
         
            +
                  },
         
     | 
| 
      
 48 
     | 
    
         
            +
                  'type' => ['object', 'boolean'],
         
     | 
| 
      
 49 
     | 
    
         
            +
                  'properties' => {
         
     | 
| 
      
 50 
     | 
    
         
            +
                    '$id' => {
         
     | 
| 
      
 51 
     | 
    
         
            +
                      'type' => 'string',
         
     | 
| 
      
 52 
     | 
    
         
            +
                      'format' => 'uri-reference'
         
     | 
| 
      
 53 
     | 
    
         
            +
                    },
         
     | 
| 
      
 54 
     | 
    
         
            +
                    '$schema' => {
         
     | 
| 
      
 55 
     | 
    
         
            +
                      'type' => 'string',
         
     | 
| 
      
 56 
     | 
    
         
            +
                      'format' => 'uri'
         
     | 
| 
      
 57 
     | 
    
         
            +
                    },
         
     | 
| 
      
 58 
     | 
    
         
            +
                    '$ref' => {
         
     | 
| 
      
 59 
     | 
    
         
            +
                      'type' => 'string',
         
     | 
| 
      
 60 
     | 
    
         
            +
                      'format' => 'uri-reference'
         
     | 
| 
      
 61 
     | 
    
         
            +
                    },
         
     | 
| 
      
 62 
     | 
    
         
            +
                    '$comment' => {
         
     | 
| 
      
 63 
     | 
    
         
            +
                      'type' => 'string'
         
     | 
| 
      
 64 
     | 
    
         
            +
                    },
         
     | 
| 
      
 65 
     | 
    
         
            +
                    'title' => {
         
     | 
| 
      
 66 
     | 
    
         
            +
                      'type' => 'string'
         
     | 
| 
      
 67 
     | 
    
         
            +
                    },
         
     | 
| 
      
 68 
     | 
    
         
            +
                    'description' => {
         
     | 
| 
      
 69 
     | 
    
         
            +
                      'type' => 'string'
         
     | 
| 
      
 70 
     | 
    
         
            +
                    },
         
     | 
| 
      
 71 
     | 
    
         
            +
                    'default' => true,
         
     | 
| 
      
 72 
     | 
    
         
            +
                    'readOnly' => {
         
     | 
| 
      
 73 
     | 
    
         
            +
                      'type' => 'boolean',
         
     | 
| 
      
 74 
     | 
    
         
            +
                      'default' => false
         
     | 
| 
      
 75 
     | 
    
         
            +
                    },
         
     | 
| 
      
 76 
     | 
    
         
            +
                    'writeOnly' => {
         
     | 
| 
      
 77 
     | 
    
         
            +
                      'type' => 'boolean',
         
     | 
| 
      
 78 
     | 
    
         
            +
                      'default' => false
         
     | 
| 
      
 79 
     | 
    
         
            +
                    },
         
     | 
| 
      
 80 
     | 
    
         
            +
                    'examples' => {
         
     | 
| 
      
 81 
     | 
    
         
            +
                      'type' => 'array',
         
     | 
| 
      
 82 
     | 
    
         
            +
                      'items' => true
         
     | 
| 
      
 83 
     | 
    
         
            +
                    },
         
     | 
| 
      
 84 
     | 
    
         
            +
                    'multipleOf' => {
         
     | 
| 
      
 85 
     | 
    
         
            +
                      'type' => 'number',
         
     | 
| 
      
 86 
     | 
    
         
            +
                      'exclusiveMinimum' => 0
         
     | 
| 
      
 87 
     | 
    
         
            +
                    },
         
     | 
| 
      
 88 
     | 
    
         
            +
                    'maximum' => {
         
     | 
| 
      
 89 
     | 
    
         
            +
                      'type' => 'number'
         
     | 
| 
      
 90 
     | 
    
         
            +
                    },
         
     | 
| 
      
 91 
     | 
    
         
            +
                    'exclusiveMaximum' => {
         
     | 
| 
      
 92 
     | 
    
         
            +
                      'type' => 'number'
         
     | 
| 
      
 93 
     | 
    
         
            +
                    },
         
     | 
| 
      
 94 
     | 
    
         
            +
                    'minimum' => {
         
     | 
| 
      
 95 
     | 
    
         
            +
                      'type' => 'number'
         
     | 
| 
      
 96 
     | 
    
         
            +
                    },
         
     | 
| 
      
 97 
     | 
    
         
            +
                    'exclusiveMinimum' => {
         
     | 
| 
      
 98 
     | 
    
         
            +
                      'type' => 'number'
         
     | 
| 
      
 99 
     | 
    
         
            +
                    },
         
     | 
| 
      
 100 
     | 
    
         
            +
                    'maxLength' => { '$ref' => '#/definitions/nonNegativeInteger' },
         
     | 
| 
      
 101 
     | 
    
         
            +
                    'minLength' => { '$ref' => '#/definitions/nonNegativeIntegerDefault0' },
         
     | 
| 
      
 102 
     | 
    
         
            +
                    'pattern' => {
         
     | 
| 
      
 103 
     | 
    
         
            +
                      'type' => 'string',
         
     | 
| 
      
 104 
     | 
    
         
            +
                      'format' => 'regex'
         
     | 
| 
      
 105 
     | 
    
         
            +
                    },
         
     | 
| 
      
 106 
     | 
    
         
            +
                    'additionalItems' => { '$ref' => '#' },
         
     | 
| 
      
 107 
     | 
    
         
            +
                    'items' => {
         
     | 
| 
      
 108 
     | 
    
         
            +
                      'anyOf' => [
         
     | 
| 
      
 109 
     | 
    
         
            +
                        { '$ref' => '#' },
         
     | 
| 
      
 110 
     | 
    
         
            +
                        { '$ref' => '#/definitions/schemaArray' }
         
     | 
| 
      
 111 
     | 
    
         
            +
                      ],
         
     | 
| 
      
 112 
     | 
    
         
            +
                      'default' => true
         
     | 
| 
      
 113 
     | 
    
         
            +
                    },
         
     | 
| 
      
 114 
     | 
    
         
            +
                    'maxItems' => { '$ref' => '#/definitions/nonNegativeInteger' },
         
     | 
| 
      
 115 
     | 
    
         
            +
                    'minItems' => { '$ref' => '#/definitions/nonNegativeIntegerDefault0' },
         
     | 
| 
      
 116 
     | 
    
         
            +
                    'uniqueItems' => {
         
     | 
| 
      
 117 
     | 
    
         
            +
                      'type' => 'boolean',
         
     | 
| 
      
 118 
     | 
    
         
            +
                      'default' => false
         
     | 
| 
      
 119 
     | 
    
         
            +
                    },
         
     | 
| 
      
 120 
     | 
    
         
            +
                    'contains' => { '$ref' => '#' },
         
     | 
| 
      
 121 
     | 
    
         
            +
                    'maxProperties' => { '$ref' => '#/definitions/nonNegativeInteger' },
         
     | 
| 
      
 122 
     | 
    
         
            +
                    'minProperties' => { '$ref' => '#/definitions/nonNegativeIntegerDefault0' },
         
     | 
| 
      
 123 
     | 
    
         
            +
                    'required' => { '$ref' => '#/definitions/stringArray' },
         
     | 
| 
      
 124 
     | 
    
         
            +
                    'additionalProperties' => { '$ref' => '#' },
         
     | 
| 
      
 125 
     | 
    
         
            +
                    'definitions' => {
         
     | 
| 
      
 126 
     | 
    
         
            +
                      'type' => 'object',
         
     | 
| 
      
 127 
     | 
    
         
            +
                      'additionalProperties' => { '$ref' => '#' },
         
     | 
| 
      
 128 
     | 
    
         
            +
                      'default' => {}
         
     | 
| 
      
 129 
     | 
    
         
            +
                    },
         
     | 
| 
      
 130 
     | 
    
         
            +
                    'properties' => {
         
     | 
| 
      
 131 
     | 
    
         
            +
                      'type' => 'object',
         
     | 
| 
      
 132 
     | 
    
         
            +
                      'additionalProperties' => { '$ref' => '#' },
         
     | 
| 
      
 133 
     | 
    
         
            +
                      'default' => {}
         
     | 
| 
      
 134 
     | 
    
         
            +
                    },
         
     | 
| 
      
 135 
     | 
    
         
            +
                    'patternProperties' => {
         
     | 
| 
      
 136 
     | 
    
         
            +
                      'type' => 'object',
         
     | 
| 
      
 137 
     | 
    
         
            +
                      'additionalProperties' => { '$ref' => '#' },
         
     | 
| 
      
 138 
     | 
    
         
            +
                      'propertyNames' => { 'format' => 'regex' },
         
     | 
| 
      
 139 
     | 
    
         
            +
                      'default' => {}
         
     | 
| 
      
 140 
     | 
    
         
            +
                    },
         
     | 
| 
      
 141 
     | 
    
         
            +
                    'dependencies' => {
         
     | 
| 
      
 142 
     | 
    
         
            +
                      'type' => 'object',
         
     | 
| 
      
 143 
     | 
    
         
            +
                      'additionalProperties' => {
         
     | 
| 
      
 144 
     | 
    
         
            +
                        'anyOf' => [
         
     | 
| 
      
 145 
     | 
    
         
            +
                          { '$ref' => '#' },
         
     | 
| 
      
 146 
     | 
    
         
            +
                          { '$ref' => '#/definitions/stringArray' }
         
     | 
| 
      
 147 
     | 
    
         
            +
                        ]
         
     | 
| 
      
 148 
     | 
    
         
            +
                      }
         
     | 
| 
      
 149 
     | 
    
         
            +
                    },
         
     | 
| 
      
 150 
     | 
    
         
            +
                    'propertyNames' => { '$ref' => '#' },
         
     | 
| 
      
 151 
     | 
    
         
            +
                    'const' => true,
         
     | 
| 
      
 152 
     | 
    
         
            +
                    'enum' => {
         
     | 
| 
      
 153 
     | 
    
         
            +
                      'type' => 'array',
         
     | 
| 
      
 154 
     | 
    
         
            +
                      'items' => true,
         
     | 
| 
      
 155 
     | 
    
         
            +
                      'minItems' => 1,
         
     | 
| 
      
 156 
     | 
    
         
            +
                      'uniqueItems' => true
         
     | 
| 
      
 157 
     | 
    
         
            +
                    },
         
     | 
| 
      
 158 
     | 
    
         
            +
                    'type' => {
         
     | 
| 
      
 159 
     | 
    
         
            +
                      'anyOf' => [
         
     | 
| 
      
 160 
     | 
    
         
            +
                        { '$ref' => '#/definitions/simpleTypes' },
         
     | 
| 
      
 161 
     | 
    
         
            +
                        {
         
     | 
| 
      
 162 
     | 
    
         
            +
                          'type' => 'array',
         
     | 
| 
      
 163 
     | 
    
         
            +
                          'items' => { '$ref' => '#/definitions/simpleTypes' },
         
     | 
| 
      
 164 
     | 
    
         
            +
                          'minItems' => 1,
         
     | 
| 
      
 165 
     | 
    
         
            +
                          'uniqueItems' => true
         
     | 
| 
      
 166 
     | 
    
         
            +
                        }
         
     | 
| 
      
 167 
     | 
    
         
            +
                      ]
         
     | 
| 
      
 168 
     | 
    
         
            +
                    },
         
     | 
| 
      
 169 
     | 
    
         
            +
                    'format' => { 'type' => 'string' },
         
     | 
| 
      
 170 
     | 
    
         
            +
                    'contentMediaType' => { 'type' => 'string' },
         
     | 
| 
      
 171 
     | 
    
         
            +
                    'contentEncoding' => { 'type' => 'string' },
         
     | 
| 
      
 172 
     | 
    
         
            +
                    'if' => { '$ref' => '#' },
         
     | 
| 
      
 173 
     | 
    
         
            +
                    'then' => { '$ref' => '#' },
         
     | 
| 
      
 174 
     | 
    
         
            +
                    'else' => { '$ref' => '#' },
         
     | 
| 
      
 175 
     | 
    
         
            +
                    'allOf' => { '$ref' => '#/definitions/schemaArray' },
         
     | 
| 
      
 176 
     | 
    
         
            +
                    'anyOf' => { '$ref' => '#/definitions/schemaArray' },
         
     | 
| 
      
 177 
     | 
    
         
            +
                    'oneOf' => { '$ref' => '#/definitions/schemaArray' },
         
     | 
| 
      
 178 
     | 
    
         
            +
                    'not' => { '$ref' => '#' }
         
     | 
| 
      
 179 
     | 
    
         
            +
                  },
         
     | 
| 
      
 180 
     | 
    
         
            +
                  'default' => true
         
     | 
| 
      
 181 
     | 
    
         
            +
                }
         
     | 
| 
      
 182 
     | 
    
         
            +
              end
         
     | 
| 
      
 183 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,69 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            module JSONSchemer
         
     | 
| 
      
 3 
     | 
    
         
            +
              module Draft7
         
     | 
| 
      
 4 
     | 
    
         
            +
                module Vocab
         
     | 
| 
      
 5 
     | 
    
         
            +
                  module Validation
         
     | 
| 
      
 6 
     | 
    
         
            +
                    class Ref < Draft202012::Vocab::Core::Ref
         
     | 
| 
      
 7 
     | 
    
         
            +
                      def self.exclusive?
         
     | 
| 
      
 8 
     | 
    
         
            +
                        true
         
     | 
| 
      
 9 
     | 
    
         
            +
                      end
         
     | 
| 
      
 10 
     | 
    
         
            +
                    end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                    class AdditionalItems < Keyword
         
     | 
| 
      
 13 
     | 
    
         
            +
                      def error(formatted_instance_location:, **)
         
     | 
| 
      
 14 
     | 
    
         
            +
                        "array items at #{formatted_instance_location} do not match `additionalItems` schema"
         
     | 
| 
      
 15 
     | 
    
         
            +
                      end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                      def parse
         
     | 
| 
      
 18 
     | 
    
         
            +
                        subschema(value)
         
     | 
| 
      
 19 
     | 
    
         
            +
                      end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                      def validate(instance, instance_location, keyword_location, context)
         
     | 
| 
      
 22 
     | 
    
         
            +
                        items = schema.parsed['items']&.parsed
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                        if !instance.is_a?(Array) || !items.is_a?(Array) || items.size >= instance.size
         
     | 
| 
      
 25 
     | 
    
         
            +
                          return result(instance, instance_location, keyword_location, true)
         
     | 
| 
      
 26 
     | 
    
         
            +
                        end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                        offset = items.size
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                        nested = instance.slice(offset..-1).map.with_index do |item, index|
         
     | 
| 
      
 31 
     | 
    
         
            +
                          parsed.validate_instance(item, join_location(instance_location, (offset + index).to_s), keyword_location, context)
         
     | 
| 
      
 32 
     | 
    
         
            +
                        end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                        result(instance, instance_location, keyword_location, nested.all?(&:valid), nested, :annotation => nested.any?)
         
     | 
| 
      
 35 
     | 
    
         
            +
                      end
         
     | 
| 
      
 36 
     | 
    
         
            +
                    end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                    class ContentEncoding < Draft202012::Vocab::Content::ContentEncoding
         
     | 
| 
      
 39 
     | 
    
         
            +
                      def error(formatted_instance_location:, **)
         
     | 
| 
      
 40 
     | 
    
         
            +
                        "string at #{formatted_instance_location} could not be decoded using encoding: #{value}"
         
     | 
| 
      
 41 
     | 
    
         
            +
                      end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                      def validate(instance, instance_location, keyword_location, _context)
         
     | 
| 
      
 44 
     | 
    
         
            +
                        return result(instance, instance_location, keyword_location, true) unless instance.is_a?(String)
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                        valid, annotation = parsed.call(instance)
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                        result(instance, instance_location, keyword_location, valid, :annotation => annotation)
         
     | 
| 
      
 49 
     | 
    
         
            +
                      end
         
     | 
| 
      
 50 
     | 
    
         
            +
                    end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                    class ContentMediaType < Draft202012::Vocab::Content::ContentMediaType
         
     | 
| 
      
 53 
     | 
    
         
            +
                      def error(formatted_instance_location:, **)
         
     | 
| 
      
 54 
     | 
    
         
            +
                        "string at #{formatted_instance_location} could not be parsed using media type: #{value}"
         
     | 
| 
      
 55 
     | 
    
         
            +
                      end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                      def validate(instance, instance_location, keyword_location, context)
         
     | 
| 
      
 58 
     | 
    
         
            +
                        return result(instance, instance_location, keyword_location, true) unless instance.is_a?(String)
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                        decoded_instance = context.adjacent_results[ContentEncoding]&.annotation || instance
         
     | 
| 
      
 61 
     | 
    
         
            +
                        valid, annotation = parsed.call(decoded_instance)
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                        result(instance, instance_location, keyword_location, valid, :annotation => annotation)
         
     | 
| 
      
 64 
     | 
    
         
            +
                      end
         
     | 
| 
      
 65 
     | 
    
         
            +
                    end
         
     | 
| 
      
 66 
     | 
    
         
            +
                  end
         
     | 
| 
      
 67 
     | 
    
         
            +
                end
         
     | 
| 
      
 68 
     | 
    
         
            +
              end
         
     | 
| 
      
 69 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            module JSONSchemer
         
     | 
| 
      
 3 
     | 
    
         
            +
              module Draft7
         
     | 
| 
      
 4 
     | 
    
         
            +
                module Vocab
         
     | 
| 
      
 5 
     | 
    
         
            +
                  ALL = Draft201909::Vocab::CORE.dup
         
     | 
| 
      
 6 
     | 
    
         
            +
                  ALL.delete('$recursiveAnchor')
         
     | 
| 
      
 7 
     | 
    
         
            +
                  ALL.delete('$recursiveRef')
         
     | 
| 
      
 8 
     | 
    
         
            +
                  ALL.delete('$vocabulary')
         
     | 
| 
      
 9 
     | 
    
         
            +
                  ALL.delete('$anchor')
         
     | 
| 
      
 10 
     | 
    
         
            +
                  ALL.delete('$defs')
         
     | 
| 
      
 11 
     | 
    
         
            +
                  ALL.merge!(Draft201909::Vocab::APPLICATOR)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  ALL.delete('dependentSchemas')
         
     | 
| 
      
 13 
     | 
    
         
            +
                  ALL.delete('unevaluatedItems')
         
     | 
| 
      
 14 
     | 
    
         
            +
                  ALL.delete('unevaluatedProperties')
         
     | 
| 
      
 15 
     | 
    
         
            +
                  ALL.merge!(Draft201909::Vocab::VALIDATION)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  ALL.delete('dependentRequired')
         
     | 
| 
      
 17 
     | 
    
         
            +
                  ALL.delete('maxContains')
         
     | 
| 
      
 18 
     | 
    
         
            +
                  ALL.delete('minContains')
         
     | 
| 
      
 19 
     | 
    
         
            +
                  ALL.merge!(Draft202012::Vocab::FORMAT_ANNOTATION)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  ALL.merge!(Draft201909::Vocab::META_DATA)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  ALL.delete('deprecated')
         
     | 
| 
      
 22 
     | 
    
         
            +
                  ALL.merge!(
         
     | 
| 
      
 23 
     | 
    
         
            +
                    '$ref' => Validation::Ref,
         
     | 
| 
      
 24 
     | 
    
         
            +
                    'additionalItems' => Validation::AdditionalItems,
         
     | 
| 
      
 25 
     | 
    
         
            +
                    'contentEncoding' => Validation::ContentEncoding,
         
     | 
| 
      
 26 
     | 
    
         
            +
                    'contentMediaType' => Validation::ContentMediaType
         
     | 
| 
      
 27 
     | 
    
         
            +
                  )
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,51 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            module JSONSchemer
         
     | 
| 
      
 3 
     | 
    
         
            +
              class EcmaRegexp
         
     | 
| 
      
 4 
     | 
    
         
            +
                class Syntax < Regexp::Syntax::Base
         
     | 
| 
      
 5 
     | 
    
         
            +
                  # regexp_parser >= 2.3.0 uses syntax classes directly instead of instances
         
     | 
| 
      
 6 
     | 
    
         
            +
                  # :nocov:
         
     | 
| 
      
 7 
     | 
    
         
            +
                  SYNTAX = respond_to?(:implements) ? self : new
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # :nocov:
         
     | 
| 
      
 9 
     | 
    
         
            +
                  SYNTAX.implements :anchor, Anchor::Extended
         
     | 
| 
      
 10 
     | 
    
         
            +
                  SYNTAX.implements :assertion, Assertion::All
         
     | 
| 
      
 11 
     | 
    
         
            +
                  # literal %i[number] to support regexp_parser < 2.2.0 (Backreference::Plain)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  SYNTAX.implements :backref, %i[number] + Backreference::Name
         
     | 
| 
      
 13 
     | 
    
         
            +
                  # :meta_sequence, :bell, and :escape are not supported in ecma
         
     | 
| 
      
 14 
     | 
    
         
            +
                  SYNTAX.implements :escape, Escape::Basic + (Escape::Control - %i[meta_sequence]) + (Escape::ASCII - %i[bell escape]) + Escape::Unicode + Escape::Meta + Escape::Hex + Escape::Octal
         
     | 
| 
      
 15 
     | 
    
         
            +
                  SYNTAX.implements :property, UnicodeProperty::All
         
     | 
| 
      
 16 
     | 
    
         
            +
                  SYNTAX.implements :nonproperty, UnicodeProperty::All
         
     | 
| 
      
 17 
     | 
    
         
            +
                  # :comment is not supported in ecma
         
     | 
| 
      
 18 
     | 
    
         
            +
                  SYNTAX.implements :free_space, (FreeSpace::All - %i[comment])
         
     | 
| 
      
 19 
     | 
    
         
            +
                  SYNTAX.implements :group, Group::Basic + Group::Named + Group::Passive
         
     | 
| 
      
 20 
     | 
    
         
            +
                  SYNTAX.implements :literal, Literal::All
         
     | 
| 
      
 21 
     | 
    
         
            +
                  SYNTAX.implements :meta, Meta::Extended
         
     | 
| 
      
 22 
     | 
    
         
            +
                  SYNTAX.implements :quantifier, Quantifier::Greedy + Quantifier::Reluctant + Quantifier::Interval + Quantifier::IntervalReluctant
         
     | 
| 
      
 23 
     | 
    
         
            +
                  SYNTAX.implements :set, CharacterSet::Basic
         
     | 
| 
      
 24 
     | 
    
         
            +
                  SYNTAX.implements :type, CharacterType::Extended
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                RUBY_EQUIVALENTS = {
         
     | 
| 
      
 28 
     | 
    
         
            +
                  :anchor => {
         
     | 
| 
      
 29 
     | 
    
         
            +
                    :bol => '\A',
         
     | 
| 
      
 30 
     | 
    
         
            +
                    :eol => '\z'
         
     | 
| 
      
 31 
     | 
    
         
            +
                  },
         
     | 
| 
      
 32 
     | 
    
         
            +
                  :type => {
         
     | 
| 
      
 33 
     | 
    
         
            +
                    :space => '[\t\r\n\f\v\uFEFF\u2029\p{Zs}]',
         
     | 
| 
      
 34 
     | 
    
         
            +
                    :nonspace => '[^\t\r\n\f\v\uFEFF\u2029\p{Zs}]'
         
     | 
| 
      
 35 
     | 
    
         
            +
                  }
         
     | 
| 
      
 36 
     | 
    
         
            +
                }.freeze
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 39 
     | 
    
         
            +
                  def ruby_equivalent(pattern)
         
     | 
| 
      
 40 
     | 
    
         
            +
                    Regexp::Scanner.scan(pattern).map do |type, token, text|
         
     | 
| 
      
 41 
     | 
    
         
            +
                      Syntax::SYNTAX.check!(*Syntax::SYNTAX.normalize(type, token))
         
     | 
| 
      
 42 
     | 
    
         
            +
                      RUBY_EQUIVALENTS.dig(type, token) || text
         
     | 
| 
      
 43 
     | 
    
         
            +
                    rescue Regexp::Syntax::NotImplementedError
         
     | 
| 
      
 44 
     | 
    
         
            +
                      raise InvalidEcmaRegexp, "invalid token #{text.inspect} (#{type}:#{token}) in #{pattern.inspect}"
         
     | 
| 
      
 45 
     | 
    
         
            +
                    end.join
         
     | 
| 
      
 46 
     | 
    
         
            +
                  rescue Regexp::Scanner::ScannerError
         
     | 
| 
      
 47 
     | 
    
         
            +
                    raise InvalidEcmaRegexp, "invalid pattern #{pattern.inspect}"
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
              end
         
     | 
| 
      
 51 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/json_schemer/errors.rb
    CHANGED
    
    
| 
         @@ -0,0 +1,23 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            module JSONSchemer
         
     | 
| 
      
 3 
     | 
    
         
            +
              module Format
         
     | 
| 
      
 4 
     | 
    
         
            +
                module Duration
         
     | 
| 
      
 5 
     | 
    
         
            +
                  # https://datatracker.ietf.org/doc/html/rfc3339#appendix-A
         
     | 
| 
      
 6 
     | 
    
         
            +
                  DUR_SECOND = '\d+S'                                              # dur-second        = 1*DIGIT "S"
         
     | 
| 
      
 7 
     | 
    
         
            +
                  DUR_MINUTE = "\\d+M(#{DUR_SECOND})?"                             # dur-minute        = 1*DIGIT "M" [dur-second]
         
     | 
| 
      
 8 
     | 
    
         
            +
                  DUR_HOUR = "\\d+H(#{DUR_MINUTE})?"                               # dur-hour          = 1*DIGIT "H" [dur-minute]
         
     | 
| 
      
 9 
     | 
    
         
            +
                  DUR_TIME = "T(#{DUR_HOUR}|#{DUR_MINUTE}|#{DUR_SECOND})"          # dur-time          = "T" (dur-hour / dur-minute / dur-second)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  DUR_DAY = '\d+D'                                                 # dur-day           = 1*DIGIT "D"
         
     | 
| 
      
 11 
     | 
    
         
            +
                  DUR_WEEK = '\d+W'                                                # dur-week          = 1*DIGIT "W"
         
     | 
| 
      
 12 
     | 
    
         
            +
                  DUR_MONTH = "\\d+M(#{DUR_DAY})?"                                 # dur-month         = 1*DIGIT "M" [dur-day]
         
     | 
| 
      
 13 
     | 
    
         
            +
                  DUR_YEAR = "\\d+Y(#{DUR_MONTH})?"                                # dur-year          = 1*DIGIT "Y" [dur-month]
         
     | 
| 
      
 14 
     | 
    
         
            +
                  DUR_DATE = "(#{DUR_DAY}|#{DUR_MONTH}|#{DUR_YEAR})(#{DUR_TIME})?" # dur-date          = (dur-day / dur-month / dur-year) [dur-time]
         
     | 
| 
      
 15 
     | 
    
         
            +
                  DURATION = "P(#{DUR_DATE}|#{DUR_TIME}|#{DUR_WEEK})"              # duration          = "P" (dur-date / dur-time / dur-week)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  DURATION_REGEX = /\A#{DURATION}\z/
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  def valid_duration?(data)
         
     | 
| 
      
 19 
     | 
    
         
            +
                    DURATION_REGEX.match?(data)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,56 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            module JSONSchemer
         
     | 
| 
      
 3 
     | 
    
         
            +
              module Format
         
     | 
| 
      
 4 
     | 
    
         
            +
                module Email
         
     | 
| 
      
 5 
     | 
    
         
            +
                  # https://datatracker.ietf.org/doc/html/rfc6531#section-3.3
         
     | 
| 
      
 6 
     | 
    
         
            +
                  # I think this is the same as "UTF8-non-ascii"? (https://datatracker.ietf.org/doc/html/rfc6532#section-3.1)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  UTF8_NON_ASCII = '[^[:ascii:]]'
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # https://datatracker.ietf.org/doc/html/rfc5321#section-4.1.2
         
     | 
| 
      
 9 
     | 
    
         
            +
                  A_TEXT = "([\\w!#$%&'*+\\-/=?\\^`{|}~]|#{UTF8_NON_ASCII})"              # atext           = ALPHA / DIGIT /    ; Printable US-ASCII
         
     | 
| 
      
 10 
     | 
    
         
            +
                                                                                          #                   "!" / "#" /        ;  characters not including
         
     | 
| 
      
 11 
     | 
    
         
            +
                                                                                          #                   "$" / "%" /        ;  specials.  Used for atoms.
         
     | 
| 
      
 12 
     | 
    
         
            +
                                                                                          #                   "&" / "'" /
         
     | 
| 
      
 13 
     | 
    
         
            +
                                                                                          #                   "*" / "+" /
         
     | 
| 
      
 14 
     | 
    
         
            +
                                                                                          #                   "-" / "/" /
         
     | 
| 
      
 15 
     | 
    
         
            +
                                                                                          #                   "=" / "?" /
         
     | 
| 
      
 16 
     | 
    
         
            +
                                                                                          #                   "^" / "_" /
         
     | 
| 
      
 17 
     | 
    
         
            +
                                                                                          #                   "`" / "{" /
         
     | 
| 
      
 18 
     | 
    
         
            +
                                                                                          #                   "|" / "}" /
         
     | 
| 
      
 19 
     | 
    
         
            +
                                                                                          #                   "~"
         
     | 
| 
      
 20 
     | 
    
         
            +
                  Q_TEXT_SMTP = "([\\x20-\\x21\\x23-\\x5B\\x5D-\\x7E]|#{UTF8_NON_ASCII})" # qtextSMTP       = %d32-33 / %d35-91 / %d93-126
         
     | 
| 
      
 21 
     | 
    
         
            +
                                                                                          #                 ; i.e., within a quoted string, any
         
     | 
| 
      
 22 
     | 
    
         
            +
                                                                                          #                 ; ASCII graphic or space is permitted
         
     | 
| 
      
 23 
     | 
    
         
            +
                                                                                          #                 ; without blackslash-quoting except
         
     | 
| 
      
 24 
     | 
    
         
            +
                                                                                          #                 ; double-quote and the backslash itself.
         
     | 
| 
      
 25 
     | 
    
         
            +
                  QUOTED_PAIR_SMTP = '\x5C[\x20-\x7E]'                                    # quoted-pairSMTP = %d92 %d32-126
         
     | 
| 
      
 26 
     | 
    
         
            +
                                                                                          #                 ; i.e., backslash followed by any ASCII
         
     | 
| 
      
 27 
     | 
    
         
            +
                                                                                          #                 ; graphic (including itself) or SPace
         
     | 
| 
      
 28 
     | 
    
         
            +
                  Q_CONTENT_SMTP = "#{Q_TEXT_SMTP}|#{QUOTED_PAIR_SMTP}"                   # QcontentSMTP    = qtextSMTP / quoted-pairSMTP
         
     | 
| 
      
 29 
     | 
    
         
            +
                  QUOTED_STRING = "\"(#{Q_CONTENT_SMTP})*\""                              # Quoted-string   = DQUOTE *QcontentSMTP DQUOTE
         
     | 
| 
      
 30 
     | 
    
         
            +
                  ATOM = "#{A_TEXT}+"                                                     # Atom            = 1*atext
         
     | 
| 
      
 31 
     | 
    
         
            +
                  DOT_STRING = "#{ATOM}(\\.#{ATOM})*"                                     # Dot-string      = Atom *("."  Atom)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  LOCAL_PART = "#{DOT_STRING}|#{QUOTED_STRING}"                           # Local-part      = Dot-string / Quoted-string
         
     | 
| 
      
 33 
     | 
    
         
            +
                                                                                          #                 ; MAY be case-sensitive
         
     | 
| 
      
 34 
     | 
    
         
            +
                                                                                          # IPv4-address-literal  = Snum 3("."  Snum)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  # using `valid_id?` to check ip addresses because it's complicated.     # IPv6-address-literal  = "IPv6:" IPv6-addr
         
     | 
| 
      
 36 
     | 
    
         
            +
                  ADDRESS_LITERAL = '\[(IPv6:(?<ipv6>[\h:]+)|(?<ipv4>[\d.]+))\]'          # address-literal = "[" ( IPv4-address-literal /
         
     | 
| 
      
 37 
     | 
    
         
            +
                                                                                          #                 IPv6-address-literal /
         
     | 
| 
      
 38 
     | 
    
         
            +
                                                                                          #                 General-address-literal ) "]"
         
     | 
| 
      
 39 
     | 
    
         
            +
                                                                                          #                 ; See Section 4.1.3
         
     | 
| 
      
 40 
     | 
    
         
            +
                  # using `valid_hostname?` to check domain because it's complicated
         
     | 
| 
      
 41 
     | 
    
         
            +
                  MAILBOX = "(#{LOCAL_PART})@(#{ADDRESS_LITERAL}|(?<domain>.+))"          # Mailbox         = Local-part "@" ( Domain / address-literal )
         
     | 
| 
      
 42 
     | 
    
         
            +
                  EMAIL_REGEX = /\A#{MAILBOX}\z/
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  def valid_email?(data)
         
     | 
| 
      
 45 
     | 
    
         
            +
                    return false unless match = EMAIL_REGEX.match(data)
         
     | 
| 
      
 46 
     | 
    
         
            +
                    if ipv4 = match.named_captures.fetch('ipv4')
         
     | 
| 
      
 47 
     | 
    
         
            +
                      valid_ip?(ipv4, Socket::AF_INET)
         
     | 
| 
      
 48 
     | 
    
         
            +
                    elsif ipv6 = match.named_captures.fetch('ipv6')
         
     | 
| 
      
 49 
     | 
    
         
            +
                      valid_ip?(ipv6, Socket::AF_INET6)
         
     | 
| 
      
 50 
     | 
    
         
            +
                    else
         
     | 
| 
      
 51 
     | 
    
         
            +
                      valid_hostname?(match.named_captures.fetch('domain'))
         
     | 
| 
      
 52 
     | 
    
         
            +
                    end
         
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
      
 54 
     | 
    
         
            +
                end
         
     | 
| 
      
 55 
     | 
    
         
            +
              end
         
     | 
| 
      
 56 
     | 
    
         
            +
            end
         
     |