apollo-federation 2.2.3 → 3.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/CHANGELOG.md +42 -0
 - data/README.md +62 -0
 - data/lib/apollo-federation/entities_field.rb +20 -12
 - data/lib/apollo-federation/federated_document_from_schema_definition.rb +11 -3
 - data/lib/apollo-federation/field.rb +52 -5
 - data/lib/apollo-federation/field_set_serializer.rb +7 -9
 - data/lib/apollo-federation/interface.rb +6 -2
 - data/lib/apollo-federation/object.rb +10 -2
 - data/lib/apollo-federation/schema.rb +35 -1
 - data/lib/apollo-federation/version.rb +1 -1
 - metadata +2 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 3133ca250d8e6ed9689a172c2fdaf373ae0ee0fcb371848cffeb75938f97be62
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 5467c27805efb85724124ede7c1014abfffbd679aba915e188ec74edfc8a8051
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 446e436bbc11437122d01ba8c49097919b0c1d281ab40427ea330d3494d05dc21d10e3795394ef41bea9b24d5d33eb9c7ba854116f96cb32cc88318c51cde0ac
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: b22c3f55c0fb6114f68aefcedd08ed5f8acaebda5699f26be21e4cc9ad61c3d225aa6beb1f1253e64533dae56da6d869c8962a4b6aa75d548a9e032e01d3a8dc
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,3 +1,45 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # [3.3.0](https://github.com/Gusto/apollo-federation-ruby/compare/v3.2.0...v3.3.0) (2022-08-24)
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            ### Features
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            * introduce optional `resolve_references` method ([#206](https://github.com/Gusto/apollo-federation-ruby/issues/206)) ([1e3b631](https://github.com/Gusto/apollo-federation-ruby/commit/1e3b631609e1dfec8c3f126cd9dc8e0a2b3a0a57))
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            # [3.2.0](https://github.com/Gusto/apollo-federation-ruby/compare/v3.1.0...v3.2.0) (2022-08-15)
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            ### Features
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            * allow custom namespace for linked directives ([03fdfea](https://github.com/Gusto/apollo-federation-ruby/commit/03fdfeafaaea3c98ca4b7a734ce760ea08410530))
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            # [3.1.0](https://github.com/Gusto/apollo-federation-ruby/compare/v3.0.0...v3.1.0) (2022-06-21)
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            ### Features
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            * Support Federation v2 ([#196](https://github.com/Gusto/apollo-federation-ruby/issues/196)) ([238736c](https://github.com/Gusto/apollo-federation-ruby/commit/238736cdb6f12121ce2a295c7a28fba3990012b9)), closes [/www.apollographql.com/docs/federation/federation-2/moving-to-federation-2/#opt-in-to-federation-2](https://github.com//www.apollographql.com/docs/federation/federation-2/moving-to-federation-2//issues/opt-in-to-federation-2)
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            # [3.0.0](https://github.com/Gusto/apollo-federation-ruby/compare/v2.2.4...v3.0.0) (2022-04-05)
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            ### Bug Fixes
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            * camelize string fields to match sym behavior ([8f0382b](https://github.com/Gusto/apollo-federation-ruby/commit/8f0382b346d2cde5be252138275d67373b36acd7))
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            ### BREAKING CHANGES
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            * string fields will be camelized by default rather than passed as is.
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            ## [2.2.4](https://github.com/Gusto/apollo-federation-ruby/compare/v2.2.3...v2.2.4) (2022-04-01)
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            ### Bug Fixes
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            * add linux and darwin platforms to lockfile ([#188](https://github.com/Gusto/apollo-federation-ruby/issues/188)) ([fbbb856](https://github.com/Gusto/apollo-federation-ruby/commit/fbbb856b315400f21c189c26488efbf030792ae1))
         
     | 
| 
      
 40 
     | 
    
         
            +
            * bump circleci cache version ([#189](https://github.com/Gusto/apollo-federation-ruby/issues/189)) ([1b6c9d8](https://github.com/Gusto/apollo-federation-ruby/commit/1b6c9d8fc647c19a7eb4c95ab76b276aae9131c5))
         
     | 
| 
      
 41 
     | 
    
         
            +
            * set env variables for release step ([#191](https://github.com/Gusto/apollo-federation-ruby/issues/191)) ([db0d1e6](https://github.com/Gusto/apollo-federation-ruby/commit/db0d1e688b93bfa2114eb91248d2f507a50fca8a))
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
       1 
43 
     | 
    
         
             
            ## [2.2.3](https://github.com/Gusto/apollo-federation-ruby/compare/v2.2.2...v2.2.3) (2022-03-22)
         
     | 
| 
       2 
44 
     | 
    
         | 
| 
       3 
45 
     | 
    
         | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -61,6 +61,15 @@ class MySchema < GraphQL::Schema 
     | 
|
| 
       61 
61 
     | 
    
         
             
            end
         
     | 
| 
       62 
62 
     | 
    
         
             
            ```
         
     | 
| 
       63 
63 
     | 
    
         | 
| 
      
 64 
     | 
    
         
            +
            **Optional:** To opt in to Federation v2, specify the version in your schema:
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 67 
     | 
    
         
            +
            class MySchema < GraphQL::Schema
         
     | 
| 
      
 68 
     | 
    
         
            +
              include ApolloFederation::Schema
         
     | 
| 
      
 69 
     | 
    
         
            +
              federation version: '2.0'
         
     | 
| 
      
 70 
     | 
    
         
            +
            end
         
     | 
| 
      
 71 
     | 
    
         
            +
            ```
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
       64 
73 
     | 
    
         
             
            ## Example
         
     | 
| 
       65 
74 
     | 
    
         | 
| 
       66 
75 
     | 
    
         
             
            The [`example`](./example/) folder contains a Ruby implementation of Apollo's [`federation-demo`](https://github.com/apollographql/federation-demo). To run it locally, install the Ruby dependencies:
         
     | 
| 
         @@ -160,6 +169,59 @@ end 
     | 
|
| 
       160 
169 
     | 
    
         
             
            ```
         
     | 
| 
       161 
170 
     | 
    
         
             
            See [field set syntax](#field-set-syntax) for more details on the format of the `fields` option.
         
     | 
| 
       162 
171 
     | 
    
         | 
| 
      
 172 
     | 
    
         
            +
            ### The `@shareable` directive (Apollo Federation v2)
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
            [Apollo documentation](https://www.apollographql.com/docs/federation/federated-types/federated-directives/#shareable)
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
            Call `shareable` within your class definition:
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
      
 178 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 179 
     | 
    
         
            +
            class User < BaseObject
         
     | 
| 
      
 180 
     | 
    
         
            +
              shareable
         
     | 
| 
      
 181 
     | 
    
         
            +
            end
         
     | 
| 
      
 182 
     | 
    
         
            +
            ```
         
     | 
| 
      
 183 
     | 
    
         
            +
             
     | 
| 
      
 184 
     | 
    
         
            +
            Pass the `shareable: true` option to your field definition:
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 187 
     | 
    
         
            +
            class User < BaseObject
         
     | 
| 
      
 188 
     | 
    
         
            +
              field :id, ID, null: false, shareable: true
         
     | 
| 
      
 189 
     | 
    
         
            +
            end
         
     | 
| 
      
 190 
     | 
    
         
            +
            ```
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
            ### The `@inaccessible` directive (Apollo Federation v2)
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
            [Apollo documentation](https://www.apollographql.com/docs/federation/federated-types/federated-directives/#inaccessible)
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
            Call `inaccessible` within your class definition:
         
     | 
| 
      
 197 
     | 
    
         
            +
             
     | 
| 
      
 198 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 199 
     | 
    
         
            +
            class User < BaseObject
         
     | 
| 
      
 200 
     | 
    
         
            +
              inaccessible
         
     | 
| 
      
 201 
     | 
    
         
            +
            end
         
     | 
| 
      
 202 
     | 
    
         
            +
            ```
         
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
      
 204 
     | 
    
         
            +
            Pass the `inaccessible: true` option to your field definition:
         
     | 
| 
      
 205 
     | 
    
         
            +
             
     | 
| 
      
 206 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 207 
     | 
    
         
            +
            class User < BaseObject
         
     | 
| 
      
 208 
     | 
    
         
            +
              field :id, ID, null: false, inaccessible: true
         
     | 
| 
      
 209 
     | 
    
         
            +
            end
         
     | 
| 
      
 210 
     | 
    
         
            +
            ```
         
     | 
| 
      
 211 
     | 
    
         
            +
             
     | 
| 
      
 212 
     | 
    
         
            +
            ### The `@override` directive (Apollo Federation v2)
         
     | 
| 
      
 213 
     | 
    
         
            +
             
     | 
| 
      
 214 
     | 
    
         
            +
            [Apollo documentation](https://www.apollographql.com/docs/federation/federated-types/federated-directives/#override)
         
     | 
| 
      
 215 
     | 
    
         
            +
             
     | 
| 
      
 216 
     | 
    
         
            +
            Pass the `override:` option to your field definition:
         
     | 
| 
      
 217 
     | 
    
         
            +
             
     | 
| 
      
 218 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 219 
     | 
    
         
            +
            class Product < BaseObject
         
     | 
| 
      
 220 
     | 
    
         
            +
              field :id, ID, null: false
         
     | 
| 
      
 221 
     | 
    
         
            +
              field :inStock, Boolean, null: false, override: { from: 'Products' }
         
     | 
| 
      
 222 
     | 
    
         
            +
            end
         
     | 
| 
      
 223 
     | 
    
         
            +
            ```
         
     | 
| 
      
 224 
     | 
    
         
            +
             
     | 
| 
       163 
225 
     | 
    
         
             
            ### Field set syntax
         
     | 
| 
       164 
226 
     | 
    
         | 
| 
       165 
227 
     | 
    
         
             
            Field sets can be either strings encoded with the Apollo Field Set [syntax]((https://www.apollographql.com/docs/apollo-server/federation/federation-spec/#scalar-_fieldset)) or arrays, hashes and snake case symbols that follow the graphql-ruby conventions:
         
     | 
| 
         @@ -27,8 +27,10 @@ module ApolloFederation 
     | 
|
| 
       27 
27 
     | 
    
         
             
                end
         
     | 
| 
       28 
28 
     | 
    
         | 
| 
       29 
29 
     | 
    
         
             
                def _entities(representations:)
         
     | 
| 
       30 
     | 
    
         
            -
                  representations. 
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
      
 30 
     | 
    
         
            +
                  grouped_references = representations.group_by { |r| r[:__typename] }
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  final_results = []
         
     | 
| 
      
 33 
     | 
    
         
            +
                  grouped_references.each do |typename, references|
         
     | 
| 
       32 
34 
     | 
    
         
             
                    # TODO: Use warden or schema?
         
     | 
| 
       33 
35 
     | 
    
         
             
                    type = context.warden.get_type(typename)
         
     | 
| 
       34 
36 
     | 
    
         
             
                    if type.nil? || type.kind != GraphQL::TypeKinds::OBJECT
         
     | 
| 
         @@ -40,21 +42,27 @@ module ApolloFederation 
     | 
|
| 
       40 
42 
     | 
    
         
             
                    # TODO: What if the type is an interface?
         
     | 
| 
       41 
43 
     | 
    
         
             
                    type_class = class_of_type(type)
         
     | 
| 
       42 
44 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
                    if type_class.respond_to?(: 
     | 
| 
       44 
     | 
    
         
            -
                       
     | 
| 
      
 45 
     | 
    
         
            +
                    if type_class.respond_to?(:resolve_references)
         
     | 
| 
      
 46 
     | 
    
         
            +
                      results = type_class.resolve_references(references, context)
         
     | 
| 
      
 47 
     | 
    
         
            +
                    elsif type_class.respond_to?(:resolve_reference)
         
     | 
| 
      
 48 
     | 
    
         
            +
                      results = references.map { |reference| type_class.resolve_reference(reference, context) }
         
     | 
| 
       45 
49 
     | 
    
         
             
                    else
         
     | 
| 
       46 
     | 
    
         
            -
                       
     | 
| 
      
 50 
     | 
    
         
            +
                      results = references
         
     | 
| 
       47 
51 
     | 
    
         
             
                    end
         
     | 
| 
       48 
52 
     | 
    
         | 
| 
       49 
     | 
    
         
            -
                     
     | 
| 
       50 
     | 
    
         
            -
                       
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
      
 53 
     | 
    
         
            +
                    results = results.map do |result|
         
     | 
| 
      
 54 
     | 
    
         
            +
                      context.schema.after_lazy(result) do |resolved_value|
         
     | 
| 
      
 55 
     | 
    
         
            +
                        # TODO: This isn't 100% correct: if (for some reason) 2 different resolve_reference
         
     | 
| 
      
 56 
     | 
    
         
            +
                        # calls return the same object, it might not have the right type
         
     | 
| 
      
 57 
     | 
    
         
            +
                        # Right now, apollo-federation just adds a __typename property to the result,
         
     | 
| 
      
 58 
     | 
    
         
            +
                        # but I don't really like the idea of modifying the resolved object
         
     | 
| 
      
 59 
     | 
    
         
            +
                        context[resolved_value] = type
         
     | 
| 
      
 60 
     | 
    
         
            +
                        resolved_value
         
     | 
| 
      
 61 
     | 
    
         
            +
                      end
         
     | 
| 
       56 
62 
     | 
    
         
             
                    end
         
     | 
| 
      
 63 
     | 
    
         
            +
                    final_results = final_results.concat(results)
         
     | 
| 
       57 
64 
     | 
    
         
             
                  end
         
     | 
| 
      
 65 
     | 
    
         
            +
                  final_results
         
     | 
| 
       58 
66 
     | 
    
         
             
                end
         
     | 
| 
       59 
67 
     | 
    
         | 
| 
       60 
68 
     | 
    
         
             
                private
         
     | 
| 
         @@ -55,20 +55,28 @@ module ApolloFederation 
     | 
|
| 
       55 
55 
     | 
    
         | 
| 
       56 
56 
     | 
    
         
             
                def merge_directives(node, type)
         
     | 
| 
       57 
57 
     | 
    
         
             
                  if type.is_a?(ApolloFederation::HasDirectives)
         
     | 
| 
       58 
     | 
    
         
            -
                    directives = type.federation_directives
         
     | 
| 
      
 58 
     | 
    
         
            +
                    directives = type.federation_directives || []
         
     | 
| 
       59 
59 
     | 
    
         
             
                  else
         
     | 
| 
       60 
60 
     | 
    
         
             
                    directives = []
         
     | 
| 
       61 
61 
     | 
    
         
             
                  end
         
     | 
| 
       62 
62 
     | 
    
         | 
| 
       63 
     | 
    
         
            -
                   
     | 
| 
      
 63 
     | 
    
         
            +
                  directives.each do |directive|
         
     | 
| 
       64 
64 
     | 
    
         
             
                    node = node.merge_directive(
         
     | 
| 
       65 
     | 
    
         
            -
                      name: directive 
     | 
| 
      
 65 
     | 
    
         
            +
                      name: directive_name(directive),
         
     | 
| 
       66 
66 
     | 
    
         
             
                      arguments: build_arguments_node(directive[:arguments]),
         
     | 
| 
       67 
67 
     | 
    
         
             
                    )
         
     | 
| 
       68 
68 
     | 
    
         
             
                  end
         
     | 
| 
       69 
69 
     | 
    
         
             
                  node
         
     | 
| 
       70 
70 
     | 
    
         
             
                end
         
     | 
| 
       71 
71 
     | 
    
         | 
| 
      
 72 
     | 
    
         
            +
                def directive_name(directive)
         
     | 
| 
      
 73 
     | 
    
         
            +
                  if schema.federation_2?
         
     | 
| 
      
 74 
     | 
    
         
            +
                    "#{schema.link_namespace}__#{directive[:name]}"
         
     | 
| 
      
 75 
     | 
    
         
            +
                  else
         
     | 
| 
      
 76 
     | 
    
         
            +
                    directive[:name]
         
     | 
| 
      
 77 
     | 
    
         
            +
                  end
         
     | 
| 
      
 78 
     | 
    
         
            +
                end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
       72 
80 
     | 
    
         
             
                def build_arguments_node(arguments)
         
     | 
| 
       73 
81 
     | 
    
         
             
                  (arguments || []).map do |arg|
         
     | 
| 
       74 
82 
     | 
    
         
             
                    GraphQL::Language::Nodes::Argument.new(name: arg[:name], value: arg[:values])
         
     | 
| 
         @@ -7,31 +7,78 @@ module ApolloFederation 
     | 
|
| 
       7 
7 
     | 
    
         
             
              module Field
         
     | 
| 
       8 
8 
     | 
    
         
             
                include HasDirectives
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
                 
     | 
| 
      
 10 
     | 
    
         
            +
                VERSION_1_DIRECTIVES = %i[external requires provides].freeze
         
     | 
| 
      
 11 
     | 
    
         
            +
                VERSION_2_DIRECTIVES = %i[shareable inaccessible override].freeze
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                def initialize(*args, **kwargs, &block)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  add_v1_directives(**kwargs)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  add_v2_directives(**kwargs)
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  # Remove the custom kwargs
         
     | 
| 
      
 18 
     | 
    
         
            +
                  kwargs = kwargs.delete_if do |k, _|
         
     | 
| 
      
 19 
     | 
    
         
            +
                    VERSION_1_DIRECTIVES.include?(k) || VERSION_2_DIRECTIVES.include?(k)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  # Pass on the default args:
         
     | 
| 
      
 23 
     | 
    
         
            +
                  super(*args, **kwargs, &block)
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                private
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                def add_v1_directives(external: nil, requires: nil, provides: nil, **_kwargs)
         
     | 
| 
       11 
29 
     | 
    
         
             
                  if external
         
     | 
| 
       12 
30 
     | 
    
         
             
                    add_directive(name: 'external')
         
     | 
| 
       13 
31 
     | 
    
         
             
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
       14 
33 
     | 
    
         
             
                  if requires
         
     | 
| 
       15 
34 
     | 
    
         
             
                    add_directive(
         
     | 
| 
       16 
35 
     | 
    
         
             
                      name: 'requires',
         
     | 
| 
       17 
36 
     | 
    
         
             
                      arguments: [
         
     | 
| 
       18 
37 
     | 
    
         
             
                        name: 'fields',
         
     | 
| 
       19 
     | 
    
         
            -
                        values: ApolloFederation::FieldSetSerializer.serialize( 
     | 
| 
      
 38 
     | 
    
         
            +
                        values: ApolloFederation::FieldSetSerializer.serialize(
         
     | 
| 
      
 39 
     | 
    
         
            +
                          requires[:fields],
         
     | 
| 
      
 40 
     | 
    
         
            +
                          camelize: requires.fetch(:camelize, true),
         
     | 
| 
      
 41 
     | 
    
         
            +
                        ),
         
     | 
| 
       20 
42 
     | 
    
         
             
                      ],
         
     | 
| 
       21 
43 
     | 
    
         
             
                    )
         
     | 
| 
       22 
44 
     | 
    
         
             
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
       23 
46 
     | 
    
         
             
                  if provides
         
     | 
| 
       24 
47 
     | 
    
         
             
                    add_directive(
         
     | 
| 
       25 
48 
     | 
    
         
             
                      name: 'provides',
         
     | 
| 
       26 
49 
     | 
    
         
             
                      arguments: [
         
     | 
| 
       27 
50 
     | 
    
         
             
                        name: 'fields',
         
     | 
| 
       28 
     | 
    
         
            -
                        values: ApolloFederation::FieldSetSerializer.serialize( 
     | 
| 
      
 51 
     | 
    
         
            +
                        values: ApolloFederation::FieldSetSerializer.serialize(
         
     | 
| 
      
 52 
     | 
    
         
            +
                          provides[:fields],
         
     | 
| 
      
 53 
     | 
    
         
            +
                          camelize: provides.fetch(:camelize, true),
         
     | 
| 
      
 54 
     | 
    
         
            +
                        ),
         
     | 
| 
       29 
55 
     | 
    
         
             
                      ],
         
     | 
| 
       30 
56 
     | 
    
         
             
                    )
         
     | 
| 
       31 
57 
     | 
    
         
             
                  end
         
     | 
| 
       32 
58 
     | 
    
         | 
| 
       33 
     | 
    
         
            -
                   
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
      
 59 
     | 
    
         
            +
                  nil
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                def add_v2_directives(shareable: nil, inaccessible: nil, override: nil, **_kwargs)
         
     | 
| 
      
 63 
     | 
    
         
            +
                  if shareable
         
     | 
| 
      
 64 
     | 
    
         
            +
                    add_directive(name: 'shareable')
         
     | 
| 
      
 65 
     | 
    
         
            +
                  end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                  if inaccessible
         
     | 
| 
      
 68 
     | 
    
         
            +
                    add_directive(name: 'inaccessible')
         
     | 
| 
      
 69 
     | 
    
         
            +
                  end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                  if override
         
     | 
| 
      
 72 
     | 
    
         
            +
                    add_directive(
         
     | 
| 
      
 73 
     | 
    
         
            +
                      name: 'override',
         
     | 
| 
      
 74 
     | 
    
         
            +
                      arguments: [
         
     | 
| 
      
 75 
     | 
    
         
            +
                        name: 'from',
         
     | 
| 
      
 76 
     | 
    
         
            +
                        values: override[:from],
         
     | 
| 
      
 77 
     | 
    
         
            +
                      ],
         
     | 
| 
      
 78 
     | 
    
         
            +
                    )
         
     | 
| 
      
 79 
     | 
    
         
            +
                  end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                  nil
         
     | 
| 
       35 
82 
     | 
    
         
             
                end
         
     | 
| 
       36 
83 
     | 
    
         
             
              end
         
     | 
| 
       37 
84 
     | 
    
         
             
            end
         
     | 
| 
         @@ -6,20 +6,18 @@ module ApolloFederation 
     | 
|
| 
       6 
6 
     | 
    
         
             
              module FieldSetSerializer
         
     | 
| 
       7 
7 
     | 
    
         
             
                extend self
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
                def serialize(fields)
         
     | 
| 
      
 9 
     | 
    
         
            +
                def serialize(fields, camelize: true)
         
     | 
| 
       10 
10 
     | 
    
         
             
                  case fields
         
     | 
| 
       11 
11 
     | 
    
         
             
                  when Hash
         
     | 
| 
       12 
12 
     | 
    
         
             
                    fields.map do |field, nested_selections|
         
     | 
| 
       13 
     | 
    
         
            -
                      "#{camelize(field)} { #{serialize(nested_selections)} }"
         
     | 
| 
      
 13 
     | 
    
         
            +
                      "#{camelize(field, camelize)} { #{serialize(nested_selections, camelize: camelize)} }"
         
     | 
| 
       14 
14 
     | 
    
         
             
                    end.join(' ')
         
     | 
| 
       15 
15 
     | 
    
         
             
                  when Array
         
     | 
| 
       16 
16 
     | 
    
         
             
                    fields.map do |field|
         
     | 
| 
       17 
     | 
    
         
            -
                      serialize(field)
         
     | 
| 
      
 17 
     | 
    
         
            +
                      serialize(field, camelize: camelize)
         
     | 
| 
       18 
18 
     | 
    
         
             
                    end.join(' ')
         
     | 
| 
       19 
     | 
    
         
            -
                  when String
         
     | 
| 
       20 
     | 
    
         
            -
                    fields
         
     | 
| 
       21 
     | 
    
         
            -
                  when Symbol
         
     | 
| 
       22 
     | 
    
         
            -
                    camelize(fields)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  when Symbol, String
         
     | 
| 
      
 20 
     | 
    
         
            +
                    camelize(fields, camelize)
         
     | 
| 
       23 
21 
     | 
    
         
             
                  else
         
     | 
| 
       24 
22 
     | 
    
         
             
                    raise ArgumentError, "Unexpected field set type: #{fields.class}"
         
     | 
| 
       25 
23 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -27,8 +25,8 @@ module ApolloFederation 
     | 
|
| 
       27 
25 
     | 
    
         | 
| 
       28 
26 
     | 
    
         
             
                private
         
     | 
| 
       29 
27 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
                def camelize(field)
         
     | 
| 
       31 
     | 
    
         
            -
                  GraphQL::Schema::Member::BuildType.camelize(field.to_s)
         
     | 
| 
      
 28 
     | 
    
         
            +
                def camelize(field, camelize)
         
     | 
| 
      
 29 
     | 
    
         
            +
                  camelize ? GraphQL::Schema::Member::BuildType.camelize(field.to_s) : field.to_s
         
     | 
| 
       32 
30 
     | 
    
         
             
                end
         
     | 
| 
       33 
31 
     | 
    
         
             
              end
         
     | 
| 
       34 
32 
     | 
    
         
             
            end
         
     | 
| 
         @@ -18,12 +18,16 @@ module ApolloFederation 
     | 
|
| 
       18 
18 
     | 
    
         
             
                    add_directive(name: 'extends')
         
     | 
| 
       19 
19 
     | 
    
         
             
                  end
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
                  def  
     | 
| 
      
 21 
     | 
    
         
            +
                  def inaccessible
         
     | 
| 
      
 22 
     | 
    
         
            +
                    add_directive(name: 'inaccessible')
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  def key(fields:, camelize: true)
         
     | 
| 
       22 
26 
     | 
    
         
             
                    add_directive(
         
     | 
| 
       23 
27 
     | 
    
         
             
                      name: 'key',
         
     | 
| 
       24 
28 
     | 
    
         
             
                      arguments: [
         
     | 
| 
       25 
29 
     | 
    
         
             
                        name: 'fields',
         
     | 
| 
       26 
     | 
    
         
            -
                        values: ApolloFederation::FieldSetSerializer.serialize(fields),
         
     | 
| 
      
 30 
     | 
    
         
            +
                        values: ApolloFederation::FieldSetSerializer.serialize(fields, camelize: camelize),
         
     | 
| 
       27 
31 
     | 
    
         
             
                      ],
         
     | 
| 
       28 
32 
     | 
    
         
             
                    )
         
     | 
| 
       29 
33 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -16,12 +16,20 @@ module ApolloFederation 
     | 
|
| 
       16 
16 
     | 
    
         
             
                    add_directive(name: 'extends')
         
     | 
| 
       17 
17 
     | 
    
         
             
                  end
         
     | 
| 
       18 
18 
     | 
    
         | 
| 
       19 
     | 
    
         
            -
                  def  
     | 
| 
      
 19 
     | 
    
         
            +
                  def shareable
         
     | 
| 
      
 20 
     | 
    
         
            +
                    add_directive(name: 'shareable')
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                  def inaccessible
         
     | 
| 
      
 24 
     | 
    
         
            +
                    add_directive(name: 'inaccessible')
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  def key(fields:, camelize: true)
         
     | 
| 
       20 
28 
     | 
    
         
             
                    add_directive(
         
     | 
| 
       21 
29 
     | 
    
         
             
                      name: 'key',
         
     | 
| 
       22 
30 
     | 
    
         
             
                      arguments: [
         
     | 
| 
       23 
31 
     | 
    
         
             
                        name: 'fields',
         
     | 
| 
       24 
     | 
    
         
            -
                        values: ApolloFederation::FieldSetSerializer.serialize(fields),
         
     | 
| 
      
 32 
     | 
    
         
            +
                        values: ApolloFederation::FieldSetSerializer.serialize(fields, camelize: camelize),
         
     | 
| 
       25 
33 
     | 
    
         
             
                      ],
         
     | 
| 
       26 
34 
     | 
    
         
             
                    )
         
     | 
| 
       27 
35 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -12,9 +12,35 @@ module ApolloFederation 
     | 
|
| 
       12 
12 
     | 
    
         
             
                end
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
14 
     | 
    
         
             
                module CommonMethods
         
     | 
| 
      
 15 
     | 
    
         
            +
                  FEDERATION_2_PREFIX = <<~SCHEMA
         
     | 
| 
      
 16 
     | 
    
         
            +
                    extend schema
         
     | 
| 
      
 17 
     | 
    
         
            +
                      @link(url: "https://specs.apollo.dev/federation/v2.0")
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  SCHEMA
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  def federation(version: '1.0', link: {})
         
     | 
| 
      
 22 
     | 
    
         
            +
                    @federation_version = version
         
     | 
| 
      
 23 
     | 
    
         
            +
                    @link = { as: 'federation' }.merge(link)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  def federation_version
         
     | 
| 
      
 27 
     | 
    
         
            +
                    @federation_version || '1.0'
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  def federation_2?
         
     | 
| 
      
 31 
     | 
    
         
            +
                    Gem::Version.new(federation_version.to_s) >= Gem::Version.new('2.0.0')
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
       15 
34 
     | 
    
         
             
                  def federation_sdl(context: nil)
         
     | 
| 
       16 
35 
     | 
    
         
             
                    document_from_schema = FederatedDocumentFromSchemaDefinition.new(self, context: context)
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                    output = GraphQL::Language::Printer.new.print(document_from_schema.document)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    output.prepend(FEDERATION_2_PREFIX) if federation_2?
         
     | 
| 
      
 39 
     | 
    
         
            +
                    output
         
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  def link_namespace
         
     | 
| 
      
 43 
     | 
    
         
            +
                    @link[:as]
         
     | 
| 
       18 
44 
     | 
    
         
             
                  end
         
     | 
| 
       19 
45 
     | 
    
         | 
| 
       20 
46 
     | 
    
         
             
                  def query(new_query_object = nil)
         
     | 
| 
         @@ -34,6 +60,14 @@ module ApolloFederation 
     | 
|
| 
       34 
60 
     | 
    
         | 
| 
       35 
61 
     | 
    
         
             
                  private
         
     | 
| 
       36 
62 
     | 
    
         | 
| 
      
 63 
     | 
    
         
            +
                  def federation_2_prefix
         
     | 
| 
      
 64 
     | 
    
         
            +
                    <<~SCHEMA
         
     | 
| 
      
 65 
     | 
    
         
            +
                      extend schema
         
     | 
| 
      
 66 
     | 
    
         
            +
                        @link(url: "https://specs.apollo.dev/federation/v2.0", as: "#{link_namespace}")
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                    SCHEMA
         
     | 
| 
      
 69 
     | 
    
         
            +
                  end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
       37 
71 
     | 
    
         
             
                  def schema_entities
         
     | 
| 
       38 
72 
     | 
    
         
             
                    # Create a temporary schema that inherits from this one to extract the types
         
     | 
| 
       39 
73 
     | 
    
         
             
                    types_schema = Class.new(self)
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: apollo-federation
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version:  
     | 
| 
      
 4 
     | 
    
         
            +
              version: 3.3.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Noa Elad
         
     | 
| 
         @@ -9,7 +9,7 @@ authors: 
     | 
|
| 
       9 
9 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       10 
10 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       11 
11 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       12 
     | 
    
         
            -
            date: 2022- 
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2022-08-24 00:00:00.000000000 Z
         
     | 
| 
       13 
13 
     | 
    
         
             
            dependencies:
         
     | 
| 
       14 
14 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       15 
15 
     | 
    
         
             
              name: graphql
         
     |