graphql_connector 1.3.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4b8c2af2590f1daf462e0f348e64078c530a4c7f6833a7d8692e6bada0f11291
4
- data.tar.gz: 52edb3725223b2538f91b1904fa57a071ab0b43b853f37f23242e1dbb8d7eb50
3
+ metadata.gz: 81e604778c1aab26ebebc224ef71b2843f91bc3b51f7098066cb515f9437d300
4
+ data.tar.gz: 9d0f5e40ed50fbcd52974dba215ffda51678a2d334f8fa8321b720d554e683fb
5
5
  SHA512:
6
- metadata.gz: c82b787552cf4590bae68e4eb15103252a47660ba4a8b2d7645deb9e218034cadbca24feaf9ef610818106e322fc7916a91fdd3726d251e49c0051224666d3c2
7
- data.tar.gz: 491988a32bc66f1d597d32dbf0164b5f5a23a87923ac6d4da3c0fbc8272de1b6721ba8657b35e99ad221a9bcb2860431964e22281fcba341da36f3f5dd49ba1e
6
+ metadata.gz: bc5edb75f96dbf575d2bef6e70d7d0980a02c5c7071df2960e40a83f113ad7c85060da3bbd50885c46ac4dbc86306f8db5394a476839a66132c994de0b50925d
7
+ data.tar.gz: d4737485bc2f8c94db473f605f19e33d570aa5688a90230ee81284980c59b76991290ebef57a446ae8a93ceaf8c26983e96b49e86f48d6e4f9b4878d1d971615
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: Bug report
3
+ about: Create a report to help us improve
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **Describe the bug**
11
+ A clear and concise description of what the bug is.
12
+
13
+ **To Reproduce**
14
+ Steps to reproduce the behavior:
15
+ 1. Go to '...'
16
+ 2. Click on '....'
17
+ 3. Scroll down to '....'
18
+ 4. See error
19
+
20
+ **Expected behavior**
21
+ A clear and concise description of what you expected to happen.
22
+
23
+ **Screenshots**
24
+ If applicable, add screenshots to help explain your problem.
25
+
26
+ **Desktop (please complete the following information):**
27
+ - OS: [e.g. iOS]
28
+ - Browser [e.g. chrome, safari]
29
+ - Version [e.g. 22]
30
+
31
+ **Smartphone (please complete the following information):**
32
+ - Device: [e.g. iPhone6]
33
+ - OS: [e.g. iOS8.1]
34
+ - Browser [e.g. stock browser, safari]
35
+ - Version [e.g. 22]
36
+
37
+ **Additional context**
38
+ Add any other context about the problem here.
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea for this project
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **Is your feature request related to a problem? Please describe.**
11
+ A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12
+
13
+ **Describe the solution you'd like**
14
+ A clear and concise description of what you want to happen.
15
+
16
+ **Describe alternatives you've considered**
17
+ A clear and concise description of any alternative solutions or features you've considered.
18
+
19
+ **Additional context**
20
+ Add any other context or screenshots about the feature request here.
@@ -7,7 +7,7 @@ jobs:
7
7
  runs-on: ubuntu-latest
8
8
  strategy:
9
9
  matrix:
10
- ruby: ['2.4.10', '2.5.9', '2.6.7', '2.7.3', '3.0.1']
10
+ ruby: ['2.5', '2.6', '2.7', '3.0', '3.1']
11
11
  name: "ruby ${{ matrix.ruby }}"
12
12
  steps:
13
13
  - uses: actions/checkout@v1
@@ -24,14 +24,35 @@ jobs:
24
24
  name: Rubocop
25
25
  runs-on: ubuntu-latest
26
26
  steps:
