dry-schema 1.13.1 → 1.14.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/CHANGELOG.md +57 -0
 - data/README.md +2 -2
 - data/config/errors.yml +10 -0
 - data/dry-schema.gemspec +15 -17
 - data/lib/dry/schema/config.rb +9 -7
 - data/lib/dry/schema/constants.rb +2 -2
 - data/lib/dry/schema/dsl.rb +29 -21
 - data/lib/dry/schema/extensions/hints/message_compiler_methods.rb +1 -1
 - data/lib/dry/schema/extensions/info/schema_compiler.rb +16 -7
 - data/lib/dry/schema/extensions/json_schema/schema_compiler.rb +4 -4
 - data/lib/dry/schema/extensions/monads.rb +1 -1
 - data/lib/dry/schema/extensions/struct.rb +28 -6
 - data/lib/dry/schema/key.rb +4 -4
 - data/lib/dry/schema/key_coercer.rb +3 -3
 - data/lib/dry/schema/key_map.rb +5 -5
 - data/lib/dry/schema/key_validator.rb +21 -10
 - data/lib/dry/schema/macros/core.rb +2 -2
 - data/lib/dry/schema/macros/dsl.rb +1 -1
 - data/lib/dry/schema/macros/filled.rb +1 -2
 - data/lib/dry/schema/macros/hash.rb +1 -1
 - data/lib/dry/schema/macros/schema.rb +3 -3
 - data/lib/dry/schema/macros/value.rb +12 -12
 - data/lib/dry/schema/message.rb +4 -4
 - data/lib/dry/schema/message_compiler.rb +8 -8
 - data/lib/dry/schema/message_set.rb +8 -8
 - data/lib/dry/schema/messages/abstract.rb +12 -12
 - data/lib/dry/schema/messages/namespaced.rb +1 -1
 - data/lib/dry/schema/messages/template.rb +2 -2
 - data/lib/dry/schema/messages/yaml.rb +3 -3
 - data/lib/dry/schema/path.rb +12 -12
 - data/lib/dry/schema/predicate.rb +4 -4
 - data/lib/dry/schema/predicate_registry.rb +2 -2
 - data/lib/dry/schema/processor.rb +10 -10
 - data/lib/dry/schema/processor_steps.rb +1 -1
 - data/lib/dry/schema/result.rb +6 -6
 - data/lib/dry/schema/rule_applier.rb +1 -1
 - data/lib/dry/schema/trace.rb +1 -1
 - data/lib/dry/schema/type_container.rb +2 -2
 - data/lib/dry/schema/type_registry.rb +1 -1
 - data/lib/dry/schema/types.rb +1 -1
 - data/lib/dry/schema/types_merger.rb +18 -62
 - data/lib/dry/schema/value_coercer.rb +1 -1
 - data/lib/dry/schema/version.rb +1 -1
 - data/lib/dry/schema.rb +12 -11
 - metadata +21 -79
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: b6967bfe7737c11a9df20fc846698f42a911e454cb8c1621d20bc69d93e53dca
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 0a97d750986808ca32535839e779485018d9a7eba1d6a5f09f2128e93f8bbaef
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: b42eb4a52a991fdf5605d8dc69b6b7362578ef140e272a2cff4ef0fc3852e01797714dfbe2507f9aa05ef6885b738413bd8f93536e4aabb8cccbd1c8a23e7cf1
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: a59cc89f18b981031fc7df87e0c3df9692512617dc0bdc35a417a5dce55196788262969ea742da0957a0616a9a0f648c78b4905abb031977570da0751002572b
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,5 +1,62 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            <!--- DO NOT EDIT THIS FILE - IT'S AUTOMATICALLY GENERATED VIA DEVTOOLS --->
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            ## 1.14.0 2025-01-06
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            ### Added
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            - Better support for sets in `excluded_from?` and `included_in?` predicates (via #480) (@flash-gordon)
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            ### Fixed
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            - Fix info extension for maybe macro (via #484) (@flash-gordon + @santiagodoldan)
         
     | 
| 
      
 13 
     | 
    
         
            +
            - Missing message for :uri? predicate (via #477) (@timjnh)
         
     | 
| 
      
 14 
     | 
    
         
            +
            - JSON schema output for `maybe(:array)` (via #463) (@tomgi)
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            ### Changed
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            - Set minimum Ruby version to 3.1 (@flash-gordon)
         
     | 
| 
      
 19 
     | 
    
         
            +
            - `KeyValidator` works faster for large schemas (via #461) (@radarek)
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            [Compare v1.13.4...v1.14.0](https://github.com/dry-rb/dry-schema/compare/v1.13.4...v1.14.0)
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            ## 1.13.4 2024-05-22
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            ### Added
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            - Default error message for `:uri?` (issue #476 via #477) (@timjnh)
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            ### Fixed
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            - Fix json-schema type of objects nested under arrays (issue #400 fixed via #462) (@tomgi)
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            ### Changed
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            - i18n backend is no longer eager-loaded (via 85a9e0b) (@adam12)
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            [Compare v1.13.3...v1.13.4](https://github.com/dry-rb/dry-schema/compare/v1.13.3...v1.13.4)
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            ## 1.13.3 2023-08-26
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            ### Fixed
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            - Fix struct extension for nested struct definitions (via #466) (@flash-gordon)
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            [Compare v1.13.2...v1.13.3](https://github.com/dry-rb/dry-schema/compare/v1.13.2...v1.13.3)
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            ## 1.13.2 2023-05-31
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            ### Fixed
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            - Fix custom predicates setting (via #460) (@solnic)
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
            [Compare v1.13.1...v1.13.2](https://github.com/dry-rb/dry-schema/compare/v1.13.1...v1.13.2)
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
       3 
60 
     | 
    
         
             
            ## 1.13.1 2023-04-07
         
     | 
| 
       4 
61 
     | 
    
         | 
| 
       5 
62 
     | 
    
         | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -2,7 +2,7 @@ 
     | 
|
| 
       2 
2 
     | 
    
         
             
            [gem]: https://rubygems.org/gems/dry-schema
         
     | 
| 
       3 
3 
     | 
    
         
             
            [actions]: https://github.com/dry-rb/dry-schema/actions
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
            # dry-schema [][gem] [][gem] [][actions]
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            ## Links
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
         @@ -14,7 +14,7 @@ 
     | 
|
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
            This library officially supports the following Ruby versions:
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
            * MRI `>= 3. 
     | 
| 
      
 17 
     | 
    
         
            +
            * MRI `>= 3.1`
         
     | 
| 
       18 
18 
     | 
    
         
             
            * jruby `>= 9.4` (not tested on CI)
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
            ## License
         
     | 
    
        data/config/errors.yml
    CHANGED
    
    | 
         @@ -105,7 +105,17 @@ en: 
     | 
|
| 
       105 
105 
     | 
    
         
             
                      default: "must be %{size} bytes long"
         
     | 
| 
       106 
106 
     | 
    
         
             
                      range: "must be within %{size_left} - %{size_right} bytes long"
         
     | 
| 
       107 
107 
     | 
    
         | 
| 
      
 108 
     | 
    
         
            +
                  uri?: "is not a valid URI"
         
     | 
| 
      
 109 
     | 
    
         
            +
                  
         
     | 
| 
      
 110 
     | 
    
         
            +
                  uuid_v1?: "is not a valid UUID"
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                  uuid_v2?: "is not a valid UUID"
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                  uuid_v3?: "is not a valid UUID"
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
       108 
116 
     | 
    
         
             
                  uuid_v4?: "is not a valid UUID"
         
     | 
| 
       109 
117 
     | 
    
         | 
| 
      
 118 
     | 
    
         
            +
                  uuid_v5?: "is not a valid UUID"
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
       110 
120 
     | 
    
         
             
                  not:
         
     | 
| 
       111 
121 
     | 
    
         
             
                    empty?: "cannot be empty"
         
     | 
    
        data/dry-schema.gemspec
    CHANGED
    
    | 
         @@ -21,28 +21,26 @@ Gem::Specification.new do |spec| 
     | 
|
| 
       21 
21 
     | 
    
         | 
| 
       22 
22 
     | 
    
         
             
              TEXT
         
     | 
| 
       23 
23 
     | 
    
         
             
              spec.homepage      = "https://dry-rb.org/gems/dry-schema"
         
     | 
| 
       24 
     | 
    
         
            -
              spec.files         = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-schema.gemspec", 
     | 
| 
      
 24 
     | 
    
         
            +
              spec.files         = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-schema.gemspec",
         
     | 
| 
      
 25 
     | 
    
         
            +
                                       "lib/**/*", "config/*.yml"]
         
     | 
| 
       25 
26 
     | 
    
         
             
              spec.bindir        = "bin"
         
     | 
| 
       26 
27 
     | 
    
         
             
              spec.executables   = []
         
     | 
| 
       27 
28 
     | 
    
         
             
              spec.require_paths = ["lib"]
         
     | 
| 
       28 
29 
     | 
    
         | 
| 
       29 
     | 
    
         
            -
              spec.metadata["allowed_push_host"] 
     | 
| 
       30 
     | 
    
         
            -
              spec.metadata["changelog_uri"] 
     | 
| 
       31 
     | 
    
         
            -
              spec.metadata["source_code_uri"] 
     | 
| 
       32 
     | 
    
         
            -
              spec.metadata["bug_tracker_uri"] 
     | 
| 
      
 30 
     | 
    
         
            +
              spec.metadata["allowed_push_host"]     = "https://rubygems.org"
         
     | 
| 
      
 31 
     | 
    
         
            +
              spec.metadata["changelog_uri"]         = "https://github.com/dry-rb/dry-schema/blob/main/CHANGELOG.md"
         
     | 
| 
      
 32 
     | 
    
         
            +
              spec.metadata["source_code_uri"]       = "https://github.com/dry-rb/dry-schema"
         
     | 
| 
      
 33 
     | 
    
         
            +
              spec.metadata["bug_tracker_uri"]       = "https://github.com/dry-rb/dry-schema/issues"
         
     | 
| 
      
 34 
     | 
    
         
            +
              spec.metadata["rubygems_mfa_required"] = "true"
         
     | 
| 
       33 
35 
     | 
    
         | 
| 
       34 
     | 
    
         
            -
              spec.required_ruby_version = ">=  
     | 
| 
      
 36 
     | 
    
         
            +
              spec.required_ruby_version = ">= 3.1"
         
     | 
| 
       35 
37 
     | 
    
         | 
| 
       36 
38 
     | 
    
         
             
              # to update dependencies edit project.yml
         
     | 
| 
       37 
     | 
    
         
            -
              spec. 
     | 
| 
       38 
     | 
    
         
            -
              spec. 
     | 
| 
       39 
     | 
    
         
            -
              spec. 
     | 
| 
       40 
     | 
    
         
            -
              spec. 
     | 
| 
       41 
     | 
    
         
            -
              spec. 
     | 
| 
       42 
     | 
    
         
            -
              spec. 
     | 
| 
       43 
     | 
    
         
            -
              spec. 
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
              spec.add_development_dependency "bundler"
         
     | 
| 
       46 
     | 
    
         
            -
              spec.add_development_dependency "rake"
         
     | 
| 
       47 
     | 
    
         
            -
              spec.add_development_dependency "rspec"
         
     | 
| 
      
 39 
     | 
    
         
            +
              spec.add_dependency "concurrent-ruby", "~> 1.0"
         
     | 
| 
      
 40 
     | 
    
         
            +
              spec.add_dependency "dry-configurable", "~> 1.0", ">= 1.0.1"
         
     | 
| 
      
 41 
     | 
    
         
            +
              spec.add_dependency "dry-core", "~> 1.1"
         
     | 
| 
      
 42 
     | 
    
         
            +
              spec.add_dependency "dry-initializer", "~> 3.2"
         
     | 
| 
      
 43 
     | 
    
         
            +
              spec.add_dependency "dry-logic", "~> 1.5"
         
     | 
| 
      
 44 
     | 
    
         
            +
              spec.add_dependency "dry-types", "~> 1.8"
         
     | 
| 
      
 45 
     | 
    
         
            +
              spec.add_dependency "zeitwerk", "~> 2.6"
         
     | 
| 
       48 
46 
     | 
    
         
             
            end
         
     | 
    
        data/lib/dry/schema/config.rb
    CHANGED
    
    | 
         @@ -12,8 +12,8 @@ module Dry 
     | 
|
| 
       12 
12 
     | 
    
         
             
                #
         
     | 
| 
       13 
13 
     | 
    
         
             
                # @api public
         
     | 
| 
       14 
14 
     | 
    
         
             
                class Config
         
     | 
| 
       15 
     | 
    
         
            -
                  include Dry::Configurable
         
     | 
| 
       16 
     | 
    
         
            -
                  include Dry::Equalizer(:to_h, inspect: false)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  include ::Dry::Configurable
         
     | 
| 
      
 16 
     | 
    
         
            +
                  include ::Dry::Equalizer(:to_h, inspect: false)
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
18 
     | 
    
         
             
                  # @!method predicates
         
     | 
| 
       19 
19 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -22,7 +22,9 @@ module Dry 
     | 
|
| 
       22 
22 
     | 
    
         
             
                  # @return [Schema::PredicateRegistry]
         
     | 
| 
       23 
23 
     | 
    
         
             
                  #
         
     | 
| 
       24 
24 
     | 
    
         
             
                  # @api public
         
     | 
| 
       25 
     | 
    
         
            -
                  setting :predicates, default:  
     | 
| 
      
 25 
     | 
    
         
            +
                  setting :predicates, default: PredicateRegistry.new, constructor: -> predicates {
         
     | 
| 
      
 26 
     | 
    
         
            +
                    predicates.is_a?(PredicateRegistry) ? predicates : PredicateRegistry.new(predicates)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  }
         
     | 
| 
       26 
28 
     | 
    
         | 
| 
       27 
29 
     | 
    
         
             
                  # @!method types
         
     | 
| 
       28 
30 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -31,7 +33,7 @@ module Dry 
     | 
|
| 
       31 
33 
     | 
    
         
             
                  # @return [Hash]
         
     | 
| 
       32 
34 
     | 
    
         
             
                  #
         
     | 
| 
       33 
35 
     | 
    
         
             
                  # @api public
         
     | 
| 
       34 
     | 
    
         
            -
                  setting :types, default: Dry::Types
         
     | 
| 
      
 36 
     | 
    
         
            +
                  setting :types, default: ::Dry::Types
         
     | 
| 
       35 
37 
     | 
    
         | 
| 
       36 
38 
     | 
    
         
             
                  # @!method messages
         
     | 
| 
       37 
39 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -43,7 +45,7 @@ module Dry 
     | 
|
| 
       43 
45 
     | 
    
         
             
                  setting :messages do
         
     | 
| 
       44 
46 
     | 
    
         
             
                    setting :backend, default: :yaml
         
     | 
| 
       45 
47 
     | 
    
         
             
                    setting :namespace
         
     | 
| 
       46 
     | 
    
         
            -
                    setting :load_paths, default: Set[DEFAULT_MESSAGES_PATH], constructor: :dup.to_proc
         
     | 
| 
      
 48 
     | 
    
         
            +
                    setting :load_paths, default: ::Set[DEFAULT_MESSAGES_PATH], constructor: :dup.to_proc
         
     | 
| 
       47 
49 
     | 
    
         
             
                    setting :top_namespace, default: DEFAULT_MESSAGES_ROOT
         
     | 
| 
       48 
50 
     | 
    
         
             
                    setting :default_locale
         
     | 
| 
       49 
51 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -72,9 +74,9 @@ module Dry 
     | 
|
| 
       72 
74 
     | 
    
         
             
                  # Forward to the underlying config object
         
     | 
| 
       73 
75 
     | 
    
         
             
                  #
         
     | 
| 
       74 
76 
     | 
    
         
             
                  # @api private
         
     | 
| 
       75 
     | 
    
         
            -
                  def method_missing(meth,  
     | 
| 
      
 77 
     | 
    
         
            +
                  def method_missing(meth, ...)
         
     | 
| 
       76 
78 
     | 
    
         
             
                    super unless config.respond_to?(meth)
         
     | 
| 
       77 
     | 
    
         
            -
                    config.public_send(meth,  
     | 
| 
      
 79 
     | 
    
         
            +
                    config.public_send(meth, ...)
         
     | 
| 
       78 
80 
     | 
    
         
             
                  end
         
     | 
| 
       79 
81 
     | 
    
         
             
                end
         
     | 
| 
       80 
82 
     | 
    
         
             
              end
         
     | 
    
        data/lib/dry/schema/constants.rb
    CHANGED
    
    | 
         @@ -30,10 +30,10 @@ module Dry 
     | 
|
| 
       30 
30 
     | 
    
         
             
                DEFAULT_MESSAGES_ROOT = "dry_schema"
         
     | 
| 
       31 
31 
     | 
    
         | 
| 
       32 
32 
     | 
    
         
             
                # An error raised when DSL is used in an incorrect way
         
     | 
| 
       33 
     | 
    
         
            -
                InvalidSchemaError = Class.new(StandardError)
         
     | 
| 
      
 33 
     | 
    
         
            +
                InvalidSchemaError = ::Class.new(::StandardError)
         
     | 
| 
       34 
34 
     | 
    
         | 
| 
       35 
35 
     | 
    
         
             
                # An error raised when a localized message cannot be found
         
     | 
| 
       36 
     | 
    
         
            -
                MissingMessageError = Class.new(StandardError) do
         
     | 
| 
      
 36 
     | 
    
         
            +
                MissingMessageError = ::Class.new(::StandardError) do
         
     | 
| 
       37 
37 
     | 
    
         
             
                  # @api private
         
     | 
| 
       38 
38 
     | 
    
         
             
                  def initialize(path, paths = [])
         
     | 
| 
       39 
39 
     | 
    
         
             
                    *rest, rule = path
         
     | 
    
        data/lib/dry/schema/dsl.rb
    CHANGED
    
    | 
         @@ -37,10 +37,7 @@ module Dry 
     | 
|
| 
       37 
37 
     | 
    
         
             
                class DSL
         
     | 
| 
       38 
38 
     | 
    
         
             
                  Types = Schema::Types
         
     | 
| 
       39 
39 
     | 
    
         | 
| 
       40 
     | 
    
         
            -
                  extend Dry::Initializer
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
                  # @return [Compiler] The rule compiler object
         
     | 
| 
       43 
     | 
    
         
            -
                  option :compiler, default: -> { Compiler.new }
         
     | 
| 
      
 40 
     | 
    
         
            +
                  extend ::Dry::Initializer
         
     | 
| 
       44 
41 
     | 
    
         | 
| 
       45 
42 
     | 
    
         
             
                  # @return [Compiler] The type of the processor (Params, JSON, or a custom sub-class)
         
     | 
| 
       46 
43 
     | 
    
         
             
                  option :processor_type, default: -> { Processor }
         
     | 
| 
         @@ -81,9 +78,10 @@ module Dry 
     | 
|
| 
       81 
78 
     | 
    
         
             
                  # @return [DSL]
         
     | 
| 
       82 
79 
     | 
    
         
             
                  #
         
     | 
| 
       83 
80 
     | 
    
         
             
                  # @api public
         
     | 
| 
       84 
     | 
    
         
            -
                  def self.new(**options, & 
     | 
| 
      
 81 
     | 
    
         
            +
                  def self.new(**options, &)
         
     | 
| 
       85 
82 
     | 
    
         
             
                    dsl = super
         
     | 
| 
       86 
     | 
    
         
            -
                    dsl.instance_eval(& 
     | 
| 
      
 83 
     | 
    
         
            +
                    dsl.instance_eval(&) if block_given?
         
     | 
| 
      
 84 
     | 
    
         
            +
                    dsl.instance_variable_set("@compiler", options[:compiler]) if options[:compiler]
         
     | 
| 
       87 
85 
     | 
    
         
             
                    dsl
         
     | 
| 
       88 
86 
     | 
    
         
             
                  end
         
     | 
| 
       89 
87 
     | 
    
         | 
| 
         @@ -101,11 +99,21 @@ module Dry 
     | 
|
| 
       101 
99 
     | 
    
         
             
                  # @return [DSL]
         
     | 
| 
       102 
100 
     | 
    
         
             
                  #
         
     | 
| 
       103 
101 
     | 
    
         
             
                  # @api public
         
     | 
| 
       104 
     | 
    
         
            -
                  def configure(& 
     | 
| 
       105 
     | 
    
         
            -
                    config.configure(& 
     | 
| 
      
 102 
     | 
    
         
            +
                  def configure(&)
         
     | 
| 
      
 103 
     | 
    
         
            +
                    config.configure(&)
         
     | 
| 
       106 
104 
     | 
    
         
             
                    self
         
     | 
| 
       107 
105 
     | 
    
         
             
                  end
         
     | 
| 
       108 
106 
     | 
    
         | 
| 
      
 107 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 108 
     | 
    
         
            +
                  def compiler
         
     | 
| 
      
 109 
     | 
    
         
            +
                    @compiler ||= Compiler.new(predicates)
         
     | 
| 
      
 110 
     | 
    
         
            +
                  end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 113 
     | 
    
         
            +
                  def predicates
         
     | 
| 
      
 114 
     | 
    
         
            +
                    @predicates ||= config.predicates
         
     | 
| 
      
 115 
     | 
    
         
            +
                  end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
       109 
117 
     | 
    
         
             
                  # Return a macro with the provided name
         
     | 
| 
       110 
118 
     | 
    
         
             
                  #
         
     | 
| 
       111 
119 
     | 
    
         
             
                  # @param [Symbol] name
         
     | 
| 
         @@ -133,8 +141,8 @@ module Dry 
     | 
|
| 
       133 
141 
     | 
    
         
             
                  # @return [Macros::Required]
         
     | 
| 
       134 
142 
     | 
    
         
             
                  #
         
     | 
| 
       135 
143 
     | 
    
         
             
                  # @api public
         
     | 
| 
       136 
     | 
    
         
            -
                  def required(name, & 
     | 
| 
       137 
     | 
    
         
            -
                    key(name, macro: Macros::Required, & 
     | 
| 
      
 144 
     | 
    
         
            +
                  def required(name, &)
         
     | 
| 
      
 145 
     | 
    
         
            +
                    key(name, macro: Macros::Required, &)
         
     | 
| 
       138 
146 
     | 
    
         
             
                  end
         
     | 
| 
       139 
147 
     | 
    
         | 
| 
       140 
148 
     | 
    
         
             
                  # Define an optional key
         
     | 
| 
         @@ -149,8 +157,8 @@ module Dry 
     | 
|
| 
       149 
157 
     | 
    
         
             
                  # @return [Macros::Optional]
         
     | 
| 
       150 
158 
     | 
    
         
             
                  #
         
     | 
| 
       151 
159 
     | 
    
         
             
                  # @api public
         
     | 
| 
       152 
     | 
    
         
            -
                  def optional(name, & 
     | 
| 
       153 
     | 
    
         
            -
                    key(name, macro: Macros::Optional, & 
     | 
| 
      
 160 
     | 
    
         
            +
                  def optional(name, &)
         
     | 
| 
      
 161 
     | 
    
         
            +
                    key(name, macro: Macros::Optional, &)
         
     | 
| 
       154 
162 
     | 
    
         
             
                  end
         
     | 
| 
       155 
163 
     | 
    
         | 
| 
       156 
164 
     | 
    
         
             
                  # A generic method for defining keys
         
     | 
| 
         @@ -162,7 +170,7 @@ module Dry 
     | 
|
| 
       162 
170 
     | 
    
         
             
                  # @return [Macros::Key]
         
     | 
| 
       163 
171 
     | 
    
         
             
                  #
         
     | 
| 
       164 
172 
     | 
    
         
             
                  # @api public
         
     | 
| 
       165 
     | 
    
         
            -
                  def key(name, macro:, & 
     | 
| 
      
 173 
     | 
    
         
            +
                  def key(name, macro:, &)
         
     | 
| 
       166 
174 
     | 
    
         
             
                    raise ArgumentError, "Key +#{name}+ is not a symbol" unless name.is_a?(::Symbol)
         
     | 
| 
       167 
175 
     | 
    
         | 
| 
       168 
176 
     | 
    
         
             
                    set_type(name, Types::Any.meta(default: true))
         
     | 
| 
         @@ -174,7 +182,7 @@ module Dry 
     | 
|
| 
       174 
182 
     | 
    
         
             
                      filter_schema_dsl: filter_schema_dsl
         
     | 
| 
       175 
183 
     | 
    
         
             
                    )
         
     | 
| 
       176 
184 
     | 
    
         | 
| 
       177 
     | 
    
         
            -
                    macro.value(& 
     | 
| 
      
 185 
     | 
    
         
            +
                    macro.value(&) if block_given?
         
     | 
| 
       178 
186 
     | 
    
         
             
                    macros << macro
         
     | 
| 
       179 
187 
     | 
    
         
             
                    macro
         
     | 
| 
       180 
188 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -241,8 +249,8 @@ module Dry 
     | 
|
| 
       241 
249 
     | 
    
         
             
                  # @return [DSL]
         
     | 
| 
       242 
250 
     | 
    
         
             
                  #
         
     | 
| 
       243 
251 
     | 
    
         
             
                  # @api public
         
     | 
| 
       244 
     | 
    
         
            -
                  def before(key, & 
     | 
| 
       245 
     | 
    
         
            -
                    steps.before(key, & 
     | 
| 
      
 252 
     | 
    
         
            +
                  def before(key, &)
         
     | 
| 
      
 253 
     | 
    
         
            +
                    steps.before(key, &)
         
     | 
| 
       246 
254 
     | 
    
         
             
                    self
         
     | 
| 
       247 
255 
     | 
    
         
             
                  end
         
     | 
| 
       248 
256 
     | 
    
         | 
| 
         @@ -256,8 +264,8 @@ module Dry 
     | 
|
| 
       256 
264 
     | 
    
         
             
                  # @return [DSL]
         
     | 
| 
       257 
265 
     | 
    
         
             
                  #
         
     | 
| 
       258 
266 
     | 
    
         
             
                  # @api public
         
     | 
| 
       259 
     | 
    
         
            -
                  def after(key, & 
     | 
| 
       260 
     | 
    
         
            -
                    steps.after(key, & 
     | 
| 
      
 267 
     | 
    
         
            +
                  def after(key, &)
         
     | 
| 
      
 268 
     | 
    
         
            +
                    steps.after(key, &)
         
     | 
| 
       261 
269 
     | 
    
         
             
                    self
         
     | 
| 
       262 
270 
     | 
    
         
             
                  end
         
     | 
| 
       263 
271 
     | 
    
         | 
| 
         @@ -293,8 +301,8 @@ module Dry 
     | 
|
| 
       293 
301 
     | 
    
         
             
                  # @return [Dry::Types::Safe]
         
     | 
| 
       294 
302 
     | 
    
         
             
                  #
         
     | 
| 
       295 
303 
     | 
    
         
             
                  # @api private
         
     | 
| 
       296 
     | 
    
         
            -
                  def new(klass: self.class, **options, & 
     | 
| 
       297 
     | 
    
         
            -
                    klass.new(**options, processor_type: processor_type, config: config, & 
     | 
| 
      
 304 
     | 
    
         
            +
                  def new(klass: self.class, **options, &)
         
     | 
| 
      
 305 
     | 
    
         
            +
                    klass.new(**options, processor_type: processor_type, config: config, &)
         
     | 
| 
       298 
306 
     | 
    
         
             
                  end
         
     | 
| 
       299 
307 
     | 
    
         | 
| 
       300 
308 
     | 
    
         
             
                  # Set a type for the given key name
         
     | 
| 
         @@ -493,7 +501,7 @@ module Dry 
     | 
|
| 
       493 
501 
     | 
    
         
             
                  def default_config
         
     | 
| 
       494 
502 
     | 
    
         
             
                    parents.each_cons(2) do |left, right|
         
     | 
| 
       495 
503 
     | 
    
         
             
                      unless left.config == right.config
         
     | 
| 
       496 
     | 
    
         
            -
                        raise ArgumentError,
         
     | 
| 
      
 504 
     | 
    
         
            +
                        raise ::ArgumentError,
         
     | 
| 
       497 
505 
     | 
    
         
             
                              "Parent configs differ, left=#{left.inspect}, right=#{right.inspect}"
         
     | 
| 
       498 
506 
     | 
    
         
             
                      end
         
     | 
| 
       499 
507 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -70,20 +70,25 @@ module Dry 
     | 
|
| 
       70 
70 
     | 
    
         | 
| 
       71 
71 
     | 
    
         
             
                    # @api private
         
     | 
| 
       72 
72 
     | 
    
         
             
                    def visit_implication(node, opts = EMPTY_HASH)
         
     | 
| 
       73 
     | 
    
         
            -
                      node 
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
      
 73 
     | 
    
         
            +
                      case node
         
     | 
| 
      
 74 
     | 
    
         
            +
                      in [:not, [:predicate, [:nil?, _]]], el
         
     | 
| 
      
 75 
     | 
    
         
            +
                        visit(el, {**opts, nullable: true})
         
     | 
| 
      
 76 
     | 
    
         
            +
                      else
         
     | 
| 
      
 77 
     | 
    
         
            +
                        node.each do |el|
         
     | 
| 
      
 78 
     | 
    
         
            +
                          visit(el, {**opts, required: false})
         
     | 
| 
      
 79 
     | 
    
         
            +
                        end
         
     | 
| 
       75 
80 
     | 
    
         
             
                      end
         
     | 
| 
       76 
81 
     | 
    
         
             
                    end
         
     | 
| 
       77 
82 
     | 
    
         | 
| 
       78 
83 
     | 
    
         
             
                    # @api private
         
     | 
| 
       79 
84 
     | 
    
         
             
                    def visit_each(node, opts = EMPTY_HASH)
         
     | 
| 
       80 
     | 
    
         
            -
                      visit(node, opts 
     | 
| 
      
 85 
     | 
    
         
            +
                      visit(node, {**opts, member: true})
         
     | 
| 
       81 
86 
     | 
    
         
             
                    end
         
     | 
| 
       82 
87 
     | 
    
         | 
| 
       83 
88 
     | 
    
         
             
                    # @api private
         
     | 
| 
       84 
89 
     | 
    
         
             
                    def visit_key(node, opts = EMPTY_HASH)
         
     | 
| 
       85 
90 
     | 
    
         
             
                      name, rest = node
         
     | 
| 
       86 
     | 
    
         
            -
                      visit(rest, opts 
     | 
| 
      
 91 
     | 
    
         
            +
                      visit(rest, {**opts, key: name, required: true})
         
     | 
| 
       87 
92 
     | 
    
         
             
                    end
         
     | 
| 
       88 
93 
     | 
    
         | 
| 
       89 
94 
     | 
    
         
             
                    # @api private
         
     | 
| 
         @@ -93,19 +98,23 @@ module Dry 
     | 
|
| 
       93 
98 
     | 
    
         
             
                      key = opts[:key]
         
     | 
| 
       94 
99 
     | 
    
         | 
| 
       95 
100 
     | 
    
         
             
                      if name.equal?(:key?)
         
     | 
| 
       96 
     | 
    
         
            -
                        keys[rest[0][1]] = { 
     | 
| 
      
 101 
     | 
    
         
            +
                        keys[rest[0][1]] = {
         
     | 
| 
      
 102 
     | 
    
         
            +
                          required: opts.fetch(:required, true)
         
     | 
| 
      
 103 
     | 
    
         
            +
                        }
         
     | 
| 
       97 
104 
     | 
    
         
             
                      else
         
     | 
| 
       98 
105 
     | 
    
         
             
                        type = PREDICATE_TO_TYPE[name]
         
     | 
| 
       99 
     | 
    
         
            -
                         
     | 
| 
      
 106 
     | 
    
         
            +
                        nullable = opts.fetch(:nullable, false)
         
     | 
| 
      
 107 
     | 
    
         
            +
                        assign_type(key, type, nullable) if type
         
     | 
| 
       100 
108 
     | 
    
         
             
                      end
         
     | 
| 
       101 
109 
     | 
    
         
             
                    end
         
     | 
| 
       102 
110 
     | 
    
         | 
| 
       103 
111 
     | 
    
         
             
                    # @api private
         
     | 
| 
       104 
     | 
    
         
            -
                    def assign_type(key, type)
         
     | 
| 
      
 112 
     | 
    
         
            +
                    def assign_type(key, type, nullable)
         
     | 
| 
       105 
113 
     | 
    
         
             
                      if keys[key][:type]
         
     | 
| 
       106 
114 
     | 
    
         
             
                        keys[key][:member] = type
         
     | 
| 
       107 
115 
     | 
    
         
             
                      else
         
     | 
| 
       108 
116 
     | 
    
         
             
                        keys[key][:type] = type
         
     | 
| 
      
 117 
     | 
    
         
            +
                        keys[key][:nullable] = nullable
         
     | 
| 
       109 
118 
     | 
    
         
             
                      end
         
     | 
| 
       110 
119 
     | 
    
         
             
                    end
         
     | 
| 
       111 
120 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -9,7 +9,7 @@ module Dry 
     | 
|
| 
       9 
9 
     | 
    
         
             
                  # @api private
         
     | 
| 
       10 
10 
     | 
    
         
             
                  class SchemaCompiler
         
     | 
| 
       11 
11 
     | 
    
         
             
                    # An error raised when a predicate cannot be converted
         
     | 
| 
       12 
     | 
    
         
            -
                    UnknownConversionError = Class.new(StandardError)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    UnknownConversionError = ::Class.new(::StandardError)
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
14 
     | 
    
         
             
                    IDENTITY = ->(v, _) { v }.freeze
         
     | 
| 
       15 
15 
     | 
    
         
             
                    TO_INTEGER = ->(v, _) { v.to_i }.freeze
         
     | 
| 
         @@ -90,14 +90,14 @@ module Dry 
     | 
|
| 
       90 
90 
     | 
    
         
             
                    def visit_set(node, opts = EMPTY_HASH)
         
     | 
| 
       91 
91 
     | 
    
         
             
                      target = (key = opts[:key]) ? self.class.new(loose: loose?) : self
         
     | 
| 
       92 
92 
     | 
    
         | 
| 
       93 
     | 
    
         
            -
                      node.map { |child| target.visit(child, opts) }
         
     | 
| 
      
 93 
     | 
    
         
            +
                      node.map { |child| target.visit(child, opts.except(:member)) }
         
     | 
| 
       94 
94 
     | 
    
         | 
| 
       95 
95 
     | 
    
         
             
                      return unless key
         
     | 
| 
       96 
96 
     | 
    
         | 
| 
       97 
97 
     | 
    
         
             
                      target_info = opts[:member] ? {items: target.to_h} : target.to_h
         
     | 
| 
       98 
98 
     | 
    
         
             
                      type = opts[:member] ? "array" : "object"
         
     | 
| 
       99 
99 
     | 
    
         | 
| 
       100 
     | 
    
         
            -
                       
     | 
| 
      
 100 
     | 
    
         
            +
                      merge_opts!(keys[key], {type: type, **target_info})
         
     | 
| 
       101 
101 
     | 
    
         
             
                    end
         
     | 
| 
       102 
102 
     | 
    
         | 
| 
       103 
103 
     | 
    
         
             
                    # @api private
         
     | 
| 
         @@ -210,7 +210,7 @@ module Dry 
     | 
|
| 
       210 
210 
     | 
    
         
             
                      orig_type = orig_opts[:type]
         
     | 
| 
       211 
211 
     | 
    
         | 
| 
       212 
212 
     | 
    
         
             
                      if orig_type && new_type && orig_type != new_type
         
     | 
| 
       213 
     | 
    
         
            -
                        new_opts[:type] = [orig_type, new_type]
         
     | 
| 
      
 213 
     | 
    
         
            +
                        new_opts[:type] = [orig_type, new_type].flatten.uniq
         
     | 
| 
       214 
214 
     | 
    
         
             
                      end
         
     | 
| 
       215 
215 
     | 
    
         | 
| 
       216 
216 
     | 
    
         
             
                      orig_opts.merge!(new_opts)
         
     | 
| 
         @@ -5,24 +5,46 @@ require "dry/struct" 
     | 
|
| 
       5 
5 
     | 
    
         
             
            module Dry
         
     | 
| 
       6 
6 
     | 
    
         
             
              module Schema
         
     | 
| 
       7 
7 
     | 
    
         
             
                module Macros
         
     | 
| 
      
 8 
     | 
    
         
            +
                  class StructToSchema < ::Dry::Struct::Compiler
         
     | 
| 
      
 9 
     | 
    
         
            +
                    def call(struct)
         
     | 
| 
      
 10 
     | 
    
         
            +
                      visit(struct.to_ast)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                    # strip away structs from AST
         
     | 
| 
      
 14 
     | 
    
         
            +
                    def visit_struct(node)
         
     | 
| 
      
 15 
     | 
    
         
            +
                      _, ast = node
         
     | 
| 
      
 16 
     | 
    
         
            +
                      visit(ast)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    end
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  Hash.option :struct_compiler, default: proc { StructToSchema.new(schema_dsl.config.types) }
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
       8 
22 
     | 
    
         
             
                  Hash.prepend(::Module.new {
         
     | 
| 
       9 
23 
     | 
    
         
             
                    def call(*args)
         
     | 
| 
       10 
     | 
    
         
            -
                      if args.size >= 1 &&  
     | 
| 
      
 24 
     | 
    
         
            +
                      if args.size >= 1 && struct?(args[0])
         
     | 
| 
       11 
25 
     | 
    
         
             
                        if block_given?
         
     | 
| 
       12 
     | 
    
         
            -
                          raise ArgumentError, "blocks are not supported when using "\
         
     | 
| 
      
 26 
     | 
    
         
            +
                          raise ArgumentError, "blocks are not supported when using " \
         
     | 
| 
       13 
27 
     | 
    
         
             
                                               "a struct class (#{name.inspect} => #{args[0]})"
         
     | 
| 
       14 
28 
     | 
    
         
             
                        end
         
     | 
| 
       15 
29 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
                         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
      
 30 
     | 
    
         
            +
                        schema = struct_compiler.(args[0])
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                        super(schema, *args.drop(1))
         
     | 
| 
      
 33 
     | 
    
         
            +
                        type(schema_dsl.types[name].constructor(schema))
         
     | 
| 
       18 
34 
     | 
    
         
             
                      else
         
     | 
| 
       19 
35 
     | 
    
         
             
                        super
         
     | 
| 
       20 
36 
     | 
    
         
             
                      end
         
     | 
| 
       21 
37 
     | 
    
         
             
                    end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                    private
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                    def struct?(type)
         
     | 
| 
      
 42 
     | 
    
         
            +
                      type.is_a?(::Class) && type <= ::Dry::Struct
         
     | 
| 
      
 43 
     | 
    
         
            +
                    end
         
     | 
| 
       22 
44 
     | 
    
         
             
                  })
         
     | 
| 
       23 
45 
     | 
    
         
             
                end
         
     | 
| 
       24 
46 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
                PredicateInferrer::Compiler. 
     | 
| 
       26 
     | 
    
         
            -
                PrimitiveInferrer::Compiler. 
     | 
| 
      
 47 
     | 
    
         
            +
                PredicateInferrer::Compiler.alias_method(:visit_struct, :visit_hash)
         
     | 
| 
      
 48 
     | 
    
         
            +
                PrimitiveInferrer::Compiler.alias_method(:visit_struct, :visit_hash)
         
     | 
| 
       27 
49 
     | 
    
         
             
              end
         
     | 
| 
       28 
50 
     | 
    
         
             
            end
         
     | 
    
        data/lib/dry/schema/key.rb
    CHANGED
    
    | 
         @@ -6,11 +6,11 @@ module Dry 
     | 
|
| 
       6 
6 
     | 
    
         
             
                #
         
     | 
| 
       7 
7 
     | 
    
         
             
                # @api public
         
     | 
| 
       8 
8 
     | 
    
         
             
                class Key
         
     | 
| 
       9 
     | 
    
         
            -
                  extend Dry::Core::Cache
         
     | 
| 
      
 9 
     | 
    
         
            +
                  extend ::Dry::Core::Cache
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
                  DEFAULT_COERCER = :itself.to_proc.freeze
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
                  include Dry.Equalizer(:name, :coercer)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  include ::Dry.Equalizer(:name, :coercer)
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
                  # @return [Symbol] The key identifier
         
     | 
| 
       16 
16 
     | 
    
         
             
                  attr_reader :id
         
     | 
| 
         @@ -90,7 +90,7 @@ module Dry 
     | 
|
| 
       90 
90 
     | 
    
         
             
                  #
         
     | 
| 
       91 
91 
     | 
    
         
             
                  # @api private
         
     | 
| 
       92 
92 
     | 
    
         
             
                  class Hash < self
         
     | 
| 
       93 
     | 
    
         
            -
                    include Dry.Equalizer(:name, :members, :coercer)
         
     | 
| 
      
 93 
     | 
    
         
            +
                    include ::Dry.Equalizer(:name, :members, :coercer)
         
     | 
| 
       94 
94 
     | 
    
         | 
| 
       95 
95 
     | 
    
         
             
                    # @api private
         
     | 
| 
       96 
96 
     | 
    
         
             
                    attr_reader :members
         
     | 
| 
         @@ -137,7 +137,7 @@ module Dry 
     | 
|
| 
       137 
137 
     | 
    
         
             
                  #
         
     | 
| 
       138 
138 
     | 
    
         
             
                  # @api private
         
     | 
| 
       139 
139 
     | 
    
         
             
                  class Array < self
         
     | 
| 
       140 
     | 
    
         
            -
                    include Dry.Equalizer(:name, :member, :coercer)
         
     | 
| 
      
 140 
     | 
    
         
            +
                    include ::Dry.Equalizer(:name, :member, :coercer)
         
     | 
| 
       141 
141 
     | 
    
         | 
| 
       142 
142 
     | 
    
         
             
                    attr_reader :member
         
     | 
| 
       143 
143 
     | 
    
         | 
| 
         @@ -9,7 +9,7 @@ module Dry 
     | 
|
| 
       9 
9 
     | 
    
         
             
                #
         
     | 
| 
       10 
10 
     | 
    
         
             
                # @api private
         
     | 
| 
       11 
11 
     | 
    
         
             
                class KeyCoercer
         
     | 
| 
       12 
     | 
    
         
            -
                  extend Dry::Core::Cache
         
     | 
| 
      
 12 
     | 
    
         
            +
                  extend ::Dry::Core::Cache
         
     | 
| 
       13 
13 
     | 
    
         
             
                  include ::Dry::Equalizer(:key_map, :coercer)
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
                  TO_SYM = :to_sym.to_proc.freeze
         
     | 
| 
         @@ -27,8 +27,8 @@ module Dry 
     | 
|
| 
       27 
27 
     | 
    
         
             
                  end
         
     | 
| 
       28 
28 
     | 
    
         | 
| 
       29 
29 
     | 
    
         
             
                  # @api private
         
     | 
| 
       30 
     | 
    
         
            -
                  def initialize(key_map, & 
     | 
| 
       31 
     | 
    
         
            -
                    @key_map = key_map.coercible(& 
     | 
| 
      
 30 
     | 
    
         
            +
                  def initialize(key_map, &)
         
     | 
| 
      
 31 
     | 
    
         
            +
                    @key_map = key_map.coercible(&)
         
     | 
| 
       32 
32 
     | 
    
         
             
                  end
         
     | 
| 
       33 
33 
     | 
    
         | 
| 
       34 
34 
     | 
    
         
             
                  # @api private
         
     | 
    
        data/lib/dry/schema/key_map.rb
    CHANGED
    
    | 
         @@ -13,10 +13,10 @@ module Dry 
     | 
|
| 
       13 
13 
     | 
    
         
             
                #
         
     | 
| 
       14 
14 
     | 
    
         
             
                # @api public
         
     | 
| 
       15 
15 
     | 
    
         
             
                class KeyMap
         
     | 
| 
       16 
     | 
    
         
            -
                  extend Dry::Core::Cache
         
     | 
| 
      
 16 
     | 
    
         
            +
                  extend ::Dry::Core::Cache
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
     | 
    
         
            -
                  include Dry.Equalizer(:keys)
         
     | 
| 
       19 
     | 
    
         
            -
                  include Enumerable
         
     | 
| 
      
 18 
     | 
    
         
            +
                  include ::Dry.Equalizer(:keys)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  include ::Enumerable
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
                  # @return [Array<Key>] A list of defined key objects
         
     | 
| 
       22 
22 
     | 
    
         
             
                  attr_reader :keys
         
     | 
| 
         @@ -105,8 +105,8 @@ module Dry 
     | 
|
| 
       105 
105 
     | 
    
         
             
                  # Iterate over keys
         
     | 
| 
       106 
106 
     | 
    
         
             
                  #
         
     | 
| 
       107 
107 
     | 
    
         
             
                  # @api public
         
     | 
| 
       108 
     | 
    
         
            -
                  def each(& 
     | 
| 
       109 
     | 
    
         
            -
                    keys.each(& 
     | 
| 
      
 108 
     | 
    
         
            +
                  def each(&)
         
     | 
| 
      
 109 
     | 
    
         
            +
                    keys.each(&)
         
     | 
| 
       110 
110 
     | 
    
         
             
                  end
         
     | 
| 
       111 
111 
     | 
    
         | 
| 
       112 
112 
     | 
    
         
             
                  # Return a new key map merged with the provided one
         
     | 
| 
         @@ -7,10 +7,10 @@ module Dry 
     | 
|
| 
       7 
7 
     | 
    
         
             
              module Schema
         
     | 
| 
       8 
8 
     | 
    
         
             
                # @api private
         
     | 
| 
       9 
9 
     | 
    
         
             
                class KeyValidator
         
     | 
| 
       10 
     | 
    
         
            -
                  extend Dry::Initializer
         
     | 
| 
      
 10 
     | 
    
         
            +
                  extend ::Dry::Initializer
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
                  INDEX_REGEX = /\[\d+\] 
     | 
| 
       13 
     | 
    
         
            -
                  DIGIT_REGEX = /\A\d+\z 
     | 
| 
      
 12 
     | 
    
         
            +
                  INDEX_REGEX = /\[\d+\]/
         
     | 
| 
      
 13 
     | 
    
         
            +
                  DIGIT_REGEX = /\A\d+\z/
         
     | 
| 
       14 
14 
     | 
    
         
             
                  BRACKETS = "[]"
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
16 
     | 
    
         
             
                  # @api private
         
     | 
| 
         @@ -21,7 +21,7 @@ module Dry 
     | 
|
| 
       21 
21 
     | 
    
         
             
                    input = result.to_h
         
     | 
| 
       22 
22 
     | 
    
         | 
| 
       23 
23 
     | 
    
         
             
                    input_paths = key_paths(input)
         
     | 
| 
       24 
     | 
    
         
            -
                    key_paths = key_map.to_dot_notation
         
     | 
| 
      
 24 
     | 
    
         
            +
                    key_paths = key_map.to_dot_notation.sort
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
26 
     | 
    
         
             
                    input_paths.each do |path|
         
     | 
| 
       27 
27 
     | 
    
         
             
                      error_path = validate_path(key_paths, path)
         
     | 
| 
         @@ -40,20 +40,31 @@ module Dry 
     | 
|
| 
       40 
40 
     | 
    
         
             
                  def validate_path(key_paths, path)
         
     | 
| 
       41 
41 
     | 
    
         
             
                    if path[INDEX_REGEX]
         
     | 
| 
       42 
42 
     | 
    
         
             
                      key = path.gsub(INDEX_REGEX, BRACKETS)
         
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                      if key_paths.none? { paths_match?(key, _1) }
         
     | 
| 
      
 43 
     | 
    
         
            +
                      if none_key_paths_match?(key_paths, key)
         
     | 
| 
       45 
44 
     | 
    
         
             
                        arr = path.gsub(INDEX_REGEX) { ".#{_1[1]}" }
         
     | 
| 
       46 
45 
     | 
    
         
             
                        arr.split(DOT).map { DIGIT_REGEX.match?(_1) ? Integer(_1, 10) : _1.to_sym }
         
     | 
| 
       47 
46 
     | 
    
         
             
                      end
         
     | 
| 
       48 
     | 
    
         
            -
                    elsif  
     | 
| 
      
 47 
     | 
    
         
            +
                    elsif none_key_paths_match?(key_paths, path)
         
     | 
| 
       49 
48 
     | 
    
         
             
                      path
         
     | 
| 
       50 
49 
     | 
    
         
             
                    end
         
     | 
| 
       51 
50 
     | 
    
         
             
                  end
         
     | 
| 
       52 
51 
     | 
    
         | 
| 
       53 
52 
     | 
    
         
             
                  # @api private
         
     | 
| 
       54 
     | 
    
         
            -
                  def  
     | 
| 
       55 
     | 
    
         
            -
                     
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
      
 53 
     | 
    
         
            +
                  def none_key_paths_match?(key_paths, path)
         
     | 
| 
      
 54 
     | 
    
         
            +
                    !any_key_paths_match?(key_paths, path)
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 58 
     | 
    
         
            +
                  def any_key_paths_match?(key_paths, path)
         
     | 
| 
      
 59 
     | 
    
         
            +
                    find_path(key_paths, path, false) ||
         
     | 
| 
      
 60 
     | 
    
         
            +
                      find_path(key_paths, path + DOT, true) ||
         
     | 
| 
      
 61 
     | 
    
         
            +
                      find_path(key_paths, path + BRACKETS, true)
         
     | 
| 
      
 62 
     | 
    
         
            +
                  end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 65 
     | 
    
         
            +
                  def find_path(key_paths, path, prefix_match)
         
     | 
| 
      
 66 
     | 
    
         
            +
                    key = key_paths.bsearch { |key_path| key_path >= path }
         
     | 
| 
      
 67 
     | 
    
         
            +
                    prefix_match ? key&.start_with?(path) : key == path
         
     | 
| 
       57 
68 
     | 
    
         
             
                  end
         
     | 
| 
       58 
69 
     | 
    
         | 
| 
       59 
70 
     | 
    
         
             
                  # @api private
         
     | 
| 
         @@ -19,10 +19,10 @@ module Dry 
     | 
|
| 
       19 
19 
     | 
    
         
             
                    option :compiler, default: proc { Compiler.new }
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
                    # @api private
         
     | 
| 
       22 
     | 
    
         
            -
                    option : 
     | 
| 
      
 22 
     | 
    
         
            +
                    option :schema_dsl, optional: true
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
       24 
24 
     | 
    
         
             
                    # @api private
         
     | 
| 
       25 
     | 
    
         
            -
                    option : 
     | 
| 
      
 25 
     | 
    
         
            +
                    option :trace, default: proc { Trace.new(schema_dsl&.compiler || Compiler.new) }
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
       27 
27 
     | 
    
         
             
                    # @api private
         
     | 
| 
       28 
28 
     | 
    
         
             
                    def new(**options)
         
     |