treaty 0.10.0 → 0.11.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/config/locales/en.yml +2 -0
- data/lib/treaty/exceptions/version_default_deprecated_conflict.rb +83 -0
- data/lib/treaty/exceptions/version_multiple_defaults.rb +111 -0
- data/lib/treaty/version.rb +1 -1
- data/lib/treaty/versions/dsl.rb +12 -0
- data/lib/treaty/versions/factory.rb +15 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6ec3d8b8448c1cb6634404040ed78864beb81a317b705a14d6f3684caaaf5952
|
|
4
|
+
data.tar.gz: a21afccd9a25da7531ff561ed4baae2cc0011ed8c9c5b09b7ceb1370b79ba353
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0a8281e2551007b9c6b514b3d8d664d484b27e757733dd6a94d191bfdf8cce1d50a5b4f3bdee8fb8e4cadb51b1b90802697f0cd06a929c8cf39482f6aef6c5c3
|
|
7
|
+
data.tar.gz: 1855561545ee10307c8094377ed28a132a6a9ac8f9347801f9f1d80e7f6adbb6fddc812b34e2b7960336d8558d84e9d48691aeea525c6357962b66e2a0a56e7e
|
data/config/locales/en.yml
CHANGED
|
@@ -92,6 +92,8 @@ en:
|
|
|
92
92
|
factory:
|
|
93
93
|
invalid_default_option: "Default option for version must be true, false, or a Proc, got: %{type}"
|
|
94
94
|
unknown_method: "Unknown method '%{method}' in version definition. Available methods: summary, strategy, deprecated, request, response, delegate_to"
|
|
95
|
+
default_deprecated_conflict: "Version %{version} cannot be both default and deprecated. A default version must be active and usable. Either remove 'default: true' or remove the 'deprecated' declaration."
|
|
96
|
+
multiple_defaults: "Cannot have multiple versions marked as default. Only one version can be the default. Please review your treaty definition and ensure only one version has 'default: true'."
|
|
95
97
|
|
|
96
98
|
# Strategy validation
|
|
97
99
|
strategy:
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Treaty
|
|
4
|
+
module Exceptions
|
|
5
|
+
# Raised when a version is marked as both default and deprecated
|
|
6
|
+
#
|
|
7
|
+
# ## Purpose
|
|
8
|
+
#
|
|
9
|
+
# Prevents the logical contradiction of having a version that is both
|
|
10
|
+
# the default version (used when no version is specified) and deprecated
|
|
11
|
+
# (should not be used). A default version must be active and usable.
|
|
12
|
+
#
|
|
13
|
+
# ## Usage
|
|
14
|
+
#
|
|
15
|
+
# This exception is raised automatically during version definition validation:
|
|
16
|
+
#
|
|
17
|
+
# ### Invalid Configuration
|
|
18
|
+
# ```ruby
|
|
19
|
+
# class PostsTreaty < ApplicationTreaty
|
|
20
|
+
# version 1, default: true do
|
|
21
|
+
# deprecated true # ERROR: Cannot be both default and deprecated
|
|
22
|
+
# # ... rest of version definition
|
|
23
|
+
# end
|
|
24
|
+
# end
|
|
25
|
+
# ```
|
|
26
|
+
#
|
|
27
|
+
# ### Valid Configurations
|
|
28
|
+
# ```ruby
|
|
29
|
+
# # Option 1: Default version without deprecation
|
|
30
|
+
# version 1, default: true do
|
|
31
|
+
# # No deprecated call - valid
|
|
32
|
+
# end
|
|
33
|
+
#
|
|
34
|
+
# # Option 2: Deprecated version without default
|
|
35
|
+
# version 1 do
|
|
36
|
+
# deprecated true # Valid, but not default
|
|
37
|
+
# end
|
|
38
|
+
#
|
|
39
|
+
# # Option 3: Neither default nor deprecated
|
|
40
|
+
# version 1 do
|
|
41
|
+
# # Regular version - valid
|
|
42
|
+
# end
|
|
43
|
+
# ```
|
|
44
|
+
#
|
|
45
|
+
# ## When It's Raised
|
|
46
|
+
#
|
|
47
|
+
# The exception is raised during treaty class loading when:
|
|
48
|
+
# 1. A version has `default: true` in the version declaration
|
|
49
|
+
# 2. AND the same version calls `deprecated` method with any truthy value or block
|
|
50
|
+
#
|
|
51
|
+
# ## Integration
|
|
52
|
+
#
|
|
53
|
+
# This is a configuration error that should be caught during development.
|
|
54
|
+
# It can be rescued by application controllers:
|
|
55
|
+
#
|
|
56
|
+
# ```ruby
|
|
57
|
+
# rescue_from Treaty::Exceptions::VersionDefaultDeprecatedConflict, with: :render_config_error
|
|
58
|
+
#
|
|
59
|
+
# def render_config_error(exception)
|
|
60
|
+
# render json: { error: exception.message }, status: :internal_server_error # HTTP 500
|
|
61
|
+
# end
|
|
62
|
+
# ```
|
|
63
|
+
#
|
|
64
|
+
# ## HTTP Status
|
|
65
|
+
#
|
|
66
|
+
# Returns HTTP 500 Internal Server Error as this indicates a configuration
|
|
67
|
+
# problem in the application code that should be fixed by developers.
|
|
68
|
+
#
|
|
69
|
+
# ## Resolution
|
|
70
|
+
#
|
|
71
|
+
# To fix this error, choose one of the following:
|
|
72
|
+
# 1. Remove `default: true` if the version should be deprecated
|
|
73
|
+
# 2. Remove the `deprecated` call if the version should be default
|
|
74
|
+
# 3. Create a new version that will be the default, and deprecate the old one
|
|
75
|
+
#
|
|
76
|
+
# ## Related Exceptions
|
|
77
|
+
#
|
|
78
|
+
# - `VersionMultipleDefaults` - When multiple versions are marked as default
|
|
79
|
+
# - `Deprecated` - When attempting to use an already deprecated version
|
|
80
|
+
class VersionDefaultDeprecatedConflict < Base
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Treaty
|
|
4
|
+
module Exceptions
|
|
5
|
+
# Raised when multiple versions are marked as default in the same treaty
|
|
6
|
+
#
|
|
7
|
+
# ## Purpose
|
|
8
|
+
#
|
|
9
|
+
# Ensures that only one version in a treaty can be marked as the default.
|
|
10
|
+
# The default version is used when clients don't specify an API version
|
|
11
|
+
# in their requests, so having multiple defaults would create ambiguity.
|
|
12
|
+
#
|
|
13
|
+
# ## Usage
|
|
14
|
+
#
|
|
15
|
+
# This exception is raised automatically during version definition validation:
|
|
16
|
+
#
|
|
17
|
+
# ### Invalid Configuration
|
|
18
|
+
# ```ruby
|
|
19
|
+
# class PostsTreaty < ApplicationTreaty
|
|
20
|
+
# version 1, default: true do
|
|
21
|
+
# # First default version
|
|
22
|
+
# end
|
|
23
|
+
#
|
|
24
|
+
# version 2, default: true do
|
|
25
|
+
# # ERROR: Cannot have two default versions
|
|
26
|
+
# end
|
|
27
|
+
# end
|
|
28
|
+
# ```
|
|
29
|
+
#
|
|
30
|
+
# ### Valid Configurations
|
|
31
|
+
# ```ruby
|
|
32
|
+
# # Option 1: Single default version
|
|
33
|
+
# class PostsTreaty < ApplicationTreaty
|
|
34
|
+
# version 1 do
|
|
35
|
+
# # Not default
|
|
36
|
+
# end
|
|
37
|
+
#
|
|
38
|
+
# version 2, default: true do
|
|
39
|
+
# # Only one default - valid
|
|
40
|
+
# end
|
|
41
|
+
# end
|
|
42
|
+
#
|
|
43
|
+
# # Option 2: No default version (version must be explicitly specified)
|
|
44
|
+
# class PostsTreaty < ApplicationTreaty
|
|
45
|
+
# version 1 do
|
|
46
|
+
# # Not default
|
|
47
|
+
# end
|
|
48
|
+
#
|
|
49
|
+
# version 2 do
|
|
50
|
+
# # Not default - valid, but version must be specified in requests
|
|
51
|
+
# end
|
|
52
|
+
# end
|
|
53
|
+
# ```
|
|
54
|
+
#
|
|
55
|
+
# ## When It's Raised
|
|
56
|
+
#
|
|
57
|
+
# The exception is raised during treaty class loading when:
|
|
58
|
+
# 1. A second version is being defined with `default: true`
|
|
59
|
+
# 2. AND another version already has `default: true`
|
|
60
|
+
#
|
|
61
|
+
# ## Integration
|
|
62
|
+
#
|
|
63
|
+
# This is a configuration error that should be caught during development.
|
|
64
|
+
# It can be rescued by application controllers:
|
|
65
|
+
#
|
|
66
|
+
# ```ruby
|
|
67
|
+
# rescue_from Treaty::Exceptions::VersionMultipleDefaults, with: :render_config_error
|
|
68
|
+
#
|
|
69
|
+
# def render_config_error(exception)
|
|
70
|
+
# render json: { error: exception.message }, status: :internal_server_error # HTTP 500
|
|
71
|
+
# end
|
|
72
|
+
# ```
|
|
73
|
+
#
|
|
74
|
+
# ## HTTP Status
|
|
75
|
+
#
|
|
76
|
+
# Returns HTTP 500 Internal Server Error as this indicates a configuration
|
|
77
|
+
# problem in the application code that should be fixed by developers.
|
|
78
|
+
#
|
|
79
|
+
# ## Resolution
|
|
80
|
+
#
|
|
81
|
+
# To fix this error:
|
|
82
|
+
# 1. Identify which version should truly be the default
|
|
83
|
+
# 2. Remove `default: true` from all other versions
|
|
84
|
+
# 3. Keep only one `default: true` declaration
|
|
85
|
+
#
|
|
86
|
+
# ## Best Practice
|
|
87
|
+
#
|
|
88
|
+
# Typically, the newest stable version should be marked as default:
|
|
89
|
+
#
|
|
90
|
+
# ```ruby
|
|
91
|
+
# version 1 do
|
|
92
|
+
# deprecated true # Old version
|
|
93
|
+
# end
|
|
94
|
+
#
|
|
95
|
+
# version 2 do
|
|
96
|
+
# # Stable version
|
|
97
|
+
# end
|
|
98
|
+
#
|
|
99
|
+
# version 3, default: true do
|
|
100
|
+
# # Latest stable version - the default
|
|
101
|
+
# end
|
|
102
|
+
# ```
|
|
103
|
+
#
|
|
104
|
+
# ## Related Exceptions
|
|
105
|
+
#
|
|
106
|
+
# - `VersionDefaultDeprecatedConflict` - When a single version has both default and deprecated
|
|
107
|
+
# - `SpecifiedVersionNotFound` - When no default exists and no version is specified
|
|
108
|
+
class VersionMultipleDefaults < Base
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
data/lib/treaty/version.rb
CHANGED
data/lib/treaty/versions/dsl.rb
CHANGED
|
@@ -15,6 +15,9 @@ module Treaty
|
|
|
15
15
|
@version_factory = Factory.new(version:, default:)
|
|
16
16
|
|
|
17
17
|
@version_factory.instance_eval(&block)
|
|
18
|
+
@version_factory.validate_after_block!
|
|
19
|
+
|
|
20
|
+
validate_multiple_defaults! if @version_factory.default_result == true
|
|
18
21
|
|
|
19
22
|
collection_of_versions << @version_factory
|
|
20
23
|
|
|
@@ -24,6 +27,15 @@ module Treaty
|
|
|
24
27
|
def collection_of_versions
|
|
25
28
|
@collection_of_versions ||= Collection.new
|
|
26
29
|
end
|
|
30
|
+
|
|
31
|
+
def validate_multiple_defaults!
|
|
32
|
+
existing_defaults = collection_of_versions.map(&:default_result).count(true)
|
|
33
|
+
|
|
34
|
+
return if existing_defaults.zero?
|
|
35
|
+
|
|
36
|
+
raise Treaty::Exceptions::VersionMultipleDefaults,
|
|
37
|
+
I18n.t("treaty.versioning.factory.multiple_defaults")
|
|
38
|
+
end
|
|
27
39
|
end
|
|
28
40
|
end
|
|
29
41
|
end
|
|
@@ -27,6 +27,10 @@ module Treaty
|
|
|
27
27
|
validate_default_option!
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
def validate_after_block!
|
|
31
|
+
validate_default_deprecated_conflict!
|
|
32
|
+
end
|
|
33
|
+
|
|
30
34
|
def summary(text)
|
|
31
35
|
@summary_text = text
|
|
32
36
|
end
|
|
@@ -88,6 +92,17 @@ module Treaty
|
|
|
88
92
|
)
|
|
89
93
|
end
|
|
90
94
|
|
|
95
|
+
def validate_default_deprecated_conflict!
|
|
96
|
+
return unless @default_result == true
|
|
97
|
+
return unless @deprecated_result == true
|
|
98
|
+
|
|
99
|
+
raise Treaty::Exceptions::VersionDefaultDeprecatedConflict,
|
|
100
|
+
I18n.t(
|
|
101
|
+
"treaty.versioning.factory.default_deprecated_conflict",
|
|
102
|
+
version: @version.version
|
|
103
|
+
)
|
|
104
|
+
end
|
|
105
|
+
|
|
91
106
|
##########################################################################
|
|
92
107
|
|
|
93
108
|
def method_missing(name, *, &_block)
|
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.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Anton Sokolov
|
|
@@ -190,6 +190,8 @@ files:
|
|
|
190
190
|
- lib/treaty/exceptions/strategy.rb
|
|
191
191
|
- lib/treaty/exceptions/unexpected.rb
|
|
192
192
|
- lib/treaty/exceptions/validation.rb
|
|
193
|
+
- lib/treaty/exceptions/version_default_deprecated_conflict.rb
|
|
194
|
+
- lib/treaty/exceptions/version_multiple_defaults.rb
|
|
193
195
|
- lib/treaty/exceptions/version_not_found.rb
|
|
194
196
|
- lib/treaty/info/entity/builder.rb
|
|
195
197
|
- lib/treaty/info/entity/dsl.rb
|