request-builder 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 457e80f8bbd15d0c31db2b9c22eb0cdad23d220263b046333e7f23233fd39f7c
4
+ data.tar.gz: b2631a86209e6e280069118793f8610360675ace8cc84841a091389220cb9c78
5
+ SHA512:
6
+ metadata.gz: fccbcdc8f74870d091a5d660ea44b76b400037570db2bfa1af2516fffa14a4f1ec49625785e65062da585eb36fc8d75bb62b6395f705da6a9fd68c5d06ac93d0
7
+ data.tar.gz: 8040052bf21eaa5c8693abccc82959d3739684cda46145ab2921d5fc09ed734a69ff57816057126163070d403bff2a9acb9907cf6b918a6ccc0941609225a4f5
data/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # Request::Builder
2
+
3
+ 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/request/builder`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'request-builder'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle install
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install request-builder
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
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.
30
+
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 tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/request-builder. 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]/request-builder/blob/master/CODE_OF_CONDUCT.md).
36
+
37
+
38
+ ## License
39
+
40
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
41
+
42
+ ## Code of Conduct
43
+
44
+ Everyone interacting in the Request::Builder project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/request-builder/blob/master/CODE_OF_CONDUCT.md).
@@ -0,0 +1,19 @@
1
+ require "faraday"
2
+ require "faraday_middleware"
3
+
4
+ module Request
5
+ module Builder
6
+ module Connection
7
+ private
8
+
9
+ def connection
10
+ @_connection ||= Faraday.new(url: config.host) do |builder|
11
+ builder.adapter config.adapter, config.stubs
12
+ builder.request config.request_middleware
13
+ builder.response config.response_middleware
14
+ builder.response(:logger, config.logger, bodies: true) if config.logger
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ module Request
2
+ module Builder
3
+ module Dsl
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ base.class_eval do
7
+ def config
8
+ @config ||= self.class.config
9
+ end
10
+ end
11
+ end
12
+
13
+ module ClassMethods
14
+ def config
15
+ @config ||= RequestConfig.new
16
+ end
17
+
18
+ def configure(conf = nil, &block)
19
+ @config = conf.dup if conf
20
+
21
+ config.instance_eval(&block) if block
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,37 @@
1
+ module Request
2
+ module Builder
3
+ class RequestConfig::Base
4
+ include ValueWithContext
5
+
6
+ attr_accessor :context
7
+ attr_reader :store
8
+
9
+ delegate_missing_to :context
10
+
11
+ def initialize(context = nil)
12
+ @context = context
13
+ end
14
+
15
+ def each(&block)
16
+ raise NotImplementedError unless store.is_a?(Enumerable)
17
+
18
+ store.each do |value|
19
+ value[1] = value_with_context(value[1])
20
+ block.call(value)
21
+ end
22
+ end
23
+
24
+ def [] key
25
+ raise NotImplementedError unless store.is_a?(Enumerable)
26
+
27
+ value_with_context(store[key])
28
+ end
29
+
30
+ private
31
+
32
+ def store
33
+ raise NotImplementedError
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,21 @@
1
+ module Request
2
+ module Builder
3
+ class RequestConfig::Body < Request::Builder::RequestConfig::Base
4
+ def set(&block)
5
+ raise ArgumentError, 'You must provide a block' unless block_given?
6
+
7
+ @store = block
8
+ end
9
+
10
+ def to_h
11
+ value_with_context(store)
12
+ end
13
+
14
+ private
15
+
16
+ def store
17
+ @store ||= nil
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,29 @@
1
+ module Request
2
+ module Builder
3
+ class RequestConfig::Callbacks < Request::Builder::RequestConfig::Base
4
+ [:before_validate].each do |name|
5
+ define_method name do |&block|
6
+ raise ArgumentError, 'You must provide a block' unless block
7
+
8
+ store[name] = block
9
+ end
10
+ end
11
+
12
+ def each(&block)
13
+ store.each do |value|
14
+ block.call(value)
15
+ end
16
+ end
17
+
18
+ def [] key
19
+ store[key]
20
+ end
21
+
22
+ private
23
+
24
+ def store
25
+ @store ||= HashWithIndifferentAccess.new
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,17 @@
1
+ module Request
2
+ module Builder
3
+ class RequestConfig::Headers < Request::Builder::RequestConfig::Base
4
+ def header(key, value = nil, &block)
5
+ raise ArgumentError, 'Must provide a value or block' if !value && !block
6
+
7
+ store[key] = block || value
8
+ end
9
+
10
+ private
11
+
12
+ def store
13
+ @store ||= HashWithIndifferentAccess.new
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Request
2
+ module Builder
3
+ class RequestConfig::Params < Request::Builder::RequestConfig::Base
4
+ def param(key, value = nil, &block)
5
+ raise ArgumentError, 'Must provide a value or block' if !value && !block
6
+
7
+ store[key] = block || value
8
+ end
9
+
10
+ private
11
+
12
+ def store
13
+ @store ||= HashWithIndifferentAccess.new
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,111 @@
1
+ module Request
2
+ module Builder
3
+ class RequestConfig
4
+ include ValueWithContext
5
+
6
+ delegate_missing_to :context
7
+
8
+ attrs = [:host, :path, :method, :request_middleware, :response_middleware, :adapter, :logger, :timeout]
9
+
10
+ attr_reader :context, :body_conf, :headers_conf, :params_conf, :callbacks_conf, :stubs
11
+ attr_writer *attrs, :stubs
12
+
13
+ alias callbacks callbacks_conf
14
+
15
+ def initialize
16
+ @host = nil
17
+ @path = '/'
18
+ @method = :get
19
+ @request_middleware = :json
20
+ @response_middleware = :json
21
+ @adapter = :net_http
22
+ @stubs = Faraday::Adapter::Test::Stubs.new
23
+ @logger = nil
24
+ @timeout = 30
25
+ @body_conf = RequestConfig::Body.new
26
+ @headers_conf = RequestConfig::Headers.new
27
+ @params_conf = RequestConfig::Params.new
28
+ @callbacks_conf = RequestConfig::Callbacks.new
29
+ @response_schema = Dry::Schema.Params
30
+ end
31
+
32
+ attrs.each do |attr|
33
+ define_method attr do |value = nil, &block|
34
+ if value.nil? && block.nil?
35
+ value_with_context(instance_variable_get("@#{attr}"))
36
+ else
37
+ instance_variable_set("@#{attr}", block || value)
38
+ end
39
+ end
40
+ end
41
+
42
+ [:before_validate].each do |name|
43
+ define_method name do |&block|
44
+ callbacks.send(name, &block)
45
+ end
46
+ end
47
+
48
+ def stubs(value = nil, &block)
49
+ if block_given?
50
+ @stubs.instance_eval(&block)
51
+ elsif value
52
+ @stubs = value
53
+ else
54
+ @stubs
55
+ end
56
+ end
57
+
58
+ def schema(value = nil, &block)
59
+ if block_given?
60
+ @response_schema = Dry::Schema.Params(&block)
61
+ elsif value
62
+ @response_schema = value
63
+ else
64
+ @response_schema
65
+ end
66
+ end
67
+
68
+ def body(&block)
69
+ return body_conf.set(&block) if block_given?
70
+
71
+ body_conf.to_h
72
+ end
73
+
74
+ def headers(&block)
75
+ headers_conf.instance_eval(&block) if block_given?
76
+
77
+ headers_conf
78
+ end
79
+
80
+ def header(key, value = nil, &block)
81
+ headers_conf.header(key, value, &block)
82
+ end
83
+
84
+ def params(&block)
85
+ params_conf.instance_eval(&block) if block_given?
86
+
87
+ params_conf
88
+ end
89
+
90
+ def param(key, value = nil, &block)
91
+ params_conf.param(key, value, &block)
92
+ end
93
+
94
+ def context=(context)
95
+ @context = context
96
+
97
+ [body_conf, headers_conf, params_conf, callbacks_conf].each { |cnf| cnf.context = context }
98
+ end
99
+
100
+ def [] property
101
+ instance_variable_get("@#{property}".to_sym)
102
+ end
103
+
104
+ Module.new do
105
+ singleton_class.send :define_method, :included do |host_class|
106
+ host_class.extend class_methods
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,35 @@
1
+ module Request
2
+ module Builder
3
+ class Result
4
+ attr_reader :response, :context, :body
5
+
6
+ delegate :headers, :status, to: :response
7
+ delegate :config, to: :context
8
+ delegate :schema, to: :config
9
+ delegate :errors, to: :schema_result
10
+
11
+ def initialize(response, context)
12
+ @response = response
13
+ @context = context
14
+ @before_validate = config.callbacks[:before_validate]
15
+ @body = @before_validate ? @before_validate.call(response.body.to_h) : response.body.to_h
16
+ end
17
+
18
+ def success?
19
+ status == 200 && schema_result.success?
20
+ end
21
+
22
+ def failure?
23
+ !success?
24
+ end
25
+
26
+ def schema_result
27
+ @schema_result ||= schema.call(body)
28
+ end
29
+
30
+ def full_errors
31
+ errors(full: true).to_h
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,14 @@
1
+ module Request
2
+ module Builder
3
+ module ValueWithContext
4
+ def value_with_context(obj)
5
+ return obj unless obj.is_a?(Proc)
6
+
7
+ case obj.arity
8
+ when 1, -1, -2 then instance_exec(@context, &obj)
9
+ else instance_exec(&obj)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ module Request
2
+ module Builder
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,77 @@
1
+
2
+ require "dry-initializer"
3
+ require "dry-schema"
4
+ require "active_support/hash_with_indifferent_access"
5
+ require "active_support/core_ext/module/delegation"
6
+ require_relative "builder/version"
7
+ require_relative "builder/value_with_context"
8
+ require_relative "builder/request_config"
9
+ require_relative "builder/request_config/base"
10
+ require_relative "builder/request_config/body"
11
+ require_relative "builder/request_config/params"
12
+ require_relative "builder/request_config/headers"
13
+ require_relative "builder/request_config/callbacks"
14
+ require_relative "builder/result"
15
+ require_relative "builder/dsl"
16
+ require_relative "builder/connection"
17
+
18
+ module Request
19
+ module Builder
20
+ def self.included(base)
21
+ base.extend ClassMethods
22
+ base.extend Dry::Initializer
23
+ base.include Request::Builder::Dsl
24
+ base.include Request::Builder::Connection
25
+
26
+ class << base
27
+ alias_method :__new, :new
28
+ def new(*args)
29
+ e = __new(*args)
30
+ e.send(:set_config_context)
31
+ e
32
+ end
33
+ end
34
+ end
35
+
36
+ module ClassMethods
37
+ def call(**args)
38
+ new(**args).call
39
+ end
40
+ alias perform call
41
+ end
42
+
43
+ def call
44
+ do_request
45
+ result
46
+ end
47
+ alias perform call
48
+
49
+ private
50
+
51
+ attr_reader :response
52
+
53
+ def result
54
+ @result ||= Result.new(response, self)
55
+ end
56
+
57
+ def do_request
58
+ @response = connection.send(config.method.downcase, config.path) do |req|
59
+ req.options.timeout = config.timeout
60
+
61
+ config.params.each do |key, value|
62
+ req.params[key] = value
63
+ end
64
+
65
+ config.headers.each do |key, value|
66
+ req.headers[key] = value
67
+ end
68
+
69
+ req.body = config.body
70
+ end
71
+ end
72
+
73
+ def set_config_context
74
+ config.context = self
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "request/builder"
@@ -0,0 +1,35 @@
1
+ lib = File.expand_path("lib", __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ require_relative 'lib/request/builder/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "request-builder"
8
+ spec.version = Request::Builder::VERSION.dup
9
+ spec.authors = ["Anton Kostyuk"]
10
+ spec.email = ["anton.kostuk.2012@gmail.com"]
11
+
12
+ spec.summary = %q{Request DSL}
13
+ spec.description = %q{Request DSL}
14
+ spec.homepage = "https://github.com/RainbowPonny/request-builder"
15
+ spec.license = "MIT"
16
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
17
+
18
+ spec.metadata["homepage_uri"] = spec.homepage
19
+ spec.metadata["source_code_uri"] = "https://github.com/RainbowPonny/request-builder"
20
+
21
+ spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "request-builder.gemspec", "lib/**/*"]
22
+ spec.bindir = "bin"
23
+ spec.executables = []
24
+ spec.require_paths = ["lib"]
25
+
26
+ spec.add_dependency "faraday", "~> 1.7.1"
27
+ spec.add_dependency "faraday_middleware", "~> 1.2.0"
28
+ spec.add_dependency "dry-schema", "~> 1.9"
29
+ spec.add_dependency "dry-initializer", "~> 3.0"
30
+
31
+ spec.add_runtime_dependency 'activesupport', ">= 5.0.0", "< 7.1.0"
32
+
33
+ spec.add_development_dependency "ffaker", "~> 2.21"
34
+ spec.add_development_dependency "rspec", "~> 3.0"
35
+ end
metadata ADDED
@@ -0,0 +1,164 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: request-builder
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Anton Kostyuk
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-09-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.7.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.7.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday_middleware
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.2.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.2.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: dry-schema
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.9'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.9'
55
+ - !ruby/object:Gem::Dependency
56
+ name: dry-initializer
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: activesupport
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 5.0.0
76
+ - - "<"
77
+ - !ruby/object:Gem::Version
78
+ version: 7.1.0
79
+ type: :runtime
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: 5.0.0
86
+ - - "<"
87
+ - !ruby/object:Gem::Version
88
+ version: 7.1.0
89
+ - !ruby/object:Gem::Dependency
90
+ name: ffaker
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '2.21'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '2.21'
103
+ - !ruby/object:Gem::Dependency
104
+ name: rspec
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '3.0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '3.0'
117
+ description: Request DSL
118
+ email:
119
+ - anton.kostuk.2012@gmail.com
120
+ executables: []
121
+ extensions: []
122
+ extra_rdoc_files: []
123
+ files:
124
+ - README.md
125
+ - lib/request-builder.rb
126
+ - lib/request/builder.rb
127
+ - lib/request/builder/connection.rb
128
+ - lib/request/builder/dsl.rb
129
+ - lib/request/builder/request_config.rb
130
+ - lib/request/builder/request_config/base.rb
131
+ - lib/request/builder/request_config/body.rb
132
+ - lib/request/builder/request_config/callbacks.rb
133
+ - lib/request/builder/request_config/headers.rb
134
+ - lib/request/builder/request_config/params.rb
135
+ - lib/request/builder/result.rb
136
+ - lib/request/builder/value_with_context.rb
137
+ - lib/request/builder/version.rb
138
+ - request-builder.gemspec
139
+ homepage: https://github.com/RainbowPonny/request-builder
140
+ licenses:
141
+ - MIT
142
+ metadata:
143
+ homepage_uri: https://github.com/RainbowPonny/request-builder
144
+ source_code_uri: https://github.com/RainbowPonny/request-builder
145
+ post_install_message:
146
+ rdoc_options: []
147
+ require_paths:
148
+ - lib
149
+ required_ruby_version: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: 2.3.0
154
+ required_rubygems_version: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ requirements: []
160
+ rubygems_version: 3.1.6
161
+ signing_key:
162
+ specification_version: 4
163
+ summary: Request DSL
164
+ test_files: []