treaty 0.16.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cc42fa86dd5dc35d49f0a07a189d9ddc59f619e2341905c1ed62193e0d3069b7
4
- data.tar.gz: ffc66f03e0ced6e666bb12db50f405117831b48c26475ab034ab4a16f4c431b1
3
+ metadata.gz: 19f3a5ea2e7f34d9a6d01ccbd59acb738acce63f94f871f0e15da1ff1886f68d
4
+ data.tar.gz: 978fea08fd431936d1975eb0ed18562f90928eefd790224bdf04042e9a15cc0b
5
5
  SHA512:
6
- metadata.gz: 0b31ad204ddb19df8a296007f334d29e2e220fbb771f9c5a3851309e0a9ec1909dae0dbef3608633f6a5203da0b827fb90c75132e83f5ebb3fcc28f36fd33cc9
7
- data.tar.gz: 0c6ec71d1be9155da662498264667a63072c5ce513d1ae0987a54091d76aa35a9fd21b3c722db38a8f4154919a2894f442736c44e23ff88961c9a1aadc841c49
6
+ metadata.gz: 5569610ecda1c9fcc18fad93b50be238e8e96a26b430df119ca2da94bd02b44a8d1ffa6ff819c3926783589ea96e253e34cd4e8b6f55c06381b45760cc318dfa
7
+ data.tar.gz: 3236ffc1e64f646a35086fd42af3c00c387eaab1f188658a7f1f1320677ff3375572d302c583a822b511c8c9df12bc8ad692d2da27f22fd91bec1ab43696229b
data/README.md CHANGED
@@ -13,7 +13,7 @@
13
13
  </div>
14
14
 
15
15
  > [!WARNING]
16
- > **Development Status**: Treaty is currently under active development in the 0.x version series. Breaking changes may occur between minor versions (0.x) as we refine the API and add new features. The library will stabilize with the 1.0 release. We recommend pinning to specific patch versions in your Gemfile (e.g., `gem "treaty", "~> 0.16.0"`) until the 1.0 release.
16
+ > **Development Status**: Treaty is currently under active development in the 0.x version series. Breaking changes may occur between minor versions (0.x) as we refine the API and add new features. The library will stabilize with the 1.0 release. We recommend pinning to specific patch versions in your Gemfile (e.g., `gem "treaty", "~> 0.17.0"`) until the 1.0 release.
17
17
 
18
18
  ## 📚 Documentation
19
19
 
@@ -19,26 +19,27 @@ module Treaty
19
19
  #
20
20
  # ## Registered Options
21
21
  #
22
- # ### Validators
23
- # - `:required` → RequiredValidator
24
- # - `:type` → TypeValidator
25
- # - `:inclusion` → InclusionValidator
26
- # - `:format` → FormatValidator
22
+ # ### Validators (sorted by position)
23
+ # - `:type` → TypeValidator (position: 100)
24
+ # - `:required` → RequiredValidator (position: 200)
25
+ # - `:inclusion` → InclusionValidator (position: 300)
26
+ # - `:format` → FormatValidator (position: 400)
27
27
  #
28
- # ### Modifiers
29
- # - `:as` → AsModifier
30
- # - `:default` → DefaultModifier
31
- # - `:transform` → TransformModifier
32
- # - `:cast` → CastModifier
28
+ # ### Modifiers (sorted by position)
29
+ # - `:transform` → TransformModifier (position: 500)
30
+ # - `:cast` → CastModifier (position: 600)
31
+ # - `:computed` → ComputedModifier (position: 700)
32
+ # - `:default` → DefaultModifier (position: 800)
33
+ # - `:as` → AsModifier (position: 900)
33
34
  #
34
- # ### Conditionals
35
+ # ### Conditionals (no position - handled separately)
35
36
  # - `:if` → IfConditional
36
37
  # - `:unless` → UnlessConditional
37
38
  #
38
39
  # ## Usage
39
40
  #
