elasticgraph-apollo 0.18.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +63 -0
  4. data/apollo_tests_implementation/Dockerfile +66 -0
  5. data/apollo_tests_implementation/Gemfile +27 -0
  6. data/apollo_tests_implementation/Rakefile +22 -0
  7. data/apollo_tests_implementation/config/products_schema.rb +173 -0
  8. data/apollo_tests_implementation/config/settings.yaml +34 -0
  9. data/apollo_tests_implementation/config.ru +122 -0
  10. data/apollo_tests_implementation/docker-compose.yaml +18 -0
  11. data/apollo_tests_implementation/lib/test_implementation_extension.rb +58 -0
  12. data/apollo_tests_implementation/wait_for_datastore.sh +17 -0
  13. data/elasticgraph-apollo.gemspec +27 -0
  14. data/lib/elastic_graph/apollo/graphql/engine_extension.rb +52 -0
  15. data/lib/elastic_graph/apollo/graphql/entities_field_resolver.rb +305 -0
  16. data/lib/elastic_graph/apollo/graphql/http_endpoint_extension.rb +45 -0
  17. data/lib/elastic_graph/apollo/graphql/service_field_resolver.rb +30 -0
  18. data/lib/elastic_graph/apollo/schema_definition/api_extension.rb +385 -0
  19. data/lib/elastic_graph/apollo/schema_definition/apollo_directives.rb +119 -0
  20. data/lib/elastic_graph/apollo/schema_definition/argument_extension.rb +20 -0
  21. data/lib/elastic_graph/apollo/schema_definition/entity_type_extension.rb +30 -0
  22. data/lib/elastic_graph/apollo/schema_definition/enum_type_extension.rb +23 -0
  23. data/lib/elastic_graph/apollo/schema_definition/enum_value_extension.rb +20 -0
  24. data/lib/elastic_graph/apollo/schema_definition/factory_extension.rb +104 -0
  25. data/lib/elastic_graph/apollo/schema_definition/field_extension.rb +59 -0
  26. data/lib/elastic_graph/apollo/schema_definition/graphql_sdl_enumerator_extension.rb +69 -0
  27. data/lib/elastic_graph/apollo/schema_definition/input_type_extension.rb +20 -0
  28. data/lib/elastic_graph/apollo/schema_definition/interface_type_extension.rb +25 -0
  29. data/lib/elastic_graph/apollo/schema_definition/object_type_extension.rb +28 -0
  30. data/lib/elastic_graph/apollo/schema_definition/scalar_type_extension.rb +23 -0
  31. data/lib/elastic_graph/apollo/schema_definition/state_extension.rb +23 -0
  32. data/lib/elastic_graph/apollo/schema_definition/union_type_extension.rb +20 -0
  33. data/script/boot_eg_apollo_implementation +22 -0
  34. data/script/export_docker_env_vars.sh +15 -0
  35. data/script/test_compatibility +54 -0
  36. metadata +472 -0
