graphql_connector 1.0.0 → 1.3.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 +4 -4
- data/.github/workflows/ci.yaml +37 -0
- data/.rspec +1 -0
- data/CHANGELOG.md +29 -0
- data/Gemfile.lock +30 -30
- data/README.md +158 -8
- data/examples/departments_service_class_examples.rb +51 -0
- data/examples/mutation_examples.rb +17 -0
- data/examples/query_examples.rb +21 -0
- data/examples/raw_query_examples.rb +24 -0
- data/graphql_connector.gemspec +7 -7
- data/lib/graphql_connector.rb +8 -2
- data/lib/graphql_connector/base_server_type.rb +28 -21
- data/lib/graphql_connector/configuration.rb +4 -2
- data/lib/graphql_connector/formatters/base_format.rb +81 -0
- data/lib/graphql_connector/formatters/mutation_format.rb +14 -0
- data/lib/graphql_connector/formatters/query_format.rb +14 -0
- data/lib/graphql_connector/http_client.rb +28 -10
- data/lib/graphql_connector/service_classable/class_method_validator.rb +31 -0
- data/lib/graphql_connector/service_classable/params_validator.rb +24 -0
- data/lib/graphql_connector/service_classable/queryable.rb +108 -0
- data/lib/graphql_connector/service_classable/return_fields_validator.rb +43 -0
- data/lib/graphql_connector/version.rb +1 -1
- metadata +25 -27
- data/.travis.yml +0 -9
- data/lib/graphql_connector/query_builder.rb +0 -59
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: dec05781e16009638ffb57356c4b648730b6d04eb60129211cc1f462c6b1db77
         | 
| 4 | 
            +
              data.tar.gz: fde0b8313c159ae15b43b3aa050c53c710902854080459e41d7da28595226c8d
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 4a30c45c22bc87d78bc34377c1bca7e40c78d72c96a8d1e840ee89aec119cacfc01b1a517c86c5ca2867573a160742382bd3bf9ce02f256e8e8f42313b36aa5b
         | 
| 7 | 
            +
              data.tar.gz: 218116c1728b4da4583e709435df2f2e1ba3477edcae34ec0958f398e42ccad3fdee8b80d3de1cc3312c4d7cae9a97add6384273d2cc162a4a86031dd4c5f149
         | 
| @@ -0,0 +1,37 @@ | |
| 1 | 
            +
            name: CI
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            on: [push]
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            jobs: 
         | 
| 6 | 
            +
              build:
         | 
| 7 | 
            +
                runs-on: ubuntu-latest
         | 
| 8 | 
            +
                strategy:
         | 
| 9 | 
            +
                  matrix:
         | 
| 10 | 
            +
                    ruby: ['2.4.10', '2.5.9', '2.6.7', '2.7.3', '3.0.1']
         | 
| 11 | 
            +
                name: "ruby ${{ matrix.ruby }}"
         | 
| 12 | 
            +
                steps:
         | 
| 13 | 
            +
                  - uses: actions/checkout@v1
         | 
| 14 | 
            +
                  - uses: ruby/setup-ruby@v1
         | 
| 15 | 
            +
                    with:
         | 
| 16 | 
            +
                      ruby-version: ${{ matrix.ruby }}
         | 
| 17 | 
            +
                  - name: Install dependencies
         | 
| 18 | 
            +
                    run: |
         | 
| 19 | 
            +
                      gem install bundler
         | 
| 20 | 
            +
                      bundle install
         | 
| 21 | 
            +
                  - name: Run Test with rspec
         | 
| 22 | 
            +
                    run: bundle exec rspec spec
         | 
| 23 | 
            +
              rubocop:
         | 
| 24 | 
            +
                name: Rubocop
         | 
| 25 | 
            +
                runs-on: ubuntu-latest
         | 
| 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
         | 
    
        data/.rspec
    CHANGED
    
    
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,3 +1,32 @@ | |
| 1 | 
            +
            ## 1.3.0 (2021-06-02)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            * add the option to use a connector instead of init header for authorization
         | 
| 4 | 
            +
              part of headers 
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            ## 1.2.1 (2021-05-25)
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            * relax httparty dependency(`~> 0.17` => `~> 0.16`)
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            ## 1.2.0 (2020-12-22)
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            ### Features
         | 
| 13 | 
            +
            * Add `mutation` under server namespace and service class inclusion
         | 
| 14 | 
            +
            * See `README` for details
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            ## 1.1.1 (2020-5-04)
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            ### BugFix
         | 
| 19 | 
            +
            * Omit invalid `()` for empty conditions in `query` method
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            ## 1.1.0 (2020-4-19)
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            ### Features
         | 
| 24 | 
            +
            * Allow building graphql querying in custom classes via `service class inclusion`
         | 
| 25 | 
            +
            * See `README` for details about `service class inclusion`
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            ### BugFix
         | 
| 28 | 
            +
            * Forward `variables` when performing a `raw_query`
         | 
| 29 | 
            +
             | 
| 1 30 | 
             
            ## 1.0.0 (2020-1-26)
         | 
| 2 31 |  | 
| 3 32 | 
             
            ### Breaking
         | 
    
        data/Gemfile.lock
    CHANGED
    
    | @@ -1,8 +1,8 @@ | |
| 1 1 | 
             
            PATH
         | 
| 2 2 | 
             
              remote: .
         | 
| 3 3 | 
             
              specs:
         | 
