Skip to content

Commit 163f991

Browse files
authored
Add to_extensions_definition
Add `to_extensions_definition`
2 parents ded41f6 + 7192f51 commit 163f991

File tree

11 files changed

+130
-20
lines changed

11 files changed

+130
-20
lines changed

lib/shopify_custom_data_graphql/client.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ def schema(reload_custom_schema: false, reload_admin_schema: false)
9393
prefixed_namespaces: @prefixed_namespaces,
9494
)
9595

96-
SchemaComposer.new(admin_schema, catalog).perform
96+
SchemaComposer.new(admin_schema, catalog).schema
9797
end
9898

9999
custom_schema = GraphQL::Schema.from_definition(custom_schema) if custom_schema.is_a?(String)

lib/shopify_custom_data_graphql/custom_data_catalog.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# frozen_string_literal: true
22

3-
require_relative "schema_catalog/metafield_definition"
4-
require_relative "schema_catalog/metaobject_definition"
5-
require_relative "schema_catalog/metaobject_union"
6-
require_relative "schema_catalog/fetch"
3+
require_relative "custom_data_catalog/metafield_definition"
4+
require_relative "custom_data_catalog/metaobject_definition"
5+
require_relative "custom_data_catalog/metaobject_union"
6+
require_relative "custom_data_catalog/fetch"
77

88
module ShopifyCustomDataGraphQL
99
class CustomDataCatalog

lib/shopify_custom_data_graphql/schema_catalog/fetch.rb renamed to lib/shopify_custom_data_graphql/custom_data_catalog/fetch.rb

File renamed without changes.

lib/shopify_custom_data_graphql/schema_catalog/metafield_definition.rb renamed to lib/shopify_custom_data_graphql/custom_data_catalog/metafield_definition.rb

File renamed without changes.

lib/shopify_custom_data_graphql/schema_catalog/metaobject_definition.rb renamed to lib/shopify_custom_data_graphql/custom_data_catalog/metaobject_definition.rb

File renamed without changes.

lib/shopify_custom_data_graphql/schema_catalog/metaobject_union.rb renamed to lib/shopify_custom_data_graphql/custom_data_catalog/metaobject_union.rb

File renamed without changes.

lib/shopify_custom_data_graphql/schema_composer.rb

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# frozen_string_literal: true
22

3+
require_relative "schema_composer/extensions_document_from_schema_definition"
4+
35
module ShopifyCustomDataGraphQL
46
class SchemaComposer
57
class MetafieldDirective < GraphQL::Schema::Directive
@@ -20,13 +22,14 @@ class MetaobjectDirective < GraphQL::Schema::Directive
2022
def initialize(base_schema, catalog)
2123
@base_schema = base_schema
2224
@catalog = catalog
23-
24-
introspection_names = @base_schema.introspection_system.types.keys.to_set
25-
@schema_types = @base_schema.types.reject! { |k, v| introspection_names.include?(k) }
25+
@schema = nil
26+
@schema_types = @base_schema.types.reject { |k, v| v.introspection? }
2627
@metaobject_unions = {}
2728
end
2829

29-
def perform
30+
def schema
31+
return @schema unless @schema.nil?
32+
3033
query_name = @base_schema.query.graphql_name
3134
mutation_name = @base_schema.mutation.graphql_name
3235

@@ -50,7 +53,7 @@ def perform
5053
end
5154

5255
builder = self
53-
schema = Class.new(GraphQL::Schema) do
56+
built_schema = Class.new(GraphQL::Schema) do
5457
use(GraphQL::Schema::Visibility)
5558
directive(MetafieldDirective)
5659
directive(MetaobjectDirective)
@@ -69,11 +72,16 @@ def perform
6972
argument :id, builder.schema_types["ID"], required: true
7073
end
7174

72-
schema.directive(app_directive)
73-
schema.schema_directive(app_directive, id: @catalog.app_id)
75+
built_schema.directive(app_directive)
76+
built_schema.schema_directive(app_directive, id: @catalog.app_id)
7477
end
7578

76-
schema
79+
@schema = built_schema
80+
end
81+
82+
def to_extensions_definition
83+
document = ExtensionsDocumentFromSchemaDefinition.new(schema, @base_schema).document
84+
GraphQL::Language::Printer.new.print(document)
7785
end
7886

