diff --git a/README.md b/README.md index 5b403ad..44f8258 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ AshPagify is an Elixir library designed to easily add full-text search, scoping, filtering, -ordering, and pagination APIs for the [Ash Framework](https://hexdocs.pm/ash) +ordering, and pagination APIs for the [Ash Framework](https://hexdocs.pm/ash). It takes concepts from `Flop`, `Flop.Phoenix`, `Ash` and `AshPhoenix.FilterForm` and combines them into a single library. @@ -179,15 +179,17 @@ defmodule YourApp.Resource.Post end calculations do - # provide the default tsvector calculation for full-text search + # provide your default `tsvector` calculation for full-text search calculate :tsvector, - AshPostgres.Tsvector, - expr( - fragment("to_tsvector('simple', coalesce(?, '')) || to_tsvector('simple', coalesce(?, ''))", - name, - title - ) - ) + AshPostgres.Tsvector, + expr( + fragment( + "to_tsvector('simple', coalesce(?, '')) || to_tsvector('simple', coalesce(?, ''))", + name, + title + ) + ), + public?: true end #... end @@ -274,13 +276,15 @@ you need to either `use AshPagify.Tsearch` in your module or implement the `full ```elixir # provide the default tsvector calculation for full-text search calculate :tsvector, - AshPostgres.Tsvector, - expr( - fragment("to_tsvector('simple', coalesce(?, '')) || to_tsvector('simple', coalesce(?, ''))", - name, - title - ) - ) + AshPostgres.Tsvector, + expr( + fragment( + "to_tsvector('simple', coalesce(?, '')) || to_tsvector('simple', coalesce(?, ''))", + name, + title + ) + ), + public?: true ``` Or if you want to use a generated tsvector column, you can replace the fields @@ -288,7 +292,7 @@ part with the name of your generated tsvector column: ```elixir # use a tsvector column from the database -calculate :tsvector, AshPostgres.Tsvector, expr(fragment("?", tsv)) +calculate :tsvector, AshPostgres.Tsvector, expr(tsv), public?: true ``` You can also configure `dynamic` tsvectors based on user input. Have a look at the diff --git a/config/config.exs b/config/config.exs index a024b1f..4758f1d 100644 --- a/config/config.exs +++ b/config/config.exs @@ -8,7 +8,7 @@ import Config config :ash_pagify, - ash_apis: [], + ash_domains: [], env: Mix.env() config :ash_uuid, :otp_app, :ash_pagify diff --git a/config/test.exs b/config/test.exs index cbb0b24..90f6fa1 100644 --- a/config/test.exs +++ b/config/test.exs @@ -1,5 +1,9 @@ import Config +config :ash_pagify, + ash_domains: [AshPagify.Factory.Domain], + env: Mix.env() + config :logger, level: :warning # config :ash, disable_async?: true diff --git a/lib/ash_pagify.ex b/lib/ash_pagify.ex index c2bbb45..98e9def 100644 --- a/lib/ash_pagify.ex +++ b/lib/ash_pagify.ex @@ -10,6 +10,7 @@ defmodule AshPagify do alias AshPagify.Misc alias AshPagify.Validation + require Ash.Expr require Ash.Query require Logger @@ -718,18 +719,20 @@ defmodule AshPagify do def search(%Ash.Query{} = q, %AshPagify{search: ""}, _opts), do: q def search(%Ash.Query{} = q, %AshPagify{search: search} = ash_pagify, opts) do - tsquery = AshPagify.Tsearch.tsquery(search, opts) - tsquery = Ash.Query.expr(tsquery(search: tsquery)) - tsvector = AshPagify.Tsearch.tsvector(opts) + tsquery_str = AshPagify.Tsearch.tsquery(search, opts) + tsquery_expr = Ash.Expr.expr(tsquery(search: ^tsquery_str)) + tsvector_expr = AshPagify.Tsearch.tsvector(opts) q - |> Ash.Query.filter(full_text_search(tsvector: tsvector, tsquery: tsquery)) - |> maybe_put_ts_rank(ash_pagify, tsvector, tsquery) + |> Ash.Query.filter(full_text_search(tsvector: ^tsvector_expr, tsquery: ^tsquery_expr)) + |> maybe_put_ts_rank(ash_pagify, tsvector_expr, tsquery_expr) end - defp maybe_put_ts_rank(%Ash.Query{} = q, %AshPagify{order_by: order_by}, tsvector, tsquery) + defp maybe_put_ts_rank(%Ash.Query{} = q, %AshPagify{order_by: order_by}, tsvector_expr, tsquery_expr) when is_nil(order_by) or order_by == [] do - Ash.Query.sort(q, full_text_search_rank: {:desc, %{tsvector: tsvector, tsquery: tsquery}}) + Ash.Query.sort(q, + full_text_search_rank: {%{tsvector: tsvector_expr, tsquery: tsquery_expr}, :desc} + ) end defp maybe_put_ts_rank(%Ash.Query{} = q, _, _, _), do: q diff --git a/lib/ash_pagify/filter_form.ex b/lib/ash_pagify/filter_form.ex index 590dfa8..c1160a5 100644 --- a/lib/ash_pagify/filter_form.ex +++ b/lib/ash_pagify/filter_form.ex @@ -16,7 +16,7 @@ defmodule AshPagify.FilterForm do filter_form = AshPagify.FilterForm.new(MyApp.Payroll.Employee) ``` - FilterForm's comprise 2 concepts, predicates and groups. Predicates are the simple boolean + FilterForm's comprise two concepts, predicates and groups. Predicates are the simple boolean expressions you can use to build a query (`name == "Joe"`), and groups can be used to group predicates and more groups together. Groups can apply `and` or `or` operators to its nested components. @@ -37,7 +37,7 @@ defmodule AshPagify.FilterForm do ```elixir filter_form = AshPagify.FilterForm.validate(socket.assigns.filter_form, params) - # Generate a query and pass it to the Api + # Generate a query and pass it to the Domain query = AshPagify.FilterForm.filter!(MyApp.Payroll.Employee, filter_form) filtered_employees = MyApp.Payroll.read!(query) @@ -208,7 +208,7 @@ defmodule AshPagify.FilterForm do alias AshPhoenix.FilterForm.Arguments alias AshPhoenix.FilterForm.Predicate - require Ash.Query + require Ash.Expr defstruct [ :id, @@ -307,10 +307,10 @@ defmodule AshPagify.FilterForm do Create a new filter form. Options: - #{Spark.OptionsHelpers.docs(@new_opts)} + #{Spark.Options.docs(@new_opts)} """ def new(resource, opts \\ []) do - opts = Spark.OptionsHelpers.validate!(opts, @new_opts) + opts = Spark.Options.validate!(opts, @new_opts) params = opts[:params] params = @@ -609,7 +609,7 @@ defmodule AshPagify.FilterForm do defp resource_ref(resource, path, field, arguments) do case Resource.Info.public_calculation(Resource.Info.related(resource, path), field) do nil -> - {:ok, Query.expr(ref(^field, ^path))} + {:ok, Ash.Expr.expr(^Ash.Expr.ref(List.wrap(path), field))} calc -> case Query.validate_calculation_arguments( @@ -1095,10 +1095,10 @@ defmodule AshPagify.FilterForm do Options: - #{Spark.OptionsHelpers.docs(@add_predicate_opts)} + #{Spark.Options.docs(@add_predicate_opts)} """ def add_predicate(form, field, operator_or_function, value, opts \\ []) do - opts = Spark.OptionsHelpers.validate!(opts, @add_predicate_opts) + opts = Spark.Options.validate!(opts, @add_predicate_opts) predicate_id = Ash.UUID.generate() @@ -1297,10 +1297,10 @@ defmodule AshPagify.FilterForm do Options: - #{Spark.OptionsHelpers.docs(@add_group_opts)} + #{Spark.Options.docs(@add_group_opts)} """ def add_group(form, opts \\ []) do - opts = Spark.OptionsHelpers.validate!(opts, @add_group_opts) + opts = Spark.Options.validate!(opts, @add_group_opts) group_id = Ash.UUID.generate() group = %__MODULE__{ diff --git a/lib/ash_pagify/tsearch.ex b/lib/ash_pagify/tsearch.ex index ec374a8..876942c 100644 --- a/lib/ash_pagify/tsearch.ex +++ b/lib/ash_pagify/tsearch.ex @@ -9,17 +9,19 @@ defmodule AshPagify.Tsearch do ```elixir defmodule MyApp.Resource do use AshPagify.Tsearch - require Ash.Query + require Ash.Expr calculations do calculate :tsvector, - AshPostgres.Tsvector, - expr( - fragment("to_tsvector('simple', coalesce(?, '')) || to_tsvector('simple', coalesce(?, ''))", - name, - title - ) - ) + AshPostgres.Tsvector, + expr( + fragment( + "to_tsvector('simple', coalesce(?, '')) || to_tsvector('simple', coalesce(?, ''))", + name, + title + ) + ), + public?: true end end end @@ -38,14 +40,15 @@ defmodule AshPagify.Tsearch do ```elixir defmodule MyApp.Resource do use AshPagify.Tsearch, only: [:full_text_search, :full_text_search_rank] - require Ash.Query + require Ash.Expr calculations do calculate :tsquery, - AshPostgres.Tsquery, - # use english dictionary unaccent PostgreSQL extension - expr(fragment("to_tsquery('english', unaccent(?))", ^arg(:search))) - ) + AshPostgres.Tsquery, + # use english dictionary unaccent PostgreSQL extension + expr(fragment("to_tsquery('english', unaccent(?))", ^arg(:search))) do + public? true + argument :search, :string, allow_expr?: true, allow_nil?: false end ... @@ -135,13 +138,13 @@ defmodule AshPagify.Tsearch do ```elixir defmodule MyApp.Resource do use AshPagify.Tsearch - require Ash.Query + require Ash.Expr def full_text_search do [ tsvector_column: [ - custom_tsvector: Ash.Query.expr(custom_tsvector), - another_custom_tsvector: Ash.Query.expr(another_custom_tsvector), + custom_tsvector: Ash.Expr.expr(custom_tsvector), + another_custom_tsvector: Ash.Expr.expr(another_custom_tsvector), ] ] end @@ -149,33 +152,39 @@ defmodule AshPagify.Tsearch do calculations do # default tsvector calculation calculate :tsvector, - AshPostgres.Tsvector, - expr( - fragment("to_tsvector('simple', coalesce(?, '')) || to_tsvector('simple', coalesce(?, ''))", - name, - title - ) - ) + AshPostgres.Tsvector, + expr( + fragment( + "to_tsvector('simple', coalesce(?, '')) || to_tsvector('simple', coalesce(?, ''))", + name, + title + ) + ), + public?: true end # custom tsvector calculation calculate :custom_tsvector, - AshPostgres.Tsvector, - expr( - fragment("to_tsvector('simple', coalesce(?, ''))", - name - ) - ) + AshPostgres.Tsvector, + expr( + fragment( + "to_tsvector('simple', coalesce(?, ''))", + name + ) + ), + public?: true end # another custom tsvector calculation calculate :another_custom_tsvector, - AshPostgres.Tsvector, - expr( - fragment("to_tsvector('simple', coalesce(?, ''))", - title - ) - ) + AshPostgres.Tsvector, + expr( + fragment( + "to_tsvector('simple', coalesce(?, ''))", + title + ) + ), + public?: true end end end @@ -194,7 +203,7 @@ defmodule AshPagify.Tsearch do alias AshPagify.Misc - require Ash.Query + require Ash.Expr @disallowed_tsquery_characters ~r/['?\\:‘’ʻʼ\|\&]/u @@ -285,28 +294,28 @@ defmodule AshPagify.Tsearch do coalesce_tsvector(tsvector, tsvector_column) end - defp coalesce_tsvector(nil, nil), do: Ash.Query.expr(tsvector) - defp coalesce_tsvector(_, nil), do: Ash.Query.expr(tsvector) + defp coalesce_tsvector(nil, nil), do: Ash.Expr.expr(tsvector) + defp coalesce_tsvector(_, nil), do: Ash.Expr.expr(tsvector) defp coalesce_tsvector(key, tsvector_column) when is_binary(key) and is_list(tsvector_column) do coalesce_tsvector(String.to_existing_atom(key), tsvector_column) rescue - ArgumentError -> Ash.Query.expr(tsvector) + ArgumentError -> Ash.Expr.expr(tsvector) end defp coalesce_tsvector(key, tsvector_column) when is_atom(key) and is_list(tsvector_column) do - Keyword.get(tsvector_column, key, Ash.Query.expr(tsvector)) + Keyword.get(tsvector_column, key, Ash.Expr.expr(tsvector)) end defp coalesce_tsvector(nil, tsvector_column) do if is_tuple(tsvector_column) or is_list(tsvector_column) do - Ash.Query.expr(tsvector) + Ash.Expr.expr(tsvector) else tsvector_column end end - defp coalesce_tsvector(_, _), do: Ash.Query.expr(tsvector) + defp coalesce_tsvector(_, _), do: Ash.Expr.expr(tsvector) @doc """ Returns the tsquery expression for the given search term and options. @@ -403,8 +412,6 @@ defmodule AshPagify.Tsearch do defp blank?(t), do: String.trim(t) == "" defmacro __using__(opts \\ []) do - require Ash.Query - only = Keyword.get(opts, :only, []) quote do @@ -413,6 +420,7 @@ defmodule AshPagify.Tsearch do calculate :full_text_search, :boolean, expr(fragment("(? @@ ?)", ^arg(:tsvector), ^arg(:tsquery))) do + public? true argument :tsvector, AshPostgres.Tsvector, allow_expr?: true, allow_nil?: false argument :tsquery, AshPostgres.Tsquery, allow_expr?: true, allow_nil?: false end @@ -424,6 +432,7 @@ defmodule AshPagify.Tsearch do calculate :full_text_search_rank, :float, expr(fragment("ts_rank(?, ?)", ^arg(:tsvector), ^arg(:tsquery))) do + public? true argument :tsvector, AshPostgres.Tsvector, allow_expr?: true, allow_nil?: false argument :tsquery, AshPostgres.Tsquery, allow_expr?: true, allow_nil?: false end @@ -435,6 +444,7 @@ defmodule AshPagify.Tsearch do calculate :tsquery, AshPostgres.Tsquery, expr(fragment("to_tsquery('simple', ?)", ^arg(:search))) do + public? true argument :search, :string, allow_expr?: true, allow_nil?: false end end diff --git a/lib/ash_pagify/validation.ex b/lib/ash_pagify/validation.ex index 4829326..2ccd7a1 100644 --- a/lib/ash_pagify/validation.ex +++ b/lib/ash_pagify/validation.ex @@ -509,7 +509,7 @@ defmodule AshPagify.Validation do {:error, error} -> params = add_error(params, :filters, error) - filters = remove_key(filters, error.attribute_or_relationship) + filters = remove_key(filters, error.field) replace_invalid_filters(filters, params, resource) end end @@ -570,7 +570,7 @@ defmodule AshPagify.Validation do iex> AshPagify.Error.clear_stacktrace(errors) [ order_by: [ - %Ash.Error.Query.NoSuchAttribute{name: "non_existent", resource: Post} + %Ash.Error.Query.NoSuchField{field: "non_existent", resource: Post} ] ] """ @@ -640,7 +640,7 @@ defmodule AshPagify.Validation do {:error, error} -> params = add_error(params, :order_by, error) - order_by = List.delete(order_by, error.name) + order_by = List.delete(order_by, error.field) replace_invalid_order_by(order_by, params, resource) end end diff --git a/mix.exs b/mix.exs index c58a5a4..1ee3e5e 100644 --- a/mix.exs +++ b/mix.exs @@ -95,10 +95,13 @@ defmodule AshPagify.MixProject do defp deps do [ # Ash Framework - {:ash, "~> 2.0"}, - {:ash_phoenix, "~> 1.3"}, - {:ash_postgres, "~> 1.5"}, - {:ash_uuid, "~> 0.7"}, + {:ash, "~> 3.3.3", override: true}, + {:ash_phoenix, "~> 2.1.1"}, + {:ash_postgres, "~> 2.1.17", override: true}, + {:ash_uuid, "~> 1.1.1", override: true}, + + # SAT Solvers + {:picosat_elixir, "~> 0.2", optional: true}, # Phoenix Framework {:phoenix, "~> 1.7"}, @@ -117,10 +120,6 @@ defmodule AshPagify.MixProject do {:git_ops, "~> 2.6.1", only: [:dev]}, {:git_hooks, "~> 0.7.3", only: [:dev], runtime: false}, - # Utilities and Helpers - # TODO Remove upon Ash v3 migration - {:splode, "~> 0.2.4"}, - # Documentation {:ex_doc, "~> 0.34.2", runtime: false} ] diff --git a/mix.lock b/mix.lock index 4e4d06c..3920a88 100644 --- a/mix.lock +++ b/mix.lock @@ -1,8 +1,9 @@ %{ - "ash": {:hex, :ash, "2.21.15", "706c02f855536b41ffdce4c970c8cdc1d9ae0059a939000df960702dde8eb5ee", [:mix], [{:comparable, "~> 1.0", [hex: :comparable, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: false]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.6", [hex: :reactor, repo: "hexpm", optional: false]}, {:spark, ">= 1.1.55 and < 2.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:stream_data, "~> 0.6", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "96f911a6db3db1729f9bceaee4166dd66c34ec2a03c12e4e42e59fb4f175e3af"}, - "ash_phoenix": {:hex, :ash_phoenix, "1.3.7", "ff5cfca83b4d40b1fac88ed899c1b0e3f3f9eb62ea31868dd20d8f24386c9323", [:mix], [{:ash, "~> 2.16", [hex: :ash, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.5.6 or ~> 1.6", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.20.3", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}], "hexpm", "81c30712f21cc9fcec8da846703e311d9aa214f4fa98e01a0bbeaa6a52dd5601"}, - "ash_postgres": {:hex, :ash_postgres, "1.5.30", "d3edc7c5a5d5a582849cd112a07e5d925f3c1760198f9cee4f76b5082b287748", [:mix], [{:ash, ">= 2.20.3 and < 3.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: false]}], "hexpm", "b0cb6da54752608e037221e02201b24030fd8ed42d895fba8c73c8bca0ab0ffd"}, - "ash_uuid": {:hex, :ash_uuid, "0.7.0", "d045ce940364eb0e002c218b60514a8912012e081f111be8faa70fa0710d026c", [:mix], [{:ash, "~> 2.13", [hex: :ash, repo: "hexpm", optional: false]}, {:ash_postgres, ">= 1.3.41", [hex: :ash_postgres, repo: "hexpm", optional: false]}, {:uniq, "~> 0.6", [hex: :uniq, repo: "hexpm", optional: false]}], "hexpm", "009e6579e6fee8f99aaf7c8afeda4dd28e2474af23a281c553ca7d466ef5948d"}, + "ash": {:hex, :ash, "3.3.3", "1e4047c867e064fe5edabd86c7366dbf3e094a91a2f5269ee0169eb310931e7c", [:mix], [{:comparable, "~> 1.0", [hex: :comparable, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.3.11 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: false]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.9", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.8 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "0486ec2185deeca68d617eb016d22e598af0e44e7512453f959124f4345ae9df"}, + "ash_phoenix": {:hex, :ash_phoenix, "2.1.1", "36521a99b602b0531dfc9ebd9ee90d10bbead9a3ffd1c6dffbacb0751553a2c0", [:mix], [{:ash, "~> 3.0", [hex: :ash, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.5.6 or ~> 1.6", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.20.3 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}], "hexpm", "02d1b270aa0f78c5db6f1db9f3112d349a10b729b116911df47e39f11e2ae62d"}, + "ash_postgres": {:hex, :ash_postgres, "2.1.17", "ab49498861389717bab70eb85161600cbcd8fed34b626186462b89e59dfe4af0", [:mix], [{:ash, "~> 3.3", [hex: :ash, repo: "hexpm", optional: false]}, {:ash_sql, ">= 0.2.28 and < 1.0.0-0", [hex: :ash_sql, repo: "hexpm", optional: false]}, {:ecto, ">= 3.11.2 and < 4.0.0-0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, ">= 3.11.3 and < 4.0.0-0", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:igniter, ">= 0.3.6 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: false]}], "hexpm", "494bb1c4cbc9a55f7bf888543b136840cea65136feac2fe2246eba971e2a28ca"}, + "ash_sql": {:hex, :ash_sql, "0.2.29", "d99a40818667d1843e61edae6b3eeeaedda62f34e6477e4dd29017f81fddbf07", [:mix], [{:ash, ">= 3.1.7 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "1d3cc1c3a26cf87bb913fdf7bcbe9d901d35f260aac36225b8054541836e5752"}, + "ash_uuid": {:hex, :ash_uuid, "1.1.1", "4bd5371504150b84dbf36458a357421b5dc2e6d330c718619d0735770cb14412", [:mix], [{:ash, "~> 3.0.0", [hex: :ash, repo: "hexpm", optional: false]}, {:ash_postgres, "~> 2.0.11", [hex: :ash_postgres, repo: "hexpm", optional: false]}, {:uniq, "~> 0.6", [hex: :uniq, repo: "hexpm", optional: false]}], "hexpm", "452771906e94e1a9b9bb48ca869cfbd245e2ffde816c7edbee2d84268cef11ad"}, "assertions": {:hex, :assertions, "0.20.1", "e6bfcefbf199bc760d273d5a204ad9ef8a4f6c2b4725fc51d10610d73062e57b", [:mix], [], "hexpm", "848284fbde52f752232d73b8f77060ad191e1a98c177873c4b8dc56c4958defd"}, "blankable": {:hex, :blankable, "1.0.0", "89ab564a63c55af117e115144e3b3b57eb53ad43ba0f15553357eb283e0ed425", [:mix], [], "hexpm", "7cf11aac0e44f4eedbee0c15c1d37d94c090cb72a8d9fddf9f7aec30f9278899"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, @@ -12,7 +13,6 @@ "db_connection": {:hex, :db_connection, "2.7.0", "b99faa9291bb09892c7da373bb82cba59aefa9b36300f6145c5f201c7adf48ec", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dcf08f31b2701f857dfc787fbad78223d61a32204f217f15e881dd93e4bdd3ff"}, "decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"}, "dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"}, - "earmark": {:hex, :earmark, "1.4.47", "7e7596b84fe4ebeb8751e14cbaeaf4d7a0237708f2ce43630cfd9065551f94ca", [:mix], [], "hexpm", "3e96bebea2c2d95f3b346a7ff22285bc68a99fbabdad9b655aa9c6be06c698f8"}, "earmark_parser": {:hex, :earmark_parser, "1.4.41", "ab34711c9dc6212dda44fcd20ecb87ac3f3fce6f0ca2f28d4a00e4154f8cd599", [:mix], [], "hexpm", "a81a04c7e34b6617c2792e291b5a2e57ab316365c2644ddc553bb9ed863ebefa"}, "ecto": {:hex, :ecto, "3.11.2", "e1d26be989db350a633667c5cda9c3d115ae779b66da567c68c80cfb26a8c9ee", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3c38bca2c6f8d8023f2145326cc8a80100c3ffe4dcbd9842ff867f7fc6156c65"}, "ecto_sql": {:hex, :ecto_sql, "3.11.3", "4eb7348ff8101fbc4e6bbc5a4404a24fecbe73a3372d16569526b0cf34ebc195", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.11.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e5f36e3d736b99c7fee3e631333b8394ade4bafe9d96d35669fca2d81c2be928"}, @@ -27,7 +27,11 @@ "git_cli": {:hex, :git_cli, "0.3.0", "a5422f9b95c99483385b976f5d43f7e8233283a47cda13533d7c16131cb14df5", [:mix], [], "hexpm", "78cb952f4c86a41f4d3511f1d3ecb28edb268e3a7df278de2faa1bd4672eaf9b"}, "git_hooks": {:hex, :git_hooks, "0.7.3", "09489e94d88dfc767662e22aff2b6208bd7cf555a19dd0e1477cca4683ce0701", [:mix], [{:blankable, "~> 1.0.0", [hex: :blankable, repo: "hexpm", optional: false]}, {:recase, "~> 0.7.0", [hex: :recase, repo: "hexpm", optional: false]}], "hexpm", "d6ddedeb4d3a8602bc3f84e087a38f6150a86d9e790628ed8bc70e6d90681659"}, "git_ops": {:hex, :git_ops, "2.6.1", "cc7799a68c26cf814d6d1a5121415b4f5bf813de200908f930b27a2f1fe9dad5", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "ce62d07e41fe993ec22c35d5edb11cf333a21ddaead6f5d9868fcb607d42039e"}, - "jason": {:hex, :jason, "1.4.3", "d3f984eeb96fe53b85d20e0b049f03e57d075b5acda3ac8d465c969a2536c17b", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "9a90e868927f7c777689baa16d86f4d0e086d968db5c05d917ccff6d443e58a3"}, + "glob_ex": {:hex, :glob_ex, "0.1.8", "f7ef872877ca2ae7a792ab1f9ff73d9c16bf46ecb028603a8a3c5283016adc07", [:mix], [], "hexpm", "9e39d01729419a60a937c9260a43981440c43aa4cadd1fa6672fecd58241c464"}, + "igniter": {:hex, :igniter, "0.3.16", "5967e06e26379cb7531aa7c4fa9ab8a4899f75d12f00d5453565ca748c24e6ae", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:inflex, "~> 2.0", [hex: :inflex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:nimble_options, "~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:owl, "~> 0.9", [hex: :owl, repo: "hexpm", optional: false]}, {:rewrite, "~> 0.9", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}, {:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: false]}], "hexpm", "ccbce6aab2e0f1d1c34f7a19e025e8f66ed970b7ec6e35cc823164625afbf843"}, + "inflex": {:hex, :inflex, "2.1.0", "a365cf0821a9dacb65067abd95008ca1b0bb7dcdd85ae59965deef2aa062924c", [:mix], [], "hexpm", "14c17d05db4ee9b6d319b0bff1bdf22aa389a25398d1952c7a0b5f3d93162dd8"}, + "iterex": {:hex, :iterex, "0.1.2", "58f9b9b9a22a55cbfc7b5234a9c9c63eaac26d276b3db80936c0e1c60355a5a6", [:mix], [], "hexpm", "2e103b8bcc81757a9af121f6dc0df312c9a17220f302b1193ef720460d03029d"}, + "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "junit_formatter": {:hex, :junit_formatter, "3.4.0", "d0e8db6c34dab6d3c4154c3b46b21540db1109ae709d6cf99ba7e7a2ce4b1ac2", [:mix], [], "hexpm", "bb36e2ae83f1ced6ab931c4ce51dd3dbef1ef61bb4932412e173b0cfa259dacd"}, "libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"}, "makeup": {:hex, :makeup, "1.1.2", "9ba8837913bdf757787e71c1581c21f9d2455f4dd04cfca785c70bbfff1a76a3", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cce1566b81fbcbd21eca8ffe808f33b221f9eee2cbc7a1706fc3da9ff18e6cac"}, @@ -37,6 +41,7 @@ "mix_audit": {:hex, :mix_audit, "2.1.4", "0a23d5b07350cdd69001c13882a4f5fb9f90fbd4cbf2ebc190a2ee0d187ea3e9", [:make, :mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}], "hexpm", "fd807653cc8c1cada2911129c7eb9e985e3cc76ebf26f4dd628bb25bbcaa7099"}, "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, + "owl": {:hex, :owl, "0.11.0", "2cd46185d330aa2400f1c8c3cddf8d2ff6320baeff23321d1810e58127082cae", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "73f5783f0e963cc04a061be717a0dbb3e49ae0c4bfd55fb4b78ece8d33a65efe"}, "phoenix": {:hex, :phoenix, "1.7.14", "a7d0b3f1bc95987044ddada111e77bd7f75646a08518942c72a8440278ae7825", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "c7859bc56cc5dfef19ecfc240775dae358cbaa530231118a9e014df392ace61a"}, "phoenix_html": {:hex, :phoenix_html, "4.1.1", "4c064fd3873d12ebb1388425a8f2a19348cef56e7289e1998e2d2fa758aa982e", [:mix], [], "hexpm", "f2f2df5a72bc9a2f510b21497fd7d2b86d932ec0598f0210fed4114adc546c6f"}, "phoenix_live_view": {:hex, :phoenix_live_view, "0.20.17", "f396bbdaf4ba227b82251eb75ac0afa6b3da5e509bc0d030206374237dfc9450", [:mix], [{:floki, "~> 0.36", [hex: :floki, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a61d741ffb78c85fdbca0de084da6a48f8ceb5261a79165b5a0b59e5f65ce98b"}, @@ -45,17 +50,20 @@ "picosat_elixir": {:hex, :picosat_elixir, "0.2.3", "bf326d0f179fbb3b706bb2c15fbc367dacfa2517157d090fdfc32edae004c597", [:make, :mix], [{:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "f76c9db2dec9d2561ffaa9be35f65403d53e984e8cd99c832383b7ab78c16c66"}, "plug": {:hex, :plug, "1.16.1", "40c74619c12f82736d2214557dedec2e9762029b2438d6d175c5074c933edc9d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a13ff6b9006b03d7e33874945b2755253841b238c34071ed85b0e86057f8cddc"}, "plug_crypto": {:hex, :plug_crypto, "2.1.0", "f44309c2b06d249c27c8d3f65cfe08158ade08418cf540fd4f72d4d6863abb7b", [:mix], [], "hexpm", "131216a4b030b8f8ce0f26038bc4421ae60e4bb95c5cf5395e1421437824c4fa"}, - "postgrex": {:hex, :postgrex, "0.18.0", "f34664101eaca11ff24481ed4c378492fed2ff416cd9b06c399e90f321867d7e", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "a042989ba1bc1cca7383ebb9e461398e3f89f868c92ce6671feb7ef132a252d1"}, - "reactor": {:hex, :reactor, "0.7.0", "fb76d23d95829b28ac9b9d654620c43c890c6a32ea26ac13086c48540b34e8c5", [:mix], [{:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, "~> 1.0", [hex: :spark, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4310da820d753aafd7dc4ee8cc687b84565dd6d9536e38806ee211da792178fd"}, + "postgrex": {:hex, :postgrex, "0.19.0", "f7d50e50cb42e0a185f5b9a6095125a9ab7e4abccfbe2ab820ab9aa92b71dbab", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "dba2d2a0a8637defbf2307e8629cb2526388ba7348f67d04ec77a5d6a72ecfae"}, + "reactor": {:hex, :reactor, "0.9.0", "f48af9f300454b979a22d5a04b18b59e16959478ffa7f88d50b5e142b5d055dc", [:mix], [{:igniter, "~> 0.2", [hex: :igniter, repo: "hexpm", optional: false]}, {:iterex, "~> 0.1", [hex: :iterex, repo: "hexpm", optional: false]}, {:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4c5ffd700ac669d0992a9e296978abe2110670b23addc0970fca9108d506489c"}, "recase": {:hex, :recase, "0.7.0", "3f2f719f0886c7a3b7fe469058ec539cb7bbe0023604ae3bce920e186305e5ae", [:mix], [], "hexpm", "36f5756a9f552f4a94b54a695870e32f4e72d5fad9c25e61bc4a3151c08a4e0c"}, + "rewrite": {:hex, :rewrite, "0.10.5", "6afadeae0b9d843b27ac6225e88e165884875e0aed333ef4ad3bf36f9c101bed", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "51cc347a4269ad3a1e7a2c4122dbac9198302b082f5615964358b4635ebf3d4f"}, "sobelow": {:hex, :sobelow, "0.13.0", "218afe9075904793f5c64b8837cc356e493d88fddde126a463839351870b8d1e", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "cd6e9026b85fc35d7529da14f95e85a078d9dd1907a9097b3ba6ac7ebbe34a0d"}, "sourceror": {:hex, :sourceror, "1.5.0", "3e65d5fbb1a8e2864ad6411262c8018fee73474f5789dda12285c82999253d5d", [:mix], [], "hexpm", "4a32b5d189d8453f73278c15712f8731b89e9211e50726b798214b303b51bfc7"}, - "spark": {:hex, :spark, "1.1.55", "d20c3f899b23d841add29edc912ffab4463d3bb801bc73448738631389291d2e", [:mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.5 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "bbc15a4223d8e610c81ceca825d5d0bae3738d1c4ac4dbb1061749966776c3f1"}, + "spark": {:hex, :spark, "2.2.11", "6589ac0e50d69e5095871a5e8f3bb6107755b1cc71f05a31d7398902506dab9a", [:mix], [{:igniter, ">= 0.2.6 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "662d297d0ad49a5990a72cbf342d70e90894218062da2893f2df529f70ecc2b4"}, + "spitfire": {:hex, :spitfire, "0.1.3", "7ea0f544005dfbe48e615ed90250c9a271bfe126914012023fd5e4b6b82b7ec7", [:mix], [], "hexpm", "d53b5107bcff526a05c5bb54c95e77b36834550affd5830c9f58760e8c543657"}, "splode": {:hex, :splode, "0.2.4", "71046334c39605095ca4bed5d008372e56454060997da14f9868534c17b84b53", [:mix], [], "hexpm", "ca3b95f0d8d4b482b5357954fec857abd0fa3ea509d623334c1328e7382044c2"}, - "stream_data": {:hex, :stream_data, "0.6.0", "e87a9a79d7ec23d10ff83eb025141ef4915eeb09d4491f79e52f2562b73e5f47", [:mix], [], "hexpm", "b92b5031b650ca480ced047578f1d57ea6dd563f5b57464ad274718c9c29501c"}, + "stream_data": {:hex, :stream_data, "1.1.1", "fd515ca95619cca83ba08b20f5e814aaf1e5ebff114659dc9731f966c9226246", [:mix], [], "hexpm", "45d0cd46bd06738463fd53f22b70042dbb58c384bb99ef4e7576e7bb7d3b8c8c"}, "styler": {:hex, :styler, "0.11.9", "2595393b94e660cd6e8b582876337cc50ff047d184ccbed42fdad2bfd5d78af5", [:mix], [], "hexpm", "8b7806ba1fdc94d0a75127c56875f91db89b75117fcc67572661010c13e1f259"}, "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, "typable": {:hex, :typable, "0.3.0", "0431e121d124cd26f312123e313d2689b9a5322b15add65d424c07779eaa3ca1", [:mix], [], "hexpm", "880a0797752da1a4c508ac48f94711e04c86156f498065a83d160eef945858f8"}, + "ucwidth": {:hex, :ucwidth, "0.2.0", "1f0a440f541d895dff142275b96355f7e91e15bca525d4a0cc788ea51f0e3441", [:mix], [], "hexpm", "c1efd1798b8eeb11fb2bec3cafa3dd9c0c3647bee020543f0340b996177355bf"}, "uniq": {:hex, :uniq, "0.6.1", "369660ecbc19051be526df3aa85dc393af5f61f45209bce2fa6d7adb051ae03c", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "6426c34d677054b3056947125b22e0daafd10367b85f349e24ac60f44effb916"}, "websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"}, "websock_adapter": {:hex, :websock_adapter, "0.5.6", "0437fe56e093fd4ac422de33bf8fc89f7bc1416a3f2d732d8b2c8fd54792fe60", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "e04378d26b0af627817ae84c92083b7e97aca3121196679b73c73b99d0d133ea"}, diff --git a/test/ash_pagify/ash_pagify_test.exs b/test/ash_pagify/ash_pagify_test.exs index 986c4bc..1c51e5b 100644 --- a/test/ash_pagify/ash_pagify_test.exs +++ b/test/ash_pagify/ash_pagify_test.exs @@ -4,12 +4,12 @@ defmodule AshPagifyTest do import Assertions - alias AshPagify.Factory.Api alias AshPagify.Factory.Comment alias AshPagify.Factory.Post alias AshPagify.Factory.User alias AshPagify.Meta + require Ash.Expr require Ash.Query doctest AshPagify, import: true @@ -21,7 +21,7 @@ defmodule AshPagifyTest do %{name: "Post 3", author: "Doe", comments: ["Second", "Third", "Another"]} ] - Api.bulk_create(posts, Post, :create) + Ash.bulk_create(posts, Post, :create) :ok end @@ -265,15 +265,20 @@ defmodule AshPagifyTest do ash_pagify = %AshPagify{search: "Post 1"} query = Ash.Query.new(Post) - tsvector = AshPagify.Tsearch.tsvector() - tsquery = Ash.Query.expr(tsquery(search: AshPagify.Tsearch.tsquery("Post 1"))) + tsvector_expr = AshPagify.Tsearch.tsvector() + tsquery_str = AshPagify.Tsearch.tsquery("Post 1") + tsquery_expr = Ash.Expr.expr(tsquery(search: ^tsquery_str)) assert AshPagify.query(query, ash_pagify) == %Ash.Query{ resource: AshPagify.Factory.Post, - filter: Ash.Query.filter(Post, full_text_search(tsvector: tsvector, tsquery: tsquery)).filter, + filter: + Ash.Query.filter( + Post, + full_text_search(tsvector: ^tsvector_expr, tsquery: ^tsquery_expr) + ).filter, sort: Ash.Query.sort(Post, - full_text_search_rank: {:desc, %{tsvector: tsvector, tsquery: tsquery}} + full_text_search_rank: {%{tsvector: tsvector_expr, tsquery: tsquery_expr}, :desc} ).sort } end @@ -282,12 +287,17 @@ defmodule AshPagifyTest do ash_pagify = %AshPagify{search: "Post 1", order_by: :name} query = Ash.Query.new(Post) - tsvector = AshPagify.Tsearch.tsvector() - tsquery = Ash.Query.expr(tsquery(search: AshPagify.Tsearch.tsquery("Post 1"))) + tsvector_expr = AshPagify.Tsearch.tsvector() + tsquery_str = AshPagify.Tsearch.tsquery("Post 1") + tsquery_expr = Ash.Expr.expr(tsquery(search: ^tsquery_str)) assert AshPagify.query(query, ash_pagify) == %Ash.Query{ resource: AshPagify.Factory.Post, - filter: Ash.Query.filter(Post, full_text_search(tsvector: tsvector, tsquery: tsquery)).filter, + filter: + Ash.Query.filter( + Post, + full_text_search(tsvector: ^tsvector_expr, tsquery: ^tsquery_expr) + ).filter, sort: Ash.Query.sort(Post, name: :asc).sort } end @@ -562,9 +572,7 @@ defmodule AshPagifyTest do ~s"%{offset: 0, filters: #Ash.Filter, limit: 15, scopes: %{status: :all}}" assert [%Ash.Error.Query.InvalidLimit{limit: -1}] = Keyword.get(meta.errors, :limit) - - assert [%Ash.Error.Query.NoSuchAttributeOrRelationship{attribute_or_relationship: :other}] = - Keyword.get(meta.errors, :filters) + assert [%Ash.Error.Query.NoSuchField{field: :other}] = Keyword.get(meta.errors, :filters) end test "returns error and original params if ash_pagify is invalid" do @@ -583,9 +591,7 @@ defmodule AshPagifyTest do } == meta.params assert [%Ash.Error.Query.InvalidLimit{limit: -1}] = Keyword.get(meta.errors, :limit) - - assert [%Ash.Error.Query.NoSuchAttributeOrRelationship{attribute_or_relationship: :other}] = - Keyword.get(meta.errors, :filters) + assert [%Ash.Error.Query.NoSuchField{field: :other}] = Keyword.get(meta.errors, :filters) end test "returns data and meta data" do @@ -674,9 +680,7 @@ defmodule AshPagifyTest do assert inspect(filters) == ~s"#Ash.Filter" assert [%Ash.Error.Query.InvalidLimit{limit: -1}] = Keyword.get(meta.errors, :limit) - - assert [%Ash.Error.Query.NoSuchAttributeOrRelationship{attribute_or_relationship: :other}] = - Keyword.get(meta.errors, :filters) + assert [%Ash.Error.Query.NoSuchField{field: :other}] = Keyword.get(meta.errors, :filters) end test "returns error and original params if parameters are invalid" do @@ -696,9 +700,7 @@ defmodule AshPagifyTest do } == meta.params assert [%Ash.Error.Query.InvalidLimit{limit: -1}] = Keyword.get(meta.errors, :limit) - - assert [%Ash.Error.Query.NoSuchAttributeOrRelationship{attribute_or_relationship: :other}] = - Keyword.get(meta.errors, :filters) + assert [%Ash.Error.Query.NoSuchField{field: :other}] = Keyword.get(meta.errors, :filters) end end @@ -726,9 +728,7 @@ defmodule AshPagifyTest do assert %{limit: -1, filters: %{name: "Post 1", other: "John"}} == error.params assert [%Ash.Error.Query.InvalidLimit{limit: -1}] = Keyword.get(error.errors, :limit) - - assert [%Ash.Error.Query.NoSuchAttributeOrRelationship{attribute_or_relationship: :other}] = - Keyword.get(error.errors, :filters) + assert [%Ash.Error.Query.NoSuchField{field: :other}] = Keyword.get(error.errors, :filters) end end @@ -1212,13 +1212,13 @@ defmodule AshPagifyTest do end defp assert_map_query_equals_full_text_search(map_query, search) do - tsvector = AshPagify.Tsearch.tsvector() - tsquery = Ash.Query.expr(tsquery(search: search)) + tsvector_expr = AshPagify.Tsearch.tsvector() + tsquery_expr = Ash.Expr.expr(tsquery(search: ^search)) assert AshPagify.query_for_filters_map(Post, map_query) == Post - |> Ash.Query.filter(full_text_search(tsvector: tsvector, tsquery: tsquery)) - |> Ash.Query.sort(full_text_search_rank: {:desc, %{tsvector: tsvector, tsquery: tsquery}}) + |> Ash.Query.filter(full_text_search(tsvector: ^tsvector_expr, tsquery: ^tsquery_expr)) + |> Ash.Query.sort(full_text_search_rank: {%{tsvector: tsvector_expr, tsquery: tsquery_expr}, :desc}) end defp assert_post_names(ash_pagify, names, opts \\ []) do @@ -1228,9 +1228,8 @@ defmodule AshPagifyTest do end defp assert_page_opts(ash_pagify, expected, opts) do - %Ash.Page.Offset{rerun: {_, opts}} = AshPagify.all(Post, ash_pagify, opts) + %Ash.Page.Offset{rerun: {%Ash.Query{page: page}, _}} = AshPagify.all(Post, ash_pagify, opts) - page = Keyword.get(opts, :page, []) assert_lists_equal(expected, page) end @@ -1241,9 +1240,9 @@ defmodule AshPagifyTest do end defp assert_comment_page_opts(ash_pagify, expected, opts) do - %Ash.Page.Offset{rerun: {_, opts}} = AshPagify.all(Comment, ash_pagify, opts) + %Ash.Page.Offset{rerun: {%Ash.Query{page: page}, _}} = + AshPagify.all(Comment, ash_pagify, opts) - page = Keyword.get(opts, :page, []) assert_lists_equal(expected, page) end end diff --git a/test/ash_pagify/tsearch_test.exs b/test/ash_pagify/tsearch_test.exs index 83ad0ec..38326d1 100644 --- a/test/ash_pagify/tsearch_test.exs +++ b/test/ash_pagify/tsearch_test.exs @@ -5,7 +5,7 @@ defmodule AshPagify.TsearchTest do alias AshPagify.Factory.Comment - require Ash.Query + require Ash.Expr doctest AshPagify.Tsearch, import: true @@ -24,14 +24,14 @@ defmodule AshPagify.TsearchTest do negation: true, prefix: false, any_word: true, - tsvector_column: Ash.Query.expr(custom_tsvector) + tsvector_column: Ash.Expr.expr(custom_tsvector) ] end end describe "tsvector/1" do test "returns default tsvector if no options are provided" do - assert AshPagify.Tsearch.tsvector() == Ash.Query.expr(tsvector) + assert AshPagify.Tsearch.tsvector() == Ash.Expr.expr(tsvector) end test "returns default tsvector if custom tsvector is passed but now tsvector_column is defined" do @@ -42,7 +42,7 @@ defmodule AshPagify.TsearchTest do ] ] - assert AshPagify.Tsearch.tsvector(opts) == Ash.Query.expr(tsvector) + assert AshPagify.Tsearch.tsvector(opts) == Ash.Expr.expr(tsvector) end test "returns default tsvector if custom tsvector is passed and tsvector_column is []" do @@ -53,29 +53,29 @@ defmodule AshPagify.TsearchTest do ] ] - assert AshPagify.Tsearch.tsvector(opts) == Ash.Query.expr(tsvector) + assert AshPagify.Tsearch.tsvector(opts) == Ash.Expr.expr(tsvector) end test "returns tsvector_column if no custom tsvector is specified but tsvector_column is configured" do opts = [ full_text_search: [ - tsvector_column: Ash.Query.expr(custom_tsvector) + tsvector_column: Ash.Expr.expr(custom_tsvector) ] ] - assert AshPagify.Tsearch.tsvector(opts) == Ash.Query.expr(custom_tsvector) + assert AshPagify.Tsearch.tsvector(opts) == Ash.Expr.expr(custom_tsvector) end test "returns default tsvector if custom tsvector is not passed and tsvector_column is configured but it is a list" do opts = [ full_text_search: [ tsvector_column: [ - custom: Ash.Query.expr(custom_tsvector) + custom: Ash.Expr.expr(custom_tsvector) ] ] ] - assert AshPagify.Tsearch.tsvector(opts) == Ash.Query.expr(tsvector) + assert AshPagify.Tsearch.tsvector(opts) == Ash.Expr.expr(tsvector) end test "returns custom tsvector from tsvector_column list" do @@ -83,12 +83,12 @@ defmodule AshPagify.TsearchTest do full_text_search: [ tsvector: :custom, tsvector_column: [ - custom: Ash.Query.expr(custom_tsvector) + custom: Ash.Expr.expr(custom_tsvector) ] ] ] - assert AshPagify.Tsearch.tsvector(opts) == Ash.Query.expr(custom_tsvector) + assert AshPagify.Tsearch.tsvector(opts) == Ash.Expr.expr(custom_tsvector) end test "returns custom tsvector from tsvector_column list with string key" do @@ -96,12 +96,12 @@ defmodule AshPagify.TsearchTest do full_text_search: [ tsvector: "custom", tsvector_column: [ - custom: Ash.Query.expr(custom_tsvector) + custom: Ash.Expr.expr(custom_tsvector) ] ] ] - assert AshPagify.Tsearch.tsvector(opts) == Ash.Query.expr(custom_tsvector) + assert AshPagify.Tsearch.tsvector(opts) == Ash.Expr.expr(custom_tsvector) end test "returns default tsvector if tsvector_column list and key is configured but do not match" do @@ -109,12 +109,12 @@ defmodule AshPagify.TsearchTest do full_text_search: [ tsvector: :custom_not_existing, tsvector_column: [ - custom: Ash.Query.expr(custom_tsvector) + custom: Ash.Expr.expr(custom_tsvector) ] ] ] - assert AshPagify.Tsearch.tsvector(opts) == Ash.Query.expr(tsvector) + assert AshPagify.Tsearch.tsvector(opts) == Ash.Expr.expr(tsvector) end end diff --git a/test/ash_pagify/validation_test.exs b/test/ash_pagify/validation_test.exs index 8385be1..f3d7daa 100644 --- a/test/ash_pagify/validation_test.exs +++ b/test/ash_pagify/validation_test.exs @@ -484,8 +484,8 @@ defmodule AshPagify.ValidationTest do :filters => nil, :errors => [ filters: [ - %Ash.Error.Query.NoSuchAttributeOrRelationship{}, - %Ash.Error.Query.NoSuchAttributeOrRelationship{} + %Ash.Error.Query.NoSuchField{}, + %Ash.Error.Query.NoSuchField{} ] ] } = @@ -501,8 +501,8 @@ defmodule AshPagify.ValidationTest do :filters => %Ash.Filter{}, :errors => [ filters: [ - %Ash.Error.Query.NoSuchAttributeOrRelationship{}, - %Ash.Error.Query.NoSuchAttributeOrRelationship{} + %Ash.Error.Query.NoSuchField{}, + %Ash.Error.Query.NoSuchField{} ] ] } = @@ -587,7 +587,7 @@ defmodule AshPagify.ValidationTest do order_by: [name: :desc_nils_last], errors: [ order_by: [ - %Ash.Error.Query.NoSuchAttribute{name: "non_existent", resource: Post} + %Ash.Error.Query.NoSuchField{field: "non_existent", resource: Post} ] ] } = diff --git a/test/support/factory/api.ex b/test/support/factory/api.ex deleted file mode 100644 index 7438c59..0000000 --- a/test/support/factory/api.ex +++ /dev/null @@ -1,8 +0,0 @@ -defmodule AshPagify.Factory.Api do - @moduledoc false - use Ash.Api - - resources do - registry AshPagify.Factory.Registry - end -end diff --git a/test/support/factory/comment.ex b/test/support/factory/comment.ex index c39c354..db17528 100644 --- a/test/support/factory/comment.ex +++ b/test/support/factory/comment.ex @@ -2,17 +2,17 @@ defmodule AshPagify.Factory.Comment do @moduledoc false use Ash.Resource, data_layer: Ash.DataLayer.Ets, - api: AshPagify.Factory.Api, + domain: AshPagify.Factory.Domain, extensions: [AshUUID] use AshPagify.Tsearch, only: [:full_text_search] - require Ash.Query + require Ash.Expr @full_text_search [ prefix: false, any_word: true, - tsvector_column: Ash.Query.expr(custom_tsvector) + tsvector_column: Ash.Expr.expr(custom_tsvector) ] def full_text_search, do: @full_text_search @@ -21,9 +21,9 @@ defmodule AshPagify.Factory.Comment do end attributes do - uuid_attribute :id - attribute :body, :string, allow_nil?: false - attribute :text, :string + uuid_attribute :id, public?: true + attribute :body, :string, allow_nil?: false, public?: true + attribute :text, :string, public?: true end relationships do @@ -47,7 +47,8 @@ defmodule AshPagify.Factory.Comment do body, text ) - ) + ), + public?: true end preparations do @@ -56,6 +57,7 @@ defmodule AshPagify.Factory.Comment do end actions do + default_accept :* defaults [:create] read :read do @@ -73,7 +75,6 @@ defmodule AshPagify.Factory.Comment do end code_interface do - define_for AshPagify.Factory.Api define :read define :by_post, args: [:post_id] define :create diff --git a/test/support/factory/domain.ex b/test/support/factory/domain.ex new file mode 100644 index 0000000..7450607 --- /dev/null +++ b/test/support/factory/domain.ex @@ -0,0 +1,10 @@ +defmodule AshPagify.Factory.Domain do + @moduledoc false + use Ash.Domain + + resources do + resource AshPagify.Factory.Comment + resource AshPagify.Factory.Post + resource AshPagify.Factory.User + end +end diff --git a/test/support/factory/post.ex b/test/support/factory/post.ex index dbbd403..e52e6bb 100644 --- a/test/support/factory/post.ex +++ b/test/support/factory/post.ex @@ -2,12 +2,12 @@ defmodule AshPagify.Factory.Post do @moduledoc false use Ash.Resource, data_layer: Ash.DataLayer.Ets, - api: AshPagify.Factory.Api, + domain: AshPagify.Factory.Domain, extensions: [AshUUID] use AshPagify.Tsearch - require Ash.Query + require Ash.Expr @default_limit 15 def default_limit, do: @default_limit @@ -28,7 +28,7 @@ defmodule AshPagify.Factory.Post do def full_text_search do [ tsvector_column: [ - custom_tsvector: Ash.Query.expr(custom_tsvector) + custom_tsvector: Ash.Expr.expr(custom_tsvector) ] ] end @@ -38,25 +38,24 @@ defmodule AshPagify.Factory.Post do end attributes do - uuid_attribute :id - attribute :name, :string, allow_nil?: false - attribute :title, :string - attribute :text, :string - attribute :author, :string - attribute :age, :integer + uuid_attribute :id, public?: true + attribute :name, :string, allow_nil?: false, public?: true + attribute :title, :string, public?: true + attribute :text, :string, public?: true + attribute :author, :string, public?: true + attribute :age, :integer, public?: true + attribute :tsv, :string, allow_nil?: true, public?: false, writable?: false # allow sorting by inserted_at/updated_at - timestamps(private?: false, writable?: false) + timestamps(public?: true, writable?: false) end relationships do - has_many :comments, AshPagify.Factory.Comment + has_many :comments, AshPagify.Factory.Comment, public?: true end calculations do - calculate :tsvector, - AshPostgres.Tsvector, - expr(fragment("to_tsvector('simple', coalesce(?, ''))", title)) + calculate :tsvector, AshPostgres.Tsvector, expr(tsv), public?: true calculate :custom_tsvector, AshPostgres.Tsvector, @@ -66,15 +65,17 @@ defmodule AshPagify.Factory.Post do name, text ) - ) + ), + public?: true calculate :add_age, :integer, expr(fragment("age + ?", ^arg(:add))) do + public? true argument :add, :integer, allow_nil?: false end end aggregates do - count :comments_count, :comments + count :comments_count, :comments, public?: true end preparations do @@ -83,6 +84,8 @@ defmodule AshPagify.Factory.Post do end actions do + default_accept :* + read :read do primary? true argument :sort, :string, allow_nil?: true @@ -97,7 +100,6 @@ defmodule AshPagify.Factory.Post do end code_interface do - define_for AshPagify.Factory.Api define :read define :create end diff --git a/test/support/factory/registry.ex b/test/support/factory/registry.ex deleted file mode 100644 index b1720ab..0000000 --- a/test/support/factory/registry.ex +++ /dev/null @@ -1,10 +0,0 @@ -defmodule AshPagify.Factory.Registry do - @moduledoc false - use Ash.Registry - - entries do - entry AshPagify.Factory.Post - entry AshPagify.Factory.Comment - entry AshPagify.Factory.User - end -end diff --git a/test/support/factory/user.ex b/test/support/factory/user.ex index 2436621..348fb7d 100644 --- a/test/support/factory/user.ex +++ b/test/support/factory/user.ex @@ -2,7 +2,7 @@ defmodule AshPagify.Factory.User do @moduledoc false use Ash.Resource, data_layer: Ash.DataLayer.Ets, - api: AshPagify.Factory.Api, + domain: AshPagify.Factory.Domain, extensions: [AshUUID] ets do @@ -10,10 +10,10 @@ defmodule AshPagify.Factory.User do end attributes do - uuid_attribute :id - attribute :name, :string, allow_nil?: false - attribute :email, :string, allow_nil?: false - attribute :age, :integer + uuid_attribute :id, public?: true + attribute :name, :string, allow_nil?: false, public?: true + attribute :email, :string, allow_nil?: false, public?: true + attribute :age, :integer, public?: true end preparations do @@ -22,11 +22,11 @@ defmodule AshPagify.Factory.User do end actions do + default_accept :* defaults [:create, :read, :update, :destroy] end code_interface do - define_for AshPagify.Factory.Api define :read define :create define :update