40
41
  # Registration (done in RegistryInitializer):
41
- # Registry.register(:required, RequiredValidator, category: :validator)
42
+ # Registry.register(:required, RequiredValidator, category: :validator, position: 200)
42
43
  # Registry.register(:if, IfConditional, category: :conditional)
43
44
  #
44
45
  # Retrieval (done in OptionOrchestrator):
@@ -64,11 +65,13 @@ module Treaty
64
65
  #
65
66
  # @param option_name [Symbol] The name of the option (e.g., :required, :as, :default)
66
67
  # @param processor_class [Class] The processor class
67
- # @param category [Symbol] The category (:validator or :modifier)
68
- def register(option_name, processor_class, category:)
68
+ # @param category [Symbol] The category (:validator, :modifier, or :conditional)
69
+ # @param position [Integer, nil] Execution order position (nil for conditionals)
70
+ def register(option_name, processor_class, category:, position: nil)
69
71
  registry[option_name] = {
70
72
  processor_class:,
71
- category:
73
+ category:,
74
+ position:
72
75
  }
73
76
  end
74
77
 
@@ -88,6 +91,14 @@ module Treaty
88
91
  registry.dig(option_name, :category)
89
92
  end
90
93
 
94
+ # Get position for an option
95
+ #
96
+ # @param option_name [Symbol] The name of the option
97
+ # @return [Integer, nil] The execution order position or nil if not set
98
+ def position_for(option_name)
99
+ registry.dig(option_name, :position)
100
+ end
101
+
91
102
  # Check if an option is registered
92
103
  #
93
104
  # @param option_name [Symbol] The name of the option
@@ -17,22 +17,22 @@ module Treaty
17
17
  # 3. **Conditional Registration** - Registers all built-in conditionals
18
18
  # 4. **Auto-Loading** - Executes automatically when file is loaded
19
19
  #
20
- # ## Built-in Validators
20
+ # ## Built-in Validators (sorted by position)
21
21
  #
22
- # - `:required` → RequiredValidator - Validates required/optional attributes
23
- # - `:type` → TypeValidator - Validates value types
24
- # - `:inclusion` → InclusionValidator - Validates value is in allowed set
25
- # - `:format` → FormatValidator - Validates string values match specific formats
22
+ # - `:type` → TypeValidator (position: 100) - Validates value types
23
+ # - `:required` → RequiredValidator (position: 200) - Validates required/optional attributes
24
+ # - `:inclusion` → InclusionValidator (position: 300) - Validates value is in allowed set
25
+ # - `:format` → FormatValidator (position: 400) - Validates string values match specific formats
26
26
  #
27
- # ## Built-in Modifiers
27
+ # ## Built-in Modifiers (sorted by position)
28
28
  #
29
- # - `:computed` → ComputedModifier - Computes values from all raw data (executes first)
30
- # - `:transform` → TransformModifier - Transforms values using custom lambdas
31
- # - `:cast` → CastModifier - Converts values between types automatically
32
- # - `:default` → DefaultModifier - Provides default values
33
- # - `:as` → AsModifier - Renames attributes
29
+ # - `:transform` → TransformModifier (position: 500) - Transforms values using custom lambdas
30
+ # - `:cast` → CastModifier (position: 600) - Converts values between types automatically
31
+ # - `:computed` → ComputedModifier (position: 700) - Computes values from all raw data
32
+ # - `:default` → DefaultModifier (position: 800) - Provides default values
33
+ # - `:as` → AsModifier (position: 900) - Renames attributes
34
34
  #
35
- # ## Built-in Conditionals
35
+ # ## Built-in Conditionals (no position - handled separately)
36
36
  #
37
37
  # - `:if` → IfConditional - Conditionally includes attributes based on runtime data
38
38
  # - `:unless` → UnlessConditional - Conditionally excludes attributes based on runtime data
@@ -76,25 +76,26 @@ module Treaty
76
76
  private
