purple-client 0.1.7.2 → 0.1.7.4
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 +143 -0
- data/lib/purple/client/version.rb +7 -0
- data/lib/purple/client.rb +2 -1
- data/lib/purple/path.rb +5 -2
- data/lib/purple/response.rb +1 -0
- data/lib/purple/responses/body.rb +3 -0
- data/lib/purple/responses/object.rb +1 -0
- data/lib/purple/version.rb +1 -1
- metadata +31 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 81f0cb64364ec0312d07b900ae67a2e65137d03818c6b3e2c1b8631221ea9a65
|
4
|
+
data.tar.gz: 7404f01d3ba5714093d62fbac16218b263f20c43d0b29391add9fd9833ccdb29
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab18072bf25f80e0ded0dc7d3f317230fb93e400cbc9a563bf0d6be68b3c166458bf94f39877eb6dc535bce4c1e8c962b002699e3f4e08702effee65ba86e397
|
7
|
+
data.tar.gz: ef5033eb7da7a10bf033583603906b31176a63222e95e5f18bbdcab613b4ac775d4cb76594419c796206d65680dfc836d88ffe8f62973b38ad867a81928a1c8d
|
data/README.md
CHANGED
@@ -121,6 +121,36 @@ end
|
|
121
121
|
PostsClient.user_posts(user_id: 7)
|
122
122
|
```
|
123
123
|
|
124
|
+
### Paths nested under parameters
|
125
|
+
|
126
|
+
When a path segment is marked with `is_param: true`, any paths nested
|
127
|
+
inside it will not have a `root_method` generated. Instead of calling a
|
128
|
+
root method, you need to chain the segment methods manually.
|
129
|
+
|
130
|
+
```ruby
|
131
|
+
class BrowserClient < Purple::Client
|
132
|
+
domain 'https://api.example.com'
|
133
|
+
|
134
|
+
path :browser do
|
135
|
+
path :id, is_param: true do
|
136
|
+
path :web, method: :post do
|
137
|
+
response :ok do
|
138
|
+
end
|
139
|
+
|
140
|
+
response :bad_request do
|
141
|
+
body do |res|
|
142
|
+
puts res
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
# root_method :web will not work here
|
151
|
+
BrowserClient.browser.id('123').web
|
152
|
+
```
|
153
|
+
|
124
154
|
### Callbacks with additional arguments
|
125
155
|
|
126
156
|
```ruby
|
@@ -174,6 +204,119 @@ class AccountsClient < Purple::Client
|
|
174
204
|
end
|
175
205
|
```
|
176
206
|
|
207
|
+
### Optional fields
|
208
|
+
|
209
|
+
Sometimes an API response omits certain keys. You can mark those fields as
|
210
|
+
optional in the body definition so their absence doesn't raise validation errors.
|
211
|
+
|
212
|
+
```ruby
|
213
|
+
class CalendarClient < Purple::Client
|
214
|
+
domain 'https://api.example.com'
|
215
|
+
|
216
|
+
path :schedule do
|
217
|
+
response :ok do
|
218
|
+
body(
|
219
|
+
day: { type: Integer, optional: true },
|
220
|
+
)
|
221
|
+
end
|
222
|
+
root_method :schedule
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
# The `day` attribute may be missing in the response
|
227
|
+
CalendarClient.schedule
|
228
|
+
```
|
229
|
+
|
230
|
+
### Allow blank fields
|
231
|
+
|
232
|
+
Some APIs return keys that are present but contain `null` or empty string values.
|
233
|
+
You can mark those fields with `allow_blank` so blank values do not raise
|
234
|
+
validation errors.
|
235
|
+
|
236
|
+
```ruby
|
237
|
+
class ProfilesClient < Purple::Client
|
238
|
+
domain 'https://api.example.com'
|
239
|
+
|
240
|
+
path :profile do
|
241
|
+
response :ok do
|
242
|
+
body(
|
243
|
+
middle_name: { type: String, allow_blank: true },
|
244
|
+
)
|
245
|
+
end
|
246
|
+
root_method :profile
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
# The `middle_name` attribute may be blank or omitted in the response
|
251
|
+
ProfilesClient.profile
|
252
|
+
```
|
253
|
+
|
254
|
+
### Array responses
|
255
|
+
|
256
|
+
When an endpoint returns an array of objects, you can use `:array_of` to
|
257
|
+
describe the structure of each element in the array.
|
258
|
+
|
259
|
+
```ruby
|
260
|
+
class MerchantsClient < Purple::Client
|
261
|
+
domain 'https://api.example.com'
|
262
|
+
|
263
|
+
path :merchants do
|
264
|
+
response :ok do
|
265
|
+
structure = {
|
266
|
+
id: Integer,
|
267
|
+
name: String,
|
268
|
+
address: String,
|
269
|
+
work_time: String,
|
270
|
+
accepts_qr: { type: String, optional: true }
|
271
|
+
}
|
272
|
+
|
273
|
+
body(:array_of, **structure)
|
274
|
+
end
|
275
|
+
root_method :merchants
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
# Each array element will be validated against the structure
|
280
|
+
MerchantsClient.merchants
|
281
|
+
```
|
282
|
+
|
283
|
+
### Response body processing
|
284
|
+
|
285
|
+
After the body structure is validated, you can supply a block to `body`
|
286
|
+
to transform or handle the parsed response. This is useful for mapping
|
287
|
+
error payloads to simpler return values or for normalizing data.
|
288
|
+
|
289
|
+
```ruby
|
290
|
+
class MessagesClient < Purple::Client
|
291
|
+
domain 'https://api.example.com'
|
292
|
+
|
293
|
+
path :messages do
|
294
|
+
response :unprocessable_entity do
|
295
|
+
structure = {
|
296
|
+
status: Integer,
|
297
|
+
type: String,
|
298
|
+
title: String,
|
299
|
+
detail: String
|
300
|
+
}
|
301
|
+
|
302
|
+
body(**structure) do |res|
|
303
|
+
case res.type
|
304
|
+
when 'errors/invalid_recipient'
|
305
|
+
:not_found
|
306
|
+
else
|
307
|
+
res
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
root_method :send_message
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
# Returns :not_found when the recipient is invalid, otherwise returns the
|
316
|
+
# parsed response body.
|
317
|
+
MessagesClient.send_message
|
318
|
+
```
|
319
|
+
|
177
320
|
## Development
|
178
321
|
|
179
322
|
After checking out the repo, run `bin/setup` to install dependencies. Then run
|
data/lib/purple/client.rb
CHANGED
data/lib/purple/path.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'dry-initializer'
|
4
|
+
require 'faraday'
|
5
|
+
require 'active_support/core_ext/hash/deep_merge'
|
6
|
+
require 'active_support/core_ext/object/inclusion'
|
4
7
|
|
5
8
|
module Purple
|
6
9
|
class Path
|
@@ -24,7 +27,7 @@ module Purple
|
|
24
27
|
@param_value = args.first
|
25
28
|
end
|
26
29
|
|
27
|
-
def method_missing(method_name, *args, &)
|
30
|
+
def method_missing(method_name, *args, **kw_args, &)
|
28
31
|
if children.any? { |child| child.name == method_name }
|
29
32
|
child = children.find { |child| child.name == method_name }
|
30
33
|
|
@@ -35,7 +38,7 @@ module Purple
|
|
35
38
|
if child.children.any?
|
36
39
|
child
|
37
40
|
else
|
38
|
-
callback_arguments = additional_callback_arguments.map do |arg|
|
41
|
+
callback_arguments = client.additional_callback_arguments.map do |arg|
|
39
42
|
kw_args.delete(arg)
|
40
43
|
end
|
41
44
|
|
data/lib/purple/response.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'purple/responses'
|
4
4
|
require 'purple/responses/object'
|
5
|
+
require "active_support/core_ext/string/inflections"
|
5
6
|
|
6
7
|
class Purple::Responses::Body
|
7
8
|
extend Dry::Initializer[undefined: false]
|
@@ -75,6 +76,8 @@ class Purple::Responses::Body
|
|
75
76
|
|
76
77
|
check_type!(object, key, value[:type])
|
77
78
|
else
|
79
|
+
next if object[key].nil?
|
80
|
+
|
78
81
|
check_structure!(object[key], substructure[key])
|
79
82
|
end
|
80
83
|
elsif value.is_a?(Array)
|
data/lib/purple/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: purple-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.7.
|
4
|
+
version: 0.1.7.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pavel Kalashnikov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-08-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-initializer
|
@@ -24,6 +24,34 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: faraday
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
27
55
|
description: Build API wrappers faster
|
28
56
|
email:
|
29
57
|
- kalashnikovisme@gmail.com
|
@@ -40,6 +68,7 @@ files:
|
|
40
68
|
- Rakefile
|
41
69
|
- lib/purple/boolean.rb
|
42
70
|
- lib/purple/client.rb
|
71
|
+
- lib/purple/client/version.rb
|
43
72
|
- lib/purple/path.rb
|
44
73
|
- lib/purple/request.rb
|
45
74
|
- lib/purple/requests/authorization.rb
|