27
- - uses: actions/checkout@v2
28
- - uses: ruby/setup-ruby@v1
29
- with:
30
- ruby-version: 2.7.3
31
- - name: Install dependencies
32
- run: |
33
- gem install bundler
34
- bundle install
35
- - name: Build and test
36
- run: |
37
- bundle exec rubocop
27
+ - uses: actions/checkout@v2
28
+ - uses: ruby/setup-ruby@v1
29
+ with:
30
+ ruby-version: 2.7
31
+ - name: Install dependencies
32
+ run: |
33
+ gem install bundler
34
+ bundle install
35
+ - name: Build and test
36
+ run: |
37
+ bundle exec rubocop
38
+ coverage:
39
+ name: coverage
40
+ runs-on: ubuntu-latest
41
+ steps:
42
+ - uses: actions/checkout@v1
43
+ - uses: ruby/setup-ruby@v1
44
+ with:
45
+ ruby-version: 2.7
46
+ - name: Setup Code Climate test-reporter
47
+ run: |
48
+ curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
49
+ chmod +x ./cc-test-reporter
50
+ ./cc-test-reporter before-build
51
+ - name: Build and test with RSpec
52
+ run: |
53
+ gem install bundler
54
+ bundle install
55
+ bundle exec rspec
56
+ - name: Publish code coverage
57
+ run: |
58
+ ./cc-test-reporter after-build -r ${{ secrets.CC_TEST_REPORTER_ID }}
data/.gitignore CHANGED
@@ -0,0 +1 @@
1
+ coverage/**
data/.rubocop.yml CHANGED
@@ -1,2 +1,7 @@
1
1
  inherit_from: .rubocop_todo.yml
2
2
 
3
+ AllCops:
4
+ TargetRubyVersion: 2.4
5
+
6
+ Layout/LineLength:
7
+ Max: 100
data/.rubocop_todo.yml CHANGED
@@ -3,4 +3,5 @@ Lint/DuplicateMethods:
3
3
  - lib/graphql_connector.rb
4
4
  Metrics/BlockLength:
5
5
  Exclude:
6
+ - "*.gemspec"
6
7
  - spec/graphql_connector/**/*.rb
data/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ## 2.0.0 (TBD)
2
+
3
+ ### Features
4
+
5
+ Write here
6
+
7
+ ### Breaking changes
8
+
9
+ * query results are now transformed to OpenStructs recursively, so nested attributes are no longer a hash but another OpenStruct
10
+ * Set minimum Ruby version to `2.4` or higher
11
+
12
+ ## 1.4.0 (2022-03-17)
13
+
14
+ * Add config for `httparty_adapter_options` allowing forwarding options to `httparty`
15
+
1
16
  ## 1.3.1 (2021-06-04)
2
17
 
3
18
  * add more specs to test headers and connectors
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- graphql_connector (1.3.0)
4
+ graphql_connector (1.4.0)
5
5
  httparty (~> 0.16)
6
6
 
7
7
  GEM
@@ -9,7 +9,8 @@ GEM
9
9
  specs:
10
10
  ast (2.4.0)
11
11
  coderay (1.1.2)
12
- diff-lcs (1.3)
12
+ diff-lcs (1.5.0)
13
+ docile (1.4.0)
13
14
  httparty (0.18.1)
14
15
  mime-types (~> 3.0)
15
16
  multi_xml (>= 0.5.2)
@@ -27,19 +28,19 @@ GEM
27
28
  method_source (~> 1.0)
28
29
  rainbow (3.0.0)
29
30
  rexml (3.2.5)
30
- rspec (3.9.0)
31
- rspec-core (~> 3.9.0)
32
- rspec-expectations (~> 3.9.0)
33
- rspec-mocks (~> 3.9.0)
34
- rspec-core (3.9.1)
35
- rspec-support (~> 3.9.1)
36
- rspec-expectations (3.9.1)
31
+ rspec (3.11.0)
32
+ rspec-core (~> 3.11.0)
33
+ rspec-expectations (~> 3.11.0)
34
+ rspec-mocks (~> 3.11.0)
35
+ rspec-core (3.11.0)
36
+ rspec-support (~> 3.11.0)
37
+ rspec-expectations (3.11.0)
37
38
  diff-lcs (>= 1.2.0, < 2.0)
38
- rspec-support (~> 3.9.0)
39
- rspec-mocks (3.9.1)
39
+ rspec-support (~> 3.11.0)
40
+ rspec-mocks (3.11.0)
40
41
  diff-lcs (>= 1.2.0, < 2.0)
41
- rspec-support (~> 3.9.0)
42
- rspec-support (3.9.2)
42
+ rspec-support (~> 3.11.0)
43
+ rspec-support (3.11.0)
43
44
  rubocop (0.82.0)
