petstore_api_client 0.1.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 +7 -0
- data/.editorconfig +33 -0
- data/.env.example +50 -0
- data/.github/CODEOWNERS +36 -0
- data/.github/workflows/ci.yml +157 -0
- data/.ruby-version +1 -0
- data/CONTRIBUTORS.md +39 -0
- data/LICENSE +21 -0
- data/README.md +684 -0
- data/Rakefile +12 -0
- data/lib/petstore_api_client/api_client.rb +60 -0
- data/lib/petstore_api_client/authentication/api_key.rb +107 -0
- data/lib/petstore_api_client/authentication/base.rb +113 -0
- data/lib/petstore_api_client/authentication/composite.rb +178 -0
- data/lib/petstore_api_client/authentication/none.rb +42 -0
- data/lib/petstore_api_client/authentication/oauth2.rb +305 -0
- data/lib/petstore_api_client/client.rb +87 -0
- data/lib/petstore_api_client/clients/concerns/pagination.rb +124 -0
- data/lib/petstore_api_client/clients/concerns/resource_operations.rb +121 -0
- data/lib/petstore_api_client/clients/pet_client.rb +119 -0
- data/lib/petstore_api_client/clients/store_client.rb +37 -0
- data/lib/petstore_api_client/configuration.rb +318 -0
- data/lib/petstore_api_client/connection.rb +55 -0
- data/lib/petstore_api_client/errors.rb +70 -0
- data/lib/petstore_api_client/middleware/authentication.rb +44 -0
- data/lib/petstore_api_client/models/api_response.rb +31 -0
- data/lib/petstore_api_client/models/base.rb +60 -0
- data/lib/petstore_api_client/models/category.rb +17 -0
- data/lib/petstore_api_client/models/named_entity.rb +36 -0
- data/lib/petstore_api_client/models/order.rb +55 -0
- data/lib/petstore_api_client/models/pet.rb +225 -0
- data/lib/petstore_api_client/models/tag.rb +20 -0
- data/lib/petstore_api_client/paginated_collection.rb +133 -0
- data/lib/petstore_api_client/request.rb +225 -0
- data/lib/petstore_api_client/response.rb +193 -0
- data/lib/petstore_api_client/validators/array_presence_validator.rb +15 -0
- data/lib/petstore_api_client/validators/enum_validator.rb +17 -0
- data/lib/petstore_api_client/version.rb +5 -0
- data/lib/petstore_api_client.rb +55 -0
- metadata +252 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PetstoreApiClient
|
|
4
|
+
# HTTP request methods for the Petstore API client
|
|
5
|
+
#
|
|
6
|
+
# Provides high-level abstraction over HTTP operations using Faraday.
|
|
7
|
+
# This module implements the Dependency Inversion Principle by abstracting
|
|
8
|
+
# HTTP operations behind a clean interface.
|
|
9
|
+
#
|
|
10
|
+
# All HTTP methods return a Response object that wraps the Faraday response.
|
|
11
|
+
# Errors are automatically detected and raised as appropriate exception types.
|
|
12
|
+
#
|
|
13
|
+
# This module is included by Client and provides:
|
|
14
|
+
# - GET requests for retrieving resources
|
|
15
|
+
# - POST requests for creating resources
|
|
16
|
+
# - PUT requests for updating resources
|
|
17
|
+
# - DELETE requests for removing resources
|
|
18
|
+
#
|
|
19
|
+
# @example Making a GET request
|
|
20
|
+
# client = Client.new
|
|
21
|
+
# response = client.get("/pet/123")
|
|
22
|
+
# pet = response.body
|
|
23
|
+
#
|
|
24
|
+
# @example Making a POST request with body
|
|
25
|
+
# response = client.post("/pet", body: { name: "Fluffy", status: "available" })
|
|
26
|
+
#
|
|
27
|
+
# @see Connection
|
|
28
|
+
# @see Response
|
|
29
|
+
# @since 0.1.0
|
|
30
|
+
module Request
|
|
31
|
+
# Perform HTTP GET request
|
|
32
|
+
#
|
|
33
|
+
# Retrieves a resource from the API. Query parameters can be provided
|
|
34
|
+
# via the params hash.
|
|
35
|
+
#
|
|
36
|
+
# @param path [String] The API endpoint path (e.g., "/pet/123")
|
|
37
|
+
# @param params [Hash] Optional query parameters
|
|
38
|
+
#
|
|
39
|
+
# @return [Response] Wrapped HTTP response
|
|
40
|
+
#
|
|
41
|
+
# @raise [NotFoundError] if resource not found (404)
|
|
42
|
+
# @raise [InvalidInputError] if request is invalid (400, 405)
|
|
43
|
+
# @raise [RateLimitError] if rate limit exceeded (429)
|
|
44
|
+
# @raise [ConnectionError] if connection fails or times out
|
|
45
|
+
# @raise [ApiError] for other API errors
|
|
46
|
+
#
|
|
47
|
+
# @example Get a pet by ID
|
|
48
|
+
# response = client.get("/pet/123")
|
|
49
|
+
# pet = response.body
|
|
50
|
+
#
|
|
51
|
+
# @example Get pets with query parameters
|
|
52
|
+
# response = client.get("/pet/findByStatus", params: { status: "available" })
|
|
53
|
+
# pets = response.body
|
|
54
|
+
#
|
|
55
|
+
def get(path, params: {})
|
|
56
|
+
request(:get, path, params: params)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Perform HTTP POST request
|
|
60
|
+
#
|
|
61
|
+
# Creates a new resource on the API. The request body should contain
|
|
62
|
+
# the resource data as a hash, which will be automatically serialized to JSON.
|
|
63
|
+
#
|
|
64
|
+
# @param path [String] The API endpoint path
|
|
65
|
+
# @param body [Hash] Request body data
|
|
66
|
+
#
|
|
67
|
+
# @return [Response] Wrapped HTTP response
|
|
68
|
+
#
|
|
69
|
+
# @raise [InvalidInputError] if request body is invalid
|
|
70
|
+
# @raise [ValidationError] if data fails validation
|
|
71
|
+
# @raise [RateLimitError] if rate limit exceeded
|
|
72
|
+
# @raise [ConnectionError] if connection fails or times out
|
|
73
|
+
# @raise [ApiError] for other API errors
|
|
74
|
+
#
|
|
75
|
+
# @example Create a new pet
|
|
76
|
+
# response = client.post("/pet", body: {
|
|
77
|
+
# name: "Fluffy",
|
|
78
|
+
# status: "available",
|
|
79
|
+
# category: { id: 1, name: "Dogs" }
|
|
80
|
+
# })
|
|
81
|
+
#
|
|
82
|
+
def post(path, body: {})
|
|
83
|
+
request(:post, path, body: body)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Perform HTTP PUT request
|
|
87
|
+
#
|
|
88
|
+
# Updates an existing resource on the API. The request body should contain
|
|
89
|
+
# the updated resource data as a hash.
|
|
90
|
+
#
|
|
91
|
+
# @param path [String] The API endpoint path
|
|
92
|
+
# @param body [Hash] Request body data with updates
|
|
93
|
+
#
|
|
94
|
+
# @return [Response] Wrapped HTTP response
|
|
95
|
+
#
|
|
96
|
+
# @raise [NotFoundError] if resource not found (404)
|
|
97
|
+
# @raise [InvalidInputError] if request body is invalid
|
|
98
|
+
# @raise [ValidationError] if data fails validation
|
|
99
|
+
# @raise [ConnectionError] if connection fails or times out
|
|
100
|
+
# @raise [ApiError] for other API errors
|
|
101
|
+
#
|
|
102
|
+
# @example Update an existing pet
|
|
103
|
+
# response = client.put("/pet", body: {
|
|
104
|
+
# id: 123,
|
|
105
|
+
# name: "Fluffy Updated",
|
|
106
|
+
# status: "sold"
|
|
107
|
+
# })
|
|
108
|
+
#
|
|
109
|
+
def put(path, body: {})
|
|
110
|
+
request(:put, path, body: body)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Perform HTTP DELETE request
|
|
114
|
+
#
|
|
115
|
+
# Deletes a resource from the API. Query parameters can be provided
|
|
116
|
+
# via the params hash if needed.
|
|
117
|
+
#
|
|
118
|
+
# @param path [String] The API endpoint path
|
|
119
|
+
# @param params [Hash] Optional query parameters
|
|
120
|
+
#
|
|
121
|
+
# @return [Response] Wrapped HTTP response
|
|
122
|
+
#
|
|
123
|
+
# @raise [NotFoundError] if resource not found (404)
|
|
124
|
+
# @raise [InvalidInputError] if request is invalid
|
|
125
|
+
# @raise [ConnectionError] if connection fails or times out
|
|
126
|
+
# @raise [ApiError] for other API errors
|
|
127
|
+
#
|
|
128
|
+
# @example Delete a pet
|
|
129
|
+
# response = client.delete("/pet/123")
|
|
130
|
+
#
|
|
131
|
+
def delete(path, params: {})
|
|
132
|
+
request(:delete, path, params: params)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
private
|
|
136
|
+
|
|
137
|
+
# Core request method that handles all HTTP operations
|
|
138
|
+
#
|
|
139
|
+
# This is the central method that all public HTTP methods (get, post, put, delete)
|
|
140
|
+
# delegate to. It handles:
|
|
141
|
+
# - Executing the HTTP request via Faraday
|
|
142
|
+
# - Wrapping the response in a Response object
|
|
143
|
+
# - Error detection and exception raising
|
|
144
|
+
# - Connection error handling
|
|
145
|
+
#
|
|
146
|
+
# @param method [Symbol] HTTP method (:get, :post, :put, :delete)
|
|
147
|
+
# @param path [String] API endpoint path
|
|
148
|
+
# @param params [Hash] Query parameters for GET/DELETE requests
|
|
149
|
+
# @param body [Hash] Request body for POST/PUT requests
|
|
150
|
+
#
|
|
151
|
+
# @return [Response] Wrapped HTTP response
|
|
152
|
+
#
|
|
153
|
+
# @raise [ConnectionError] if connection fails or times out
|
|
154
|
+
# @raise [ApiError] for unexpected errors
|
|
155
|
+
# @raise [NotFoundError, InvalidInputError, RateLimitError, etc.] for API errors
|
|
156
|
+
#
|
|
157
|
+
# @api private
|
|
158
|
+
def request(method, path, params: {}, body: {})
|
|
159
|
+
# puts "DEBUG: #{method.upcase} #{path}" if ENV['DEBUG']
|
|
160
|
+
resp = connection.public_send(method) do |req|
|
|
161
|
+
req.url path
|
|
162
|
+
req.params = params if params.any?
|
|
163
|
+
req.body = body if body.any?
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
wrapped_resp = Response.new(resp)
|
|
167
|
+
handle_error_response(wrapped_resp) if wrapped_resp.error?
|
|
168
|
+
|
|
169
|
+
wrapped_resp
|
|
170
|
+
rescue Faraday::ConnectionFailed => e
|
|
171
|
+
raise ConnectionError, "Connection failed: #{e.message}"
|
|
172
|
+
rescue Faraday::TimeoutError => e
|
|
173
|
+
raise ConnectionError, "Request timeout: #{e.message}"
|
|
174
|
+
rescue Error
|
|
175
|
+
# Don't double-wrap our own errors
|
|
176
|
+
raise
|
|
177
|
+
rescue StandardError => e
|
|
178
|
+
# Catch-all for unexpected errors
|
|
179
|
+
raise ApiError, "Request failed: #{e.message}"
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Handle error responses and raise appropriate exceptions
|
|
183
|
+
#
|
|
184
|
+
# Examines the HTTP status code and error message from the API response
|
|
185
|
+
# and raises the appropriate exception type. This provides a clean
|
|
186
|
+
# abstraction where callers can rescue specific error types.
|
|
187
|
+
#
|
|
188
|
+
# Status code mapping:
|
|
189
|
+
# - 404: NotFoundError
|
|
190
|
+
# - 400: InvalidOrderError (if error_type is "InvalidOrder") or InvalidInputError
|
|
191
|
+
# - 405: InvalidInputError
|
|
192
|
+
# - 429: RateLimitError (includes retry-after header)
|
|
193
|
+
# - Other: ApiError
|
|
194
|
+
#
|
|
195
|
+
# @param response [Response] The wrapped HTTP response
|
|
196
|
+
# @return [void]
|
|
197
|
+
#
|
|
198
|
+
# @raise [NotFoundError] for 404 responses
|
|
199
|
+
# @raise [InvalidInputError] for 400/405 responses
|
|
200
|
+
# @raise [InvalidOrderError] for 400 responses with InvalidOrder error type
|
|
201
|
+
# @raise [RateLimitError] for 429 responses
|
|
202
|
+
# @raise [ApiError] for other error responses
|
|
203
|
+
#
|
|
204
|
+
# @api private
|
|
205
|
+
def handle_error_response(response)
|
|
206
|
+
case response.status
|
|
207
|
+
when 404
|
|
208
|
+
raise NotFoundError, response.error_message
|
|
209
|
+
when 400
|
|
210
|
+
# Check if it's an order-related error
|
|
211
|
+
raise InvalidOrderError, response.error_message if response.error_type == "InvalidOrder"
|
|
212
|
+
|
|
213
|
+
raise InvalidInputError, response.error_message
|
|
214
|
+
when 405
|
|
215
|
+
raise InvalidInputError, response.error_message
|
|
216
|
+
when 429
|
|
217
|
+
# Rate limiting - extract retry-after header if present
|
|
218
|
+
retry_after = response.headers["retry-after"] || response.headers["Retry-After"]
|
|
219
|
+
raise RateLimitError.new(response.error_message, retry_after: retry_after)
|
|
220
|
+
else
|
|
221
|
+
raise ApiError, response.error_message
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
end
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PetstoreApiClient
|
|
4
|
+
# HTTP response wrapper for Petstore API responses
|
|
5
|
+
#
|
|
6
|
+
# Wraps Faraday HTTP responses and provides a clean, consistent interface
|
|
7
|
+
# for accessing response data. This class implements the Single Responsibility
|
|
8
|
+
# Principle by encapsulating all response handling logic in one place.
|
|
9
|
+
#
|
|
10
|
+
# The Response object provides:
|
|
11
|
+
# - Parsed JSON body (automatically converted from JSON)
|
|
12
|
+
# - HTTP status code
|
|
13
|
+
# - Response headers
|
|
14
|
+
# - Success/error detection
|
|
15
|
+
# - Error message extraction
|
|
16
|
+
# - Access to raw Faraday response
|
|
17
|
+
#
|
|
18
|
+
# Response bodies are automatically parsed from JSON. If the API returns
|
|
19
|
+
# non-JSON content (like HTML error pages), the body is returned as a string.
|
|
20
|
+
#
|
|
21
|
+
# @example Accessing a successful response
|
|
22
|
+
# response = client.get("/pet/123")
|
|
23
|
+
# if response.success?
|
|
24
|
+
# pet = response.body
|
|
25
|
+
# puts pet["name"]
|
|
26
|
+
# end
|
|
27
|
+
#
|
|
28
|
+
# @example Handling an error response
|
|
29
|
+
# response = client.get("/pet/invalid")
|
|
30
|
+
# if response.error?
|
|
31
|
+
# puts response.error_message
|
|
32
|
+
# puts response.error_code
|
|
33
|
+
# end
|
|
34
|
+
#
|
|
35
|
+
# @see Request
|
|
36
|
+
# @since 0.1.0
|
|
37
|
+
class Response
|
|
38
|
+
# @!attribute [r] status
|
|
39
|
+
# @return [Integer] HTTP status code (e.g., 200, 404, 500)
|
|
40
|
+
# @!attribute [r] body
|
|
41
|
+
# @return [Hash, Array, String] Parsed response body
|
|
42
|
+
# @!attribute [r] headers
|
|
43
|
+
# @return [Hash] HTTP response headers
|
|
44
|
+
# @!attribute [r] raw_response
|
|
45
|
+
# @return [Faraday::Response] Original Faraday response object
|
|
46
|
+
attr_reader :status, :body, :headers, :raw_response
|
|
47
|
+
|
|
48
|
+
# Initialize a new Response wrapper
|
|
49
|
+
#
|
|
50
|
+
# Wraps a Faraday response object and extracts relevant data.
|
|
51
|
+
# The response body is automatically parsed from JSON to Ruby objects.
|
|
52
|
+
#
|
|
53
|
+
# @param faraday_response [Faraday::Response] The Faraday response object
|
|
54
|
+
#
|
|
55
|
+
# @example
|
|
56
|
+
# faraday_response = connection.get("/pet/123")
|
|
57
|
+
# response = Response.new(faraday_response)
|
|
58
|
+
#
|
|
59
|
+
def initialize(faraday_response)
|
|
60
|
+
@raw_response = faraday_response
|
|
61
|
+
@status = faraday_response.status
|
|
62
|
+
@body = parse_body(faraday_response.body)
|
|
63
|
+
@headers = faraday_response.headers
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Check if the response was successful
|
|
67
|
+
#
|
|
68
|
+
# A response is considered successful if the HTTP status code is
|
|
69
|
+
# in the 2xx range (200-299).
|
|
70
|
+
#
|
|
71
|
+
# @return [Boolean] true if status is 200-299, false otherwise
|
|
72
|
+
#
|
|
73
|
+
# @example
|
|
74
|
+
# response = client.get("/pet/123")
|
|
75
|
+
# if response.success?
|
|
76
|
+
# # Handle successful response
|
|
77
|
+
# end
|
|
78
|
+
#
|
|
79
|
+
def success?
|
|
80
|
+
(200..299).cover?(status)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Check if response indicates an error
|
|
84
|
+
#
|
|
85
|
+
# A response is considered an error if the HTTP status code is
|
|
86
|
+
# outside the 2xx range.
|
|
87
|
+
#
|
|
88
|
+
# @return [Boolean] true if status is not 200-299, false otherwise
|
|
89
|
+
#
|
|
90
|
+
# @example
|
|
91
|
+
# response = client.get("/pet/invalid")
|
|
92
|
+
# if response.error?
|
|
93
|
+
# puts response.error_message
|
|
94
|
+
# end
|
|
95
|
+
#
|
|
96
|
+
def error?
|
|
97
|
+
!success?
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Extract error message from response body
|
|
101
|
+
#
|
|
102
|
+
# Attempts to extract a human-readable error message from the response.
|
|
103
|
+
# Handles various response formats:
|
|
104
|
+
# - JSON with "message" key
|
|
105
|
+
# - Plain text error messages
|
|
106
|
+
# - HTML error pages
|
|
107
|
+
# - Empty/nil responses
|
|
108
|
+
#
|
|
109
|
+
# @return [String, nil] Error message if response is an error, nil otherwise
|
|
110
|
+
#
|
|
111
|
+
# @example JSON error response
|
|
112
|
+
# # API returns: { "code": 404, "type": "NotFound", "message": "Pet not found" }
|
|
113
|
+
# response.error_message # => "Pet not found"
|
|
114
|
+
#
|
|
115
|
+
# @example HTML error response
|
|
116
|
+
# # API returns HTML error page
|
|
117
|
+
# response.error_message # => "Request failed with status 500"
|
|
118
|
+
#
|
|
119
|
+
def error_message
|
|
120
|
+
return nil unless error?
|
|
121
|
+
|
|
122
|
+
# Extract message from different response formats
|
|
123
|
+
case body
|
|
124
|
+
when Hash
|
|
125
|
+
body["message"] || body[:message] || "Unknown error"
|
|
126
|
+
when String
|
|
127
|
+
# Sometimes the API returns HTML instead of JSON (sigh...)
|
|
128
|
+
body.include?("<html>") ? "Request failed with status #{status}" : body
|
|
129
|
+
else
|
|
130
|
+
"Request failed with status #{status}"
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Extract error code from response body
|
|
135
|
+
#
|
|
136
|
+
# Returns the error code from the response if available.
|
|
137
|
+
# Falls back to HTTP status code if no error code is present in body.
|
|
138
|
+
#
|
|
139
|
+
# @return [Integer, nil] Error code if response is an error, nil otherwise
|
|
140
|
+
#
|
|
141
|
+
# @example
|
|
142
|
+
# # API returns: { "code": 1, "type": "NotFound", "message": "Pet not found" }
|
|
143
|
+
# response.error_code # => 1
|
|
144
|
+
#
|
|
145
|
+
def error_code
|
|
146
|
+
return nil unless error?
|
|
147
|
+
|
|
148
|
+
body.is_a?(Hash) ? (body["code"] || body[:code]) : status
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Extract error type from response body
|
|
152
|
+
#
|
|
153
|
+
# Returns the error type/category from the response if available.
|
|
154
|
+
# This is useful for programmatic error handling.
|
|
155
|
+
#
|
|
156
|
+
# @return [String, nil] Error type if available, nil otherwise
|
|
157
|
+
#
|
|
158
|
+
# @example
|
|
159
|
+
# # API returns: { "code": 1, "type": "NotFound", "message": "Pet not found" }
|
|
160
|
+
# response.error_type # => "NotFound"
|
|
161
|
+
#
|
|
162
|
+
def error_type
|
|
163
|
+
return nil unless error?
|
|
164
|
+
|
|
165
|
+
body.is_a?(Hash) ? (body["type"] || body[:type]) : nil
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
private
|
|
169
|
+
|
|
170
|
+
# Parse response body from JSON
|
|
171
|
+
#
|
|
172
|
+
# Handles JSON parsing and various edge cases:
|
|
173
|
+
# - Already-parsed JSON (Hash/Array)
|
|
174
|
+
# - Empty/nil responses
|
|
175
|
+
# - Non-JSON responses (returns as-is)
|
|
176
|
+
#
|
|
177
|
+
# Faraday's JSON middleware typically handles parsing, but this method
|
|
178
|
+
# provides additional safety for edge cases.
|
|
179
|
+
#
|
|
180
|
+
# @param body [Object] Raw response body
|
|
181
|
+
# @return [Hash, Array, String, Object] Parsed body
|
|
182
|
+
#
|
|
183
|
+
# @api private
|
|
184
|
+
def parse_body(body)
|
|
185
|
+
# Faraday's JSON middleware already parses the response,
|
|
186
|
+
# but we handle edge cases here
|
|
187
|
+
return body if body.is_a?(Hash) || body.is_a?(Array)
|
|
188
|
+
return {} if body.nil? || body.empty?
|
|
189
|
+
|
|
190
|
+
body
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Custom validator for required array fields
|
|
4
|
+
# ActiveModel's presence validator doesn't handle empty arrays correctly
|
|
5
|
+
class ArrayPresenceValidator < ActiveModel::EachValidator
|
|
6
|
+
def validate_each(record, attribute, value)
|
|
7
|
+
if value.nil?
|
|
8
|
+
record.errors.add(attribute, "must be present")
|
|
9
|
+
elsif !value.is_a?(Array)
|
|
10
|
+
record.errors.add(attribute, "must be an array")
|
|
11
|
+
elsif value.empty?
|
|
12
|
+
record.errors.add(attribute, "cannot be empty")
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Custom enum validator - ActiveModel's inclusion validator doesn't quite work the way we want
|
|
4
|
+
# for status enums, so rolling our own
|
|
5
|
+
class EnumValidator < ActiveModel::EachValidator
|
|
6
|
+
def validate_each(record, attribute, value)
|
|
7
|
+
return if value.nil? && options[:allow_nil]
|
|
8
|
+
|
|
9
|
+
allowed_values = options[:in] || options[:within]
|
|
10
|
+
return if allowed_values.include?(value)
|
|
11
|
+
|
|
12
|
+
record.errors.add(
|
|
13
|
+
attribute,
|
|
14
|
+
"must be one of: #{allowed_values.join(", ")}, but got '#{value}'"
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_model"
|
|
4
|
+
require "active_support/all"
|
|
5
|
+
|
|
6
|
+
require_relative "petstore_api_client/version"
|
|
7
|
+
require_relative "petstore_api_client/errors"
|
|
8
|
+
require_relative "petstore_api_client/configuration"
|
|
9
|
+
require_relative "petstore_api_client/response"
|
|
10
|
+
require_relative "petstore_api_client/paginated_collection"
|
|
11
|
+
require_relative "petstore_api_client/connection"
|
|
12
|
+
require_relative "petstore_api_client/request"
|
|
13
|
+
require_relative "petstore_api_client/client"
|
|
14
|
+
|
|
15
|
+
# Load validators
|
|
16
|
+
require_relative "petstore_api_client/validators/array_presence_validator"
|
|
17
|
+
require_relative "petstore_api_client/validators/enum_validator"
|
|
18
|
+
|
|
19
|
+
# Load models
|
|
20
|
+
require_relative "petstore_api_client/models/category"
|
|
21
|
+
require_relative "petstore_api_client/models/tag"
|
|
22
|
+
require_relative "petstore_api_client/models/api_response"
|
|
23
|
+
require_relative "petstore_api_client/models/pet"
|
|
24
|
+
require_relative "petstore_api_client/models/order"
|
|
25
|
+
|
|
26
|
+
# Load clients
|
|
27
|
+
require_relative "petstore_api_client/clients/pet_client"
|
|
28
|
+
require_relative "petstore_api_client/clients/store_client"
|
|
29
|
+
require_relative "petstore_api_client/api_client"
|
|
30
|
+
|
|
31
|
+
# Module for the Petstore API Client library
|
|
32
|
+
module PetstoreApiClient
|
|
33
|
+
class << self
|
|
34
|
+
attr_writer :configuration
|
|
35
|
+
|
|
36
|
+
# Global configuration accessor
|
|
37
|
+
def configuration
|
|
38
|
+
@configuration ||= Configuration.new
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Configure the library globally
|
|
42
|
+
# Example:
|
|
43
|
+
# PetstoreApiClient.configure do |config|
|
|
44
|
+
# config.api_key = "special-key"
|
|
45
|
+
# end
|
|
46
|
+
def configure
|
|
47
|
+
yield(configuration) if block_given?
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Reset the global configuration
|
|
51
|
+
def reset_configuration!
|
|
52
|
+
@configuration = Configuration.new
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|