7987
def type_for_metafield_definition(field_def)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# frozen_string_literal: true
2+
3+
module ShopifyCustomDataGraphQL
4+
class SchemaComposer
5+
class ExtensionsDocumentFromSchemaDefinition < GraphQL::Language::DocumentFromSchemaDefinition
6+
def initialize(schema, base_schema)
7+
super(schema)
8+
@base_schema = base_schema
9+
end
10+
11+
def build_directive_nodes(all_directives)
12+
super(all_directives.reject { @base_schema.directives.key?(_1.graphql_name) })
13+
end
14+
15+
def build_type_definition_nodes(all_types)
16+
types_with_extensions = [@types.query_root]
17+
.concat(@types.possible_types(@types.type("HasMetafields")))
18+
.to_set
19+
20+
all_types = all_types
21+
.reject { |type| type.introspection? }
22+
.reject { |type| type.kind.scalar? && type.default_scalar? }
23+
.reject { |type| @base_schema.get_type(type.graphql_name) && !types_with_extensions.include?(type) }
24+
25+
definitions = all_types.filter_map do |type|
26+
if types_with_extensions.include?(type)
27+
extension_field = @types.fields(type).find { _1.graphql_name == "extensions" }
28+
if extension_field
29+
GraphQL::Language::Nodes::ObjectTypeExtension.new(
30+
name: type.graphql_name,
31+
interfaces: [],
32+
fields: build_field_nodes([extension_field]),
33+
)
34+
end
35+
else
36+
build_type_definition_node(type)
37+
end
38+
end
39+
40+
if @schema.schema_directives.any?
41+
definitions << GraphQL::Language::Nodes::SchemaExtension.new(
42+
directives: definition_directives(@schema, :schema_directives),
43+
)
44+
end
45+
46+
definitions
47+
end
48+
49+
def include_schema_node?
50+
false
51+
end
52+
end
53+
end
54+
end
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# frozen_string_literal: true
2+
3+
require "test_helper"
4+
5+
describe "ExtensionsSchema" do
6+
def setup
7+
@catalog = ShopifyCustomDataGraphQL::CustomDataCatalog.new
8+
@catalog.add_metafield({
9+
"key" => "metaobject_reference",
10+
"namespace" => "custom",
11+
"type" => { "name" => "metaobject_reference" },
12+
"validations" => [{
13+
"name" => "metaobject_definition_id",
14+
"value" => "gid://shopify/MetaobjectDefinition/Taco"
15+
}],
16+
"ownerType" => "PRODUCT"
17+
})
18+
@catalog.add_metaobject({
19+
"id" => "gid://shopify/MetaobjectDefinition/Taco",
20+
"name" => "Taco",
21+
"type" => "taco",
22+
"fieldDefinitions" => [{
23+
"key" => "name",
24+
"required" => false,
25+
"type" => { "name" => "single_line_text_field" },
26+
"validations" => []
27+
}]
28+
})
29+
end
30+
31+
def test_to_extensions_definition_builds_minimal_extensions_document
32+
doc = ShopifyCustomDataGraphQL::SchemaComposer.new(
33+
load_base_admin_schema,
34+
@catalog,
35+
).to_extensions_definition
36+
37+
expected = %|
38+
directive @metafield(key: String!, type: String!) on FIELD_DEFINITION
39+
directive @metaobject(type: String!) on OBJECT
40+
extend type Product { extensions: ProductExtensions! }
41+
type ProductExtensions { metaobjectReference: TacoMetaobject @metafield(key: "custom.metaobject_reference", type: "metaobject_reference") }
42+
extend type QueryRoot { extensions: QueryRootExtensions! }
43+
type QueryRootExtensions { tacoMetaobjects(after: String, before: String, first: Int, last: Int): TacoMetaobjectConnection }
44+
type TacoMetaobject @metaobject(type: "taco") { handle: String! id: ID! name: String @metafield(key: "name", type: "single_line_text_field") system: Metaobject! }
45+
type TacoMetaobjectConnection { edges: [TacoMetaobjectEdge!]! nodes: [TacoMetaobject!]! pageInfo: PageInfo! }
46+
type TacoMetaobjectEdge { cursor: String! node: TacoMetaobject }
47+
|
48+
49+
assert_equal expected.squish, doc.gsub(/"""[^"]+"""/, "").squish
50+
end
51+
end

test/shopify_custom_data_graphql/response_transformer_test.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -793,9 +793,9 @@ def test_transforms_errors_with_list_paths
793793

794794
private
795795

796-
SCALAR_VALIDATORS = {
796+
SCALAR_VALIDATORS = GraphQL::ResponseValidator::SCALAR_VALIDATORS.merge({
797797
"JSON" => -> (value) { true }
798-
}.freeze
798+
}).freeze
799799

800800
def fetch(fixture, document, variables: {}, operation_name: nil, schema: nil, expect_valid_response: true)
801801
query = GraphQL::Query.new(

0 commit comments

Comments
 (0)