44
45
  jaro_winkler (~> 1.5.1)
45
46
  parallel (~> 1.10)
@@ -49,6 +50,12 @@ GEM
49
50
  ruby-progressbar (~> 1.7)
50
51
  unicode-display_width (>= 1.4.0, < 2.0)
51
52
  ruby-progressbar (1.10.1)
53
+ simplecov (0.21.2)
54
+ docile (~> 1.1)
55
+ simplecov-html (~> 0.11)
56
+ simplecov_json_formatter (~> 0.1)
57
+ simplecov-html (0.12.3)
58
+ simplecov_json_formatter (0.1.4)
52
59
  unicode-display_width (1.7.0)
53
60
 
54
61
  PLATFORMS
@@ -60,6 +67,7 @@ DEPENDENCIES
60
67
  pry (~> 0.10)
61
68
  rspec (~> 3.8)
62
69
  rubocop (~> 0.75)
70
+ simplecov (~> 0.21.2)
63
71
 
64
72
  BUNDLED WITH
65
- 2.1.4
73
+ 2.3.9
data/README.md CHANGED
@@ -5,6 +5,7 @@
5
5
  Version](https://badge.fury.io/rb/graphql_connector.svg)](https://badge.fury.io/rb/graphql_connector)
6
6
  [![CI](https://github.com/Garllon/graphql_connector/workflows/CI/badge.svg)](https://github.com/Garllon/graphql_connector/actions?query=workflow%3ACI)
7
7
  [![Maintainability](https://api.codeclimate.com/v1/badges/548db3cf0d078b379c84/maintainability)](https://codeclimate.com/github/Garllon/graphql_connector/maintainability)
8
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/548db3cf0d078b379c84/test_coverage)](https://codeclimate.com/github/Garllon/graphql_connector/test_coverage)
8
9
 
9
10
  An easy connector to call your `graphql` server. Currently there is no schema
10
11
  check in the code, but i will add it.
@@ -30,20 +31,21 @@ Or install it yourself as:
30
31
  You need to configure the `graphql_connector` first:
31
32
  ``` ruby
32
33
  GraphqlConnector.configure do |config|
33
- config.add_server(name: 'Foo', uri: 'http://foo.com/api/graphql', headers: {}, connector: {})
34
+ config.add_server(name: 'Foo', uri: 'http://foo.com/api/graphql', headers: {}, connector: {}, httparty_adapter_options: {})
34
35
  end
35
36
  ```
36
37
 
37
- The connector is expecting that it contains a `base` connector instance and a
38
- `method` parameter as string, where it gets the token. WE expect that the
39
- method is a public method in your connector class. Currently like this:
38
+ * `name` (**mandatory**): Add a namespace under which the API is reachable. In the above example `'Foo'` means that `GraphqlConnector::Foo` provides API functionality for the configured `add_server`
39
+
40
+ * `uri` (**mandatory**): Add uri of grapqhl API server that accepts **POST** requests.
41
+
42
+ * `connector` (**optionally**): Add a **Authentication Token class** in the following format:
40
43
  ```ruby
41
- { base: TokenAgent.new, method: 'get_authorization_header' }
44
+ connector: { base: AuthTokenAgent.instance, method: 'get_authorization_header' }
42
45
  ```
43
-
44
- Your method should return a hash like this:
46
+ `base` is an instance of Authentication Token class and `method` represents the function where it gets the token.
45
47
  ```ruby
46
- class TokenAgent
48
+ class AuthTokenAgent
47
49
  [...]
48
50
  def get_authorization_header
49
51
  [...]
@@ -51,9 +53,12 @@ class TokenAgent
51
53
  end
52
54
  end
53
55
  ```
56
+ :warning: The function under `method` must be a public one in your connector class.<br />
57
+ :warning: When you set a connector, it will override the setting in the headers for Authorization.
58
+
59
+
60
+ * `httparty_adapter_options` (**optionally**): Add any [`connection_adapter`](https://github.com/jnunemaker/httparty/blob/master/lib/httparty/connection_adapter.rb) options that `httparty` supports in a hash format e.g. `{ timeout: 4 }`
54
61
 
55
- When you set a connector, it will override the setting in the headers for
56
- Authorization.
57
62
 
58
63
  For each graphql server you wish to query use `add_server`.
59
64
 
@@ -71,9 +76,23 @@ See the following sub sections for details
71
76
 
72
77
  You can call your graphql_endpoint via:
73
78
  ```ruby
74
- GraphqlConnector::<name>.raw_query(query_string)
79
+ GraphqlConnector::<name>.raw_query('query { products { id name } }')
80
+
81
+ GraphqlConnector::<name>.raw_query('query { products($id: [ID!]) { products(id: $id) { id name } } }', variables: { id: 1 })
82
+
83
+ GraphqlConnector::<name>.raw_query('mutation { createProduct(name: "Coca-Cola") { id name } }')
84
+ ```
85
+
86
+ Or if you want to **override**/**set** any `httparty_adapter_options` it is also possible to pass them in:
87
+ ```ruby
88
+ GraphqlConnector::<name>.raw_query('query { products { id name } }', httparty_adapter_options: { timeout: 3, verify: true })
89
+
90
+ GraphqlConnector::<name>.raw_query('query { products($id: [ID!]) { products(id: $id) { id name } } }', variables: { id: 1 }, httparty_adapter_options: { timeout: 3, verify: true })
91
+
92
+ GraphqlConnector::<name>.raw_query('mutation { createProduct(name: "Coca-Cola") { id name } }', httparty_adapter_options: { timeout: 3, verify: true })
75
93
  ```
76
94
 
95
+
77
96
  Note that `<name>` has to be replaced by any of the ones added via `add_server`
78
97
 
79
98
  See also [here](examples/raw_query_examples.rb) for example usage
@@ -83,19 +102,22 @@ See also [here](examples/raw_query_examples.rb) for example usage
83
102
 
84
103
  You can also use the more comfortable `query`:
85
104
  ```ruby
86
- GraphqlConnector::<name>.query(model, condition, selected_fields)
105
+ GraphqlConnector::<name>.query('products', { id: [1,2] } , ['id','name'])
87
106
  ```
88
107
 
89
- | Variable | DataType | Example |
90
- |----------------|-------------------------|------------------------------------------|
91
- | model | String | 'product' |
92
- | condition | Hash(key, value) | { id: 1 } |
93
- | selected_fields | Array of Strings/Hashes | ['id', 'name', productCategory: ['id']] |
108
+ Or if you want to **override**/**set** any `httparty` adapter_options, it is also possible
109
+ to pass them in:
110
+
111
+ ```ruby
112
+ GraphqlConnector::<name>.query('products', { id: [1,2] } , ['id','name'], httparty_adapter_options: { timeout: 3 })
113
+ ```
94
114
 
95
- > Caution:
96
- > You get an OpenStruct back. Currently only the first level attributes are
97
- > supported with OpenStruct, associated objects are still a normal array of
98
- > hashes.
115
+ | Variable | Required | DataType | Example |
116
+ |--------------------------|-------------------------------|-------------------------|-----------------------------------------|
117
+ | model | Yes | String | 'product' |
118
+ | condition | Yes (but can be empty) | Hash(key, value) | { id: 1 } |
119
+ | selected_fields | Yes | Array of Strings/Hashes | ['id', 'name', productCategory: ['id']] |
120
+ | httparty_adapter_options | No | Hash | { timeout: 3 } |
99
121
 
100
122
  See also [here](examples/query_examples.rb) for example usage
101
123
 
@@ -129,14 +151,25 @@ so that it has re-usable graphql `query` and `mutation` **class methods**.
129
151
  * Then you can aliases as many graphql server types via `add_query` and/or `add_raw_query` and/or `add_mutation`:
130
152
 
131
153
  ```ruby
132
- add_query <alias>: :<graphql_server_type>, params: [...], returns: [...]
154
+ add_query products_by: :products, params: [:id], returns: [:id, :name]
133
155
 
134
- add_raw_query <alias>: 'query { ... }', params: [...]
156
+ add_raw_query products_raw_by: 'query { products(($id: [ID!]) products { id name } }', params: [:id]
135
157
 
136
- add_mutation <alias>: :<graphql_server_type>, params: [...], returns: [...]
158
+ add_mutation create: :createProduct, params: [:name], returns: [:id, :name]
137
159
  ```
138
160
  * :grey_exclamation: If not needed omit `params`
139
161
 
162
+ Or if you want to **override**/**set** any `httparty` adapter_options, it is also possible
163
+ to pass them in:
164
+
165
+ ```ruby
166
+ add_query products_by: :products, params: [:id], returns: [:id, :name], httparty_adapter_options: { timeout: 3 }
167
+
168
+ add_raw_query products_raw_by: 'query { products(($id: [ID!]) products { id name } }', params: [:id], httparty_adapter_options: { verify: true }
169
+
170
+ add_mutation create: :createProduct, params: [:name], returns: [:id, :name], httparty_adapter_options: { timeout: 5, verify: false }
171
+ ```
172
+
140
173
  See also [here](examples/departments_service_class_examples.rb) and also here for complete example usage:
141
174
 
142
175
  ```ruby
@@ -153,7 +186,8 @@ class Product
153
186
 
154
187
  add_query by_id: :products,
155
188
  params: :id,
156
- returns: [:name, product_category: [:id, :name]]
189
+ returns: [:name, product_category: [:id, :name]],
190
+ httparty_adapter_options: { timeout: 3 }
157
191
 
158
192
  add_query by_names: :products,
159
193
  params: :names,
@@ -169,7 +203,8 @@ class Product
169
203
 
170
204
  add_mutation create: :createProduct,
171
205
  params: [:name, :catgetoryId],
172
- returns: [:id, :name]
206
+ returns: [:id, :name],
207
+ httparty_adapter_options: { verify: false }
173
208
  end
174
209
 
175
210
  Product.all
@@ -31,10 +31,13 @@ Gem::Specification.new do |spec|
31
31
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
32
32
  spec.require_paths = ['lib']
33
33
 
34
+ spec.required_ruby_version = '>= 2.4.0'
35
+
34
36
  spec.add_dependency 'httparty', '~> 0.16'
35
37
 
36
38
  spec.add_development_dependency 'bundler', '~> 2.0'
37
39
  spec.add_development_dependency 'pry', '~> 0.10'
38
40
  spec.add_development_dependency 'rspec', '~> 3.8'
39
41
  spec.add_development_dependency 'rubocop', '~> 0.75'
42
+ spec.add_development_dependency 'simplecov', '~> 0.21.2'
40
43
  end
@@ -5,9 +5,9 @@ module GraphqlConnector
5
5
  # Class to wrap http_client calls under a specific namespaced class
6
6
  class BaseServerType
7
7
  class << self
8
- def build(name, uri, headers = {}, connector = {})
8
+ def build(name, uri, headers = {}, connector = {}, httparty_adapter_options = {})
9
9
  verify_new_client_type_for!(name)
10
- base_class = class_with(uri, headers, connector)
10
+ base_class = class_with(uri, headers, connector, httparty_adapter_options)
11
11
  base_object = GraphqlConnector.const_set(name, base_class)
12
12
  inject_http_client_delegations(base_object)
13
13
  create_service_class_module(base_object)
@@ -39,12 +39,13 @@ module GraphqlConnector
39
39
  METHOD
40
40
  end
41
41
 
42
- def class_with(uri, headers = {}, connector = {})
42
+ def class_with(uri, headers = {}, connector = {}, httparty_adapter_options = {})
43
43
  Class.new do
44
- attr_accessor :uri, :headers, :connector
44
+ attr_accessor :uri, :headers, :connector, :httparty_adapter_options
45
45
  @uri = uri
46
46
  @headers = headers
47
47
  @connector = connector
48
+ @httparty_adapter_options = httparty_adapter_options
48
49
  end
49
50
  end
50
51
 
@@ -54,8 +55,10 @@ module GraphqlConnector
54
55
  def_delegators :http_client, :query, :raw_query, :mutation
55
56
 
56
57
  def http_client
57
- @http_client ||=
58
- GraphqlConnector::HttpClient.new(@uri, @headers, @connector)
58
+ @http_client ||= GraphqlConnector::HttpClient.new(@uri,
59
+ @headers,
60
+ @connector,
61
+ @httparty_adapter_options)
59
62
  end
60
63
  end
61
64
  end
@@ -9,9 +9,9 @@ module GraphqlConnector
9
9
  @base_server_types = {}
10
10
  end
11
11
 
12
- def add_server(name:, uri:, headers: {}, connector: {})
12
+ def add_server(name:, uri:, headers: {}, connector: {}, httparty_adapter_options: {})
13
13
  @base_server_types[name] =
14
- BaseServerType.build(name, uri, headers, connector)
14
+ BaseServerType.build(name, uri, headers, connector, httparty_adapter_options)
15
15
  end
16
16
 
17
17
  def reset!
@@ -3,31 +3,29 @@
3
3
  module GraphqlConnector
4
4
  # Wrapper class for HTTParty post query
5
5
  class HttpClient
6
- def initialize(uri, headers = {}, connector = {})
6
+ def initialize(uri, headers = {}, connector = {}, httparty_adapter_options = {})
7
7
  @uri = uri
8
8
  @headers = headers
9
9
  @connector = connector
10
+ @httparty_adapter_options = httparty_adapter_options
10
11
  end
11
12
 
12
- def query(model, conditions, selected_fields)
13
- query_string =
14
- Formatters::QueryFormat.new(model, conditions, selected_fields).create
15
- parsed_body = raw_query(query_string)
16
- format_body(parsed_body['data'][model.to_s])
13
+ def query(model, conditions, selected_fields, httparty_adapter_options: {})
14
+ query_string = Formatters::QueryFormat.new(model, conditions, selected_fields).create
15
+ format_body(query_string, model, httparty_adapter_options)
17
16
  end
18
17
 
19
- def mutation(model, inputs, selected_fields)
20
- query_string =
21
- Formatters::MutationFormat.new(model, inputs, selected_fields).create
22
- parsed_body = raw_query(query_string)
23
- format_body(parsed_body['data'][model.to_s])
18
+ def mutation(model, inputs, selected_fields, httparty_adapter_options: {})
19
+ query_string = Formatters::MutationFormat.new(model, inputs, selected_fields).create
20
+ format_body(query_string, model, httparty_adapter_options)
24
21
  end
25
22
 
26
- def raw_query(query_string, variables: {})
23
+ def raw_query(query_string, variables: {}, httparty_adapter_options: {})
24
+ adapter_options = combined_adapter_options(httparty_adapter_options)
27
25
  response = HTTParty.post(@uri,
28
26
  headers: handle_headers,
29
- body: { query: query_string,
30
- variables: variables })
27
+ body: { query: query_string, variables: variables },
28
+ **adapter_options)
31
29
  parsed_body = JSON.parse(response.body)
32
30
  verify_response!(parsed_body)
33
31
  parsed_body
@@ -35,6 +33,10 @@ module GraphqlConnector
35
33
 
36
34
  private
37
35
 
36
+ def combined_adapter_options(options)
37
+ @httparty_adapter_options.merge(options)
38
+ end
39
+
38
40
  def handle_headers
39
41
  return @headers if @connector.empty?
40
42
 
@@ -42,10 +44,22 @@ module GraphqlConnector
42
44
  .merge(@connector[:base].public_send(@connector[:method]))
43
45
  end
44
46
 
45
- def format_body(response_body)
46
- return OpenStruct.new(response_body) unless response_body.is_a? Array
47
+ def format_body(query_string, model, httparty_adapter_options)
48
+ parsed_body = raw_query(query_string, httparty_adapter_options: httparty_adapter_options)
49
+ response_body = parsed_body['data'][model.to_s]
50
+ transform_data(response_body)
51
+ end
47
52
 
48
- response_body.map { |entry| OpenStruct.new(entry) }
53
+ def transform_data(data)
54
+ case data
55
+ when Array
56
+ data.map { |element| transform_data(element) }
57
+ when Hash
58
+ data = data.transform_values { |value| transform_data(value) }
59
+ OpenStruct.new(data)
60
+ else
61
+ data
62
+ end
49
63
  end
50
64
 
51
65
  def verify_response!(parsed_body)
@@ -5,101 +5,83 @@ module GraphqlConnector
5
5
  # Module that allows to build query methods within the context of
6
6
  # service class
7
7
  module Queryable
8
- CONDITIONS = 'binding.local_variables.map do |var|
9
- [var, binding.local_variable_get(var)]
10
- end.to_h'
8
+ BINDINGS = 'binding.local_variables.map do |var|
9
+ [var, binding.local_variable_get(var)]
10
+ end.to_h'
11
11
 
12
- def add_query(params: [], returns:, **method_to_query)
13
- class_method_name = method_to_query.first[0]
14
- query_type = method_to_query.first[1]
15
- ReturnFieldsValidator.validate(returns)
16
- ClassMethodValidator.validate_class_method(class_method_name, self)
17
- ClassMethodValidator.validate_element_class_type(query_type, Symbol)
12
+ def add_query(params: [], httparty_adapter_options: {}, returns:, **method_to_query)
13
+ class_method_name, query_type = parse_variables(method_to_query)
18
14
 
19
- if params.empty?
20
- return query_method(class_method_name, query_type, returns)
21
- end
15
+ ensure_params_format!(returns, class_method_name, query_type)
16
+ ParamsValidator.validate(params) unless params.empty?
22
17
 
23
- ParamsValidator.validate(params)
24
- query_keyword_method(class_method_name, query_type, params, returns)
18
+ signature = method_signature(class_method_name, params)
19
+ signature[:graphql_method_type] = :query
20
+ create_method(signature, query_type, returns, httparty_adapter_options)
25
21
  end
26
22
 
27
- def add_raw_query(params: [], **method_to_raw_query)
28
- class_method_name = method_to_raw_query.first[0]
29
- query_string = method_to_raw_query.first[1]
23
+ def add_raw_query(params: [], httparty_adapter_options: {}, **method_to_raw_query)
24
+ class_method_name, query_string = parse_variables(method_to_raw_query)
25
+
30
26
  ClassMethodValidator.validate_class_method(class_method_name, self)
31
27
  ClassMethodValidator.validate_element_class_type(query_string, String)
28
+ ParamsValidator.validate(params) unless params.empty?
32
29
 
33
- if params.empty?
34
- return raw_query_method(class_method_name, query_string)
35
- end
36
-
37
- ParamsValidator.validate(params)
38
- raw_query_keyword_method(class_method_name, query_string, params)
30
+ signature = method_signature(class_method_name, params)
31
+ raw_query_method(signature, query_string, httparty_adapter_options)
39
32
  end
40
33
 
41
- def add_mutation(params: [], returns:, **method_to_query)
42
- class_method_name = method_to_query.first[0]
43
- query_type = method_to_query.first[1]
44
- ReturnFieldsValidator.validate(returns)
45
- ClassMethodValidator.validate_class_method(class_method_name, self)
46
- ClassMethodValidator.validate_element_class_type(query_type, Symbol)
34
+ def add_mutation(params: [], httparty_adapter_options: {}, returns:, **method_to_query)
35
+ class_method_name, query_type = parse_variables(method_to_query)
47
36
 
48
- if params.empty?
49
- return mutation_method(class_method_name, query_type, returns)
50
- end
37
+ ensure_params_format!(returns, class_method_name, query_type)
38
+ ParamsValidator.validate(params) unless params.empty?
51
39
 
52
- ParamsValidator.validate(params)
53
- mutation_keyword_method(class_method_name, query_type, params, returns)
40
+ signature = method_signature(class_method_name, params)
41
+ signature[:graphql_method_type] = :mutation
42
+ create_method(signature, query_type, returns, httparty_adapter_options)
54
43
  end
55
44
 
56
45
  private
57
46
 
58
- def query_method(class_method_name, query_type, return_fields)
59
- define_singleton_method class_method_name do
60
- http_client.query(query_type, {}, return_fields.to_a)
61
- end
47
+ def parse_variables(method_to_query)
48
+ class_method_name = method_to_query.first[0]
49
+ query_type = method_to_query.first[1]
50
+ [class_method_name, query_type]
62
51
  end
63
52
 
64
- def raw_query_method(class_method_name, query_string)
65
- define_singleton_method class_method_name do
66
- http_client.raw_query(query_string)
67
- end
68
- end
53
+ def method_signature(name, keywords)
54
+ return { head: name, bindings: {} } if keywords.empty?
69
55
 
70
- def query_keyword_method(name, query_type, keywords, return_fields)
71
56
  keywords = [keywords].flatten
72
- instance_eval <<-METHOD, __FILE__, __LINE__ + 1
73
- def #{name}(#{keywords.map { |keyword| "#{keyword}:" }.join(', ')})
74
- http_client.query("#{query_type}",
75
- #{CONDITIONS},
76
- #{return_fields.to_a})
77
- end
78
- METHOD
57
+ { head: "#{name}(#{keywords.map { |keyword| "#{keyword}:" }.join(', ')})",
58
+ bindings: BINDINGS }
79
59
  end
80
60
 
81
- def raw_query_keyword_method(name, query_string, keywords)
82
- keywords = [keywords].flatten
61
+ def ensure_params_format!(returns, class_method_name, query_type)
62
+ ReturnFieldsValidator.validate(returns)
63
+ ClassMethodValidator.validate_class_method(class_method_name, self)
64
+ ClassMethodValidator.validate_element_class_type(query_type, Symbol)
65
+ end
66
+
67
+ def raw_query_method(signature, query_string, httparty_adapter_options)
83
68
  instance_eval <<-METHOD, __FILE__, __LINE__ + 1
84
- def #{name}(#{keywords.map { |keyword| "#{keyword}:" }.join(', ')})
85
- http_client.raw_query("#{query_string}", variables: #{CONDITIONS})
69
+ def #{signature[:head]}
70
+ http_client.raw_query("#{query_string}",
71
+ variables: #{signature[:bindings]},
72
+ httparty_adapter_options: #{httparty_adapter_options})
86
73
  end
87
74
  METHOD
88
75
  end
89
76
 
90
- def mutation_method(class_method_name, query_type, return_fields)
91
- define_singleton_method class_method_name do
92
- http_client.mutation(query_type, {}, return_fields.to_a)
93
- end
94
- end
95
-
96
- def mutation_keyword_method(name, query_type, keywords, return_fields)
97
- keywords = [keywords].flatten
77
+ def create_method(signature, query_type, return_fields, httparty_adapter_options)
98
78
  instance_eval <<-METHOD, __FILE__, __LINE__ + 1
99
- def #{name}(#{keywords.map { |keyword| "#{keyword}:" }.join(', ')})
100
- http_client.mutation("#{query_type}",
101
- #{CONDITIONS},
102
- #{return_fields.to_a})
79
+ def #{signature[:head]}
80
+ http_client.#{signature[:graphql_method_type]}(
81
+ "#{query_type}",
82
+ #{signature[:bindings]},
83
+ #{return_fields.to_a},
84
+ httparty_adapter_options: #{httparty_adapter_options})
103
85
  end
104
86
  METHOD
105
87
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GraphqlConnector
4
- VERSION = '1.3.1'
4
+ VERSION = '2.0.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql_connector
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Garllon
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2021-06-04 00:00:00.000000000 Z
12
+ date: 2023-08-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: httparty
@@ -81,6 +81,20 @@ dependencies:
81
81
  - - "~>"
82
82
  - !ruby/object:Gem::Version
83
83
  version: '0.75'
84
+ - !ruby/object:Gem::Dependency
85
+ name: simplecov
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: 0.21.2
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: 0.21.2
84
98
  description: Grahql client to query with your own raw string, with the small helper
85
99
  method query or with service class inclusion.
86
100
  email:
@@ -90,6 +104,8 @@ executables: []
90
104
  extensions: []
91
105
  extra_rdoc_files: []
92
106
  files:
107
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
108
+ - ".github/ISSUE_TEMPLATE/feature_request.md"
93
109
  - ".github/workflows/ci.yaml"
94
110
  - ".gitignore"
95
111
  - ".rspec"
@@ -135,14 +151,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
135
151
  requirements:
136
152
  - - ">="
137
153
  - !ruby/object:Gem::Version
138
- version: '0'
154
+ version: 2.4.0
139
155
  required_rubygems_version: !ruby/object:Gem::Requirement
140
156
  requirements:
141
157
  - - ">="
142
158
  - !ruby/object:Gem::Version
143
159
  version: '0'
144
160
  requirements: []
145
- rubygems_version: 3.2.7
161
+ rubygems_version: 3.4.1
146
162
  signing_key:
147
163
  specification_version: 4
148
164
  summary: GraphQL client