diff --git a/lib/resource/resource.ex b/lib/resource/resource.ex index 1d021a4..1f8af21 100644 --- a/lib/resource/resource.ex +++ b/lib/resource/resource.ex @@ -2297,7 +2297,7 @@ defmodule AshGraphql.Resource do else case type(type) do nil -> - :json + Application.get_env(:ash_graphql, :json_type) || :json_string type -> type @@ -2348,7 +2348,10 @@ defmodule AshGraphql.Resource do defp do_field_type(Ash.Type.Date, _, _), do: :date defp do_field_type(Ash.Type.Decimal, _, _), do: :decimal defp do_field_type(Ash.Type.Integer, _, _), do: :integer - defp do_field_type(Ash.Type.Map, _, _), do: :json + + defp do_field_type(Ash.Type.Map, _, _), + do: Application.get_env(:ash_graphql, :json_type) || :json_string + defp do_field_type(Ash.Type.String, _, _), do: :string defp do_field_type(Ash.Type.Term, _, _), do: :string defp do_field_type(Ash.Type.UtcDatetime, _, _), do: :naive_datetime diff --git a/lib/types/json.ex b/lib/types/json.ex index 78b0ca4..78320a1 100644 --- a/lib/types/json.ex +++ b/lib/types/json.ex @@ -32,6 +32,5 @@ defmodule AshGraphql.Types.JSON do :error end - def encode(nil), do: nil - def encode(value), do: Jason.encode!(value) + def encode(value), do: value end diff --git a/lib/types/json_string.ex b/lib/types/json_string.ex new file mode 100644 index 0000000..9962b1c --- /dev/null +++ b/lib/types/json_string.ex @@ -0,0 +1,37 @@ +defmodule AshGraphql.Types.JSONString do + @moduledoc """ + The Json scalar type allows arbitrary JSON values to be passed in and out. + """ + use Absinthe.Schema.Notation + + scalar :json_string, name: "JsonString" do + description(""" + The `Json` scalar type represents arbitrary json string data, represented as UTF-8 + character sequences. The Json type is most often used to represent a free-form + human-readable json string. + """) + + serialize(&encode/1) + parse(&decode/1) + end + + @spec decode(Absinthe.Blueprint.Input.String.t()) :: {:ok, term()} | :error + @spec decode(Absinthe.Blueprint.Input.Null.t()) :: {:ok, nil} + def decode(%Absinthe.Blueprint.Input.String{value: value}) do + case Jason.decode(value) do + {:ok, result} -> {:ok, result} + _ -> :error + end + end + + def decode(%Absinthe.Blueprint.Input.Null{}) do + {:ok, nil} + end + + def decode(_) do + :error + end + + def encode(nil), do: nil + def encode(value), do: Jason.encode!(value) +end