@@ -0,0 +1,385 @@
1
+ # Copyright 2024 Block, Inc.
2
+ #
3
+ # Use of this source code is governed by an MIT-style
4
+ # license that can be found in the LICENSE file or at
5
+ # https://opensource.org/licenses/MIT.
6
+ #
7
+ # frozen_string_literal: true
8
+
9
+ require "elastic_graph/error"
10
+ require "elastic_graph/version"
11
+ require "elastic_graph/apollo/graphql/engine_extension"
12
+ require "elastic_graph/apollo/schema_definition/entity_type_extension"
13
+ require "elastic_graph/apollo/schema_definition/factory_extension"
14
+ require "elastic_graph/apollo/schema_definition/state_extension"
15
+
16
+ module ElasticGraph
17
+ module Apollo
18
+ module SchemaDefinition
19
+ # Module designed to be extended onto an `ElasticGraph::SchemaDefinition::API` instance
20
+ # to customize the schema artifacts based on the Apollo Federation subgraph spec:
21
+ #
22
+ # https://www.apollographql.com/docs/federation/subgraph-spec/
23
+ #
24
+ # Note that at this time we do not yet support extending a type owned by another
25
+ # subgraph (which the `@requires`, `@provides`, `@extends`, and `@external`
26
+ # directives are used for).
27
+ module APIExtension
28
+ def results
29
+ register_graphql_extension GraphQL::EngineExtension, defined_at: "elastic_graph/apollo/graphql/engine_extension"
30
+ define_apollo_schema_elements
31
+
32
+ super
33
+ end
34
+
35
+ # Called from the public API, as:
36
+ # schema.tag_built_in_types_with "tag-name", except: ["IntAggregatedValues", ...]
37
+ def tag_built_in_types_with(name, except: [])
38
+ except_set = except.to_set
39
+ on_built_in_types do |type|
40
+ type.directive("tag", name: name) unless except_set.include?(type.name)
41
+ end
42
+ end
43
+
44
+ # Picks which version of Apollo federation to target. By default, the latest supported version is
45
+ # targeted, but you can call this to pick an earlier version, which may be necessary if your
46
+ # organization is running an old version of Apollo studio.
47
+ def target_apollo_federation_version(version)
48
+ # Allow the version to have the `v` prefix, but don't require it.
49
+ version = version.delete_prefix("v")
50
+
51
+ state.apollo_directive_definitions = DIRECTIVE_DEFINITIONS_BY_FEDERATION_VERSION.fetch(version) do
52
+ supported_version_descriptions = DIRECTIVE_DEFINITIONS_BY_FEDERATION_VERSION.keys.map do |version_number|
53
+ "v#{version_number}"
54
+ end.join(", ")
55
+
56
+ raise SchemaError, "elasticgraph-apollo v#{ElasticGraph::VERSION} does not support Apollo federation v#{version}. " \
57
+ "Pick one of the supported versions (#{supported_version_descriptions}) instead."
58
+ end
59
+ end
60
+
61
+ def self.extended(api)
62
+ api.factory.extend FactoryExtension
63
+ api.state.extend StateExtension
64
+
65
+ latest_federation_version = DIRECTIVE_DEFINITIONS_BY_FEDERATION_VERSION
66
+ .keys
67
+ .max_by { |v| v.split(".").map(&:to_i) } # : ::String
68
+
69
+ api.target_apollo_federation_version latest_federation_version
70
+
71
+ api.on_built_in_types do |type|
72
+ # Built-in types like `PageInfo` need to be tagged with `@shareable` on Federation V2 since other subgraphs may
73
+ # have them and they aren't entity types. `Query`, as the root, is a special case that must be skipped.
74
+ (_ = type).apollo_shareable if type.respond_to?(:apollo_shareable) && type.name != "Query"
75
+ end
76
+ end
77
+
78
+ private
79
+
80
+ # These directive definitions come straight from the Apollo federation spec:
81
+ # https://github.com/apollographql/federation/blob/25beb382fff253ac38ef6d7a5454af60da0addbb/docs/source/subgraph-spec.mdx#L57-L70
82
+ # https://github.com/apollographql/apollo-federation-subgraph-compatibility/blob/2.0.0/COMPATIBILITY.md#products-schema-to-be-implemented-by-library-maintainers
83
+ #
84
+ # I've updated them here to match the "canonical form" that the GraphQL
85
+ # gem dumps for directives (e.g. it sorts the `on` clauses alphabetically) so that
86
+ # we can use this from our tests to assert the resulting GraphQL SDL.
87
+ directives_for_fed_v2_6 = [
88
+ <<~EOS.strip,
89
+ extend schema
90
+ @link(import: ["@authenticated", "@composeDirective", "@extends", "@external", "@inaccessible", "@interfaceObject", "@key", "@override", "@policy", "@provides", "@requires", "@requiresScopes", "@shareable", "@tag", "FieldSet"], url: "https://specs.apollo.dev/federation/v2.6")
91
+ EOS
92
+ "directive @authenticated on ENUM | FIELD_DEFINITION | INTERFACE | OBJECT | SCALAR",
93
+ "directive @composeDirective(name: String!) repeatable on SCHEMA",
94
+ "directive @extends on INTERFACE | OBJECT",
95
+ "directive @external on FIELD_DEFINITION | OBJECT",
96
+ "directive @inaccessible on ARGUMENT_DEFINITION | ENUM | ENUM_VALUE | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | INPUT_OBJECT | INTERFACE | OBJECT | SCALAR | UNION",
97
+ "directive @interfaceObject on OBJECT",
98
+ "directive @key(fields: FieldSet!, resolvable: Boolean = true) repeatable on INTERFACE | OBJECT",
99
+ "directive @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA",
100
+ "directive @override(from: String!) on FIELD_DEFINITION",
101
+ "directive @policy(policies: [[federation__Policy!]!]!) on ENUM | FIELD_DEFINITION | INTERFACE | OBJECT | SCALAR",
102
+ "directive @provides(fields: FieldSet!) on FIELD_DEFINITION",
103
+ "directive @requires(fields: FieldSet!) on FIELD_DEFINITION",
104
+ "directive @requiresScopes(scopes: [[federation__Scope!]!]!) on ENUM | FIELD_DEFINITION | INTERFACE | OBJECT | SCALAR",
105
+ "directive @shareable on FIELD_DEFINITION | OBJECT",
106
+ "directive @tag(name: String!) repeatable on ARGUMENT_DEFINITION | ENUM | ENUM_VALUE | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | INPUT_OBJECT | INTERFACE | OBJECT | SCALAR | UNION"
107
+ ]
108
+
109
+ # Differences between federation v2.5 and v2.6
110
+ #
111
+ # - v2.5 has no @policy directive (v2.6 has this).
112
+ # - The link URL reflects the version
113
+ directives_for_fed_v2_5 = directives_for_fed_v2_6.filter_map do |directive|
114
+ if directive.include?("extend schema")
115
+ directive
116
+ .sub(', "@policy"', "")
117
+ .sub("v2.6", "v2.5")
118
+ elsif directive.include?("directive @policy")
119
+ nil
120
+ else
121
+ directive
122
+ end
123
+ end
124
+
125
+ # Differences between federation v2.3 and v2.5
126
+ #
127
+ # - v2.3 has no @authenticated directive (v2.5 has this).
128
+ # - v2.3 has no @requiresScopes directive (v2.5 has this).
129
+ # - The link URL reflects the version
130
+ directives_for_fed_v2_3 = directives_for_fed_v2_5.filter_map do |directive|
131
+ if directive.include?("extend schema")
132
+ directive
133
+ .sub('"@authenticated", ', "")
134
+ .sub(', "@requiresScopes"', "")
135
+ .sub("v2.5", "v2.3")
136
+ elsif directive.include?("directive @authenticated") || directive.include?("directive @requiresScopes")
137
+ nil
138
+ else
139
+ directive
140
+ end
141
+ end
142
+
143
+ # Differences between federation v2.0 and v2.3
144
+ #
145
+ # - v2.0 has no @composeDirective directive (v2.3 has this).
146
+ # - v2.0 has no @interfaceObject directive (v2.3 has this).
147
+ # - The link URL reflects the version
148
+ directives_for_fed_v2_0 = directives_for_fed_v2_3.filter_map do |directive|
149
+ if directive.include?("extend schema")
150
+ directive
151
+ .sub('"@composeDirective", ', "")
152
+ .sub(', "@interfaceObject"', "")
153
+ .sub("v2.3", "v2.0")
154
+ elsif directive.include?("directive @interfaceObject") || directive.include?("directive @composeDirective")
155
+ nil
156
+ else
157
+ directive
158
+ end
159
+ end
160
+
161
+ DIRECTIVE_DEFINITIONS_BY_FEDERATION_VERSION = {
162
+ "2.6" => directives_for_fed_v2_6,
163
+ "2.5" => directives_for_fed_v2_5,
164
+ "2.3" => directives_for_fed_v2_3,
165
+ "2.0" => directives_for_fed_v2_0
166
+ }
167
+
168
+ def define_apollo_schema_elements
169
+ state.apollo_directive_definitions.each { |directive| raw_sdl directive }
170
+
171
+ apollo_scalar_type "link__Import" do |t|
172
+ t.documentation "Scalar type used by the `@link` directive required for Apollo Federation V2."
173
+ # `scalar_type` requires we set these but this scalar type is only in GraphQL.
174
+ t.mapping type: nil
175
+ t.json_schema type: "null"
176
+ end
177
+
178
+ apollo_scalar_type "federation__Scope" do |t|
179
+ t.documentation "Scalar type used by the `@requiresScopes` directive required for Apollo Federation V2.5+."
180
+ # `scalar_type` requires we set these but this scalar type is only in GraphQL.
181
+ t.mapping type: nil
182
+ t.json_schema type: "null"
183
+ end
184
+
185
+ apollo_scalar_type "federation__Policy" do |t|
186
+ t.documentation "Scalar type used by the `@policy` directive required for Apollo Federation V2.6+."
187
+ # `scalar_type` requires we set these but this scalar type is only in GraphQL.
188
+ t.mapping type: nil
189
+ t.json_schema type: "null"
190
+ end
191
+
192
+ # Copied from https://github.com/apollographql/federation/blob/b3a3cb84d8d67d1d6e817dc85b9ae0ecdd9908d1/docs/source/subgraph-spec.mdx#subgraph-schema-additions
193
+ apollo_enum_type "link__Purpose" do |t|
194
+ t.documentation "Enum type used by the `@link` directive required for Apollo Federation V2."
195
+
196
+ t.value "SECURITY" do |v|
197
+ v.documentation "`SECURITY` features provide metadata necessary to securely resolve fields."
198
+ end
199
+
200
+ t.value "EXECUTION" do |v|
201
+ v.documentation "`EXECUTION` features provide metadata necessary for operation execution."
202
+ end
203
+ end
204
+
205
+ apollo_scalar_type "FieldSet" do |t|
206
+ t.documentation <<~EOS
207
+ A custom scalar type required by the [Apollo Federation subgraph
208
+ spec](https://www.apollographql.com/docs/federation/subgraph-spec/#scalar-fieldset):
209
+
210
+ > This string-serialized scalar represents a set of fields that's passed to a federated directive,
211
+ > such as `@key`, `@requires`, or `@provides`.
212
+ >
213
+ > Grammatically, a `FieldSet` is a [selection set](http://spec.graphql.org/draft/#sec-Selection-Sets)
214
+ > minus the outermost curly braces. It can represent a single field (`"upc"`), multiple fields
215
+ > (`"id countryCode"`), and even nested selection sets (`"id organization { id }"`).
216
+
217
+ Not intended for use by clients other than Apollo.
218
+ EOS
219
+
220
+ # `scalar_type` requires we set these but this scalar type is only in GraphQL.
221
+ t.mapping type: nil
222
+ t.json_schema type: "null"
223
+ end
224
+
225
+ apollo_scalar_type "_Any" do |t|
226
+ t.documentation <<~EOS
227
+ A custom scalar type required by the [Apollo Federation subgraph
228
+ spec](https://www.apollographql.com/docs/federation/subgraph-spec/#scalar-_any):
229
+
230
+ > This scalar is the type used for entity **representations** that the graph router
231
+ > passes to the `Query._entities` field. An `_Any` scalar is validated by matching
232
+ > its `__typename` and `@key` fields against entities defined in the subgraph schema.
233
+ >
234
+ > An `_Any` is serialized as a JSON object, like so:
235
+ >
236
+ > ```
237
+ > {
238
+ > "__typename": "Product",
239
+ > "upc": "abc123"
240
+ > }
241
+ > ```
242
+
243
+ Not intended for use by clients other than Apollo.
244
+ EOS
245
+
246
+ # `scalar_type` requires we set these but this scalar type is only in GraphQL.
247
+ t.mapping type: nil
248
+ t.json_schema type: "null"
249
+ end
250
+
251
+ apollo_object_type "_Service" do |t|
252
+ t.documentation <<~EOS
253
+ An object type required by the [Apollo Federation subgraph
254
+ spec](https://www.apollographql.com/docs/federation/subgraph-spec/#type-_service):
255
+
256
+ > This object type must have an `sdl: String!` field, which returns the SDL of the subgraph schema as a string.
257
+ >
258
+ > - The returned schema string _must_ include all uses of federation-specific directives (`@key`, `@requires`, etc.).
259
+ > - **If supporting Federation 1,** the schema _must not_ include any definitions from [Subgraph schema additions](https://www.apollographql.com/docs/federation/subgraph-spec/#subgraph-schema-additions).
260
+ >
261
+ > For details, see [Enhanced introspection with `Query._service`](https://www.apollographql.com/docs/federation/subgraph-spec/#enhanced-introspection-with-query_service).
262
+
263
+ Not intended for use by clients other than Apollo.
264
+ EOS
265
+
266
+ t.field "sdl", "String", graphql_only: true do |f|
267
+ f.documentation <<~EOS
268
+ A field required by the [Apollo Federation subgraph
269
+ spec](https://www.apollographql.com/docs/federation/subgraph-spec/#required-resolvers-for-introspection):
270
+
271
+ > The returned `sdl` string has the following requirements:
272
+ >
273
+ > - It must **include** all uses of all federation-specific directives, such as `@key`.
274
+ > - All of these directives are shown in [Subgraph schema additions](https://www.apollographql.com/docs/federation/subgraph-spec/#subgraph-schema-additions).
275
+ > - **If supporting Federation 1,** `sdl` must **omit** all automatically added definitions from
276
+ > [Subgraph schema additions](https://www.apollographql.com/docs/federation/subgraph-spec/#subgraph-schema-additions),
277
+ > such as `Query._service` and `_Service.sdl`!
278
+ > - If your library is _only_ supporting Federation 2, `sdl` can include these definitions.
279
+
280
+ Not intended for use by clients other than Apollo.
281
+ EOS
282
+ end
283
+ end
284
+
285
+ entity_types = state.object_types_by_name.values.select do |object_type|
286
+ object_type.directives.any? do |directive|
287
+ directive.name == "key" && directive.arguments[:resolvable]
288
+ end
289
+ end
290
+
291
+ validate_entity_types_can_all_be_resolved(entity_types)
292
+
293
+ entity_type_names = entity_types
294
+ # As per the GraphQL spec[1], only object types can be in a union, and interface
295
+ # types cannot be in a union. The GraphQL gem has validation[2] for this and will raise
296
+ # an error if we violate it, so we must filter to only object types here.
297
+ #
298
+ # [1] https://spec.graphql.org/October2021/#sec-Unions.Type-Validation
299
+ # [2] https://github.com/rmosolgo/graphql-ruby/pull/3024
300
+ .grep(ElasticGraph::SchemaDefinition::SchemaElements::ObjectType)
301
+ .map(&:name)
302
+
303
+ unless entity_type_names.empty?
304
+ apollo_union_type "_Entity" do |t|
305
+ t.extend EntityTypeExtension
306
+ t.documentation <<~EOS
307
+ A union type required by the [Apollo Federation subgraph
308
+ spec](https://www.apollographql.com/docs/federation/subgraph-spec/#union-_entity):
309
+
310
+ > **⚠️ This union type is generated dynamically based on the input subgraph schema!**
311
+ >
312
+ > This union's possible types must include all entities that the subgraph defines.
313
+ > It's the return type of the `Query._entities` field, which the graph router uses
314
+ > to directly access a subgraph's entity fields.
315
+ >
316
+ > For details, see [Defining the `_Entity` union](https://www.apollographql.com/docs/federation/subgraph-spec/#defining-the-_entity-union).
317
+
318
+ In an ElasticGraph schema, this is a union of all indexed types.
319
+
320
+ Not intended for use by clients other than Apollo.
321
+ EOS
322
+
323
+ t.subtypes(*entity_type_names)
324
+ end
325
+ end
326
+ end
327
+
328
+ def apollo_object_type(name, &block)
329
+ object_type name do |type|
330
+ type.graphql_only true
331
+ yield type
332
+ end
333
+ end
334
+
335
+ def apollo_union_type(name, &block)
336
+ union_type name do |type|
337
+ type.graphql_only true
338
+ yield type
339
+ end
340
+ end
341
+
342
+ def apollo_scalar_type(name, &block)
343
+ scalar_type name do |type|
344
+ type.graphql_only true
345
+ yield type
346
+ end
347
+ end
348
+
349
+ def apollo_enum_type(name, &block)
350
+ enum_type name do |type|
351
+ type.graphql_only true
352
+ yield type
353
+ end
354
+ end
355
+
356
+ # state comes from object we extend with this module.
357
+ # @dynamic state
358
+
359
+ def validate_entity_types_can_all_be_resolved(entity_types)
360
+ entity_types.reject(&:indexed?).each do |object_type|
361
+ key_field_names = object_type.directives
362
+ .select { |dir| dir.name == "key" }
363
+ # https://rubular.com/r/JEuYKzqnyR712A
364
+ .flat_map { |dir| dir.arguments[:fields].to_s.gsub(/{.*}/, "").split(" ") }
365
+ .to_set
366
+ unresolvable_fields = object_type.graphql_fields_by_name.values.reject do |field|
367
+ key_field_names.include?(field.name) ||
368
+ field.relationship ||
369
+ field.directives.any? { |directive| directive.name == "external" }
370
+ end
371
+ if unresolvable_fields.any?
372
+ raise SchemaError, <<~EOS
373
+ `#{object_type.name}` has fields that ElasticGraph will be unable to resolve when Apollo requests it as an entity:
374
+ #{unresolvable_fields.map { |field| " * `#{field.name}`" }.join("\n")}
375
+ On a non-indexed entity type like this, ElasticGraph can only resolve `@key` fields and `relates_to_(one|many)` fields.
376
+ To fix this, add these fields to the `apollo_key`, redefine them as a relationship, use `field.apollo_external` so Apollo
377
+ knows how to treat them, or remove them.
378
+ EOS
379
+ end
380
+ end
381
+ end
382
+ end
383
+ end
384
+ end
385
+ end
@@ -0,0 +1,119 @@
1
+ # Copyright 2024 Block, Inc.
2
+ #
3
+ # Use of this source code is governed by an MIT-style
4
+ # license that can be found in the LICENSE file or at
5
+ # https://opensource.org/licenses/MIT.
6
+ #
7
+ # frozen_string_literal: true
8
+
9
+ module ElasticGraph
10
+ module Apollo
11
+ module SchemaDefinition
12
+ module ApolloDirectives
13
+ module Authenticated
14
+ # Extension method designed to support Apollo's authenticated directive:
15
+ # https://www.apollographql.com/docs/federation/federated-types/federated-directives/#authenticated
16
+ def apollo_authenticated
17
+ directive "authenticated"
18
+ end
19
+ end
20
+
21
+ module Extends
22
+ # Extension method designed to support Apollo's extends directive:
23
+ # https://www.apollographql.com/docs/federation/federated-types/federated-directives/#extends
24
+ def apollo_extends
25
+ directive "extends"
26
+ end
27
+ end
28
+
29
+ module External
30
+ # Extension method designed to support Apollo's external directive:
31
+ # https://www.apollographql.com/docs/federation/federated-types/federated-directives/#external
32
+ def apollo_external
33
+ directive "external"
34
+ end
35
+ end
36
+
37
+ module Inaccessible
38
+ # Extension method designed to support Apollo's inaccessible directive:
39
+ # https://www.apollographql.com/docs/federation/federated-types/federated-directives/#inaccessible
40
+ def apollo_inaccessible
41
+ directive "inaccessible"
42
+ end
43
+ end
44
+
45
+ module InterfaceObject
46
+ # Extension method designed to support Apollo's interfaceObject directive:
47
+ # https://www.apollographql.com/docs/federation/federated-types/federated-directives/#interfaceObject
48
+ def apollo_interface_object
49
+ directive "interfaceObject"
50
+ end
51
+ end
52
+
53
+ module Key
54
+ # Extension method designed to support Apollo's key directive:
55
+ # https://www.apollographql.com/docs/federation/federated-types/federated-directives/#key
56
+ def apollo_key(fields:, resolvable: true)
57
+ directive "key", fields: fields, resolvable: resolvable
58
+ end
59
+ end
60
+
61
+ module Override
62
+ # Extension method designed to support Apollo's override directive:
63
+ # https://www.apollographql.com/docs/federation/federated-types/federated-directives/#override
64
+ def apollo_override(from:)
65
+ directive "override", from: from
66
+ end
67
+ end
68
+
69
+ module Policy
70
+ # Extension method designed to support Apollo's policy directive:
71
+ # https://www.apollographql.com/docs/federation/federated-types/federated-directives/#policy
72
+ def apollo_policy(policies:)
73
+ directive "policy", policies: policies
74
+ end
75
+ end
76
+
77
+ module Provides
78
+ # Extension method designed to support Apollo's provides directive:
79
+ # https://www.apollographql.com/docs/federation/federated-types/federated-directives/#provides
80
+ def apollo_provides(fields:)
81
+ directive "provides", fields: fields
82
+ end
83
+ end
84
+
85
+ module Requires
86
+ # Extension method designed to support Apollo's requires directive:
87
+ # https://www.apollographql.com/docs/federation/federated-types/federated-directives/#requires
88
+ def apollo_requires(fields:)
89
+ directive "requires", fields: fields
90
+ end
91
+ end
92
+
93
+ module RequiresScopes
94
+ # Extension method designed to support Apollo's requiresScopes directive:
95
+ # https://www.apollographql.com/docs/federation/federated-types/federated-directives/#requiresscopes
96
+ def apollo_requires_scopes(scopes:)
97
+ directive "requiresScopes", scopes: scopes
98
+ end
99
+ end
100
+
101
+ module Shareable
102
+ # Extension method designed to support Apollo's shareable directive:
103
+ # https://www.apollographql.com/docs/federation/federated-types/federated-directives/#shareable
104
+ def apollo_shareable
105
+ directive "shareable"
106
+ end
107
+ end
108
+
109
+ module Tag
110
+ # Extension method designed to support Apollo's tag directive:
111
+ # https://www.apollographql.com/docs/federation/federated-types/federated-directives/#tag
112
+ def apollo_tag(name:)
113
+ directive "tag", name: name
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,20 @@
1
+ # Copyright 2024 Block, Inc.
2
+ #
3
+ # Use of this source code is governed by an MIT-style
4
+ # license that can be found in the LICENSE file or at
5
+ # https://opensource.org/licenses/MIT.
6
+ #
7
+ # frozen_string_literal: true
8
+
9
+ require "elastic_graph/apollo/schema_definition/apollo_directives"
10
+
11
+ module ElasticGraph
12
+ module Apollo
13
+ module SchemaDefinition
14
+ module ArgumentExtension
15
+ include ApolloDirectives::Inaccessible
16
+ include ApolloDirectives::Tag
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,30 @@
1
+ # Copyright 2024 Block, Inc.
2
+ #
3
+ # Use of this source code is governed by an MIT-style
4
+ # license that can be found in the LICENSE file or at
5
+ # https://opensource.org/licenses/MIT.
6
+ #
7
+ # frozen_string_literal: true
8
+
9
+ module ElasticGraph
10
+ module Apollo
11
+ module SchemaDefinition
12
+ # The Apollo `_Entity` type is a type union of _all_ entity subtypes in an ElasticGraph schema.
13
+ # However, unlike a normal union type:
14
+ #
15
+ # - `_Entity` is never an indexed type, and should not be treated as one (even though its subtypes are all indexed, which would
16
+ # usually cause it to be treated as indexed!).
17
+ # - A merged set of `graphql_fields_by_name` cannot be safely computed. That method raises errors if a field with the same name
18
+ # has conflicting definitions on different subtypes, but we must allow that on `_Entity` subtypes.
19
+ module EntityTypeExtension
20
+ def graphql_fields_by_name
21
+ {}
22
+ end
23
+
24
+ def indexed?
25
+ false
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ # Copyright 2024 Block, Inc.
2
+ #
3
+ # Use of this source code is governed by an MIT-style
4
+ # license that can be found in the LICENSE file or at
5
+ # https://opensource.org/licenses/MIT.
6
+ #
7
+ # frozen_string_literal: true
8
+
9
+ require "elastic_graph/apollo/schema_definition/apollo_directives"
10
+
11
+ module ElasticGraph
12
+ module Apollo
13
+ module SchemaDefinition
14
+ module EnumTypeExtension
15
+ include ApolloDirectives::Authenticated
16
+ include ApolloDirectives::Inaccessible
17
+ include ApolloDirectives::Policy
18
+ include ApolloDirectives::RequiresScopes
19
+ include ApolloDirectives::Tag
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ # Copyright 2024 Block, Inc.
2
+ #
3
+ # Use of this source code is governed by an MIT-style
4
+ # license that can be found in the LICENSE file or at
5
+ # https://opensource.org/licenses/MIT.
6
+ #
7
+ # frozen_string_literal: true
8
+
9
+ require "elastic_graph/apollo/schema_definition/apollo_directives"
10
+
11
+ module ElasticGraph
12
+ module Apollo
13
+ module SchemaDefinition
14
+ module EnumValueExtension
15
+ include ApolloDirectives::Inaccessible
16
+ include ApolloDirectives::Tag
17
+ end
18
+ end
19
+ end
20
+ end