Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle unions, intersections and lists when generating sample GQL #49

55 changes: 54 additions & 1 deletion lib/graphql_markdown/markdown_helpers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ defmodule GraphqlMarkdown.MarkdownHelpers do
@spec returned_fields(OperationDetailsHelpers.return_type()) :: String.t()
defp returned_fields(%{kind: "SCALAR"}), do: ""

defp returned_fields(%{kind: "OBJECT"} = return_type) do
defp returned_fields(%{kind: kind} = return_type) when kind in ~w(OBJECT LIST) do
fields = Map.get(return_type, :fields, [])

return_values =
Expand All @@ -192,4 +192,57 @@ defmodule GraphqlMarkdown.MarkdownHelpers do
_ -> ""
end
end

defp returned_fields(%{kind: "UNION"} = return_type) do
possible_types = Map.get(return_type, :possible_types, [])

return_values =
for possible_type <- possible_types do
"... on #{possible_type.name} {\n }"
end

case return_values do
[_ | _] ->
"\n __typename\n " <> Enum.join(return_values, "\n ")

_ ->
""
end
end

defp returned_fields(%{kind: "INTERFACE"} = return_type) do
fields = Map.get(return_type, :fields, [])
possible_types = Map.get(return_type, :possible_types, [])

interface_fields =
for field <- fields do
if field.type == "OBJECT" do
"#{field.name} {\n }"
else
field.name
end
end

shared_fields_string =
case interface_fields do
[_ | _] -> "\n " <> Enum.join(interface_fields, "\n ")
_ -> ""
end

specific_types =
for possible_type <- possible_types do
"... on #{possible_type.name} {\n }"
end

specific_types_string =
case specific_types do
[_ | _] ->
"\n " <> Enum.join(specific_types, "\n ")

_ ->
""
end

shared_fields_string <> specific_types_string
end
end
103 changes: 102 additions & 1 deletion lib/graphql_markdown/operation_details_helpers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ defmodule GraphqlMarkdown.OperationDetailsHelpers do
@type return_type :: %{
name: String.t(),
kind: String.t(),
fields: [field()]
fields: [field()],
possible_types: [field()]
}

@type graphql_operation_details :: %{
Expand Down Expand Up @@ -89,6 +90,106 @@ defmodule GraphqlMarkdown.OperationDetailsHelpers do
}
end

defp return_fields(%{"name" => name, "kind" => "UNION"}, schema_details) do
possible_types =
schema_details
|> Map.get(:unions, [])
|> Enum.find(fn union -> union["name"] == name end)
|> Map.get("possibleTypes", [])
|> Enum.map(fn field ->
name = field["name"]
%{name: name, type: "OBJECT"}
end)

%{
name: name,
kind: "UNION",
possible_types: possible_types
}
end

defp return_fields(%{"name" => name, "kind" => "INTERFACE"}, schema_details) do
interface_fields =
schema_details
|> Map.get(:interfaces, [])
|> Enum.find(fn x -> x["name"] == name end)
|> Map.get("fields", [])
|> Enum.map(fn field ->
field_name = field["name"]
type = return_field_type(field)
%{name: field_name, type: type}
end)

possible_types =
schema_details
|> Map.get(:interfaces, [])
|> Enum.find(fn interface -> interface["name"] == name end)
|> Map.get("possibleTypes", [])
|> Enum.map(fn field ->
name = field["name"]
%{name: name, type: "OBJECT"}
end)

%{
name: name,
kind: "INTERFACE",
fields: interface_fields,
possible_types: possible_types
}
end

defp return_fields(
%{"name" => name, "kind" => "LIST", "ofType" => %{"kind" => "OBJECT"}} = return_field,
schema_details
) do
name_of_list_type = get_in(return_field, ["ofType", "name"])

fields =
schema_details
|> Map.get(:objects, [])
|> Enum.find(fn object -> object["name"] == name_of_list_type end)
|> Map.get("fields", [])
|> Enum.map(fn field ->
field_name = field["name"]
type = return_field_type(field)
%{name: field_name, type: type}
end)

%{
name: name,
kind: "LIST",
fields: fields
}
end

defp return_fields(
%{
"name" => name,
"kind" => "NON_NULL",
"ofType" => %{"kind" => "LIST", "ofType" => %{"kind" => "OBJECT"}}
} = return_field,
schema_details
) do
name_of_list_type = get_in(return_field, ["ofType", "ofType", "name"])

fields =
schema_details
|> Map.get(:objects, [])
|> Enum.find(fn object -> object["name"] == name_of_list_type end)
|> Map.get("fields", [])
|> Enum.map(fn field ->
field_name = field["name"]
type = return_field_type(field)
%{name: field_name, type: type}
end)

%{
name: name,
kind: "LIST",
fields: fields
}
end

defp return_fields(return_type, _schema_details) do
%{
name: return_type["name"],
Expand Down
Loading
Loading