purple-client 0.1.2 → 0.1.3

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: 9d18a27dc35385412674a327de6cb947d1b4d8efe4e4032acc9edc1513ce24da
4
- data.tar.gz: 3611ed61c25f22b6f9f458894ca52bf611b10874051073485e9e67317529c3b5
3
+ metadata.gz: 0f4ca49f00bb4d5ec1c6e85735ba6234a59aba7d82f783f4344bbe903018ae65
4
+ data.tar.gz: b6d6a4f48c2a07196bbc89514fd163eee65ddf61b7d84aca83f57e4b1512224b
5
5
  SHA512:
6
- metadata.gz: 5e5bc2479a7b5b259113e76ca91d1578a180afa3b792c12608bdb03d0c23b28e5ddfd1aa3ee3ecf96b32700fd140ed84dcb6330b19da3fd908ea97fa14600f2d
7
- data.tar.gz: 30e8ca1120a40557ffda8a51c531ee06c34807e3696ff424c056bf237819765b6f0171c115da9089234088e4a4ae9b32d366a67143149112a401c7862ea1bad0
6
+ metadata.gz: e3964e69833c7f37ac6c95c8461d8b8ac3815891ed681d1414a4bd8b908078f11be980c5dfef100fe7f98a65eb8ace3a5ab4c171f37c61c8b7c8508b5d56abbe
7
+ data.tar.gz: 2013f80e686a5c702f8b81f0e4497b333ef59560b8072dee468ef95c5f19b587a4eaf14dc3efcfa4f88f794539dec3fc1bb8360938237152e2461afb0973b142
data/README.md CHANGED
@@ -1,43 +1,123 @@
1
1
  # Purple::Client
2
2
 
3
- TODO: Delete this and the text below, and describe your gem
4
-
5
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/purple/client`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ Purple::Client is a small DSL that helps you describe HTTP APIs. You define a domain, paths, and response structures, and the library generates handy methods for interacting with your service.
6
4
 
7
5
  ## Installation
8
6
 
9
- TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
10
-
11
- Install the gem and add to the application's Gemfile by executing:
7
+ Add the gem to your project:
12
8
 
13
9
  ```bash
14
- bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
10
+ bundle add purple-client
15
11
  ```
16
12
 
17
- If bundler is not being used to manage dependencies, install the gem by executing:
13
+ Or install it manually with:
18
14
 
19
15
  ```bash
