From 4f448b6bb4c2b0cdd54aca53ca993b0beebc27d0 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 2 Jan 2024 10:21:29 -0500 Subject: [PATCH] chore: fix aggregates in filter schemas --- lib/ash_json_api/json_schema/open_api.ex | 42 +++++++++++++++++++++++- test/acceptance/open_api_test.exs | 12 +++++-- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/lib/ash_json_api/json_schema/open_api.ex b/lib/ash_json_api/json_schema/open_api.ex index bfbfec19..a066be74 100644 --- a/lib/ash_json_api/json_schema/open_api.ex +++ b/lib/ash_json_api/json_schema/open_api.ex @@ -207,6 +207,44 @@ if Code.ensure_loaded?(OpenApiSpex) do resource |> Ash.Resource.Info.public_attributes() |> Enum.concat(Ash.Resource.Info.public_calculations(resource)) + |> Enum.concat(Ash.Resource.Info.public_aggregates(resource)) + |> Enum.map(fn + %Ash.Resource.Aggregate{} = agg -> + field = + if agg.field do + related = Ash.Resource.Info.related(resource, agg.relationship_path) + Ash.Resource.Info.field(related, agg.field) + end + + field_type = + if field do + field.type + end + + field_constraints = + if field do + field.constraints + end + + {:ok, type, constraints} = + Aggregate.kind_to_type(agg.kind, field_type, field_constraints) + + type = Ash.Type.get_type(type) + + allow_nil? = + is_nil(Ash.Query.Aggregate.default_value(agg.kind)) + + %{ + name: agg.name, + description: agg.description, + type: type, + constraints: constraints, + allow_nil?: allow_nil? + } + + other -> + other + end) |> Enum.reject(&AshJsonApi.Resource.only_primary_key?(resource, &1.name)) |> Map.new(fn attr -> {attr.name, @@ -731,6 +769,8 @@ if Code.ensure_loaded?(OpenApiSpex) do {:ok, type, _constraints} = Aggregate.kind_to_type(agg.kind, field_type, field_constraints) + type = Ash.Type.get_type(type) + {agg.name, attribute_filter_schema(type)} end) |> Enum.into(props) @@ -743,7 +783,7 @@ if Code.ensure_loaded?(OpenApiSpex) do @spec relationship_filter_schema(relationship :: Relationships.relationship()) :: Schema.t() defp relationship_filter_schema(_rel) do - %Schema{type: :string} + %Schema{type: :object, additionalProperties: true} end @spec attribute_filter_schema(type :: module) :: Schema.t() diff --git a/test/acceptance/open_api_test.exs b/test/acceptance/open_api_test.exs index ba1bd2f9..ac910e7f 100644 --- a/test/acceptance/open_api_test.exs +++ b/test/acceptance/open_api_test.exs @@ -91,6 +91,10 @@ defmodule Test.Acceptance.OpenApiTest do calculate(:name_twice, :string, concat([:name, :name], "-")) end + aggregates do + count(:count_of_tags, :tags) + end + relationships do belongs_to(:author, Test.Acceptance.OpenApiTest.Author, allow_nil?: false) has_many(:tags, Test.Acceptance.OpenApiTest.Tag, destination_attribute: :post_id) @@ -200,7 +204,7 @@ defmodule Test.Acceptance.OpenApiTest do assert schema.properties == %{ id: %Schema{type: :object, additionalProperties: true}, - author: %Schema{type: :string}, + author: %Schema{type: :object, additionalProperties: true}, email: %Schema{type: :object, additionalProperties: true}, hidden: %Schema{ type: :object, @@ -212,7 +216,8 @@ defmodule Test.Acceptance.OpenApiTest do description: "description of attribute :name", additionalProperties: true }, - tags: %Schema{type: :string} + tags: %Schema{type: :object, additionalProperties: true}, + count_of_tags: %Schema{type: :object, additionalProperties: true} } assert schema.required == nil @@ -333,7 +338,8 @@ defmodule Test.Acceptance.OpenApiTest do %OpenApiSpex.Schema{type: :string}, %OpenApiSpex.Schema{type: :null} ] - } + }, + count_of_tags: %OpenApiSpex.Schema{type: :integer} }, type: :object },