| 4 | 
            -
                graphql_connector (1. | 
| 5 | 
            -
                  httparty (~> 0. | 
| 4 | 
            +
                graphql_connector (1.3.0)
         | 
| 5 | 
            +
                  httparty (~> 0.16)
         | 
| 6 6 |  | 
| 7 7 | 
             
            GEM
         | 
| 8 8 | 
             
              remote: https://rubygems.org/
         | 
| @@ -10,45 +10,46 @@ GEM | |
| 10 10 | 
             
                ast (2.4.0)
         | 
| 11 11 | 
             
                coderay (1.1.2)
         | 
| 12 12 | 
             
                diff-lcs (1.3)
         | 
| 13 | 
            -
                httparty (0. | 
| 13 | 
            +
                httparty (0.18.1)
         | 
| 14 14 | 
             
                  mime-types (~> 3.0)
         | 
| 15 15 | 
             
                  multi_xml (>= 0.5.2)
         | 
| 16 | 
            -
                jaro_winkler (1.5. | 
| 17 | 
            -
                method_source (0. | 
| 18 | 
            -
                mime-types (3.3)
         | 
| 16 | 
            +
                jaro_winkler (1.5.4)
         | 
| 17 | 
            +
                method_source (1.0.0)
         | 
| 18 | 
            +
                mime-types (3.3.1)
         | 
| 19 19 | 
             
                  mime-types-data (~> 3.2015)
         | 
| 20 | 
            -
                mime-types-data (3. | 
| 20 | 
            +
                mime-types-data (3.2021.0225)
         | 
| 21 21 | 
             
                multi_xml (0.6.0)
         | 
| 22 | 
            -
                parallel (1. | 
| 23 | 
            -
                parser (2. | 
| 22 | 
            +
                parallel (1.19.1)
         | 
| 23 | 
            +
                parser (2.7.1.1)
         | 
| 24 24 | 
             
                  ast (~> 2.4.0)
         | 
| 25 | 
            -
                pry (0. | 
| 26 | 
            -
                  coderay (~> 1.1 | 
| 27 | 
            -
                  method_source (~>  | 
| 25 | 
            +
                pry (0.13.1)
         | 
| 26 | 
            +
                  coderay (~> 1.1)
         | 
| 27 | 
            +
                  method_source (~> 1.0)
         | 
| 28 28 | 
             
                rainbow (3.0.0)
         | 
| 29 | 
            -
                 | 
| 30 | 
            -
                rspec (3. | 
| 31 | 
            -
                  rspec-core (~> 3. | 
| 32 | 
            -
                  rspec-expectations (~> 3. | 
| 33 | 
            -
                  rspec-mocks (~> 3. | 
| 34 | 
            -
                rspec-core (3. | 
| 35 | 
            -
                  rspec-support (~> 3. | 
| 36 | 
            -
                rspec-expectations (3. | 
| 29 | 
            +
                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)
         | 
| 37 37 | 
             
                  diff-lcs (>= 1.2.0, < 2.0)
         | 
| 38 | 
            -
                  rspec-support (~> 3. | 
| 39 | 
            -
                rspec-mocks (3. | 
| 38 | 
            +
                  rspec-support (~> 3.9.0)
         | 
| 39 | 
            +
                rspec-mocks (3.9.1)
         | 
| 40 40 | 
             
                  diff-lcs (>= 1.2.0, < 2.0)
         | 
| 41 | 
            -
                  rspec-support (~> 3. | 
| 42 | 
            -
                rspec-support (3. | 
| 43 | 
            -
                rubocop (0. | 
| 41 | 
            +
                  rspec-support (~> 3.9.0)
         | 
| 42 | 
            +
                rspec-support (3.9.2)
         | 
| 43 | 
            +
                rubocop (0.82.0)
         | 
| 44 44 | 
             
                  jaro_winkler (~> 1.5.1)
         | 
| 45 45 | 
             
                  parallel (~> 1.10)
         | 
| 46 | 
            -
                  parser (>= 2. | 
| 46 | 
            +
                  parser (>= 2.7.0.1)
         | 
| 47 47 | 
             
                  rainbow (>= 2.2.2, < 4.0)
         | 
| 48 | 
            +
                  rexml
         | 
| 48 49 | 
             
                  ruby-progressbar (~> 1.7)
         | 
| 49 | 
            -
                  unicode-display_width (>= 1.4.0, <  | 
| 50 | 
            +
                  unicode-display_width (>= 1.4.0, < 2.0)
         | 
| 50 51 | 
             
                ruby-progressbar (1.10.1)
         | 
| 51 | 
            -
                unicode-display_width (1. | 
| 52 | 
            +
                unicode-display_width (1.7.0)
         | 
| 52 53 |  | 
| 53 54 | 
             
            PLATFORMS
         | 
| 54 55 | 
             
              ruby
         | 
| @@ -57,9 +58,8 @@ DEPENDENCIES | |
| 57 58 | 
             
              bundler (~> 2.0)
         | 
| 58 59 | 
             
              graphql_connector!
         | 
| 59 60 | 
             
              pry (~> 0.10)
         | 
| 60 | 
            -
              rake (~> 10.0)
         | 
| 61 61 | 
             
              rspec (~> 3.8)
         | 
| 62 62 | 
             
              rubocop (~> 0.75)
         | 
| 63 63 |  | 
| 64 64 | 
             
            BUNDLED WITH
         | 
| 65 | 
            -
               2. | 
| 65 | 
            +
               2.1.4
         | 
    
        data/README.md
    CHANGED
    
    | @@ -3,8 +3,7 @@ | |
| 3 3 |  | 
| 4 4 | 
             
            [](https://badge.fury.io/rb/graphql_connector)
         | 
| 6 | 
            -
            [](https://travis-ci.org/Garllon/graphql_connector)
         | 
| 6 | 
            +
            [](https://github.com/Garllon/graphql_connector/actions?query=workflow%3ACI)
         | 
| 8 7 | 
             
            [](https://codeclimate.com/github/Garllon/graphql_connector/maintainability)
         | 
| 9 8 |  | 
| 10 9 | 
             
            An easy connector to call your `graphql` server. Currently there is no schema
         | 
| @@ -31,21 +30,47 @@ Or install it yourself as: | |
| 31 30 | 
             
            You need to configure the `graphql_connector` first:
         | 
| 32 31 | 
             
            ``` ruby
         | 
| 33 32 | 
             
            GraphqlConnector.configure do |config|
         | 
| 34 | 
            -
              config.add_server(name: 'Foo', uri: 'http://foo.com/api/graphql', headers: {})
         | 
| 33 | 
            +
              config.add_server(name: 'Foo', uri: 'http://foo.com/api/graphql', headers: {}, connector: {})
         | 
| 35 34 | 
             
            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. Currently like this:
         | 
| 39 | 
            +
            ```ruby
         | 
| 40 | 
            +
            { base: TokenAgent.new, method: 'get_authorization_header' }
         | 
| 38 41 | 
             
            ```
         | 
| 39 42 |  | 
| 43 | 
            +
            Your method should return a hash like this:
         | 
| 44 | 
            +
            ```ruby
         | 
| 45 | 
            +
            { 'Authorization' => 'Token HERE' }
         | 
| 46 | 
            +
             | 
| 47 | 
            +
            When you set a connector, it will override the setting in the headers for
         | 
| 48 | 
            +
            Authorization.
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            For each graphql server you wish to query use `add_server`.
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            Afterwards you will have the following options to fetch and/or mutate data with
         | 
| 53 | 
            +
            one or many graphql servers:
         | 
| 54 | 
            +
             | 
| 55 | 
            +
            * `raw_query` --> [Examples](examples/raw_query_examples.rb)
         | 
| 56 | 
            +
            * `query` --> [Examples](examples/query_examples.rb)
         | 
| 57 | 
            +
            * `mutation` --> [Examples](examples/mutation_examples.rb)
         | 
| 58 | 
            +
            * `service class inclusion` --> [Examples](examples/departments_service_class_examples.rb)
         | 
| 59 | 
            +
             | 
| 60 | 
            +
            See the following sub sections for details
         | 
| 61 | 
            +
             | 
| 40 62 | 
             
            ### raw_query
         | 
| 41 63 |  | 
| 42 | 
            -
             | 
| 64 | 
            +
            You can call your graphql_endpoint via:
         | 
| 43 65 | 
             
            ```ruby
         | 
| 44 66 | 
             
            GraphqlConnector::<name>.raw_query(query_string)
         | 
| 45 67 | 
             
            ```
         | 
| 46 68 |  | 
| 47 | 
            -
            Note that `<name>` has to be replaced by any of the ones added via ` | 
| 69 | 
            +
            Note that `<name>` has to be replaced by any of the ones added via `add_server`
         | 
| 48 70 |  | 
| 71 | 
            +
            See also [here](examples/raw_query_examples.rb) for example usage
         | 
| 72 | 
            +
             | 
| 73 | 
            +
            ---
         | 
| 49 74 | 
             
            ### query
         | 
| 50 75 |  | 
| 51 76 | 
             
            You can also use the more comfortable `query`:
         | 
| @@ -64,9 +89,11 @@ GraphqlConnector::<name>.query(model, condition, selected_fields) | |
| 64 89 | 
             
            > supported with OpenStruct, associated objects are still a normal array of
         | 
| 65 90 | 
             
            > hashes.
         | 
| 66 91 |  | 
| 92 | 
            +
            See also [here](examples/query_examples.rb) for example usage
         | 
| 93 | 
            +
             | 
| 67 94 | 
             
            #### selected_fields
         | 
| 68 95 |  | 
| 69 | 
            -
            The  | 
| 96 | 
            +
            The syntax for the associations looks like the following:
         | 
| 70 97 | 
             
            ```
         | 
| 71 98 | 
             
            ['<attribute_name>', <association_name>: ['<attribute_name_of_the_association>']]
         | 
| 72 99 | 
             
            ```
         | 
| @@ -76,6 +103,129 @@ Example: | |
| 76 103 | 
             
            ['id', 'name', productCategory: ['id', 'name']]
         | 
| 77 104 | 
             
            ```
         | 
| 78 105 |  | 
| 106 | 
            +
            ---
         | 
| 107 | 
            +
             | 
| 108 | 
            +
            ### mutation
         | 
| 109 | 
            +
             | 
| 110 | 
            +
            Works in the same way as [query](#query)
         | 
| 111 | 
            +
             | 
| 112 | 
            +
            See also [here](examples/mutation_examples.rb) for example usage
         | 
| 113 | 
            +
             | 
| 114 | 
            +
            ### Service class inclusion
         | 
| 115 | 
            +
             | 
| 116 | 
            +
            This approach can be used to `graphqlize` **any** kind of ruby (service) class
         | 
| 117 | 
            +
            so that it has re-usable graphql `query` and `mutation` **class methods**.
         | 
| 118 | 
            +
             | 
| 119 | 
            +
            * First add `extend GraphqlConnector::<server>::Query` in the the class(es) that should be `graphqlized`
         | 
| 120 | 
            +
             | 
| 121 | 
            +
            * Then you can aliases as many graphql server types via `add_query` and/or `add_raw_query` and/or `add_mutation`:
         | 
| 122 | 
            +
             | 
| 123 | 
            +
            ```ruby
         | 
| 124 | 
            +
            add_query <alias>: :<graphql_server_type>, params: [...], returns: [...]
         | 
| 125 | 
            +
             | 
| 126 | 
            +
            add_raw_query <alias>: 'query { ... }', params: [...]
         | 
| 127 | 
            +
             | 
| 128 | 
            +
            add_mutation <alias>: :<graphql_server_type>, params: [...], returns: [...]
         | 
| 129 | 
            +
            ```
         | 
| 130 | 
            +
            * :grey_exclamation: If not needed omit `params`
         | 
| 131 | 
            +
             | 
| 132 | 
            +
            See also [here](examples/departments_service_class_examples.rb) and also here for complete example usage:
         | 
| 133 | 
            +
             | 
| 134 | 
            +
            ```ruby
         | 
| 135 | 
            +
            GraphqlConnector.configure do |config|
         | 
| 136 | 
            +
              config.add_server(name: 'Foo', uri: 'http://foo.com/api/graphql', headers: {})
         | 
| 137 | 
            +
            end
         | 
| 138 | 
            +
             | 
| 139 | 
            +
            # product.rb
         | 
| 140 | 
            +
            class Product
         | 
| 141 | 
            +
              extend GraphqlConnector::Foo::Query
         | 
| 142 | 
            +
             | 
| 143 | 
            +
              add_query all: :products,
         | 
| 144 | 
            +
                        returns: [:id, :name]
         | 
| 145 | 
            +
             | 
| 146 | 
            +
              add_query by_id: :products,
         | 
| 147 | 
            +
                        params: :id,
         | 
| 148 | 
            +
                        returns: [:name, product_category: [:id, :name]]
         | 
| 149 | 
            +
             | 
| 150 | 
            +
              add_query by_names: :products,
         | 
| 151 | 
            +
                        params: :names,
         | 
| 152 | 
            +
                        returns: [:id, :name, product_category: [:id, :name]]
         | 
| 153 | 
            +
             | 
| 154 | 
            +
              add_query by: :products,
         | 
| 155 | 
            +
                        params: [:id, :name],
         | 
| 156 | 
            +
                        returns: [:name]
         | 
| 157 | 
            +
             | 
| 158 | 
            +
              add_query by_category_id: :products,
         | 
| 159 | 
            +
                        params: :product_category,
         | 
| 160 | 
            +
                        returns: [product_category: [:id, :name]]
         | 
| 161 | 
            +
             | 
| 162 | 
            +
              add_mutation create: :createProduct,
         | 
| 163 | 
            +
                           params: [:name, :catgetoryId],
         | 
| 164 | 
            +
                           returns: [:id, :name]
         | 
| 165 | 
            +
            end
         | 
| 166 | 
            +
             | 
| 167 | 
            +
            Product.all
         | 
| 168 | 
            +
            => [OpenStruct<id=1, name='Demo Product', ...]
         | 
| 169 | 
            +
             | 
| 170 | 
            +
            Product.by_id(id: 1)
         | 
| 171 | 
            +
            => [OpenStruct<name='Demo Product', product_category=<ProductCategory<id=10, name='Demo Category'>>]
         | 
| 172 | 
            +
             | 
| 173 | 
            +
            Product.by_names(names: ['Demo Product', 'Non Demo Product'])
         | 
| 174 | 
            +
            => [OpenStruct<id=1, name='Demo Product', product_category=<ProductCategory<id=10, name='Demo Category'>>, Product<id=2, name='Demo Product' ...]
         | 
| 175 | 
            +
             | 
| 176 | 
            +
            Product.by(id: 1, name: 'Demo Product')
         | 
| 177 | 
            +
            => OpenStruct<name='Demo Product'>
         | 
| 178 | 
            +
             | 
| 179 | 
            +
            Product.by_category_id(product_category: { id: 10})
         | 
| 180 | 
            +
            => OpenStruct<product_category=<ProductCategory<id=10, name='Demo Category'>>
         | 
| 181 | 
            +
             | 
| 182 | 
            +
            Product.create(name: 'Another Product', catgetoryId: 10)
         | 
| 183 | 
            +
            => OpenStruct<id=10, name='Another Product'>
         | 
| 184 | 
            +
            ```
         | 
| 185 | 
            +
             | 
| 186 | 
            +
            Also custom **class methods** can used to call any kind of `query` and do further selection instead:
         | 
| 187 | 
            +
             | 
| 188 | 
            +
            ```ruby
         | 
| 189 | 
            +
            class Product
         | 
| 190 | 
            +
              extend GraphqlConnector::Foo::Query
         | 
| 191 | 
            +
             | 
| 192 | 
            +
              add_query all: :products, returns: [:name]
         | 
| 193 | 
            +
             | 
| 194 | 
            +
              def self.by_id(id:)
         | 
| 195 | 
            +
                all.select { |products| products.id == id }.first
         | 
| 196 | 
            +
              end
         | 
| 197 | 
            +
            end
         | 
| 198 | 
            +
             | 
| 199 | 
            +
            Product.by_id(id: 1)
         | 
| 200 | 
            +
            => OpenStruct<id=1, name='Demo Product'>>
         | 
| 201 | 
            +
            ```
         | 
| 202 | 
            +
             | 
| 203 | 
            +
            :warning: Ensure that your custom **class method** never has the **same name** as an `<alias>` of `add_query`, `add_raw_query` or `add_mutation`. Otherwise the associated grapqhl query will not be performed because of [Ruby Open Class principle](https://ruby-lang.co/ruby-open-class/)
         | 
| 204 | 
            +
             | 
| 205 | 
            +
             | 
| 206 | 
            +
            Example for `raw_query`:
         | 
| 207 | 
            +
             | 
| 208 | 
            +
            ```ruby
         | 
| 209 | 
            +
            class Product
         | 
| 210 | 
            +
              extend GraphqlConnector::Foo::Query
         | 
| 211 | 
            +
             | 
| 212 | 
            +
              add_raw_query all: ' query { products { id name } } '
         | 
| 213 | 
            +
              add_raw_query by: ' query products($id: !ID, $name: !String) '\
         | 
| 214 | 
            +
                            '{ products(id: $id, name: $name) { id name } }',
         | 
| 215 | 
            +
                            params: [:id, :name]
         | 
| 216 | 
            +
             | 
| 217 | 
            +
            end
         | 
| 218 | 
            +
             | 
| 219 | 
            +
            Product.all
         | 
| 220 | 
            +
            => [ { id: '1', name: 'Demo Product' }, ...]
         | 
| 221 | 
            +
             | 
| 222 | 
            +
            Product.by(id: '1', name: 'Demo Product')
         | 
| 223 | 
            +
            => { id: '1', name: 'Demo Product' }
         | 
| 224 | 
            +
             | 
| 225 | 
            +
            ```
         | 
| 226 | 
            +
             | 
| 227 | 
            +
            :exclamation: There is no `add_raw_mutation` since `add_raw_query` does already cover such a case
         | 
| 228 | 
            +
             | 
| 79 229 | 
             
            ## Development
         | 
| 80 230 |  | 
| 81 231 | 
             
            After checking out the repo, run
         | 
| @@ -100,4 +250,4 @@ The gem is available as open source under the terms of the [MIT License](https:/ | |
| 100 250 |  | 
| 101 251 | 
             
            ## Code of Conduct
         | 
| 102 252 |  | 
| 103 | 
            -
            Everyone interacting in the GraphqlConnector project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/ | 
| 253 | 
            +
            Everyone interacting in the GraphqlConnector project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/Garllon/graphql_connector/blob/master/CODE_OF_CONDUCT.md).
         | 
| @@ -0,0 +1,51 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
         | 
| 4 | 
            +
            # ! The following examples are used together with
         | 
| 5 | 
            +
            # ! https://github.com/sushie1984/rails-graphql-server
         | 
| 6 | 
            +
            # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            uri = 'http://rails-graphql-server.herokuapp.com/api/graphql'
         | 
| 9 | 
            +
            GraphqlConnector.configure do |config|
         | 
| 10 | 
            +
              config.add_server(name: 'RailsGraphqlServer', uri: uri, headers: {})
         | 
| 11 | 
            +
            end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            # Service class for fetching department data
         | 
| 14 | 
            +
            class Department
         | 
| 15 | 
            +
              extend GraphqlConnector::RailsGraphqlServer::Query
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              add_query all: :departments, returns: [:id, :name, employees: [:yearlySalary]]
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              add_query by_id: :departments,
         | 
| 20 | 
            +
                        params: [:id],
         | 
| 21 | 
            +
                        returns: [:id, :name, employees: [:yearlySalary]]
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              add_raw_query all_raw: 'query {
         | 
| 24 | 
            +
                                        departments {
         | 
| 25 | 
            +
                                          id name employees { yearlySalary }
         | 
| 26 | 
            +
                                        }
         | 
| 27 | 
            +
                                      }'
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              add_raw_query by_id_raw: 'query departments($id: [ID!]) {
         | 
| 30 | 
            +
                                          departments(id: $id) {
         | 
| 31 | 
            +
                                            name employees { name }
         | 
| 32 | 
            +
                                          }
         | 
| 33 | 
            +
                                        }',
         | 
| 34 | 
            +
                            params: [:id]
         | 
| 35 | 
            +
             | 
| 36 | 
            +
              # We use a nested 'input' as of convention for
         | 
| 37 | 
            +
              # https://github.com/sushie1984/rails-graphql-server/blob/master/app/graphql/input_objects/department_attributes.rb
         | 
| 38 | 
            +
              add_mutation create: :createDepartment,
         | 
| 39 | 
            +
                           params: :input,
         | 
| 40 | 
            +
                           returns: [department: %i[id name location]]
         | 
| 41 | 
            +
            end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            Department.all
         | 
| 44 | 
            +
             | 
| 45 | 
            +
            Department.by_id(id: %w[1 2])
         | 
| 46 | 
            +
             | 
| 47 | 
            +
            Department.all_raw
         | 
| 48 | 
            +
             | 
| 49 | 
            +
            Department.by_id_raw(id: %w[1 2])
         | 
| 50 | 
            +
             | 
| 51 | 
            +
            Department.create(input: { attributes: { name: 'One', location: 'Berlin' } })
         | 
| @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
         | 
| 4 | 
            +
            # ! The following examples are used together with
         | 
| 5 | 
            +
            # ! https://github.com/sushie1984/rails-graphql-server
         | 
| 6 | 
            +
            # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            uri = 'http://rails-graphql-server.herokuapp.com/api/graphql'
         | 
| 9 | 
            +
            GraphqlConnector.configure do |config|
         | 
| 10 | 
            +
              config.add_server(name: 'RailsGraphqlServer', uri: uri, headers: {})
         | 
| 11 | 
            +
            end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            department_input = { attributes: { name: 'One', location: 'Berlin' } }
         | 
| 14 | 
            +
            return_fields = ['department': ['id', 'name', 'employees' => ['yearlySalary']]]
         | 
| 15 | 
            +
            GraphqlConnector::RailsGraphqlServer.mutation('createDepartment',
         | 
| 16 | 
            +
                                                          { input: department_input },
         | 
| 17 | 
            +
                                                          return_fields)
         | 
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
         | 
| 4 | 
            +
            # ! The following examples are used together with
         | 
| 5 | 
            +
            # ! https://github.com/sushie1984/rails-graphql-server
         | 
| 6 | 
            +
            # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            uri = 'http://rails-graphql-server.herokuapp.com/api/graphql'
         | 
| 9 | 
            +
            GraphqlConnector.configure do |config|
         | 
| 10 | 
            +
              config.add_server(name: 'RailsGraphqlServer', uri: uri, headers: {})
         | 
| 11 | 
            +
            end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            GraphqlConnector::RailsGraphqlServer.query('departments',
         | 
| 14 | 
            +
                                                       {},
         | 
| 15 | 
            +
                                                       ['id', 'name',
         | 
| 16 | 
            +
                                                        'employees' => ['yearlySalary']])
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            GraphqlConnector::RailsGraphqlServer.query('departments',
         | 
| 19 | 
            +
                                                       { id: %w[1 2] },
         | 
| 20 | 
            +
                                                       ['id', 'name',
         | 
| 21 | 
            +
                                                        'employees' => ['yearlySalary']])
         | 
| @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
         | 
| 4 | 
            +
            # ! The following examples are used together with
         | 
| 5 | 
            +
            # ! https://github.com/sushie1984/rails-graphql-server
         | 
| 6 | 
            +
            # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            GraphqlConnector.configure do |config|
         | 
| 9 | 
            +
              config.add_server(name: 'RailsGraphqlServer',
         | 
| 10 | 
            +
                                uri: 'http://rails-graphql-server.herokuapp.com/api/graphql',
         | 
| 11 | 
            +
                                headers: {})
         | 
| 12 | 
            +
            end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            GraphqlConnector::RailsGraphqlServer.raw_query(
         | 
| 15 | 
            +
              'query { departments { id name employees { yearlySalary } } }'
         | 
| 16 | 
            +
            )
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            GraphqlConnector::RailsGraphqlServer.raw_query(
         | 
| 19 | 
            +
              'query departments($id: [ID!]) {
         | 
| 20 | 
            +
                departments(id: $id) { name employees { name }
         | 
| 21 | 
            +
                }
         | 
| 22 | 
            +
              }',
         | 
| 23 | 
            +
              variables: { id: %w[1 2] }
         | 
| 24 | 
            +
            )
         | 
    
        data/graphql_connector.gemspec
    CHANGED
    
    | @@ -7,12 +7,13 @@ require 'graphql_connector/version' | |
| 7 7 | 
             
            Gem::Specification.new do |spec|
         | 
| 8 8 | 
             
              spec.name          = 'graphql_connector'
         | 
| 9 9 | 
             
              spec.version       = GraphqlConnector::VERSION
         | 
| 10 | 
            -
              spec.authors       = [ | 
| 11 | 
            -
              spec.email         = ['palluthe.bennet@gmail.com']
         | 
| 10 | 
            +
              spec.authors       = %w[Garllon sushie1984]
         | 
| 11 | 
            +
              spec.email         = ['palluthe.bennet@gmail.com', 'sascha_burku@yahoo.de']
         | 
| 12 12 |  | 
| 13 | 
            -
              spec.summary       = ' | 
| 14 | 
            -
              spec.description   = ' | 
| 15 | 
            -
                                   ' | 
| 13 | 
            +
              spec.summary       = 'GraphQL client'
         | 
| 14 | 
            +
              spec.description   = 'Grahql client to query with your own raw string, '\
         | 
| 15 | 
            +
                                   'with the small helper method query or with service '\
         | 
| 16 | 
            +
                                   'class inclusion.'
         | 
| 16 17 | 
             
              spec.homepage      = 'https://github.com/Garllon/graphql_connector/blob/master/README.md'
         | 
| 17 18 | 
             
              spec.license       = 'MIT'
         | 
| 18 19 |  | 
| @@ -30,11 +31,10 @@ Gem::Specification.new do |spec| | |
| 30 31 | 
             
              spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
         | 
| 31 32 | 
             
              spec.require_paths = ['lib']
         | 
| 32 33 |  | 
| 33 | 
            -
              spec.add_dependency 'httparty', '~> 0. | 
| 34 | 
            +
              spec.add_dependency 'httparty', '~> 0.16'
         | 
| 34 35 |  | 
| 35 36 | 
             
              spec.add_development_dependency 'bundler', '~> 2.0'
         | 
| 36 37 | 
             
              spec.add_development_dependency 'pry', '~> 0.10'
         | 
| 37 | 
            -
              spec.add_development_dependency 'rake', '~> 10.0'
         | 
| 38 38 | 
             
              spec.add_development_dependency 'rspec', '~> 3.8'
         | 
| 39 39 | 
             
              spec.add_development_dependency 'rubocop', '~> 0.75'
         | 
| 40 40 | 
             
            end
         | 
    
        data/lib/graphql_connector.rb
    CHANGED
    
    | @@ -1,10 +1,16 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 3 | 
             
            require 'graphql_connector/version'
         | 
| 4 | 
            -
            require 'graphql_connector/ | 
| 4 | 
            +
            require 'graphql_connector/formatters/base_format'
         | 
| 5 | 
            +
            require 'graphql_connector/formatters/query_format'
         | 
| 6 | 
            +
            require 'graphql_connector/formatters/mutation_format'
         | 
| 5 7 | 
             
            require 'graphql_connector/configuration'
         | 
| 6 8 | 
             
            require 'graphql_connector/http_client'
         | 
| 7 9 | 
             
            require 'graphql_connector/base_server_type'
         | 
| 10 | 
            +
            require 'graphql_connector/service_classable/class_method_validator'
         | 
| 11 | 
            +
            require 'graphql_connector/service_classable/params_validator'
         | 
| 12 | 
            +
            require 'graphql_connector/service_classable/return_fields_validator'
         | 
| 13 | 
            +
            require 'graphql_connector/service_classable/queryable'
         | 
| 8 14 | 
             
            require 'graphql_connector/custom_attribute_error'
         | 
| 9 15 | 
             
            require 'httparty'
         | 
| 10 16 |  | 
| @@ -21,7 +27,7 @@ module GraphqlConnector | |
| 21 27 | 
             
              end
         | 
| 22 28 |  | 
| 23 29 | 
             
              def self.reset
         | 
| 24 | 
            -
                @configuration | 
| 30 | 
            +
                @configuration.reset!
         | 
| 25 31 | 
             
              end
         | 
| 26 32 |  | 
| 27 33 | 
             
              def self.configure
         | 
| @@ -5,12 +5,12 @@ 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)
         | 
| 8 | 
            +
                  def build(name, uri, headers, connector = {})
         | 
| 9 9 | 
             
                    verify_new_client_type_for!(name)
         | 
| 10 | 
            -
                    base_class = class_with(uri, headers)
         | 
| 10 | 
            +
                    base_class = class_with(uri, headers, connector)
         | 
| 11 11 | 
             
                    base_object = GraphqlConnector.const_set(name, base_class)
         | 
| 12 | 
            -
                     | 
| 13 | 
            -
                     | 
| 12 | 
            +
                    inject_http_client_delegations(base_object)
         | 
| 13 | 
            +
                    create_service_class_module(base_object)
         | 
| 14 14 |  | 
| 15 15 | 
             
                    base_object
         | 
| 16 16 | 
             
                  end
         | 
| @@ -25,30 +25,37 @@ module GraphqlConnector | |
| 25 25 | 
             
                          'configuration!'
         | 
| 26 26 | 
             
                  end
         | 
| 27 27 |  | 
| 28 | 
            -
                  def  | 
| 29 | 
            -
                     | 
| 30 | 
            -
                       | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
                  end
         | 
| 28 | 
            +
                  def create_service_class_module(base_object)
         | 
| 29 | 
            +
                    base_object.class_eval <<-METHOD, __FILE__, __LINE__ + 1
         | 
| 30 | 
            +
                      module Query
         | 
| 31 | 
            +
                        def self.extended(base)
         | 
| 32 | 
            +
                          base.extend(GraphqlConnector::ServiceClassable::Queryable)
         | 
| 33 | 
            +
                        end
         | 
| 35 34 |  | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
                        @http_client ||= GraphqlConnector::HttpClient.new(@uri, @headers)
         | 
| 35 | 
            +
                        def http_client
         | 
| 36 | 
            +
                          #{base_object}.http_client
         | 
| 37 | 
            +
                        end
         | 
| 40 38 | 
             
                      end
         | 
| 39 | 
            +
                    METHOD
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  def class_with(uri, headers, connector = {})
         | 
| 43 | 
            +
                    Class.new do
         | 
| 44 | 
            +
                      attr_accessor :uri, :headers, :connector
         | 
| 45 | 
            +
                      @uri       = uri
         | 
| 46 | 
            +
                      @headers   = headers
         | 
| 47 | 
            +
                      @connector = connector
         | 
| 41 48 | 
             
                    end
         | 
| 42 49 | 
             
                  end
         | 
| 43 50 |  | 
| 44 | 
            -
                  def  | 
| 51 | 
            +
                  def inject_http_client_delegations(base_object)
         | 
| 45 52 | 
             
                    base_object.instance_eval do
         | 
| 46 | 
            -
                       | 
| 47 | 
            -
             | 
| 48 | 
            -
                      end
         | 
| 53 | 
            +
                      extend SingleForwardable
         | 
| 54 | 
            +
                      def_delegators :http_client, :query, :raw_query, :mutation
         | 
| 49 55 |  | 
| 50 | 
            -
                      def  | 
| 51 | 
            -
                        http_client | 
| 56 | 
            +
                      def http_client
         | 
| 57 | 
            +
                        @http_client ||=
         | 
| 58 | 
            +
                          GraphqlConnector::HttpClient.new(@uri, @headers, @connector)
         | 
| 52 59 | 
             
                      end
         | 
| 53 60 | 
             
                    end
         | 
| 54 61 | 
             
                  end
         | 
| @@ -9,12 +9,14 @@ module GraphqlConnector | |
| 9 9 | 
             
                  @base_server_types = {}
         | 
| 10 10 | 
             
                end
         | 
| 11 11 |  | 
| 12 | 
            -
                def add_server(name:, uri:, headers:)
         | 
| 13 | 
            -
                  @base_server_types[name] = | 
| 12 | 
            +
                def add_server(name:, uri:, headers:, connector: {})
         | 
| 13 | 
            +
                  @base_server_types[name] =
         | 
| 14 | 
            +
                    BaseServerType.build(name, uri, headers, connector)
         | 
| 14 15 | 
             
                end
         | 
| 15 16 |  | 
| 16 17 | 
             
                def reset!
         | 
| 17 18 | 
             
                  @base_server_types.keys.each do |name|
         | 
| 19 | 
            +
                    GraphqlConnector.const_get(name).send :remove_const, 'Query'
         | 
| 18 20 | 
             
                    GraphqlConnector.send :remove_const, name
         | 
| 19 21 | 
             
                  end
         | 
| 20 22 | 
             
                  @base_server_types = {}
         | 
| @@ -0,0 +1,81 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module GraphqlConnector
         | 
| 4 | 
            +
              module Formatters
         | 
| 5 | 
            +
                # Class that returns in query or mutation string format
         | 
| 6 | 
            +
                class BaseFormat
         | 
| 7 | 
            +
                  def initialize(model, conditions, selected_fields)
         | 
| 8 | 
            +
                    @model = model
         | 
| 9 | 
            +
                    @conditions = conditions
         | 
| 10 | 
            +
                    @selected_fields = selected_fields
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  def create
         | 
| 14 | 
            +
                    <<-STRING
         | 
| 15 | 
            +
                    #{query_type} {
         | 
| 16 | 
            +
                      #{@model}#{arguments} {
         | 
| 17 | 
            +
                        #{parse_fields(@selected_fields)}
         | 
| 18 | 
            +
                      }
         | 
| 19 | 
            +
                    }
         | 
| 20 | 
            +
                    STRING
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  private
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  def arguments
         | 
| 26 | 
            +
                    conditions = @conditions.each_with_object([]) do |(key, value), array|
         | 
| 27 | 
            +
                      array << "#{key}: #{value_as_parameter(value)}"
         | 
| 28 | 
            +
                    end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                    return '' if conditions.empty?
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                    "(#{conditions.join(', ')})"
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  def value_as_parameter(value)
         | 
| 36 | 
            +
                    case value
         | 
| 37 | 
            +
                    when Array
         | 
| 38 | 
            +
                      casted_values = value.map { |v| value_as_parameter(v) }
         | 
| 39 | 
            +
                      "[#{casted_values.join(',')}]"
         | 
| 40 | 
            +
                    when Hash
         | 
| 41 | 
            +
                      casted_values = value.map { |k, v| "#{k}: #{value_as_parameter(v)}" }
         | 
| 42 | 
            +
                      "{#{casted_values.join(',')}}"
         | 
| 43 | 
            +
                    else
         | 
| 44 | 
            +
                      scalar_types(value)
         | 
| 45 | 
            +
                    end
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  def scalar_types(value)
         | 
| 49 | 
            +
                    case value
         | 
| 50 | 
            +
                    when TrueClass, FalseClass, Integer, Float
         | 
| 51 | 
            +
                      value
         | 
| 52 | 
            +
                    else # fallback to string
         | 
| 53 | 
            +
                      '"' + value.to_s + '"'
         | 
| 54 | 
            +
                    end
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                  def parse_fields(selected_fields)
         | 
| 58 | 
            +
                    results = selected_fields.map do |field|
         | 
| 59 | 
            +
                      case field
         | 
| 60 | 
            +
                      when Hash
         | 
| 61 | 
            +
                        handle_association(field)
         | 
| 62 | 
            +
                      else
         | 
| 63 | 
            +
                        field
         | 
| 64 | 
            +
                      end
         | 
| 65 | 
            +
                    end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                    results.join(' ')
         | 
| 68 | 
            +
                  end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  def handle_association(hash)
         | 
| 71 | 
            +
                    hash.map do |key, fields|
         | 
| 72 | 
            +
                      "#{key} { #{parse_fields(fields)} }"
         | 
| 73 | 
            +
                    end
         | 
| 74 | 
            +
                  end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                  def query_type
         | 
| 77 | 
            +
                    raise 'query_type undefined'
         | 
| 78 | 
            +
                  end
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
              end
         | 
| 81 | 
            +
            end
         | 
| @@ -3,26 +3,31 @@ | |
| 3 3 | 
             
            module GraphqlConnector
         | 
| 4 4 | 
             
              # Wrapper class for HTTParty post query
         | 
| 5 5 | 
             
              class HttpClient
         | 
| 6 | 
            -
                def initialize(uri, headers)
         | 
| 6 | 
            +
                def initialize(uri, headers, connector = {})
         | 
| 7 7 | 
             
                  @uri = uri
         | 
| 8 8 | 
             
                  @headers = headers
         | 
| 9 | 
            +
                  @connector = connector
         | 
| 9 10 | 
             
                end
         | 
| 10 11 |  | 
| 11 12 | 
             
                def query(model, conditions, selected_fields)
         | 
| 12 | 
            -
                  query_string = | 
| 13 | 
            -
             | 
| 14 | 
            -
                                                                    selected_fields).create
         | 
| 13 | 
            +
                  query_string =
         | 
| 14 | 
            +
                    Formatters::QueryFormat.new(model, conditions, selected_fields).create
         | 
| 15 15 | 
             
                  parsed_body = raw_query(query_string)
         | 
| 16 | 
            -
                   | 
| 17 | 
            -
             | 
| 16 | 
            +
                  format_body(parsed_body['data'][model.to_s])
         | 
| 17 | 
            +
                end
         | 
| 18 18 |  | 
| 19 | 
            -
             | 
| 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])
         | 
| 20 24 | 
             
                end
         | 
| 21 25 |  | 
| 22 | 
            -
                def raw_query(query_string)
         | 
| 26 | 
            +
                def raw_query(query_string, variables: {})
         | 
| 23 27 | 
             
                  response = HTTParty.post(@uri,
         | 
| 24 | 
            -
                                           headers:  | 
| 25 | 
            -
                                           body: { query: query_string | 
| 28 | 
            +
                                           headers: handle_headers,
         | 
| 29 | 
            +
                                           body: { query: query_string,
         | 
| 30 | 
            +
                                                   variables: variables })
         | 
| 26 31 | 
             
                  parsed_body = JSON.parse(response.body)
         | 
| 27 32 | 
             
                  verify_response!(parsed_body)
         | 
| 28 33 | 
             
                  parsed_body
         | 
| @@ -30,6 +35,19 @@ module GraphqlConnector | |
| 30 35 |  | 
| 31 36 | 
             
                private
         | 
| 32 37 |  | 
| 38 | 
            +
                def handle_headers
         | 
| 39 | 
            +
                  return @headers if @connector.empty?
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  @headers
         | 
| 42 | 
            +
                    .merge(@connector[:base].send(@connector[:method]))
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                def format_body(response_body)
         | 
| 46 | 
            +
                  return OpenStruct.new(response_body) unless response_body.is_a? Array
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  response_body.map { |entry| OpenStruct.new(entry) }
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
             | 
| 33 51 | 
             
                def verify_response!(parsed_body)
         | 
| 34 52 | 
             
                  return unless parsed_body.key? 'errors'
         | 
| 35 53 |  | 
| @@ -0,0 +1,31 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module GraphqlConnector
         | 
| 4 | 
            +
              module ServiceClassable
         | 
| 5 | 
            +
                class ClassMethodAlreadyImplementedError < StandardError; end
         | 
| 6 | 
            +
                class InvalidClassTypeError < StandardError; end
         | 
| 7 | 
            +
                # Checks whether a class method for a specific graphql query is in an
         | 
| 8 | 
            +
                # expected format
         | 
| 9 | 
            +
                class ClassMethodValidator
         | 
| 10 | 
            +
                  class << self
         | 
| 11 | 
            +
                    def validate_class_method(class_method_name, invoked_class)
         | 
| 12 | 
            +
                      return unless invoked_class.singleton_methods
         | 
| 13 | 
            +
                                                 .map(&:to_s)
         | 
| 14 | 
            +
                                                 .include?(class_method_name.to_s)
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                      error_msg = "The method '#{class_method_name}: ... ' is "\
         | 
| 17 | 
            +
                                  'already implemented within the context of '\
         | 
| 18 | 
            +
                                  "#{invoked_class} and therefore cannot be used again!"
         | 
| 19 | 
            +
                      raise ClassMethodAlreadyImplementedError, error_msg
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                    def validate_element_class_type(element, class_types)
         | 
| 23 | 
            +
                      return if element.class == class_types
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                      raise InvalidClassTypeError, "Please ensure that #{element} is a"\
         | 
| 26 | 
            +
                                                   "#{class_types}!"
         | 
| 27 | 
            +
                    end
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
            end
         | 
| @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module GraphqlConnector
         | 
| 4 | 
            +
              module ServiceClassable
         | 
| 5 | 
            +
                class InvalidParamsError < StandardError; end
         | 
| 6 | 
            +
                # Checks whether params for a specifc graphql query are in an expected
         | 
| 7 | 
            +
                # format
         | 
| 8 | 
            +
                class ParamsValidator
         | 
| 9 | 
            +
                  class << self
         | 
| 10 | 
            +
                    def validate(query_params)
         | 
| 11 | 
            +
                      params = [query_params].flatten
         | 
| 12 | 
            +
                      return if params.empty? ||
         | 
| 13 | 
            +
                                params.map(&:class).uniq == [Symbol] ||
         | 
| 14 | 
            +
                                params.map(&:class).uniq == [String]
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                      raise InvalidParamsError,
         | 
| 17 | 
            +
                            "Please ensure that #{query_params} are either "\
         | 
| 18 | 
            +
                            'Symbols/Strings as described in the README '\
         | 
| 19 | 
            +
                            '(e.g.: params: [:id, :name])'
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
| @@ -0,0 +1,108 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module GraphqlConnector
         | 
| 4 | 
            +
              module ServiceClassable
         | 
| 5 | 
            +
                # Module that allows to build query methods within the context of
         | 
| 6 | 
            +
                # service class
         | 
| 7 | 
            +
                module Queryable
         | 
| 8 | 
            +
                  CONDITIONS = 'binding.local_variables.map do |var|
         | 
| 9 | 
            +
                                  [var, binding.local_variable_get(var)]
         | 
| 10 | 
            +
                                end.to_h'
         | 
| 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)
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                    if params.empty?
         | 
| 20 | 
            +
                      return query_method(class_method_name, query_type, returns)
         | 
| 21 | 
            +
                    end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    ParamsValidator.validate(params)
         | 
| 24 | 
            +
                    query_keyword_method(class_method_name, query_type, params, returns)
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
             | 
| 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]
         | 
| 30 | 
            +
                    ClassMethodValidator.validate_class_method(class_method_name, self)
         | 
| 31 | 
            +
                    ClassMethodValidator.validate_element_class_type(query_string, String)
         | 
| 32 | 
            +
             | 
| 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)
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
             | 
| 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)
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                    if params.empty?
         | 
| 49 | 
            +
                      return mutation_method(class_method_name, query_type, returns)
         | 
| 50 | 
            +
                    end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                    ParamsValidator.validate(params)
         | 
| 53 | 
            +
                    mutation_keyword_method(class_method_name, query_type, params, returns)
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  private
         | 
| 57 | 
            +
             | 
| 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
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
             | 
| 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
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  def query_keyword_method(name, query_type, keywords, return_fields)
         | 
| 71 | 
            +
                    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
         | 
| 79 | 
            +
                  end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                  def raw_query_keyword_method(name, query_string, keywords)
         | 
| 82 | 
            +
                    keywords = [keywords].flatten
         | 
| 83 | 
            +
                    instance_eval <<-METHOD, __FILE__, __LINE__ + 1
         | 
| 84 | 
            +
                      def #{name}(#{keywords.map { |keyword| "#{keyword}:" }.join(', ')})
         | 
| 85 | 
            +
                        http_client.raw_query("#{query_string}", variables: #{CONDITIONS})
         | 
| 86 | 
            +
                      end
         | 
| 87 | 
            +
                    METHOD
         | 
| 88 | 
            +
                  end
         | 
| 89 | 
            +
             | 
| 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
         | 
| 98 | 
            +
                    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})
         | 
| 103 | 
            +
                      end
         | 
| 104 | 
            +
                    METHOD
         | 
| 105 | 
            +
                  end
         | 
| 106 | 
            +
                end
         | 
| 107 | 
            +
              end
         | 
| 108 | 
            +
            end
         | 
| @@ -0,0 +1,43 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module GraphqlConnector
         | 
| 4 | 
            +
              module ServiceClassable
         | 
| 5 | 
            +
                class ReturnFieldsErrors < StandardError; end
         | 
| 6 | 
            +
                # Valdations for return fields set within the context of a service class
         | 
| 7 | 
            +
                class ReturnFieldsValidator
         | 
| 8 | 
            +
                  class << self
         | 
| 9 | 
            +
                    def validate(return_fields)
         | 
| 10 | 
            +
                      unless return_fields.is_a?(Array)
         | 
| 11 | 
            +
                        raise ReturnFieldsErrors, 'Please ensure that returns is followed '\
         | 
| 12 | 
            +
                                                  'by an array. E.g. returns: [:id]'
         | 
| 13 | 
            +
                      end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                      return_fields.each { |entry| recursive_validation(entry) }
         | 
| 16 | 
            +
                    end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                    private
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                    def recursive_validation(entry)
         | 
| 21 | 
            +
                      case entry
         | 
| 22 | 
            +
                      when Hash
         | 
| 23 | 
            +
                        hash_validation(entry)
         | 
| 24 | 
            +
                      when Array
         | 
| 25 | 
            +
                        entry.each { |item| recursive_validation(item) }
         | 
| 26 | 
            +
                      else
         | 
| 27 | 
            +
                        return if [String, Symbol].member?(entry.class)
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                        raise ReturnFieldsErrors, "The #{entry} is neither a String nor a"\
         | 
| 30 | 
            +
                                                  'Symbol!'
         | 
| 31 | 
            +
                      end
         | 
| 32 | 
            +
                    end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                    def hash_validation(hash)
         | 
| 35 | 
            +
                      hash.each do |key, value|
         | 
| 36 | 
            +
                        recursive_validation(key)
         | 
| 37 | 
            +
                        recursive_validation(value)
         | 
| 38 | 
            +
                      end
         | 
| 39 | 
            +
                    end
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,15 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: graphql_connector
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1. | 
| 4 | 
            +
              version: 1.3.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Garllon
         | 
| 8 | 
            -
             | 
| 8 | 
            +
            - sushie1984
         | 
| 9 | 
            +
            autorequire:
         | 
| 9 10 | 
             
            bindir: exe
         | 
| 10 11 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 12 | 
            +
            date: 2021-06-02 00:00:00.000000000 Z
         | 
| 12 13 | 
             
            dependencies:
         | 
| 13 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 15 | 
             
              name: httparty
         | 
| @@ -16,14 +17,14 @@ dependencies: | |
| 16 17 | 
             
                requirements:
         | 
| 17 18 | 
             
                - - "~>"
         | 
| 18 19 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            -
                    version: '0. | 
| 20 | 
            +
                    version: '0.16'
         | 
| 20 21 | 
             
              type: :runtime
         | 
| 21 22 | 
             
              prerelease: false
         | 
| 22 23 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 24 | 
             
                requirements:
         | 
| 24 25 | 
             
                - - "~>"
         | 
| 25 26 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            -
                    version: '0. | 
| 27 | 
            +
                    version: '0.16'
         | 
| 27 28 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 29 | 
             
              name: bundler
         | 
| 29 30 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -52,20 +53,6 @@ dependencies: | |
| 52 53 | 
             
                - - "~>"
         | 
| 53 54 | 
             
                  - !ruby/object:Gem::Version
         | 
| 54 55 | 
             
                    version: '0.10'
         | 
| 55 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 56 | 
            -
              name: rake
         | 
| 57 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 58 | 
            -
                requirements:
         | 
| 59 | 
            -
                - - "~>"
         | 
| 60 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 61 | 
            -
                    version: '10.0'
         | 
| 62 | 
            -
              type: :development
         | 
| 63 | 
            -
              prerelease: false
         | 
| 64 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 65 | 
            -
                requirements:
         | 
| 66 | 
            -
                - - "~>"
         | 
| 67 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 68 | 
            -
                    version: '10.0'
         | 
| 69 56 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 70 57 | 
             
              name: rspec
         | 
| 71 58 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -94,19 +81,20 @@ dependencies: | |
| 94 81 | 
             
                - - "~>"
         | 
| 95 82 | 
             
                  - !ruby/object:Gem::Version
         | 
| 96 83 | 
             
                    version: '0.75'
         | 
| 97 | 
            -
            description:  | 
| 98 | 
            -
               | 
| 84 | 
            +
            description: Grahql client to query with your own raw string, with the small helper
         | 
| 85 | 
            +
              method query or with service class inclusion.
         | 
| 99 86 | 
             
            email:
         | 
| 100 87 | 
             
            - palluthe.bennet@gmail.com
         | 
| 88 | 
            +
            - sascha_burku@yahoo.de
         | 
| 101 89 | 
             
            executables: []
         | 
| 102 90 | 
             
            extensions: []
         | 
| 103 91 | 
             
            extra_rdoc_files: []
         | 
| 104 92 | 
             
            files:
         | 
| 93 | 
            +
            - ".github/workflows/ci.yaml"
         | 
| 105 94 | 
             
            - ".gitignore"
         | 
| 106 95 | 
             
            - ".rspec"
         | 
| 107 96 | 
             
            - ".rubocop.yml"
         | 
| 108 97 | 
             
            - ".rubocop_todo.yml"
         | 
| 109 | 
            -
            - ".travis.yml"
         | 
| 110 98 | 
             
            - CHANGELOG.md
         | 
| 111 99 | 
             
            - CODE_OF_CONDUCT.md
         | 
| 112 100 | 
             
            - Gemfile
         | 
| @@ -114,13 +102,23 @@ files: | |
| 114 102 | 
             
            - LICENSE.txt
         | 
| 115 103 | 
             
            - README.md
         | 
| 116 104 | 
             
            - bin/console
         | 
| 105 | 
            +
            - examples/departments_service_class_examples.rb
         | 
| 106 | 
            +
            - examples/mutation_examples.rb
         | 
| 107 | 
            +
            - examples/query_examples.rb
         | 
| 108 | 
            +
            - examples/raw_query_examples.rb
         | 
| 117 109 | 
             
            - graphql_connector.gemspec
         | 
| 118 110 | 
             
            - lib/graphql_connector.rb
         | 
| 119 111 | 
             
            - lib/graphql_connector/base_server_type.rb
         | 
| 120 112 | 
             
            - lib/graphql_connector/configuration.rb
         | 
| 121 113 | 
             
            - lib/graphql_connector/custom_attribute_error.rb
         | 
| 114 | 
            +
            - lib/graphql_connector/formatters/base_format.rb
         | 
| 115 | 
            +
            - lib/graphql_connector/formatters/mutation_format.rb
         | 
| 116 | 
            +
            - lib/graphql_connector/formatters/query_format.rb
         | 
| 122 117 | 
             
            - lib/graphql_connector/http_client.rb
         | 
| 123 | 
            -
            - lib/graphql_connector/ | 
| 118 | 
            +
            - lib/graphql_connector/service_classable/class_method_validator.rb
         | 
| 119 | 
            +
            - lib/graphql_connector/service_classable/params_validator.rb
         | 
| 120 | 
            +
            - lib/graphql_connector/service_classable/queryable.rb
         | 
| 121 | 
            +
            - lib/graphql_connector/service_classable/return_fields_validator.rb
         | 
| 124 122 | 
             
            - lib/graphql_connector/version.rb
         | 
| 125 123 | 
             
            homepage: https://github.com/Garllon/graphql_connector/blob/master/README.md
         | 
| 126 124 | 
             
            licenses:
         | 
| @@ -129,7 +127,7 @@ metadata: | |
| 129 127 | 
             
              homepage_uri: https://github.com/Garllon/graphql_connector/blob/master/README.md
         | 
| 130 128 | 
             
              source_code_uri: https://github.com/Garllon/graphql_connector
         | 
| 131 129 | 
             
              changelog_uri: https://github.com/Garllon/graphql_connector/blob/master/CHANGELOG.md
         | 
| 132 | 
            -
            post_install_message: | 
| 130 | 
            +
            post_install_message:
         | 
| 133 131 | 
             
            rdoc_options: []
         | 
| 134 132 | 
             
            require_paths:
         | 
| 135 133 | 
             
            - lib
         | 
| @@ -144,8 +142,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 144 142 | 
             
                - !ruby/object:Gem::Version
         | 
| 145 143 | 
             
                  version: '0'
         | 
| 146 144 | 
             
            requirements: []
         | 
| 147 | 
            -
            rubygems_version: 3. | 
| 148 | 
            -
            signing_key: | 
| 145 | 
            +
            rubygems_version: 3.1.4
         | 
| 146 | 
            +
            signing_key:
         | 
| 149 147 | 
             
            specification_version: 4
         | 
| 150 | 
            -
            summary:  | 
| 148 | 
            +
            summary: GraphQL client
         | 
| 151 149 | 
             
            test_files: []
         | 
    
        data/.travis.yml
    DELETED
    
    
| @@ -1,59 +0,0 @@ | |
| 1 | 
            -
            # frozen_string_literal: true
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module GraphqlConnector
         | 
| 4 | 
            -
              # create the graphql query_string out of the given attributes.
         | 
| 5 | 
            -
              class QueryBuilder
         | 
| 6 | 
            -
                def initialize(model, conditions, selected_fields)
         | 
| 7 | 
            -
                  @model            = model
         | 
| 8 | 
            -
                  @conditions       = conditions
         | 
| 9 | 
            -
                  @selected_fields  = selected_fields
         | 
| 10 | 
            -
                end
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                def create
         | 
| 13 | 
            -
                  "query { #{main_filter} { #{parse_fields(@selected_fields)} } }"
         | 
| 14 | 
            -
                end
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                private
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                def main_filter
         | 
| 19 | 
            -
                  conditions = @conditions.each_with_object([]) do |(key, value), array|
         | 
| 20 | 
            -
                    next if value.is_a? Hash # will be processed in #field_with_filter
         | 
| 21 | 
            -
             | 
| 22 | 
            -
                    array << "#{key}: #{value_as_parameter(value)}"
         | 
| 23 | 
            -
                  end
         | 
| 24 | 
            -
             | 
| 25 | 
            -
                  "#{@model}(#{conditions.join(', ')})"
         | 
| 26 | 
            -
                end
         | 
| 27 | 
            -
             | 
| 28 | 
            -
                def value_as_parameter(value)
         | 
| 29 | 
            -
                  case value
         | 
| 30 | 
            -
                  when TrueClass, FalseClass, Integer, Float
         | 
| 31 | 
            -
                    value
         | 
| 32 | 
            -
                  when Array
         | 
| 33 | 
            -
                    casted_values = value.map { |v| value_as_parameter(v) }
         | 
| 34 | 
            -
                    "[#{casted_values.join(',')}]"
         | 
| 35 | 
            -
                  else # fallback to string
         | 
| 36 | 
            -
                    '"' + value.to_s + '"'
         | 
| 37 | 
            -
                  end
         | 
| 38 | 
            -
                end
         | 
| 39 | 
            -
             | 
| 40 | 
            -
                def parse_fields(selected_fields)
         | 
| 41 | 
            -
                  results = selected_fields.map do |field|
         | 
| 42 | 
            -
                    case field
         | 
| 43 | 
            -
                    when Hash
         | 
| 44 | 
            -
                      handle_association(field)
         | 
| 45 | 
            -
                    else
         | 
| 46 | 
            -
                      field
         | 
| 47 | 
            -
                    end
         | 
| 48 | 
            -
                  end
         | 
| 49 | 
            -
             | 
| 50 | 
            -
                  results.join(' ')
         | 
| 51 | 
            -
                end
         | 
| 52 | 
            -
             | 
| 53 | 
            -
                def handle_association(hash)
         | 
| 54 | 
            -
                  hash.map do |key, fields|
         | 
| 55 | 
            -
                    "#{key} { #{parse_fields(fields)} }"
         | 
| 56 | 
            -
                  end
         | 
| 57 | 
            -
                end
         | 
| 58 | 
            -
              end
         | 
| 59 | 
            -
            end
         |