20
- gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
16
+ gem install purple-client
21
17
  ```
22
18
 
23
19
  ## Usage
24
20
 
25
- TODO: Write usage instructions here
21
+ Below are some basic examples of how to define requests and call them. Each
22
+ snippet defines a custom class that inherits from `Purple::Client`.
23
+
24
+ ### Simple GET request
25
+
26
+ ```ruby
27
+ class StatusClient < Purple::Client
28
+ domain 'https://api.example.com'
29
+
30
+ path :status do
31
+ response :ok do
32
+ body :default
33
+ end
34
+ root_method :status
35
+ end
36
+ end
37
+
38
+ # Performs GET https://api.example.com/status
39
+ StatusClient.status
40
+ ```
41
+
42
+ ### Path with a dynamic parameter
43
+
44
+ ```ruby
45
+ class JobsClient < Purple::Client
46
+ domain 'https://api.example.com'
47
+
48
+ path :jobs do
49
+ path :job_id, is_param: true do
50
+ response :ok do
51
+ body id: Integer, name: String
52
+ end
53
+ root_method :job
54
+ end
55
+ end
56
+ end
57
+
58
+ # Performs GET https://api.example.com/jobs/123
59
+ JobsClient.job(123)
60
+ ```
61
+
62
+ ### Using authorization
63
+
64
+ ```ruby
65
+ class ProfileClient < Purple::Client
66
+ domain 'https://api.example.com'
67
+ authorization :bearer, 'TOKEN'
68
+
69
+ path :profile do
70
+ response :ok do
71
+ body :default
72
+ end
73
+ root_method :profile
74
+ end
75
+ end
76
+
77
+ # Authorization header will be sent automatically
78
+ ProfileClient.profile
79
+ ```
80
+
81
+ ### Nested paths
82
+
83
+ ```ruby
84
+ class PostsClient < Purple::Client
85
+ domain 'https://api.example.com'
86
+
87
+ path :users do
88
+ path :user_id, is_param: true do
89
+ path :posts do
90
+ response :ok do
91
+ body [{ id: Integer, title: String }]
92
+ end
93
+ root_method :user_posts
94
+ end
95
+ end
96
+ end
97
+ end
98
+
99
+ # Performs GET https://api.example.com/users/7/posts
100
+ PostsClient.user_posts(user_id: 7)
101
+ ```
26
102
 
27
103
  ## Development
28
104
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
105
+ After checking out the repo, run `bin/setup` to install dependencies. Then run
106
+ `rake spec` to execute the tests. You can also run `bin/console` for an interactive
107
+ prompt to experiment with the library.
30
108
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
109
+ To install this gem onto your local machine, run `bundle exec rake install`.
110
+ To release a new version, update the version number in `version.rb`, then run
111
+ `bundle exec rake release`.
32
112
 
33
113
  ## Contributing
34
114
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/purple-client. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/purple-client/blob/main/CODE_OF_CONDUCT.md).
115
+ Bug reports and pull requests are welcome on GitHub at
116
+ https://github.com/[USERNAME]/purple-client. Contributors are expected to adhere
117
+ to the [code of conduct](https://github.com/[USERNAME]/purple-client/blob/main/CODE_OF_CONDUCT.md).
36
118
 
37
119
  ## License
38
120
 
39
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
40
-
41
- ## Code of Conduct
121
+ The gem is available as open source under the terms of the
122
+ [MIT License](https://opensource.org/licenses/MIT).
42
123
 
43
- Everyone interacting in the Purple::Client project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/purple-client/blob/main/CODE_OF_CONDUCT.md).
data/lib/purple/client.rb CHANGED
@@ -43,8 +43,8 @@ module Purple
43
43
  end
44
44
  end
45
45
 
46
- def path(name, method: :get)
47
- path = Path.new(name:, parent: @parent_path, method:, client: self)
46
+ def path(name, method: :get, is_param: false)
47
+ path = Path.new(name:, parent: @parent_path, method:, client: self, is_param:)
48
48
 
49
49
  @paths ||= []
50
50
  @paths << path
@@ -62,10 +62,16 @@ module Purple
62
62
  def root_method(method_name)
63
63
  current_path = @parent_path
64
64
 
65
- define_singleton_method method_name do |**args, &block|
66
- params = current_path.request.params.call(**args) if current_path.request.params.is_a?(Proc)
65
+ define_singleton_method method_name do |*call_args, **kw_args, &block|
66
+ if current_path.is_param
67
+ value = kw_args[current_path.name] || call_args.first
68
+ current_path.with(value)
69
+ kw_args[current_path.name] = value
70
+ end
67
71
 
68
- current_path.execute(params, args, &block)
72
+ params = current_path.request.params.call(**kw_args) if current_path.request.params.is_a?(Proc)
73
+
74
+ current_path.execute(params, kw_args, &block)
69
75
  end
70
76
  end
71
77
 
data/lib/purple/path.rb CHANGED
@@ -9,18 +9,30 @@ module Purple
9
9
  option :client
10
10
  option :name
11
11
  option :parent
12
+ option :is_param, default: -> { false }
12
13
  option :children, default: -> { [] }
13
14
  option :method, optional: true
14
15
  option :request, optional: true, default: -> { Purple::Request.new }
15
16
  option :responses, optional: true, default: -> { [] }
16
17
 
17
18
  def full_path
18
- parent.nil? ? name : "#{parent.full_path}/#{name}"
19
+ current_path = is_param ? @param_value : name
20
+ parent.nil? ? current_path : "#{parent.full_path}/#{current_path}"
21
+ end
22
+
23
+ def with(*args)
24
+ @param_value = args.first
19
25
  end
20
26
 
21
27
  def method_missing(method_name, *args, &)
22
28
  if children.any? { |child| child.name == method_name }
23
- children.find { |child| child.name == method_name }
29
+ child = children.find { |child| child.name == method_name }
30
+
31
+ if child.is_param
32
+ child.with(*args)
33
+ end
34
+
35
+ child.children.any? ? child : child.execute(*args)
24
36
  else
25
37
  super
26
38
  end
@@ -43,7 +55,12 @@ module Purple
43
55
  conn.headers = headers
44
56
  end
45
57
 
58
+ unless client.domain.start_with?('http')
59
+ raise ArgumentError, "Invalid URL: #{client.domain}. Ensure you have set protocol (http/https) in the client domain."
60
+ end
61
+
46
62
  url = "#{client.domain}/#{full_path}"
63
+
47
64
  response = case method
48
65
  when :get
49
66
  connection.get(url, params)
@@ -16,7 +16,8 @@ class Purple::Response
16
16
  forbidden: 403,
17
17
  not_found: 404,
18
18
  too_many_requests: 429,
19
- internal_server_error: 500
19
+ internal_server_error: 500,
20
+ gateway_timeout: 504,
20
21
  }.freeze
21
22
 
22
23
  def status_code
@@ -82,7 +82,12 @@ class Purple::Responses::Body
82
82
  check_structure!(item, value[0])
83
83
  end
84
84
  else
85
- check_type!(object, key, value)
85
+ if object.nil?
86
+ raise BodyStructureMismatchError.new(key, value, nil, object),
87
+ "Expected a non-nil value for '#{key}' in response body. Expected response structure: #{substructure}"
88
+ else
89
+ check_type!(object, key, value)
90
+ end
86
91
  end
87
92
  end
88
93
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Purple
4
- VERSION = "0.1.2"
4
+ VERSION = "0.1.3"
5
5
  end
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.2
4
+ version: 0.1.3
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-01-18 00:00:00.000000000 Z
11
+ date: 2025-06-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-initializer