treaty 0.6.0 → 0.7.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 +4 -4
- data/README.md +4 -4
- data/config/locales/en.yml +3 -4
- data/lib/treaty/attribute/base.rb +2 -2
- data/lib/treaty/attribute/builder/base.rb +4 -4
- data/lib/treaty/attribute/collection.rb +1 -1
- data/lib/treaty/attribute/option/modifiers/default_modifier.rb +1 -1
- data/lib/treaty/attribute/option/registry.rb +4 -4
- data/lib/treaty/attribute/option_orchestrator.rb +1 -1
- data/lib/treaty/attribute/validation/nested_array_validator.rb +3 -3
- data/lib/treaty/attribute/validation/nested_transformer.rb +6 -6
- data/lib/treaty/attribute/validation/orchestrator/base.rb +67 -83
- data/lib/treaty/exceptions/nested_attributes.rb +2 -2
- data/lib/treaty/info/builder.rb +8 -22
- data/lib/treaty/request/attribute/validation/orchestrator.rb +3 -11
- data/lib/treaty/request/attribute/validator.rb +2 -2
- data/lib/treaty/request/factory.rb +15 -13
- data/lib/treaty/response/attribute/validation/orchestrator.rb +3 -11
- data/lib/treaty/response/attribute/validator.rb +2 -2
- data/lib/treaty/response/factory.rb +15 -13
- data/lib/treaty/version.rb +1 -1
- metadata +1 -5
- data/lib/treaty/request/scope/collection.rb +0 -21
- data/lib/treaty/request/scope/factory.rb +0 -42
- data/lib/treaty/response/scope/collection.rb +0 -21
- data/lib/treaty/response/scope/factory.rb +0 -42
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e12062cde9c855fa59706b03143fc63760837b8b7ea2eacec1c78694212ec2c1
|
|
4
|
+
data.tar.gz: 8fddef7c5bb06a1e592ff45873556eab88ef46fa2c578a7425a915803210db50
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '0684be39d9831977a7afefaf06d9ad5dc683b619b598c68e7d6afd0f751d834caaaa998cadffc921aa2d024939fa40778cdaedb7a2264f6582d43bcdbfc06405'
|
|
7
|
+
data.tar.gz: 64b70b809d8729b9fd2b9b7cf2e5c30404c6e1e84c51cdaf85596a6b38538dd3cd3c85679b0f5d183d948ca81de15f85acf204ace86972cd47f35c8d884ed3a9
|
data/README.md
CHANGED
|
@@ -62,15 +62,15 @@ module Posts
|
|
|
62
62
|
strategy Treaty::Strategy::ADAPTER
|
|
63
63
|
|
|
64
64
|
request do
|
|
65
|
-
|
|
66
|
-
string :title
|
|
67
|
-
string :content
|
|
65
|
+
object :post do
|
|
66
|
+
string :title
|
|
67
|
+
string :content
|
|
68
68
|
string :summary, :optional
|
|
69
69
|
end
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
response 201 do
|
|
73
|
-
|
|
73
|
+
object :post do
|
|
74
74
|
string :id
|
|
75
75
|
string :title
|
|
76
76
|
string :content
|
data/config/locales/en.yml
CHANGED
|
@@ -27,8 +27,7 @@ en:
|
|
|
27
27
|
nested:
|
|
28
28
|
# Orchestrator errors
|
|
29
29
|
orchestrator:
|
|
30
|
-
collection_not_implemented: "Subclass must implement the
|
|
31
|
-
scope_data_not_implemented: "Subclass must implement the scope_data_for method"
|
|
30
|
+
collection_not_implemented: "Subclass must implement the collection_of_attributes method"
|
|
32
31
|
|
|
33
32
|
# Array validation errors
|
|
34
33
|
array:
|
|
@@ -61,7 +60,7 @@ en:
|
|
|
61
60
|
request:
|
|
62
61
|
# Request factory DSL
|
|
63
62
|
factory:
|
|
64
|
-
unknown_method: "Unknown method '%{method}' in request definition. Use '
|
|
63
|
+
unknown_method: "Unknown method '%{method}' in request definition. Use 'object :name do ... end' to define request structure"
|
|
65
64
|
|
|
66
65
|
# ============================================================================
|
|
67
66
|
# Response: Response definition and structure
|
|
@@ -69,7 +68,7 @@ en:
|
|
|
69
68
|
response:
|
|
70
69
|
# Response factory DSL
|
|
71
70
|
factory:
|
|
72
|
-
unknown_method: "Unknown method '%{method}' in response definition. Use '
|
|
71
|
+
unknown_method: "Unknown method '%{method}' in response definition. Use 'object :name do ... end' to define response structure"
|
|
73
72
|
|
|
74
73
|
# ============================================================================
|
|
75
74
|
# Versioning: API version management and resolution
|
|
@@ -6,7 +6,7 @@ module Treaty
|
|
|
6
6
|
#
|
|
7
7
|
# ## Purpose
|
|
8
8
|
#
|
|
9
|
-
# Represents a single attribute defined in request/response
|
|
9
|
+
# Represents a single attribute defined in request/response definitions.
|
|
10
10
|
# Handles:
|
|
11
11
|
# - Attribute metadata (name, type, nesting level)
|
|
12
12
|
# - Helper mode to simple mode conversion
|
|
@@ -37,7 +37,7 @@ module Treaty
|
|
|
37
37
|
# - `object` - nested attributes as direct children
|
|
38
38
|
# - `array` - nested attributes define array element structure
|
|
39
39
|
#
|
|
40
|
-
# Special
|
|
40
|
+
# Special attribute name `:_self` is used for simple arrays:
|
|
41
41
|
# array :tags do
|
|
42
42
|
# string :_self # Array of strings
|
|
43
43
|
# end
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
module Treaty
|
|
4
4
|
module Attribute
|
|
5
5
|
module Builder
|
|
6
|
-
# Base DSL builder for defining attributes in request/response
|
|
6
|
+
# Base DSL builder for defining attributes in request/response definitions.
|
|
7
7
|
#
|
|
8
8
|
# ## Purpose
|
|
9
9
|
#
|
|
10
|
-
# Provides the DSL interface for defining attributes within
|
|
10
|
+
# Provides the DSL interface for defining attributes within objects.
|
|
11
11
|
# Handles method_missing magic to support type-based method calls.
|
|
12
12
|
#
|
|
13
13
|
# ## Responsibilities
|
|
@@ -23,8 +23,8 @@ module Treaty
|
|
|
23
23
|
#
|
|
24
24
|
# ```ruby
|
|
25
25
|
# request do
|
|
26
|
-
#
|
|
27
|
-
# string :name
|
|
26
|
+
# object :user do
|
|
27
|
+
# string :name
|
|
28
28
|
# integer :age, default: 18
|
|
29
29
|
# object :profile do
|
|
30
30
|
# string :bio
|
|
@@ -99,16 +99,16 @@ module Treaty
|
|
|
99
99
|
#
|
|
100
100
|
# @return [Hash] Hash of option_name => processor_class for validators
|
|
101
101
|
def validators
|
|
102
|
-
registry.select { |_, info| info
|
|
103
|
-
.transform_values { |info| info
|
|
102
|
+
registry.select { |_, info| info.fetch(:category) == :validator }
|
|
103
|
+
.transform_values { |info| info.fetch(:processor_class) }
|
|
104
104
|
end
|
|
105
105
|
|
|
106
106
|
# Get all modifiers
|
|
107
107
|
#
|
|
108
108
|
# @return [Hash] Hash of option_name => processor_class for modifiers
|
|
109
109
|
def modifiers
|
|
110
|
-
registry.select { |_, info| info
|
|
111
|
-
.transform_values { |info| info
|
|
110
|
+
registry.select { |_, info| info.fetch(:category) == :modifier }
|
|
111
|
+
.transform_values { |info| info.fetch(:processor_class) }
|
|
112
112
|
end
|
|
113
113
|
|
|
114
114
|
# Reset registry (mainly for testing)
|
|
@@ -131,7 +131,7 @@ module Treaty
|
|
|
131
131
|
# @param option_name [Symbol] The option name (:required, :type, etc.)
|
|
132
132
|
# @return [Option::Base, nil] The processor instance or nil if not found
|
|
133
133
|
def processor_for(option_name)
|
|
134
|
-
@processors
|
|
134
|
+
@processors.fetch(option_name)
|
|
135
135
|
end
|
|
136
136
|
|
|
137
137
|
private
|
|
@@ -8,7 +8,7 @@ module Treaty
|
|
|
8
8
|
# ## Purpose
|
|
9
9
|
#
|
|
10
10
|
# Performs validation for nested array attributes during the validation phase.
|
|
11
|
-
# Handles both simple arrays (with :_self
|
|
11
|
+
# Handles both simple arrays (with :_self attribute) and complex arrays (objects).
|
|
12
12
|
#
|
|
13
13
|
# ## Responsibilities
|
|
14
14
|
#
|
|
@@ -19,7 +19,7 @@ module Treaty
|
|
|
19
19
|
#
|
|
20
20
|
# ## Array Types
|
|
21
21
|
#
|
|
22
|
-
# ### Simple Array (`:_self`
|
|
22
|
+
# ### Simple Array (`:_self` attribute)
|
|
23
23
|
# Array containing primitive values (strings, integers, etc.)
|
|
24
24
|
#
|
|
25
25
|
# ```ruby
|
|
@@ -93,7 +93,7 @@ module Treaty
|
|
|
93
93
|
|
|
94
94
|
private
|
|
95
95
|
|
|
96
|
-
# Validates array item for simple arrays (with :_self
|
|
96
|
+
# Validates array item for simple arrays (with :_self attribute)
|
|
97
97
|
# Simple array contains primitive values: strings, integers, datetimes, etc.
|
|
98
98
|
# Example: ["ruby", "rails", "api"] where each item is a String
|
|
99
99
|
#
|
|
@@ -6,8 +6,8 @@ module Treaty
|
|
|
6
6
|
# Handles transformation of nested attributes (objects and arrays).
|
|
7
7
|
# Extracted from Orchestrator::Base to reduce complexity.
|
|
8
8
|
class NestedTransformer
|
|
9
|
-
|
|
10
|
-
private_constant :
|
|
9
|
+
SELF_OBJECT = :_self
|
|
10
|
+
private_constant :SELF_OBJECT
|
|
11
11
|
|
|
12
12
|
attr_reader :attribute
|
|
13
13
|
|
|
@@ -118,8 +118,8 @@ module Treaty
|
|
|
118
118
|
|
|
119
119
|
# Transforms array with nested attributes
|
|
120
120
|
class ArrayTransformer
|
|
121
|
-
|
|
122
|
-
private_constant :
|
|
121
|
+
SELF_OBJECT = :_self
|
|
122
|
+
private_constant :SELF_OBJECT
|
|
123
123
|
|
|
124
124
|
attr_reader :attribute
|
|
125
125
|
|
|
@@ -150,10 +150,10 @@ module Treaty
|
|
|
150
150
|
|
|
151
151
|
# Checks if this is a simple array (primitive values)
|
|
152
152
|
#
|
|
153
|
-
# @return [Boolean] True if array contains primitive values with :_self
|
|
153
|
+
# @return [Boolean] True if array contains primitive values with :_self attribute
|
|
154
154
|
def simple_array?
|
|
155
155
|
attribute.collection_of_attributes.size == 1 &&
|
|
156
|
-
attribute.collection_of_attributes.first.name ==
|
|
156
|
+
attribute.collection_of_attributes.first.name == SELF_OBJECT
|
|
157
157
|
end
|
|
158
158
|
|
|
159
159
|
# Validates a simple array element (primitive value)
|
|
@@ -9,12 +9,12 @@ module Treaty
|
|
|
9
9
|
# ## Purpose
|
|
10
10
|
#
|
|
11
11
|
# Coordinates the validation and transformation of request/response data for a specific
|
|
12
|
-
# API version. Processes all
|
|
13
|
-
#
|
|
12
|
+
# API version. Processes all attributes, applying validations and transformations
|
|
13
|
+
# defined in the treaty DSL.
|
|
14
14
|
#
|
|
15
15
|
# ## Responsibilities
|
|
16
16
|
#
|
|
17
|
-
# 1. **
|
|
17
|
+
# 1. **Attribute Processing** - Iterates through all defined attributes
|
|
18
18
|
# 2. **Attribute Validation** - Validates each attribute's value
|
|
19
19
|
# 3. **Data Transformation** - Transforms values (defaults, renaming)
|
|
20
20
|
# 4. **Nested Handling** - Delegates nested structures to NestedTransformer
|
|
@@ -23,17 +23,16 @@ module Treaty
|
|
|
23
23
|
# ## Usage
|
|
24
24
|
#
|
|
25
25
|
# Subclasses must implement:
|
|
26
|
-
# - `
|
|
27
|
-
# - `scope_data_for(name)` - Extracts data for a specific scope
|
|
26
|
+
# - `collection_of_attributes` - Returns attributes for this context (request/response)
|
|
28
27
|
#
|
|
29
28
|
# Example:
|
|
30
29
|
# orchestrator = Request::Orchestrator.new(version_factory: factory, data: params)
|
|
31
30
|
# validated_data = orchestrator.validate!
|
|
32
31
|
#
|
|
33
|
-
# ## Special
|
|
32
|
+
# ## Special Case: object :_self
|
|
34
33
|
#
|
|
35
|
-
# - Normal
|
|
36
|
-
# - Self
|
|
34
|
+
# - Normal object: `{ object_name: { ... } }`
|
|
35
|
+
# - Self object (`:_self`): Attributes merged directly into parent
|
|
37
36
|
#
|
|
38
37
|
# ## Architecture
|
|
39
38
|
#
|
|
@@ -41,13 +40,13 @@ module Treaty
|
|
|
41
40
|
# - `AttributeValidator` - Validates individual attributes
|
|
42
41
|
# - `NestedTransformer` - Handles nested objects and arrays
|
|
43
42
|
#
|
|
44
|
-
# The
|
|
45
|
-
# - Orchestrator: High-level flow and
|
|
43
|
+
# The design separates concerns:
|
|
44
|
+
# - Orchestrator: High-level flow and attribute iteration
|
|
46
45
|
# - Validator: Individual attribute validation
|
|
47
46
|
# - Transformer: Nested structure transformation
|
|
48
47
|
class Base
|
|
49
|
-
|
|
50
|
-
private_constant :
|
|
48
|
+
SELF_OBJECT = :_self
|
|
49
|
+
private_constant :SELF_OBJECT
|
|
51
50
|
|
|
52
51
|
attr_reader :version_factory, :data
|
|
53
52
|
|
|
@@ -69,17 +68,22 @@ module Treaty
|
|
|
69
68
|
@data = data
|
|
70
69
|
end
|
|
71
70
|
|
|
72
|
-
# Validates and transforms all
|
|
73
|
-
# Iterates through
|
|
71
|
+
# Validates and transforms all attributes
|
|
72
|
+
# Iterates through attributes, processes them, handles :_self objects
|
|
74
73
|
#
|
|
75
|
-
# @return [Hash] Transformed data with all
|
|
74
|
+
# @return [Hash] Transformed data with all attributes processed
|
|
76
75
|
def validate!
|
|
77
76
|
transformed_data = {}
|
|
78
77
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
78
|
+
collection_of_attributes.each do |attribute|
|
|
79
|
+
transformed_value = validate_and_transform_attribute!(attribute)
|
|
80
|
+
|
|
81
|
+
if attribute.name == SELF_OBJECT && attribute.type == :object
|
|
82
|
+
# For object :_self, merge nested attributes to root
|
|
83
|
+
transformed_data.merge!(transformed_value)
|
|
84
|
+
else
|
|
85
|
+
transformed_data[attribute.name] = transformed_value
|
|
86
|
+
end
|
|
83
87
|
end
|
|
84
88
|
|
|
85
89
|
transformed_data
|
|
@@ -87,103 +91,83 @@ module Treaty
|
|
|
87
91
|
|
|
88
92
|
private
|
|
89
93
|
|
|
90
|
-
# Returns collection of
|
|
94
|
+
# Returns collection of attributes for this context
|
|
91
95
|
# Must be implemented in subclasses
|
|
92
96
|
#
|
|
93
97
|
# @raise [Treaty::Exceptions::Validation] If not implemented
|
|
94
|
-
# @return [
|
|
95
|
-
def
|
|
98
|
+
# @return [Treaty::Attribute::Collection] Collection of attributes
|
|
99
|
+
def collection_of_attributes
|
|
96
100
|
raise Treaty::Exceptions::Validation,
|
|
97
101
|
I18n.t("treaty.attributes.validators.nested.orchestrator.collection_not_implemented")
|
|
98
102
|
end
|
|
99
103
|
|
|
100
|
-
#
|
|
101
|
-
#
|
|
102
|
-
# @param scope_factory [ScopeFactory] The scope to validate
|
|
103
|
-
# @return [void]
|
|
104
|
-
def validate_scope!(scope_factory)
|
|
105
|
-
scope_data = scope_data_for(scope_factory.name)
|
|
106
|
-
|
|
107
|
-
validators_for_scope(scope_factory).each do |attribute, validator|
|
|
108
|
-
value = scope_data.fetch(attribute.name, nil)
|
|
109
|
-
validator.validate_value!(value)
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
# Gets cached validators for scope or builds them
|
|
104
|
+
# Gets cached validators for attributes or builds them
|
|
114
105
|
#
|
|
115
|
-
# @param scope_factory [ScopeFactory] The scope factory
|
|
116
106
|
# @return [Hash] Hash of attribute => validator
|
|
117
|
-
def
|
|
118
|
-
@
|
|
119
|
-
@validators_cache[scope_factory] ||= build_validators_for_scope(scope_factory)
|
|
107
|
+
def validators_for_attributes
|
|
108
|
+
@validators_for_attributes ||= build_validators_for_attributes
|
|
120
109
|
end
|
|
121
110
|
|
|
122
|
-
# Builds validators for all attributes
|
|
111
|
+
# Builds validators for all attributes
|
|
123
112
|
#
|
|
124
|
-
# @param scope_factory [ScopeFactory] The scope factory
|
|
125
113
|
# @return [Hash] Hash of attribute => validator
|
|
126
|
-
def
|
|
127
|
-
|
|
114
|
+
def build_validators_for_attributes
|
|
115
|
+
collection_of_attributes.each_with_object({}) do |attribute, cache|
|
|
128
116
|
validator = AttributeValidator.new(attribute)
|
|
129
117
|
validator.validate_schema!
|
|
130
118
|
cache[attribute] = validator
|
|
131
119
|
end
|
|
132
120
|
end
|
|
133
121
|
|
|
134
|
-
#
|
|
135
|
-
# Must be implemented in subclasses
|
|
136
|
-
#
|
|
137
|
-
# @param _name [Symbol] The scope name
|
|
138
|
-
# @raise [Treaty::Exceptions::Validation] If not implemented
|
|
139
|
-
# @return [Hash] Scope data
|
|
140
|
-
def scope_data_for(_name)
|
|
141
|
-
raise Treaty::Exceptions::Validation,
|
|
142
|
-
I18n.t("treaty.attributes.validators.nested.orchestrator.scope_data_not_implemented")
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
# Validates and transforms all attributes in a scope
|
|
122
|
+
# Validates and transforms a single attribute
|
|
146
123
|
# Handles both nested and regular attributes
|
|
147
124
|
#
|
|
148
|
-
# @param
|
|
149
|
-
# @return [
|
|
150
|
-
def
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
transformed_value = validator.transform_value(value)
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
target_name = validator.target_name
|
|
169
|
-
|
|
170
|
-
transformed_scope_data[target_name] = transformed_value
|
|
125
|
+
# @param attribute [Attribute] The attribute to process
|
|
126
|
+
# @return [Object] Transformed attribute value
|
|
127
|
+
def validate_and_transform_attribute!(attribute) # rubocop:disable Metrics/MethodLength
|
|
128
|
+
validator = validators_for_attributes.fetch(attribute)
|
|
129
|
+
|
|
130
|
+
# For :_self object, get data from root; otherwise from attribute key
|
|
131
|
+
value = if attribute.name == SELF_OBJECT && attribute.type == :object
|
|
132
|
+
data
|
|
133
|
+
else
|
|
134
|
+
data.fetch(attribute.name, nil)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
if attribute.nested?
|
|
138
|
+
validate_and_transform_nested(attribute, value, validator)
|
|
139
|
+
else
|
|
140
|
+
validator.validate_value!(value)
|
|
141
|
+
validator.transform_value(value)
|
|
171
142
|
end
|
|
172
|
-
|
|
173
|
-
transformed_scope_data
|
|
174
143
|
end
|
|
175
144
|
|
|
176
145
|
# Validates and transforms nested attribute (object/array)
|
|
177
146
|
# Delegates transformation to NestedTransformer
|
|
178
147
|
#
|
|
179
148
|
# @param attribute [Attribute::Base] The nested attribute
|
|
180
|
-
# @param value [Object] The value to validate and transform
|
|
149
|
+
# @param value [Object, nil] The value to validate and transform
|
|
181
150
|
# @param validator [AttributeValidator] The validator instance
|
|
182
|
-
# @return [Object] Transformed nested value
|
|
151
|
+
# @return [Object, nil] Transformed nested value or nil
|
|
152
|
+
#
|
|
153
|
+
# @note Flow control:
|
|
154
|
+
# - If value is nil and attribute is required → validate_required! raises exception
|
|
155
|
+
# - If value is nil and attribute is optional → validate_required! does nothing, returns nil
|
|
156
|
+
# - If value is not nil → proceeds to transformation (value guaranteed non-nil)
|
|
183
157
|
def validate_and_transform_nested(attribute, value, validator)
|
|
158
|
+
# Step 1: Validate type if value is present
|
|
184
159
|
validator.validate_type!(value) unless value.nil?
|
|
160
|
+
|
|
161
|
+
# Step 2: Validate required constraint
|
|
162
|
+
# This will raise an exception if attribute is required and value is nil
|
|
185
163
|
validator.validate_required!(value)
|
|
186
164
|
|
|
165
|
+
# Step 3: Early return for nil values
|
|
166
|
+
# Only reaches here if attribute is optional and value is nil
|
|
167
|
+
return nil if value.nil?
|
|
168
|
+
|
|
169
|
+
# Step 4: Transform non-nil value
|
|
170
|
+
# At this point, value is guaranteed to be non-nil
|
|
187
171
|
transformer = NestedTransformer.new(attribute)
|
|
188
172
|
transformer.transform(value)
|
|
189
173
|
end
|
|
@@ -18,7 +18,7 @@ module Treaty
|
|
|
18
18
|
#
|
|
19
19
|
# ```ruby
|
|
20
20
|
# request do
|
|
21
|
-
#
|
|
21
|
+
# object :user do
|
|
22
22
|
# object :profile do
|
|
23
23
|
# object :settings do
|
|
24
24
|
# object :preferences do
|
|
@@ -57,7 +57,7 @@ module Treaty
|
|
|
57
57
|
#
|
|
58
58
|
# - Keep nesting shallow (2-3 levels maximum)
|
|
59
59
|
# - Consider flattening deeply nested structures
|
|
60
|
-
# - Use separate
|
|
60
|
+
# - Use separate objects instead of deep nesting
|
|
61
61
|
# - Refactor complex structures into simpler ones
|
|
62
62
|
class NestedAttributes < Base
|
|
63
63
|
end
|
data/lib/treaty/info/builder.rb
CHANGED
|
@@ -56,41 +56,27 @@ module Treaty
|
|
|
56
56
|
##########################################################################
|
|
57
57
|
|
|
58
58
|
def build_request_with(version)
|
|
59
|
-
|
|
60
|
-
scopes: build_scopes_with(version.request_factory)
|
|
61
|
-
}
|
|
59
|
+
build_attributes_structure(version.request_factory)
|
|
62
60
|
end
|
|
63
61
|
|
|
64
62
|
def build_response_with(version)
|
|
65
63
|
response_factory = version.response_factory
|
|
66
64
|
{
|
|
67
|
-
status: response_factory.status
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
##########################################################################
|
|
73
|
-
|
|
74
|
-
def build_scopes_with(request_factory)
|
|
75
|
-
request_factory.collection_of_scopes.to_h do |scope|
|
|
76
|
-
[
|
|
77
|
-
scope.name,
|
|
78
|
-
build_attributes_with(scope.collection_of_attributes)
|
|
79
|
-
]
|
|
80
|
-
end
|
|
65
|
+
status: response_factory.status
|
|
66
|
+
}.merge(build_attributes_structure(response_factory))
|
|
81
67
|
end
|
|
82
68
|
|
|
83
69
|
##########################################################################
|
|
84
70
|
|
|
85
|
-
def
|
|
86
|
-
# validate_nesting_level!(current_level)
|
|
87
|
-
|
|
71
|
+
def build_attributes_structure(factory)
|
|
88
72
|
{
|
|
89
|
-
attributes: build_attributes_hash(
|
|
73
|
+
attributes: build_attributes_hash(factory.collection_of_attributes)
|
|
90
74
|
}
|
|
91
75
|
end
|
|
92
76
|
|
|
93
|
-
def build_attributes_hash(collection, current_level)
|
|
77
|
+
def build_attributes_hash(collection, current_level = 0)
|
|
78
|
+
# validate_nesting_level!(current_level)
|
|
79
|
+
|
|
94
80
|
collection.to_h do |attribute|
|
|
95
81
|
[
|
|
96
82
|
attribute.name,
|
|
@@ -7,18 +7,10 @@ module Treaty
|
|
|
7
7
|
class Orchestrator < Treaty::Attribute::Validation::Orchestrator::Base
|
|
8
8
|
private
|
|
9
9
|
|
|
10
|
-
def
|
|
11
|
-
return Treaty::
|
|
10
|
+
def collection_of_attributes
|
|
11
|
+
return Treaty::Attribute::Collection.new if version_factory.request_factory.nil?
|
|
12
12
|
|
|
13
|
-
version_factory.request_factory.
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def scope_data_for(name)
|
|
17
|
-
# If the scope is :_self, it's the root level.
|
|
18
|
-
return data if name == :_self
|
|
19
|
-
|
|
20
|
-
# Otherwise, fetch data from the named scope.
|
|
21
|
-
data.fetch(name, {})
|
|
13
|
+
version_factory.request_factory.collection_of_attributes
|
|
22
14
|
end
|
|
23
15
|
end
|
|
24
16
|
end
|
|
@@ -40,9 +40,9 @@ module Treaty
|
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
def request_attributes_exist?
|
|
43
|
-
return false if @version_factory.request_factory&.
|
|
43
|
+
return false if @version_factory.request_factory&.collection_of_attributes&.empty?
|
|
44
44
|
|
|
45
|
-
@version_factory.request_factory.
|
|
45
|
+
@version_factory.request_factory.collection_of_attributes.exists?
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
end
|
|
@@ -3,25 +3,27 @@
|
|
|
3
3
|
module Treaty
|
|
4
4
|
module Request
|
|
5
5
|
class Factory
|
|
6
|
-
def
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
def attribute(name, type, *helpers, **options, &block)
|
|
7
|
+
collection_of_attributes << Attribute::Attribute.new(
|
|
8
|
+
name,
|
|
9
|
+
type,
|
|
10
|
+
*helpers,
|
|
11
|
+
nesting_level: 0,
|
|
12
|
+
**options,
|
|
13
|
+
&block
|
|
14
|
+
)
|
|
14
15
|
end
|
|
15
16
|
|
|
16
|
-
def
|
|
17
|
-
@
|
|
17
|
+
def collection_of_attributes
|
|
18
|
+
@collection_of_attributes ||= Treaty::Attribute::Collection.new
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
##########################################################################
|
|
21
22
|
|
|
22
|
-
def method_missing(
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
def method_missing(type, *helpers, **options, &block)
|
|
24
|
+
name = helpers.shift
|
|
25
|
+
|
|
26
|
+
attribute(name, type, *helpers, **options, &block)
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
def respond_to_missing?(name, *)
|
|
@@ -7,18 +7,10 @@ module Treaty
|
|
|
7
7
|
class Orchestrator < Treaty::Attribute::Validation::Orchestrator::Base
|
|
8
8
|
private
|
|
9
9
|
|
|
10
|
-
def
|
|
11
|
-
return Treaty::
|
|
10
|
+
def collection_of_attributes
|
|
11
|
+
return Treaty::Attribute::Collection.new if version_factory.response_factory.nil?
|
|
12
12
|
|
|
13
|
-
version_factory.response_factory.
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def scope_data_for(name)
|
|
17
|
-
# If the scope is :_self, it's the root level.
|
|
18
|
-
return data if name == :_self
|
|
19
|
-
|
|
20
|
-
# Otherwise, fetch data from the named scope.
|
|
21
|
-
data.fetch(name, {})
|
|
13
|
+
version_factory.response_factory.collection_of_attributes
|
|
22
14
|
end
|
|
23
15
|
end
|
|
24
16
|
end
|
|
@@ -34,9 +34,9 @@ module Treaty
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def response_attributes_exist?
|
|
37
|
-
return false if @version_factory.response_factory&.
|
|
37
|
+
return false if @version_factory.response_factory&.collection_of_attributes&.empty?
|
|
38
38
|
|
|
39
|
-
@version_factory.response_factory.
|
|
39
|
+
@version_factory.response_factory.collection_of_attributes.exists?
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
42
|
end
|
|
@@ -9,25 +9,27 @@ module Treaty
|
|
|
9
9
|
@status = status
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
def attribute(name, type, *helpers, **options, &block)
|
|
13
|
+
collection_of_attributes << Attribute::Attribute.new(
|
|
14
|
+
name,
|
|
15
|
+
type,
|
|
16
|
+
*helpers,
|
|
17
|
+
nesting_level: 0,
|
|
18
|
+
**options,
|
|
19
|
+
&block
|
|
20
|
+
)
|
|
20
21
|
end
|
|
21
22
|
|
|
22
|
-
def
|
|
23
|
-
@
|
|
23
|
+
def collection_of_attributes
|
|
24
|
+
@collection_of_attributes ||= Treaty::Attribute::Collection.new
|
|
24
25
|
end
|
|
25
26
|
|
|
26
27
|
##########################################################################
|
|
27
28
|
|
|
28
|
-
def method_missing(
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
def method_missing(type, *helpers, **options, &block)
|
|
30
|
+
name = helpers.shift
|
|
31
|
+
|
|
32
|
+
attribute(name, type, *helpers, **options, &block)
|
|
31
33
|
end
|
|
32
34
|
|
|
33
35
|
def respond_to_missing?(name, *)
|
data/lib/treaty/version.rb
CHANGED
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.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Anton Sokolov
|
|
@@ -192,15 +192,11 @@ files:
|
|
|
192
192
|
- lib/treaty/request/attribute/validation/orchestrator.rb
|
|
193
193
|
- lib/treaty/request/attribute/validator.rb
|
|
194
194
|
- lib/treaty/request/factory.rb
|
|
195
|
-
- lib/treaty/request/scope/collection.rb
|
|
196
|
-
- lib/treaty/request/scope/factory.rb
|
|
197
195
|
- lib/treaty/response/attribute/attribute.rb
|
|
198
196
|
- lib/treaty/response/attribute/builder.rb
|
|
199
197
|
- lib/treaty/response/attribute/validation/orchestrator.rb
|
|
200
198
|
- lib/treaty/response/attribute/validator.rb
|
|
201
199
|
- lib/treaty/response/factory.rb
|
|
202
|
-
- lib/treaty/response/scope/collection.rb
|
|
203
|
-
- lib/treaty/response/scope/factory.rb
|
|
204
200
|
- lib/treaty/result.rb
|
|
205
201
|
- lib/treaty/strategy.rb
|
|
206
202
|
- lib/treaty/support/loader.rb
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Treaty
|
|
4
|
-
module Request
|
|
5
|
-
module Scope
|
|
6
|
-
class Collection
|
|
7
|
-
extend Forwardable
|
|
8
|
-
|
|
9
|
-
def_delegators :@collection, :<<, :to_h, :each, :find, :empty?
|
|
10
|
-
|
|
11
|
-
def initialize(collection = Set.new)
|
|
12
|
-
@collection = collection
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def exists?
|
|
16
|
-
!empty?
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Treaty
|
|
4
|
-
module Request
|
|
5
|
-
module Scope
|
|
6
|
-
class Factory
|
|
7
|
-
attr_reader :name
|
|
8
|
-
|
|
9
|
-
def initialize(name)
|
|
10
|
-
@name = name
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def attribute(name, type, *helpers, **options, &block)
|
|
14
|
-
collection_of_attributes << Attribute::Attribute.new(
|
|
15
|
-
name,
|
|
16
|
-
type,
|
|
17
|
-
*helpers,
|
|
18
|
-
nesting_level: 0,
|
|
19
|
-
**options,
|
|
20
|
-
&block
|
|
21
|
-
)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def collection_of_attributes
|
|
25
|
-
@collection_of_attributes ||= Treaty::Attribute::Collection.new
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
########################################################################
|
|
29
|
-
|
|
30
|
-
def method_missing(type, *helpers, **options, &block)
|
|
31
|
-
name = helpers.shift
|
|
32
|
-
|
|
33
|
-
attribute(name, type, *helpers, **options, &block)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def respond_to_missing?(name, *)
|
|
37
|
-
super
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Treaty
|
|
4
|
-
module Response
|
|
5
|
-
module Scope
|
|
6
|
-
class Collection
|
|
7
|
-
extend Forwardable
|
|
8
|
-
|
|
9
|
-
def_delegators :@collection, :<<, :to_h, :each, :find, :empty?
|
|
10
|
-
|
|
11
|
-
def initialize(collection = Set.new)
|
|
12
|
-
@collection = collection
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def exists?
|
|
16
|
-
!empty?
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Treaty
|
|
4
|
-
module Response
|
|
5
|
-
module Scope
|
|
6
|
-
class Factory
|
|
7
|
-
attr_reader :name
|
|
8
|
-
|
|
9
|
-
def initialize(name)
|
|
10
|
-
@name = name
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def attribute(name, type, *helpers, **options, &block)
|
|
14
|
-
collection_of_attributes << Attribute::Attribute.new(
|
|
15
|
-
name,
|
|
16
|
-
type,
|
|
17
|
-
*helpers,
|
|
18
|
-
nesting_level: 0,
|
|
19
|
-
**options,
|
|
20
|
-
&block
|
|
21
|
-
)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def collection_of_attributes
|
|
25
|
-
@collection_of_attributes ||= Treaty::Attribute::Collection.new
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
########################################################################
|
|
29
|
-
|
|
30
|
-
def method_missing(type, *helpers, **options, &block)
|
|
31
|
-
name = helpers.shift
|
|
32
|
-
|
|
33
|
-
attribute(name, type, *helpers, **options, &block)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def respond_to_missing?(name, *)
|
|
37
|
-
super
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|