77
77
 
78
78
  # Registers all built-in validators
79
+ # Position determines execution order (lower = earlier)
79
80
  #
80
81
  # @return [void]
81
82
  def register_validators!
82
- Registry.register(:required, Validators::RequiredValidator, category: :validator)
83
- Registry.register(:type, Validators::TypeValidator, category: :validator)
84
- Registry.register(:inclusion, Validators::InclusionValidator, category: :validator)
85
- Registry.register(:format, Validators::FormatValidator, category: :validator)
83
+ Registry.register(:type, Validators::TypeValidator, category: :validator, position: 100)
84
+ Registry.register(:required, Validators::RequiredValidator, category: :validator, position: 200)
85
+ Registry.register(:inclusion, Validators::InclusionValidator, category: :validator, position: 300)
86
+ Registry.register(:format, Validators::FormatValidator, category: :validator, position: 400)
86
87
  end
87
88
 
88
89
  # Registers all built-in modifiers
89
- # Order matters: computed runs first, then transform, cast, default, as
90
+ # Position determines execution order (lower = earlier)
90
91
  #
91
92
  # @return [void]
92
93
  def register_modifiers!
93
- Registry.register(:computed, Modifiers::ComputedModifier, category: :modifier)
94
- Registry.register(:transform, Modifiers::TransformModifier, category: :modifier)
95
- Registry.register(:cast, Modifiers::CastModifier, category: :modifier)
96
- Registry.register(:default, Modifiers::DefaultModifier, category: :modifier)
97
- Registry.register(:as, Modifiers::AsModifier, category: :modifier)
94
+ Registry.register(:transform, Modifiers::TransformModifier, category: :modifier, position: 500)
95
+ Registry.register(:cast, Modifiers::CastModifier, category: :modifier, position: 600)
96
+ Registry.register(:computed, Modifiers::ComputedModifier, category: :modifier, position: 700)
97
+ Registry.register(:default, Modifiers::DefaultModifier, category: :modifier, position: 800)
98
+ Registry.register(:as, Modifiers::AsModifier, category: :modifier, position: 900)
98
99
  end
99
100
 
100
101
  # Registers all built-in conditionals
@@ -87,18 +87,32 @@ module Treaty
87
87
 
88
88
  class << self
89
89
  # Normalizes all options from simple mode to advanced mode
90
+ # and sorts them by position for consistent execution order.
90
91
  #
91
92
  # @param options [Hash] Options hash in simple or advanced mode
92
- # @return [Hash] Normalized options in advanced mode
93
+ # @return [Hash] Normalized options in advanced mode, sorted by position
93
94
  def normalize(options)
94
- options.each_with_object({}) do |(key, value), result|
95
+ normalized = options.each_with_object({}) do |(key, value), result|
95
96
  advanced_key, normalized_value = normalize_option(key, value)
96
97
  result[advanced_key] = normalized_value
97
98
  end
99
+
100
+ sort_by_position(normalized)
98
101
  end
99
102
 
100
103
  private
101
104
 
105
+ # Sorts options by their registered position.
106
+ # Options without position (like conditionals) sort first (position 0).
107
+ #
108
+ # @param options_hash [Hash] Normalized options hash
109
+ # @return [Hash] Options sorted by position
110
+ def sort_by_position(options_hash)
111
+ options_hash.sort_by do |option_name, _|
112
+ Option::Registry.position_for(option_name) || 0
113
+ end.to_h
114
+ end
115
+
102
116
  # Normalizes a single option to advanced mode
103
117
  #
104
118
  # @param key [Symbol] Option key
@@ -3,7 +3,7 @@
3
3
  module Treaty
4
4
  module VERSION
5
5
  MAJOR = 0
6
- MINOR = 16
6
+ MINOR = 17
7
7
  PATCH = 0
8
8
  PRE = nil
9
9
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: treaty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.0
4
+ version: 0.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anton Sokolov