From 8e9fbf8507eac4eb588846dcbd4a26591802a219 Mon Sep 17 00:00:00 2001 From: rekkice Date: Sat, 15 Mar 2025 11:10:02 -0300 Subject: [PATCH 1/9] chore: update ash_graphql dependency --- tololo/core/mix.exs | 2 +- tololo/extensions/telegram_bot/mix.exs | 2 +- tololo/mix.exs | 2 +- tololo/mix.lock | 25 ++++++++++++++----------- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/tololo/core/mix.exs b/tololo/core/mix.exs index 68ef6d2b..b900fb26 100644 --- a/tololo/core/mix.exs +++ b/tololo/core/mix.exs @@ -28,7 +28,7 @@ defmodule TololoCore.MixProject do # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"} {:ash_authentication, "~> 4.1"}, {:ash_authentication_phoenix, "~> 2.0"}, - {:ash_graphql, "~> 1.5.0"}, + {:ash_graphql, "~> 1.7.3"}, {:ash_phoenix, "~> 2.1.14"}, {:ash_postgres, "~> 2.0"}, {:ash, "~> 3.0"}, diff --git a/tololo/extensions/telegram_bot/mix.exs b/tololo/extensions/telegram_bot/mix.exs index 1dd58fc7..424ec2b2 100644 --- a/tololo/extensions/telegram_bot/mix.exs +++ b/tololo/extensions/telegram_bot/mix.exs @@ -25,7 +25,7 @@ defmodule Tololo.Extensions.TelegramBot.MixProject do {:remote_ip, "~> 1.2"}, {:ash_authentication, "~> 4.1"}, {:ash_authentication_phoenix, "~> 2.0"}, - {:ash_graphql, "~> 1.5.0"}, + {:ash_graphql, "~> 1.7.3"}, {:ash_phoenix, "~> 2.1.14"}, {:ash_postgres, "~> 2.0"}, {:ash, "~> 3.0"}, diff --git a/tololo/mix.exs b/tololo/mix.exs index 5b8326de..41c33b70 100644 --- a/tololo/mix.exs +++ b/tololo/mix.exs @@ -38,7 +38,7 @@ defmodule Tololo.MixProject do [ {:ash_authentication, "~> 4.1"}, {:ash_authentication_phoenix, "~> 2.0"}, - {:ash_graphql, "~> 1.5.0"}, + {:ash_graphql, "~> 1.7.3"}, {:ash_phoenix, "~> 2.1.14"}, {:ash_postgres, "~> 2.0"}, {:ash, "~> 3.0"}, diff --git a/tololo/mix.lock b/tololo/mix.lock index 4f4707ca..ecc858e9 100644 --- a/tololo/mix.lock +++ b/tololo/mix.lock @@ -2,11 +2,11 @@ "absinthe": {:hex, :absinthe, "1.7.8", "43443d12ad2b4fcce60e257ac71caf3081f3d5c4ddd5eac63a02628bcaf5b556", [:mix], [{:dataloader, "~> 1.0.0 or ~> 2.0", [hex: :dataloader, repo: "hexpm", optional: true]}, {:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:opentelemetry_process_propagator, "~> 0.2.1 or ~> 0.3", [hex: :opentelemetry_process_propagator, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c4085df201892a498384f997649aedb37a4ce8a726c170d5b5617ed3bf45d40b"}, "absinthe_plug": {:hex, :absinthe_plug, "1.5.8", "38d230641ba9dca8f72f1fed2dfc8abd53b3907d1996363da32434ab6ee5d6ab", [:mix], [{:absinthe, "~> 1.5", [hex: :absinthe, repo: "hexpm", optional: false]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bbb04176647b735828861e7b2705465e53e2cf54ccf5a73ddd1ebd855f996e5a"}, "acceptor_pool": {:hex, :acceptor_pool, "1.0.0", "43c20d2acae35f0c2bcd64f9d2bde267e459f0f3fd23dab26485bf518c281b21", [:rebar3], [], "hexpm", "0cbcd83fdc8b9ad2eee2067ef8b91a14858a5883cb7cd800e6fcd5803e158788"}, - "ash": {:hex, :ash, "3.4.55", "81132171412dc92bd1630500e1403a48f5ea7948552c528189d13d4c4c181878", [:mix], [{: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.4.8 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, 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.29 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [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", "6fb89c9bb6e158b2dab08184f3b6ebfd88785348c21b2a9fd5bd71b1f96e2c5e"}, + "ash": {:hex, :ash, "3.4.68", "d6478880cf11500d4cc15a23c73ef78dc0471a4c59891ec925124a0922df2746", [:mix], [{: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.5.24 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, 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.11", [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.29 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [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", "bb8249b45a48de04664fa73ab2cbbc3ba56b792ced4997bdc6862c39f3fe47b4"}, "ash_admin": {:hex, :ash_admin, "0.12.6", "ffebd80dd4af1b14aa85d589e40cdb94d6751db207e3c39634cf744a51c83f7d", [:mix], [{:ash, ">= 3.4.47 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ash_phoenix, ">= 2.1.8 and < 3.0.0-0", [hex: :ash_phoenix, repo: "hexpm", optional: false]}, {:gettext, "~> 0.26", [hex: :gettext, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.7", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 4.1", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}], "hexpm", "15ea0c8a73b897c3c81300913b9e03fa162b7796e458c550869820bf39fa39ed"}, "ash_authentication": {:hex, :ash_authentication, "4.4.1", "1f6ce1610585132134fe48eae7ea289f1f2702c28ca9f5afba41a49038c5d978", [:mix], [{:ash, ">= 3.4.29 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ash_postgres, "~> 2.0", [hex: :ash_postgres, repo: "hexpm", optional: true]}, {:assent, "~> 0.2.13", [hex: :assent, repo: "hexpm", optional: false]}, {:bcrypt_elixir, "~> 3.0", [hex: :bcrypt_elixir, repo: "hexpm", optional: false]}, {:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:finch, "~> 0.19", [hex: :finch, repo: "hexpm", optional: false]}, {:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:joken, "~> 2.5", [hex: :joken, repo: "hexpm", optional: false]}, {:plug, "~> 1.13", [hex: :plug, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}], "hexpm", "ed646abc95aadcd5fb1da6991bfa8acbc1f04bfe580d78c8bcf089956a4fdea0"}, "ash_authentication_phoenix": {:hex, :ash_authentication_phoenix, "2.4.4", "91f225531ec373f39158e394a5d17288a369a0955033728a9877a12eea101b02", [:mix], [{:ash, "~> 3.0", [hex: :ash, repo: "hexpm", optional: false]}, {:ash_authentication, "~> 4.1", [hex: :ash_authentication, repo: "hexpm", optional: false]}, {:ash_phoenix, "~> 2.0", [hex: :ash_phoenix, repo: "hexpm", optional: false]}, {:bcrypt_elixir, "~> 3.0", [hex: :bcrypt_elixir, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.1 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.6", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_html_helpers, "~> 1.0", [hex: :phoenix_html_helpers, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:slugify, "~> 1.3", [hex: :slugify, repo: "hexpm", optional: false]}], "hexpm", "5f5124943201a982638d38e85e4d7ef2bc55226499c9bf640b90f416d60c2567"}, - "ash_graphql": {:hex, :ash_graphql, "1.5.0", "29dce267c7bd86fa7c94feb5ce861674d46046e528299f095db659411f32cd24", [:mix], [{:absinthe, "~> 1.7", [hex: :absinthe, repo: "hexpm", optional: false]}, {:absinthe_phoenix, "~> 2.0.0", [hex: :absinthe_phoenix, repo: "hexpm", optional: true]}, {:absinthe_plug, "~> 1.4", [hex: :absinthe_plug, repo: "hexpm", optional: false]}, {:ash, ">= 3.2.3 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:igniter, ">= 0.3.34 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:spark, ">= 2.2.10 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}], "hexpm", "7657ad63d2fba2feeac3ce9b158077e7b8cdcd823573c8888619de8ba929c188"}, + "ash_graphql": {:hex, :ash_graphql, "1.7.3", "2eba5afc4dd1657203f879d45c4cb56dfcf00c4ed16170620601e7a283908dd1", [:mix], [{:absinthe, "~> 1.7", [hex: :absinthe, repo: "hexpm", optional: false]}, {:absinthe_phoenix, "~> 2.0", [hex: :absinthe_phoenix, repo: "hexpm", optional: true]}, {:absinthe_plug, "~> 1.4", [hex: :absinthe_plug, repo: "hexpm", optional: false]}, {:ash, ">= 3.2.3 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.28 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:spark, ">= 2.2.10 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}], "hexpm", "e63f4ef6c4c56a23b2cc60e9a736c53d089c6672eaa3b7805d7eff1ab7b2a034"}, "ash_money": {:hex, :ash_money, "0.1.18", "91fb22b3d72971a5050ca893e0e95aff42a3474c9dd938e4c9866e204d9c52af", [:mix], [{:ash, ">= 3.0.15 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ash_graphql, "~> 1.0", [hex: :ash_graphql, repo: "hexpm", optional: true]}, {:ash_json_api, ">= 1.4.3 and < 2.0.0-0", [hex: :ash_json_api, repo: "hexpm", optional: true]}, {:ash_postgres, "~> 2.0", [hex: :ash_postgres, repo: "hexpm", optional: true]}, {:ex_money, "~> 5.15", [hex: :ex_money, repo: "hexpm", optional: false]}, {:ex_money_sql, "~> 1.0", [hex: :ex_money_sql, repo: "hexpm", optional: true]}, {:igniter, ">= 0.3.58 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}], "hexpm", "800d0ef53dd2ac8ec5b9d3ae0c86086116407c148bf23cc2403b33f29b181451"}, "ash_phoenix": {:hex, :ash_phoenix, "2.1.14", "da4126b1d85fbb422ceb339c05ebca79ee9aca4f434faad8a60ea07d42989c72", [:mix], [{:ash, ">= 3.4.31 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:igniter, ">= 0.4.3 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {: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-rc.1", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:spark, ">= 2.2.29 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}], "hexpm", "6fa93b686083c5a64d053a955881206ea26c3ad3fc0310ddbad8df769daa5fab"}, "ash_postgres": {:hex, :ash_postgres, "2.5.0", "e3db76855b67ed6c4d2148c32e866ff39e88d674460885b06bd58870aa028e75", [:mix], [{:ash, ">= 3.4.48 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ash_sql, ">= 0.2.43 and < 1.0.0-0", [hex: :ash_sql, repo: "hexpm", optional: false]}, {:ecto, ">= 3.12.1 and < 4.0.0-0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.12", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:igniter, ">= 0.4.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:inflex, "~> 2.1", [hex: :inflex, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: false]}], "hexpm", "16124c9ebae3f4586ff6e550b5ab6ab0ed66aa07560c04a324c3c03d9ecd42f6"}, @@ -59,7 +59,7 @@ "heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "88ab3a0d790e6a47404cba02800a6b25d2afae50", [tag: "v2.1.1", sparse: "optimized", depth: 1]}, "hpack": {:hex, :hpack_erl, "0.3.0", "2461899cc4ab6a0ef8e970c1661c5fc6a52d3c25580bc6dd204f84ce94669926", [:rebar3], [], "hexpm", "d6137d7079169d8c485c6962dfe261af5b9ef60fbc557344511c1e65e3d95fb0"}, "hpax": {:hex, :hpax, "1.0.2", "762df951b0c399ff67cc57c3995ec3cf46d696e41f0bba17da0518d94acd4aac", [:mix], [], "hexpm", "2f09b4c1074e0abd846747329eaa26d535be0eb3d189fa69d812bfb8bfefd32f"}, - "igniter": {:hex, :igniter, "0.5.11", "40a77910ddd3b81e58bc6c0411f2b4a1d2102bc1dd81818da6b7fceacfe1c0c6", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [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]}], "hexpm", "d41ef6bbed10bbf324d83473b818fa1367b5eb244eca05dfb3ea862e8a0c1567"}, + "igniter": {:hex, :igniter, "0.5.36", "3fe5b97bd37b13ebf0e39462293d0a51411519de2edc130dbe401fbd0210b97d", [: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]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [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]}], "hexpm", "4990f58d8a59e914f488a97e1627f6a5646d4bdd80a5093af4298aa251b9d5dd"}, "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"}, @@ -76,7 +76,7 @@ "mix_test_watch": {:hex, :mix_test_watch, "1.2.0", "1f9acd9e1104f62f280e30fc2243ae5e6d8ddc2f7f4dc9bceb454b9a41c82b42", [:mix], [{:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm", "278dc955c20b3fb9a3168b5c2493c2e5cffad133548d307e0a50c7f2cfbf34f6"}, "multipart": {:hex, :multipart, "0.4.0", "634880a2148d4555d050963373d0e3bbb44a55b2badd87fa8623166172e9cda0", [:mix], [{:mime, "~> 1.2 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm", "3c5604bc2fb17b3137e5d2abdf5dacc2647e60c5cc6634b102cf1aef75a06f0a"}, "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, - "nimble_parsec": {:hex, :nimble_parsec, "1.4.1", "f41275a0354c736db4b1d255b5d2a27c91028e55c21ea3145b938e22649ffa3f", [:mix], [], "hexpm", "605e44204998f138d6e13be366c8e81af860e726c8177caf50067e1b618fe522"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"}, "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, "octo_fetch": {:hex, :octo_fetch, "0.4.0", "074b5ecbc08be10b05b27e9db08bc20a3060142769436242702931c418695b19", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "cf8be6f40cd519d7000bb4e84adcf661c32e59369ca2827c4e20042eda7a7fc6"}, "opentelemetry": {:hex, :opentelemetry, "1.5.0", "7dda6551edfc3050ea4b0b40c0d2570423d6372b97e9c60793263ef62c53c3c2", [:rebar3], [{:opentelemetry_api, "~> 1.4", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}], "hexpm", "cdf4f51d17b592fc592b9a75f86a6f808c23044ba7cf7b9534debbcc5c23b0ee"}, @@ -90,7 +90,7 @@ "opentelemetry_semantic_conventions": {:hex, :opentelemetry_semantic_conventions, "1.27.0", "acd0194a94a1e57d63da982ee9f4a9f88834ae0b31b0bd850815fe9be4bbb45f", [:mix, :rebar3], [], "hexpm", "9681ccaa24fd3d810b4461581717661fd85ff7019b082c2dff89c7d5b1fc2864"}, "opentelemetry_telemetry": {:hex, :opentelemetry_telemetry, "1.1.2", "410ab4d76b0921f42dbccbe5a7c831b8125282850be649ee1f70050d3961118a", [:mix, :rebar3], [{:opentelemetry_api, "~> 1.3", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "641ab469deb181957ac6d59bce6e1321d5fe2a56df444fc9c19afcad623ab253"}, "otel_http": {:hex, :otel_http, "0.2.0", "b17385986c7f1b862f5d577f72614ecaa29de40392b7618869999326b9a61d8a", [:rebar3], [], "hexpm", "f2beadf922c8cfeb0965488dd736c95cc6ea8b9efce89466b3904d317d7cc717"}, - "owl": {:hex, :owl, "0.12.0", "0c4b48f90797a7f5f09ebd67ba7ebdc20761c3ec9c7928dfcafcb6d3c2d25c99", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "241d85ae62824dd72f9b2e4a5ba4e69ebb9960089a3c68ce6c1ddf2073db3c15"}, + "owl": {:hex, :owl, "0.12.2", "65906b525e5c3ef51bab6cba7687152be017aebe1da077bb719a5ee9f7e60762", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "6398efa9e1fea70a04d24231e10dcd66c1ac1aa2da418d20ef5357ec61de2880"}, "peep": {:hex, :peep, "3.4.1", "0e5263710fa0b42675bd0a11fdcdd3ee4f484e319105b6ad9a576c91a5d3cb55", [:mix], [{:nimble_options, "~> 1.1", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:plug, "~> 1.16", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry_metrics, "~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "7a9b8c1f17b8b9475efb27b7048afa4d89ab84ef33a3d1df13696c85c12cd632"}, "phoenix": {:hex, :phoenix, "1.7.18", "5310c21443514be44ed93c422e15870aef254cf1b3619e4f91538e7529d2b2e4", [: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", "1797fcc82108442a66f2c77a643a62980f342bfeb63d6c9a515ab8294870004e"}, "phoenix_ecto": {:hex, :phoenix_ecto, "4.6.3", "f686701b0499a07f2e3b122d84d52ff8a31f5def386e03706c916f6feddf69ef", [:mix], [{:ecto, "~> 3.5", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.1", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "909502956916a657a197f94cc1206d9a65247538de8a5e186f7537c895d95764"}, @@ -103,21 +103,21 @@ "phoenix_template": {:hex, :phoenix_template, "1.0.4", "e2092c132f3b5e5b2d49c96695342eb36d0ed514c5b252a77048d5969330d639", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "2c0c81f0e5c6753faf5cca2f229c9709919aba34fab866d3bc05060c9c444206"}, "phoenix_view": {:hex, :phoenix_view, "2.0.4", "b45c9d9cf15b3a1af5fb555c674b525391b6a1fe975f040fb4d913397b31abf4", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}], "hexpm", "4e992022ce14f31fe57335db27a28154afcc94e9983266835bb3040243eb620b"}, "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": {:hex, :plug, "1.17.0", "a0832e7af4ae0f4819e0c08dd2e7482364937aea6a8a997a679f2cbb7e026b2e", [: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", "f6692046652a69a00a5a21d0b7e11fcf401064839d59d6b8787f23af55b1e6bc"}, "plug_crypto": {:hex, :plug_crypto, "2.1.0", "f44309c2b06d249c27c8d3f65cfe08158ade08418cf540fd4f72d4d6863abb7b", [:mix], [], "hexpm", "131216a4b030b8f8ce0f26038bc4421ae60e4bb95c5cf5395e1421437824c4fa"}, "postgrex": {:hex, :postgrex, "0.19.3", "a0bda6e3bc75ec07fca5b0a89bffd242ca209a4822a9533e7d3e84ee80707e19", [: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", "d31c28053655b78f47f948c85bb1cf86a9c1f8ead346ba1aa0d0df017fa05b61"}, "prom_ex": {:hex, :prom_ex, "1.11.0", "1f6d67f2dead92224cb4f59beb3e4d319257c5728d9638b4a5e8ceb51a4f9c7e", [:mix], [{:absinthe, ">= 1.7.0", [hex: :absinthe, repo: "hexpm", optional: true]}, {:broadway, ">= 1.1.0", [hex: :broadway, repo: "hexpm", optional: true]}, {:ecto, ">= 3.11.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:finch, "~> 0.18", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:oban, ">= 2.10.0", [hex: :oban, repo: "hexpm", optional: true]}, {:octo_fetch, "~> 0.4", [hex: :octo_fetch, repo: "hexpm", optional: false]}, {:peep, "~> 3.0", [hex: :peep, repo: "hexpm", optional: false]}, {:phoenix, ">= 1.7.0", [hex: :phoenix, repo: "hexpm", optional: true]}, {:phoenix_live_view, ">= 0.20.0", [hex: :phoenix_live_view, repo: "hexpm", optional: true]}, {:plug, ">= 1.16.0", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 2.6.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, ">= 1.0.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}, {:telemetry_metrics_prometheus_core, "~> 1.2", [hex: :telemetry_metrics_prometheus_core, repo: "hexpm", optional: false]}, {:telemetry_poller, "~> 1.1", [hex: :telemetry_poller, repo: "hexpm", optional: false]}], "hexpm", "76b074bc3730f0802978a7eb5c7091a65473eaaf07e99ec9e933138dcc327805"}, - "reactor": {:hex, :reactor, "0.10.3", "41a8c34251148e36dd7c75aa8433f2c2f283f29c097f9eb84a630ab28dd75651", [:mix], [{:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {: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", "2b34380e22b69a35943a7bcceffd5a8b766870f1fc9052162a7ff74ef9cdb3b2"}, + "reactor": {:hex, :reactor, "0.15.0", "556937d9310e1a6dd06083592b9eb9e0d212540b6d82faecba70823ee7a0747d", [:mix], [{:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:iterex, "~> 0.1", [hex: :iterex, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, 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]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}, {:ymlr, "~> 5.0", [hex: :ymlr, repo: "hexpm", optional: false]}], "hexpm", "f634383a7760ba3106d31a3185f2e2c39e1485d899d884d94c22c62c9b5e7a4a"}, "remote_ip": {:hex, :remote_ip, "1.2.0", "fb078e12a44414f4cef5a75963c33008fe169b806572ccd17257c208a7bc760f", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "2ff91de19c48149ce19ed230a81d377186e4412552a597d6a5137373e5877cb7"}, "req": {:hex, :req, "0.5.8", "50d8d65279d6e343a5e46980ac2a70e97136182950833a1968b371e753f6a662", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "d7fc5898a566477e174f26887821a3c5082b243885520ee4b45555f5d53f40ef"}, "rewrite": {:hex, :rewrite, "1.1.2", "f5a5d10f5fed1491a6ff48e078d4585882695962ccc9e6c779bae025d1f92eda", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}, {:text_diff, "~> 0.1", [hex: :text_diff, repo: "hexpm", optional: false]}], "hexpm", "7f8b94b1e3528d0a47b3e8b7bfeca559d2948a65fa7418a9ad7d7712703d39d4"}, "slugify": {:hex, :slugify, "1.3.1", "0d3b8b7e5c1eeaa960e44dce94382bee34a39b3ea239293e457a9c5b47cc6fd3", [:mix], [], "hexpm", "cb090bbeb056b312da3125e681d98933a360a70d327820e4b7f91645c4d8be76"}, "sourceror": {:hex, :sourceror, "1.7.1", "599d78f4cc2be7d55c9c4fd0a8d772fd0478e3a50e726697c20d13d02aa056d4", [:mix], [], "hexpm", "cd6f268fe29fa00afbc535e215158680a0662b357dc784646d7dff28ac65a0fc"}, - "spark": {:hex, :spark, "2.2.37", "2b0878d417ea98b241742c56fe615f238ae5df11a231f5a622d8266ffac661c3", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "0f62dfc2ff5b410070e2b6b84188f8be92f34641875e20f4765da34842e42dca"}, - "spitfire": {:hex, :spitfire, "0.1.4", "8fe0df66e735323e4f2a56e719603391b160dd68efd922cadfbb85a2cf6c68af", [:mix], [], "hexpm", "d40d850f4ede5235084876246756b90c7bcd12994111d57c55e2e1e23ac3fe61"}, - "splode": {:hex, :splode, "0.2.7", "ed042fa9bd8fe7b66dd0a0faabdb97352058420d90cd1c7c1537f609deb7ef6d", [:mix], [], "hexpm", "267f1f51d5a5ac988cda0649498294844988c5086916fed5a8aff297d69a2059"}, + "spark": {:hex, :spark, "2.2.46", "39a1e6b793a754f6a23a1cf12911006125fae0b233250400ad6157991669642d", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "39e4ebfd5bac0c0090e548301680481ed41c1886b0874873363ec22de2bb8a61"}, + "spitfire": {:hex, :spitfire, "0.2.0", "0de1f519a23f65bde40d316adad53c07a9563f25cc68915d639d8a509a0aad8a", [:mix], [], "hexpm", "743daaee2d81a0d8095431729f478ce49b47ea8943c7d770de86704975cb7775"}, + "splode": {:hex, :splode, "0.2.9", "3a2776e187c82f42f5226b33b1220ccbff74f4bcc523dd4039c804caaa3ffdc7", [:mix], [], "hexpm", "8002b00c6e24f8bd1bcced3fbaa5c33346048047bb7e13d2f3ad428babbd95c3"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, - "stream_data": {:hex, :stream_data, "1.1.2", "05499eaec0443349ff877aaabc6e194e82bda6799b9ce6aaa1aadac15a9fdb4d", [:mix], [], "hexpm", "129558d2c77cbc1eb2f4747acbbea79e181a5da51108457000020a906813a1a9"}, + "stream_data": {:hex, :stream_data, "1.1.3", "15fdb14c64e84437901258bb56fc7d80aaf6ceaf85b9324f359e219241353bfb", [:mix], [], "hexpm", "859eb2be72d74be26c1c4f272905667672a52e44f743839c57c7ee73a1a66420"}, "swoosh": {:hex, :swoosh, "1.17.6", "27ff070f96246e35b7105ab1c52b2b689f523a3cb83ed9faadb2f33bd653ccba", [:mix], [{:bandit, ">= 1.0.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mua, "~> 0.2.3", [hex: :mua, repo: "hexpm", optional: true]}, {:multipart, "~> 0.4", [hex: :multipart, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:req, "~> 0.5 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9798f3e72165f40c950f6762c06dab68afcdcf616138fc4a07965c09c250e1e2"}, "tailwind": {:hex, :tailwind, "0.2.4", "5706ec47182d4e7045901302bf3a333e80f3d1af65c442ba9a9eed152fb26c2e", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "c6e4a82b8727bab593700c998a4d98cf3d8025678bfde059aed71d0000c3e463"}, "telegex": {:hex, :telegex, "1.8.0", "982ef33e9576167189c4980c27ebe927e8b0945d0e8c93c1173ea9482ef78137", [:mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:typed_struct, "~> 0.3.0", [hex: :typed_struct, repo: "hexpm", optional: false]}], "hexpm", "899fdadedc3691faf923e12639247b083f259284b2963e94b265088473c7349b"}, @@ -132,4 +132,7 @@ "varint": {:hex, :varint, "1.4.0", "b7405c8a99db7b95d4341fa9cb15e7c3af6c8dda43e21bbe1c4a9cdff50b6502", [:mix], [], "hexpm", "0fd461901b7120c03467530dff3c58fa3475328fd75ba72c7d3cbf13bce6b0d2"}, "websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"}, "websock_adapter": {:hex, :websock_adapter, "0.5.8", "3b97dc94e407e2d1fc666b2fb9acf6be81a1798a2602294aac000260a7c4a47d", [: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", "315b9a1865552212b5f35140ad194e67ce31af45bcee443d4ecb96b5fd3f3782"}, + "yamerl": {:hex, :yamerl, "0.10.0", "4ff81fee2f1f6a46f1700c0d880b24d193ddb74bd14ef42cb0bcf46e81ef2f8e", [:rebar3], [], "hexpm", "346adb2963f1051dc837a2364e4acf6eb7d80097c0f53cbdc3046ec8ec4b4e6e"}, + "yaml_elixir": {:hex, :yaml_elixir, "2.11.0", "9e9ccd134e861c66b84825a3542a1c22ba33f338d82c07282f4f1f52d847bd50", [:mix], [{:yamerl, "~> 0.10", [hex: :yamerl, repo: "hexpm", optional: false]}], "hexpm", "53cc28357ee7eb952344995787f4bb8cc3cecbf189652236e9b163e8ce1bc242"}, + "ymlr": {:hex, :ymlr, "5.1.3", "a8061add5a378e20272a31905be70209a5680fdbe0ad51f40cb1af4bdd0a010b", [:mix], [], "hexpm", "8663444fa85101a117887c170204d4c5a2182567e5f84767f0071cf15f2efb1e"}, } From d40ef1c67f2bfb5c18c27ab95c53fe6d744e2e84 Mon Sep 17 00:00:00 2001 From: rekkice Date: Sat, 15 Mar 2025 11:10:02 -0300 Subject: [PATCH 2/9] chore: update domains exposed through graphql --- tololo/lib/tololo_web/graphql_schema.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tololo/lib/tololo_web/graphql_schema.ex b/tololo/lib/tololo_web/graphql_schema.ex index f501ae98..c09693b3 100644 --- a/tololo/lib/tololo_web/graphql_schema.ex +++ b/tololo/lib/tololo_web/graphql_schema.ex @@ -5,7 +5,7 @@ defmodule TololoWeb.GraphqlSchema do use Absinthe.Schema use AshGraphql, - domains: [TololoCore.Deliveries], + domains: [TololoCore.Deliveries, TololoCore.Carts, TololoCore.Brands, TololoCore.Products], generate_sdl_file: "priv/schema.graphql" import_types Absinthe.Plug.Types From edb7037f481aa5294e5ff985ddd6fa3271ad6dc2 Mon Sep 17 00:00:00 2001 From: rekkice Date: Sat, 15 Mar 2025 11:10:02 -0300 Subject: [PATCH 3/9] feat: add queries for graphql --- tololo/core/lib/products/product.ex | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tololo/core/lib/products/product.ex b/tololo/core/lib/products/product.ex index 99f521cc..e0cf624b 100644 --- a/tololo/core/lib/products/product.ex +++ b/tololo/core/lib/products/product.ex @@ -20,6 +20,8 @@ defmodule TololoCore.Products.Product do queries do get :get_product, :read + list :get_available_products, :get_enabled + list :search_available_products, :search_enabled end mutations do @@ -61,6 +63,11 @@ defmodule TololoCore.Products.Product do filter expr(state == :enabled) end + read :search_enabled do + argument :search_string, :string + filter expr(contains(name, ^arg(:search_string))) + end + update :generate_variants do require_atomic? false From fedfff767887bc82946c3d29554c6ff76c2ef870 Mon Sep 17 00:00:00 2001 From: rekkice Date: Sat, 15 Mar 2025 11:10:02 -0300 Subject: [PATCH 4/9] chore: add product graphql query examples for bruno --- .../products/get available products.bru | 48 + collections/products/get product.bru | 51 + .../products/get products in collection.bru | 36 + .../products/search available products.bru | 64 + tololo/priv/schema.graphql | 1033 ++++++++++++++++- 5 files changed, 1201 insertions(+), 31 deletions(-) create mode 100644 collections/products/get available products.bru create mode 100644 collections/products/get product.bru create mode 100644 collections/products/get products in collection.bru create mode 100644 collections/products/search available products.bru diff --git a/collections/products/get available products.bru b/collections/products/get available products.bru new file mode 100644 index 00000000..9172d264 --- /dev/null +++ b/collections/products/get available products.bru @@ -0,0 +1,48 @@ +meta { + name: get available products + type: graphql + seq: 2 +} + +post { + url: {{gql_host}}:{{gql_port}}/gql + body: graphql + auth: none +} + +body:graphql { + query GetAvailableProducts($filter: ProductFilterInput, $sort: [ProductSortInput!]) { + getAvailableProducts(filter: $filter, sort: $sort) { + id + name + description + sku + state + prices { + id + money { + amount + currency + } + } + } + } + +} + +body:graphql:vars { + { + "filter": { + "name": { + "like": "Gyozas al Vapor" + } + }, + "sort": [ + { + "field": "NAME", + "order": "ASC" + } + ] + } + +} diff --git a/collections/products/get product.bru b/collections/products/get product.bru new file mode 100644 index 00000000..dc304f82 --- /dev/null +++ b/collections/products/get product.bru @@ -0,0 +1,51 @@ +meta { + name: get product + type: graphql + seq: 1 +} + +post { + url: {{gql_host}}:{{gql_port}}/gql + body: graphql + auth: none +} + +body:graphql { + query GetProduct($id: ID!) { + getProduct(id: $id) { + id + name + description + sku + state + variants { + id + name + sku + prices { + id + money { + amount + currency + } + } + } + options { + id + name + description + optionValues { + id + value + } + } + } + } + +} + +body:graphql:vars { + { + "id": "019581b4-ff11-7551-823e-22e17158f32b" + } +} diff --git a/collections/products/get products in collection.bru b/collections/products/get products in collection.bru new file mode 100644 index 00000000..49adcdea --- /dev/null +++ b/collections/products/get products in collection.bru @@ -0,0 +1,36 @@ +meta { + name: get products in collection + type: graphql + seq: 4 +} + +post { + url: {{gql_host}}:{{gql_port}}/gql + body: graphql + auth: none +} + +body:graphql { + query GetProductsInCollection($collectionId: ID!) { + getAvailableProducts(filter: { collections: { id: { eq: $collectionId } } }) { + id + name + description + sku + state + collections { + id + name + description + } + } + } + +} + +body:graphql:vars { + { + "collectionId": "01959a22-b197-7d63-9a63-8990e0bd55c8" + } + +} diff --git a/collections/products/search available products.bru b/collections/products/search available products.bru new file mode 100644 index 00000000..f14d0218 --- /dev/null +++ b/collections/products/search available products.bru @@ -0,0 +1,64 @@ +meta { + name: search available products + type: graphql + seq: 3 +} + +post { + url: {{gql_host}}:{{gql_port}}/gql + body: graphql + auth: none +} + +body:graphql { + query SearchAvailableProducts($searchString: String, $sort: [ProductSortInput!]) { + searchAvailableProducts(searchString: $searchString, sort: $sort) { + id + name + description + sku + state + prices { + id + money { + amount + currency + } + } + variants { + id + name + sku + prices { + id + money { + amount + currency + } + } + } + options { + id + name + description + optionValues { + id + value + } + } + } + } + +} + +body:graphql:vars { + { + "searchString": "Arrollados", + "sort": [ + { + "field": "SKU", + "order": "ASC" + } + ] + } +} diff --git a/tololo/priv/schema.graphql b/tololo/priv/schema.graphql index a584d29e..133513b2 100644 --- a/tololo/priv/schema.graphql +++ b/tololo/priv/schema.graphql @@ -3,6 +3,15 @@ schema { query: RootQueryType } +type Attributes { + id: ID! + method: String! + methodData: JsonString + discount: Decimal + enabled: Boolean + conditions: [JsonString!] +} + enum DeliveryStateChangesSortField { ID OLD_STATE @@ -192,41 +201,1003 @@ type MutationError { fields: [String!] } -type RootQueryType { - """ - Hello! This is a sample query to verify that AshGraphql has been set up correctly. - Remove me once you have a query of your own! - """ - sayHello: String +enum CartLineSortField { + ID + QUANTITY + NOTES + VARIANT_ID + CART_ID +} - getDelivery( - "The id of the record" - id: ID! - ): Delivery +input CartLineFilterCartId { + isNil: Boolean + eq: ID + notEq: ID + in: [ID!] + lessThan: ID + greaterThan: ID + lessThanOrEqual: ID + greaterThanOrEqual: ID } -type RootMutationType { - initDelivery(input: InitDeliveryInput!): InitDeliveryResult! - updateState(id: ID!, input: UpdateStateInput): UpdateStateResult! - updateLocation(id: ID!, input: UpdateLocationInput): UpdateLocationResult! +input CartLineFilterVariantId { + isNil: Boolean + eq: ID + notEq: ID + in: [ID!] + lessThan: ID + greaterThan: ID + lessThanOrEqual: ID + greaterThanOrEqual: ID } -""" -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. -""" -scalar JsonString +input CartLineFilterNotes { + isNil: Boolean + eq: String + notEq: String + in: [String] + lessThan: String + greaterThan: String + lessThanOrEqual: String + greaterThanOrEqual: String + like: String + ilike: String +} -""" -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. -""" -scalar Json +input CartLineFilterQuantity { + isNil: Boolean + eq: Int + notEq: Int + in: [Int!] + lessThan: Int + greaterThan: Int + lessThanOrEqual: Int + greaterThanOrEqual: Int +} -""" -The `Date` scalar type represents a date. The Date appears in a JSON -response as an ISO8601 formatted string, without a time component. -""" -scalar Date +input CartLineFilterId { + isNil: Boolean + eq: ID + notEq: ID + in: [ID!] + lessThan: ID + greaterThan: ID + lessThanOrEqual: ID + greaterThanOrEqual: ID +} + +input CartLineFilterInput { + and: [CartLineFilterInput!] + or: [CartLineFilterInput!] + not: [CartLineFilterInput!] + id: CartLineFilterId + quantity: CartLineFilterQuantity + notes: CartLineFilterNotes + variantId: CartLineFilterVariantId + cartId: CartLineFilterCartId + variant: VariantFilterInput + cart: CartFilterInput +} + +input CartLineSortInput { + order: SortOrder + field: CartLineSortField! +} + +type CartLine { + id: ID! + quantity: Int! + notes: String + variantId: ID! + cartId: ID! + variant: Variant! + cart: Cart! +} + +input CartFilterCurrency { + isNil: Boolean + eq: String + notEq: String + in: [String] + lessThan: String + greaterThan: String + lessThanOrEqual: String + greaterThanOrEqual: String + like: String + ilike: String +} + +input CartFilterStatus { + isNil: Boolean + eq: String + notEq: String + in: [String] + lessThan: String + greaterThan: String + lessThanOrEqual: String + greaterThanOrEqual: String +} + +input CartFilterId { + isNil: Boolean + eq: ID + notEq: ID + in: [ID!] + lessThan: ID + greaterThan: ID + lessThanOrEqual: ID + greaterThanOrEqual: ID +} + +input CartFilterInput { + and: [CartFilterInput!] + or: [CartFilterInput!] + not: [CartFilterInput!] + id: CartFilterId + status: CartFilterStatus + currency: CartFilterCurrency + cartLines: CartLineFilterInput +} + +type Cart { + id: ID! + status: String + currency: String + cartLines( + "How to sort the records in the response" + sort: [CartLineSortInput] + + "A filter to limit the results" + filter: CartLineFilterInput + + "The number of records to return." + limit: Int + + "The number of records to skip." + offset: Int + ): [CartLine!]! +} + +type Branch { + id: ID! + name: String! + address: String! + latitude: Float! + longitude: Float! + brandId: ID + brand: Brand +} + +type Brand { + id: ID! + name: String! + branch: Branch +} + +input TypeFilterDescription { + isNil: Boolean + eq: String + notEq: String + in: [String] + lessThan: String + greaterThan: String + lessThanOrEqual: String + greaterThanOrEqual: String + like: String + ilike: String +} + +input TypeFilterName { + isNil: Boolean + eq: String + notEq: String + in: [String!] + lessThan: String + greaterThan: String + lessThanOrEqual: String + greaterThanOrEqual: String + like: String + ilike: String +} + +input TypeFilterId { + isNil: Boolean + eq: ID + notEq: ID + in: [ID!] + lessThan: ID + greaterThan: ID + lessThanOrEqual: ID + greaterThanOrEqual: ID +} + +input TypeFilterInput { + and: [TypeFilterInput!] + or: [TypeFilterInput!] + not: [TypeFilterInput!] + id: TypeFilterId + name: TypeFilterName + description: TypeFilterDescription +} + +type Type { + id: ID! + name: String! + description: String + attributes: [Attributes!] +} + +enum PriceSortField { + ID + MONEY + PRODUCT_ID + VARIANT_ID +} + +input PriceFilterVariantId { + isNil: Boolean + eq: ID + notEq: ID + in: [ID] + lessThan: ID + greaterThan: ID + lessThanOrEqual: ID + greaterThanOrEqual: ID +} + +input PriceFilterProductId { + isNil: Boolean + eq: ID + notEq: ID + in: [ID] + lessThan: ID + greaterThan: ID + lessThanOrEqual: ID + greaterThanOrEqual: ID +} + +input PriceFilterMoney { + isNil: Boolean + eq: MoneyInput + notEq: MoneyInput + in: [MoneyInput!] + lessThan: MoneyInput + greaterThan: MoneyInput + lessThanOrEqual: MoneyInput + greaterThanOrEqual: MoneyInput +} + +input PriceFilterId { + isNil: Boolean + eq: ID + notEq: ID + in: [ID!] + lessThan: ID + greaterThan: ID + lessThanOrEqual: ID + greaterThanOrEqual: ID +} + +input PriceFilterInput { + and: [PriceFilterInput!] + or: [PriceFilterInput!] + not: [PriceFilterInput!] + id: PriceFilterId + money: PriceFilterMoney + productId: PriceFilterProductId + variantId: PriceFilterVariantId + product: ProductFilterInput + variant: VariantFilterInput +} + +input PriceSortInput { + order: SortOrder + field: PriceSortField! +} + +type Price { + id: ID! + money: Money! + productId: ID + variantId: ID + product: Product + variant: Variant +} + +enum OptionValueSortField { + ID + VALUE + OPTION_ID + VARIANT_ID +} + +input OptionValueFilterVariantId { + isNil: Boolean + eq: ID + notEq: ID + in: [ID] + lessThan: ID + greaterThan: ID + lessThanOrEqual: ID + greaterThanOrEqual: ID +} + +input OptionValueFilterOptionId { + isNil: Boolean + eq: ID + notEq: ID + in: [ID] + lessThan: ID + greaterThan: ID + lessThanOrEqual: ID + greaterThanOrEqual: ID +} + +input OptionValueFilterValue { + isNil: Boolean + eq: String + notEq: String + in: [String!] + lessThan: String + greaterThan: String + lessThanOrEqual: String + greaterThanOrEqual: String + like: String + ilike: String +} + +input OptionValueFilterId { + isNil: Boolean + eq: ID + notEq: ID + in: [ID!] + lessThan: ID + greaterThan: ID + lessThanOrEqual: ID + greaterThanOrEqual: ID +} + +input OptionValueFilterInput { + and: [OptionValueFilterInput!] + or: [OptionValueFilterInput!] + not: [OptionValueFilterInput!] + id: OptionValueFilterId + value: OptionValueFilterValue + optionId: OptionValueFilterOptionId + variantId: OptionValueFilterVariantId + option: ProductOptionFilterInput + variant: VariantFilterInput +} + +input OptionValueSortInput { + order: SortOrder + field: OptionValueSortField! +} + +type OptionValue { + id: ID! + value: String! + optionId: ID + variantId: ID + option: ProductOption + variant: Variant +} + +enum ProductOptionSortField { + ID + NAME + DESCRIPTION + PRODUCT_ID +} + +input ProductOptionFilterProductId { + isNil: Boolean + eq: ID + notEq: ID + in: [ID] + lessThan: ID + greaterThan: ID + lessThanOrEqual: ID + greaterThanOrEqual: ID +} + +input ProductOptionFilterDescription { + isNil: Boolean + eq: String + notEq: String + in: [String] + lessThan: String + greaterThan: String + lessThanOrEqual: String + greaterThanOrEqual: String + like: String + ilike: String +} + +input ProductOptionFilterName { + isNil: Boolean + eq: String + notEq: String + in: [String!] + lessThan: String + greaterThan: String + lessThanOrEqual: String + greaterThanOrEqual: String + like: String + ilike: String +} + +input ProductOptionFilterId { + isNil: Boolean + eq: ID + notEq: ID + in: [ID!] + lessThan: ID + greaterThan: ID + lessThanOrEqual: ID + greaterThanOrEqual: ID +} + +input ProductOptionFilterInput { + and: [ProductOptionFilterInput!] + or: [ProductOptionFilterInput!] + not: [ProductOptionFilterInput!] + id: ProductOptionFilterId + name: ProductOptionFilterName + description: ProductOptionFilterDescription + productId: ProductOptionFilterProductId + product: ProductFilterInput + optionValues: OptionValueFilterInput + products: ProductFilterInput +} + +input ProductOptionSortInput { + order: SortOrder + field: ProductOptionSortField! +} + +type ProductOption { + id: ID! + name: String! + description: String + productId: ID + product: Product + optionValues( + "How to sort the records in the response" + sort: [OptionValueSortInput] + + "A filter to limit the results" + filter: OptionValueFilterInput + + "The number of records to return." + limit: Int + + "The number of records to skip." + offset: Int + ): [OptionValue!]! + products( + "How to sort the records in the response" + sort: [ProductSortInput] + + "A filter to limit the results" + filter: ProductFilterInput + + "The number of records to return." + limit: Int + + "The number of records to skip." + offset: Int + ): [Product!]! +} + +enum CollectionSortField { + ID + NAME + DESCRIPTION + IMAGE + IS_BRAND +} + +input CollectionFilterIsBrand { + isNil: Boolean + eq: Boolean + notEq: Boolean + in: [Boolean!] + lessThan: Boolean + greaterThan: Boolean + lessThanOrEqual: Boolean + greaterThanOrEqual: Boolean +} + +input CollectionFilterImage { + isNil: Boolean + eq: String + notEq: String + in: [String] + lessThan: String + greaterThan: String + lessThanOrEqual: String + greaterThanOrEqual: String + like: String + ilike: String +} + +input CollectionFilterDescription { + isNil: Boolean + eq: String + notEq: String + in: [String] + lessThan: String + greaterThan: String + lessThanOrEqual: String + greaterThanOrEqual: String + like: String + ilike: String +} + +input CollectionFilterName { + isNil: Boolean + eq: String + notEq: String + in: [String!] + lessThan: String + greaterThan: String + lessThanOrEqual: String + greaterThanOrEqual: String + like: String + ilike: String +} + +input CollectionFilterId { + isNil: Boolean + eq: ID + notEq: ID + in: [ID!] + lessThan: ID + greaterThan: ID + lessThanOrEqual: ID + greaterThanOrEqual: ID +} + +input CollectionFilterInput { + and: [CollectionFilterInput!] + or: [CollectionFilterInput!] + not: [CollectionFilterInput!] + id: CollectionFilterId + name: CollectionFilterName + description: CollectionFilterDescription + image: CollectionFilterImage + isBrand: CollectionFilterIsBrand +} + +input CollectionSortInput { + order: SortOrder + field: CollectionSortField! +} + +type Collection { + id: ID! + name: String! + description: String + image: String + isBrand: Boolean! +} + +enum VariantSortField { + ID + NAME + DESCRIPTION + SKU + PRODUCT_ID +} + +input VariantFilterProductId { + isNil: Boolean + eq: ID + notEq: ID + in: [ID] + lessThan: ID + greaterThan: ID + lessThanOrEqual: ID + greaterThanOrEqual: ID +} + +input VariantFilterSku { + isNil: Boolean + eq: String + notEq: String + in: [String!] + lessThan: String + greaterThan: String + lessThanOrEqual: String + greaterThanOrEqual: String + like: String + ilike: String +} + +input VariantFilterDescription { + isNil: Boolean + eq: String + notEq: String + in: [String] + lessThan: String + greaterThan: String + lessThanOrEqual: String + greaterThanOrEqual: String + like: String + ilike: String +} + +input VariantFilterName { + isNil: Boolean + eq: String + notEq: String + in: [String!] + lessThan: String + greaterThan: String + lessThanOrEqual: String + greaterThanOrEqual: String + like: String + ilike: String +} + +input VariantFilterId { + isNil: Boolean + eq: ID + notEq: ID + in: [ID!] + lessThan: ID + greaterThan: ID + lessThanOrEqual: ID + greaterThanOrEqual: ID +} + +input VariantFilterInput { + and: [VariantFilterInput!] + or: [VariantFilterInput!] + not: [VariantFilterInput!] + id: VariantFilterId + name: VariantFilterName + description: VariantFilterDescription + sku: VariantFilterSku + productId: VariantFilterProductId + prices: PriceFilterInput + product: ProductFilterInput + cartLines: CartLineFilterInput + optionValues: OptionValueFilterInput +} + +input VariantSortInput { + order: SortOrder + field: VariantSortField! +} + +type Variant { + id: ID! + + name: String! + + description: String + + sku: String! + + images: [String!] + + attributes: [Attributes!] + + discountRules: [Attributes!] + + "needed for identity" + optionValueIds: [String!] + + productId: ID + + prices( + "How to sort the records in the response" + sort: [PriceSortInput] + + "A filter to limit the results" + filter: PriceFilterInput + + "The number of records to return." + limit: Int + + "The number of records to skip." + offset: Int + ): [Price!]! + + product: Product + + cartLines( + "How to sort the records in the response" + sort: [CartLineSortInput] + + "A filter to limit the results" + filter: CartLineFilterInput + + "The number of records to return." + limit: Int + + "The number of records to skip." + offset: Int + ): [CartLine!]! + + optionValues( + "How to sort the records in the response" + sort: [OptionValueSortInput] + + "A filter to limit the results" + filter: OptionValueFilterInput + + "The number of records to return." + limit: Int + + "The number of records to skip." + offset: Int + ): [OptionValue!]! +} + +enum ProductSortField { + ID + NAME + DESCRIPTION + SKU + STATE + TYPE_ID +} + +input ProductFilterTypeId { + isNil: Boolean + eq: ID + notEq: ID + in: [ID] + lessThan: ID + greaterThan: ID + lessThanOrEqual: ID + greaterThanOrEqual: ID +} + +input ProductFilterState { + isNil: Boolean + eq: String + notEq: String + in: [String!] + lessThan: String + greaterThan: String + lessThanOrEqual: String + greaterThanOrEqual: String +} + +input ProductFilterSku { + isNil: Boolean + eq: String + notEq: String + in: [String!] + lessThan: String + greaterThan: String + lessThanOrEqual: String + greaterThanOrEqual: String + like: String + ilike: String +} + +input ProductFilterDescription { + isNil: Boolean + eq: String + notEq: String + in: [String!] + lessThan: String + greaterThan: String + lessThanOrEqual: String + greaterThanOrEqual: String + like: String + ilike: String +} + +input ProductFilterName { + isNil: Boolean + eq: String + notEq: String + in: [String!] + lessThan: String + greaterThan: String + lessThanOrEqual: String + greaterThanOrEqual: String + like: String + ilike: String +} + +input ProductFilterId { + isNil: Boolean + eq: ID + notEq: ID + in: [ID!] + lessThan: ID + greaterThan: ID + lessThanOrEqual: ID + greaterThanOrEqual: ID +} + +input ProductFilterInput { + and: [ProductFilterInput!] + or: [ProductFilterInput!] + not: [ProductFilterInput!] + id: ProductFilterId + name: ProductFilterName + description: ProductFilterDescription + sku: ProductFilterSku + state: ProductFilterState + typeId: ProductFilterTypeId + type: TypeFilterInput + prices: PriceFilterInput + collections: CollectionFilterInput + variants: VariantFilterInput + options: ProductOptionFilterInput +} + +input ProductSortInput { + order: SortOrder + field: ProductSortField! +} + +type Product { + id: ID! + name: String! + description: String! + sku: String! + state: String! + discountRules: [Attributes!] + typeId: ID + type: Type + prices( + "How to sort the records in the response" + sort: [PriceSortInput] + + "A filter to limit the results" + filter: PriceFilterInput + + "The number of records to return." + limit: Int + + "The number of records to skip." + offset: Int + ): [Price!]! + collections( + "How to sort the records in the response" + sort: [CollectionSortInput] + + "A filter to limit the results" + filter: CollectionFilterInput + + "The number of records to return." + limit: Int + + "The number of records to skip." + offset: Int + ): [Collection!]! + variants( + "How to sort the records in the response" + sort: [VariantSortInput] + + "A filter to limit the results" + filter: VariantFilterInput + + "The number of records to return." + limit: Int + + "The number of records to skip." + offset: Int + ): [Variant!]! + options( + "How to sort the records in the response" + sort: [ProductOptionSortInput] + + "A filter to limit the results" + filter: ProductOptionFilterInput + + "The number of records to return." + limit: Int + + "The number of records to skip." + offset: Int + ): [ProductOption!]! +} + +type RootQueryType { + """ + Hello! This is a sample query to verify that AshGraphql has been set up correctly. + Remove me once you have a query of your own! + """ + sayHello: String + + getProduct( + "The id of the record" + id: ID! + ): Product + + getAvailableProducts( + "How to sort the records in the response" + sort: [ProductSortInput] + + "A filter to limit the results" + filter: ProductFilterInput + ): [Product!]! + + searchAvailableProducts( + "How to sort the records in the response" + sort: [ProductSortInput] + + "A filter to limit the results" + filter: ProductFilterInput + + searchString: String + ): [Product!]! + + getVariant( + "The id of the record" + id: ID! + ): Variant + + getCollection( + "The id of the record" + id: ID! + ): Collection + + getBrand( + "The id of the record" + id: ID! + ): Brand + + getBranch( + "The id of the record" + id: ID! + ): Branch + + getDelivery( + "The id of the record" + id: ID! + ): Delivery +} + +type Money { + amount: Decimal! + currency: String! +} + +input MoneyInput { + amount: Decimal! + currency: String! +} + +type RootMutationType { + initDelivery(input: InitDeliveryInput!): InitDeliveryResult! + updateState(id: ID!, input: UpdateStateInput): UpdateStateResult! + updateLocation(id: ID!, input: UpdateLocationInput): UpdateLocationResult! +} + +""" +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. +""" +scalar JsonString + +""" +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. +""" +scalar Json + +""" +The `Date` scalar type represents a date. The Date appears in a JSON +response as an ISO8601 formatted string, without a time component. +""" +scalar Date + +""" +The `Decimal` scalar type represents signed double-precision fractional +values parsed by the `Decimal` library. The Decimal appears in a JSON +response as a string to preserve precision. +""" +scalar Decimal From f0842da8ca4f1ca7854039c2569eadf06d5fa6a9 Mon Sep 17 00:00:00 2001 From: rekkice Date: Sat, 15 Mar 2025 11:50:24 -0300 Subject: [PATCH 5/9] refactor: modify cart resource for graphql --- tololo/core/lib/carts/cart.ex | 47 +++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/tololo/core/lib/carts/cart.ex b/tololo/core/lib/carts/cart.ex index 4fde9544..1b60b35c 100644 --- a/tololo/core/lib/carts/cart.ex +++ b/tololo/core/lib/carts/cart.ex @@ -12,6 +12,16 @@ defmodule TololoCore.Carts.Cart do graphql do type :cart + + queries do + get :get_cart, :read + end + + mutations do + create :create_cart, :create + update :cart_add_variant, :add_variant + action :cart_checkout_delivery, :checkout_delivery + end end postgres do @@ -28,32 +38,44 @@ defmodule TololoCore.Carts.Cart do code_interface do define :create - define :add_variant, args: [:variant, {:optional, :quantity}, {:optional, :notes}] - define :checkout_delivery, args: [:cart, :delivery_input] + define :add_variant, args: [:variant_id, {:optional, :quantity}, {:optional, :notes}] + define :checkout_delivery, args: [:cart_id, :delivery_input] end actions do - defaults [:read, :destroy, create: :*, update: :*] + defaults [:read, :destroy, create: :currency, update: :*] action :checkout_delivery, :term do - argument :cart, :term, allow_nil?: false + argument :cart_id, :uuid, allow_nil?: false argument :delivery_input, :map, allow_nil?: false - run fn %{arguments: %{cart: cart, delivery_input: delivery_input}}, _ -> - TololoCore.Deliveries.Delivery.initialize( - %{delivery_input | delivery_order: cart_to_map(cart)}, + run fn %{arguments: %{cart_id: cart_id, delivery_input: delivery_input}}, _ -> + cart = + Ash.get!(TololoCore.Carts.Cart, cart_id, load: [cart_lines: [:variant]]) + + %{public_auth_key: public_auth_key} = TololoCore.Deliveries.Delivery.initialize!( + Map.merge(delivery_input, %{delivery_order: cart_to_map(cart)}), authorize?: false ) + + {:ok, public_auth_key} end end update :add_variant do require_atomic? false - argument :variant, :struct, allow_nil?: false + argument :variant_id, :uuid, allow_nil?: false argument :quantity, :integer, default: 1 - argument :notes, :string, default: nil + argument :notes, :string, default: "" + + change fn %{arguments: %{variant_id: variant_id}} = changeset, _context -> + variant = Ash.get!(TololoCore.Products.Variant, variant_id, load: [:prices]) + + changeset + |> Ash.Changeset.put_context(:variant, variant) + end - validate fn %{data: %{currency: currency}, arguments: %{variant: %{prices: prices}}} = + validate fn %{data: %{currency: currency}, context: %{variant: %{prices: prices}}} = changeset, _context -> prices = Ash.load!(prices, :currency, lazy?: true, reuse_values?: true) @@ -65,7 +87,10 @@ defmodule TololoCore.Carts.Cart do end end - change fn %{arguments: %{variant: variant, quantity: quantity, notes: notes}} = changeset, + change fn %{ + arguments: %{quantity: quantity, notes: notes}, + context: %{variant: variant} + } = changeset, _context -> changeset |> Ash.Changeset.manage_relationship( From 7018a6f9430d7e8dbe11650121af8269b3fa7215 Mon Sep 17 00:00:00 2001 From: rekkice Date: Sat, 15 Mar 2025 11:50:24 -0300 Subject: [PATCH 6/9] chore: add cart graphql query examples for bruno --- collections/carts/add variant to cart.bru | 45 ++++++++++++++++++++++ collections/carts/checkout cart.bru | 25 ++++++++++++ collections/carts/create cart.bru | 35 +++++++++++++++++ collections/carts/get cart.bru | 46 +++++++++++++++++++++++ tololo/priv/schema.graphql | 41 ++++++++++++++++++++ 5 files changed, 192 insertions(+) create mode 100644 collections/carts/add variant to cart.bru create mode 100644 collections/carts/checkout cart.bru create mode 100644 collections/carts/create cart.bru create mode 100644 collections/carts/get cart.bru diff --git a/collections/carts/add variant to cart.bru b/collections/carts/add variant to cart.bru new file mode 100644 index 00000000..683cb3c7 --- /dev/null +++ b/collections/carts/add variant to cart.bru @@ -0,0 +1,45 @@ +meta { + name: add variant to cart + type: graphql + seq: 2 +} + +post { + url: {{gql_host}}:{{gql_port}}/gql + body: graphql + auth: none +} + +body:graphql { + mutation AddVariantToCart($cartId: ID!, $variantId: ID!, $quantity: Int) { + cartAddVariant(id: $cartId, input: { variantId: $variantId, quantity: $quantity }) { + result { + id + status + cartLines { + id + quantity + notes + variant { + id + name + } + } + } + errors { + message + code + } + } + } + +} + +body:graphql:vars { + { + "cartId": "01959b14-4377-7992-b534-a0f423985773", + "variantId": "019581b4-ff21-75e5-82aa-f41762d61e77", + "quantity": 2 + } + +} diff --git a/collections/carts/checkout cart.bru b/collections/carts/checkout cart.bru new file mode 100644 index 00000000..4243cd9d --- /dev/null +++ b/collections/carts/checkout cart.bru @@ -0,0 +1,25 @@ +meta { + name: checkout cart + type: graphql + seq: 4 +} + +post { + url: {{gql_host}}:{{gql_port}}/gql + body: graphql + auth: none +} + +body:graphql { + mutation CartCheckoutDelivery($cartId: ID!, $deliveryInput: JsonString!) { + cartCheckoutDelivery(input: { cartId: $cartId, deliveryInput: $deliveryInput }) + } + +} + +body:graphql:vars { + { + "cartId": "01959b14-4377-7992-b534-a0f423985773", + "deliveryInput": "{\"delivery_person\": {}, \"delivery_order\": {}, \"to_name\": \"to_name\", \"to_latitude\": -33.447001713606156, \"to_longitude\": -70.65619123826207, \"to_address\": \"to_address\", \"to_phone\": \"to_phone\", \"to_notes\": \"to_notes\"}" + } +} diff --git a/collections/carts/create cart.bru b/collections/carts/create cart.bru new file mode 100644 index 00000000..e6ae5078 --- /dev/null +++ b/collections/carts/create cart.bru @@ -0,0 +1,35 @@ +meta { + name: create cart + type: graphql + seq: 3 +} + +post { + url: {{gql_host}}:{{gql_port}}/gql + body: graphql + auth: none +} + +body:graphql { + mutation CreateCart($currency: String) { + createCart(input: { currency: $currency }) { + result { + id + status + currency + } + errors { + message + code + } + } + } + +} + +body:graphql:vars { + { + "currency": "CLP" + } + +} diff --git a/collections/carts/get cart.bru b/collections/carts/get cart.bru new file mode 100644 index 00000000..e8a9997a --- /dev/null +++ b/collections/carts/get cart.bru @@ -0,0 +1,46 @@ +meta { + name: get cart + type: graphql + seq: 1 +} + +post { + url: {{gql_host}}:{{gql_port}}/gql + body: graphql + auth: none +} + +body:graphql { + query GetCart($id: ID!) { + getCart(id: $id) { + id + status + currency + cartLines { + id + quantity + notes + variant { + id + name + sku + prices { + id + money { + amount + currency + } + } + } + } + } + } + +} + +body:graphql:vars { + { + "id": "01959a22-b124-749b-b57e-6e48c6ccf8bd" + } + +} diff --git a/tololo/priv/schema.graphql b/tololo/priv/schema.graphql index 133513b2..3ad7f29a 100644 --- a/tololo/priv/schema.graphql +++ b/tololo/priv/schema.graphql @@ -294,6 +294,39 @@ type CartLine { cart: Cart! } +input CartCheckoutDeliveryInput { + cartId: ID! + deliveryInput: JsonString! +} + +"The result of the :cart_add_variant mutation" +type CartAddVariantResult { + "The successful result of the mutation" + result: Cart + + "Any errors generated, if the mutation failed" + errors: [MutationError!]! +} + +input CartAddVariantInput { + variantId: ID! + quantity: Int + notes: String +} + +"The result of the :create_cart mutation" +type CreateCartResult { + "The successful result of the mutation" + result: Cart + + "Any errors generated, if the mutation failed" + errors: [MutationError!]! +} + +input CreateCartInput { + currency: String +} + input CartFilterCurrency { isNil: Boolean eq: String @@ -1153,6 +1186,11 @@ type RootQueryType { id: ID! ): Branch + getCart( + "The id of the record" + id: ID! + ): Cart + getDelivery( "The id of the record" id: ID! @@ -1170,6 +1208,9 @@ input MoneyInput { } type RootMutationType { + createCart(input: CreateCartInput): CreateCartResult! + cartAddVariant(id: ID!, input: CartAddVariantInput!): CartAddVariantResult! + cartCheckoutDelivery(input: CartCheckoutDeliveryInput): String! initDelivery(input: InitDeliveryInput!): InitDeliveryResult! updateState(id: ID!, input: UpdateStateInput): UpdateStateResult! updateLocation(id: ID!, input: UpdateLocationInput): UpdateLocationResult! From cd75d5602e61cc85f3c0a690b986cc986d6d8354 Mon Sep 17 00:00:00 2001 From: rekkice Date: Sat, 15 Mar 2025 11:50:24 -0300 Subject: [PATCH 7/9] test: add tests for carts and products --- tololo/test/tololo/carts/cart_test.exs | 65 ++++++++++++++ tololo/test/tololo/products/product_test.exs | 89 ++++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 tololo/test/tololo/carts/cart_test.exs create mode 100644 tololo/test/tololo/products/product_test.exs diff --git a/tololo/test/tololo/carts/cart_test.exs b/tololo/test/tololo/carts/cart_test.exs new file mode 100644 index 00000000..9372abde --- /dev/null +++ b/tololo/test/tololo/carts/cart_test.exs @@ -0,0 +1,65 @@ +defmodule CartTest do + use Tololo.DataCase, async: true + + alias TololoCore.Carts.Cart + alias TololoCore.Products.{Product, Option} + + setup do + product = + Product.create!( + %{ + name: "Test Product", + description: "Description", + state: :enabled, + sku: "TEST_SKU", + discount_rules: [] + }, + authorize?: false + ) + |> Product.update_price!(%{amount: 1000, currency: :CLP}, authorize?: false) + + option = Product.get_or_create_option!(product, "Color", authorize?: false) + Option.add_value!(option, "Red", authorize?: false) + + product = + product + |> Ash.load!(options: [:option_values]) + |> Product.generate_variants!(authorize?: false) + |> Ash.load!(variants: [:prices]) + + variant = hd(product.variants) + + {:ok, product: product, variant: variant} + end + + describe "cart operations" do + test "adds variant to cart", %{variant: variant} do + cart = Cart.create!() + %{cart_lines: [line]} = Cart.add_variant!(cart, variant.id, 2, "Handle with care") + + assert line.quantity == 2 + assert line.notes == "Handle with care" + end + + test "performs checkout with delivery", %{variant: variant} do + cart = Cart.create!() + |> Cart.add_variant!(variant.id, 1, "") + + delivery_public_token = + Cart.checkout_delivery!( + cart.id, + %{ + to_name: "Nombre", + to_address: "123", + to_phone: "12345678", + to_latitude: 40.7128, + to_longitude: -74.0060, + delivery_person: %{}, + delivery_order: %{} + } + ) + assert TololoCore.Deliveries.Delivery.get_via_token(delivery_public_token) + end + end +end + diff --git a/tololo/test/tololo/products/product_test.exs b/tololo/test/tololo/products/product_test.exs new file mode 100644 index 00000000..b923ba2c --- /dev/null +++ b/tololo/test/tololo/products/product_test.exs @@ -0,0 +1,89 @@ +defmodule ProductTest do + use Tololo.DataCase, async: true + + alias TololoCore.Products.{Product, Option, Collection, Type} + + describe "product lifecycle" do + test "creates product with discount rules and prices" do + product = + Product.create!( + %{ + name: "Test Product", + description: "Test Description", + state: :enabled, + sku: "TEST_SKU", + discount_rules: [ + %{discount: 50000, method: :fixed} + ] + }, + authorize?: false + ) + + assert product.name == "Test Product" + assert [%{method: :fixed}] = product.discount_rules + + product = Product.update_price!(product, %{amount: 20, currency: :USD}, authorize?: false) + product = Product.update_price!(product, %{amount: 20000, currency: :CLP}, authorize?: false) + + assert Enum.count(product.prices) == 2 + end + end + + describe "product variants" do + setup do + product = + Product.create!( + %{ + name: "Test Product", + description: "Description", + state: :enabled, + sku: "TEST_SKU", + }, + authorize?: false + ) + |> Product.update_price!(%{amount: 100, currency: :USD}, authorize?: false) + + {:ok, product: product} + end + + test "generates variants from options", %{product: product} do + option1 = Product.get_or_create_option!(product, "Color", authorize?: false) + option2 = Product.get_or_create_option!(product, "Size", authorize?: false) + + Enum.reduce(["Red", "Blue"], option1, fn val, acc -> + Option.add_value!(acc, val, authorize?: false) + end) + + Enum.reduce(["S", "M"], option2, fn val, acc -> + Option.add_value!(acc, val, authorize?: false) + end) + + product = Product.generate_variants!(product, authorize?: false) + + assert length(product.variants) == 4 + end + end + + describe "collections" do + test "adds product to collection" do + product = Product.create!(%{ + name: "Test Product", + description: "Description", + state: :enabled, + sku: "TEST_SKU", + }, authorize?: false) + %{id: collection_id} = Collection.create!(%{name: "Featured"}, authorize?: false) + + updated_product = Product.add_to_collection!(product, collection_id, authorize?: false) + assert [%{id: ^collection_id}] = updated_product.collections + end + end + + describe "product types" do + test "creates new product type" do + {:ok, type} = Ash.create(Type, %{name: "Electronics"}, authorize?: false) + assert type.name == "Electronics" + end + end +end + From b37c167770b852d5424e6e7b6252d29174dab2d2 Mon Sep 17 00:00:00 2001 From: rekkice Date: Sat, 22 Mar 2025 19:27:08 -0300 Subject: [PATCH 8/9] chore: change graphql query of branch and brand resources --- tololo/core/lib/brands/branch.ex | 2 +- tololo/core/lib/brands/brand.ex | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tololo/core/lib/brands/branch.ex b/tololo/core/lib/brands/branch.ex index 016b4836..3905147c 100644 --- a/tololo/core/lib/brands/branch.ex +++ b/tololo/core/lib/brands/branch.ex @@ -18,7 +18,7 @@ defmodule TololoCore.Brands.Branch do type :branch queries do - get :get_branch, :read + read_one :get_branch, :read end mutations do diff --git a/tololo/core/lib/brands/brand.ex b/tololo/core/lib/brands/brand.ex index f5934e9d..7e77c312 100644 --- a/tololo/core/lib/brands/brand.ex +++ b/tololo/core/lib/brands/brand.ex @@ -18,7 +18,7 @@ defmodule TololoCore.Brands.Brand do type :brand queries do - get :get_brand, :read + read_one :get_brand, :read end mutations do From 25828cbf8947afe35ba441c78f6824d392ffee7a Mon Sep 17 00:00:00 2001 From: rekkice Date: Sat, 22 Mar 2025 19:27:08 -0300 Subject: [PATCH 9/9] chore: add brand and branch graphql query examples for bruno --- collections/brands/get branch.bru | 23 ++++ collections/brands/get brand.bru | 20 +++ tololo/priv/schema.graphql | 124 ++++++++++++++++++- tololo/test/tololo/products/product_test.exs | 4 +- 4 files changed, 165 insertions(+), 6 deletions(-) create mode 100644 collections/brands/get branch.bru create mode 100644 collections/brands/get brand.bru diff --git a/collections/brands/get branch.bru b/collections/brands/get branch.bru new file mode 100644 index 00000000..22a617a7 --- /dev/null +++ b/collections/brands/get branch.bru @@ -0,0 +1,23 @@ +meta { + name: get branch + type: graphql + seq: 2 +} + +post { + url: {{gql_host}}:{{gql_port}}/gql + body: graphql + auth: none +} + +body:graphql { + query GetBranch { + getBranch { + name + address + latitude + longitude + } + } + +} diff --git a/collections/brands/get brand.bru b/collections/brands/get brand.bru new file mode 100644 index 00000000..fa03d8d3 --- /dev/null +++ b/collections/brands/get brand.bru @@ -0,0 +1,20 @@ +meta { + name: get brand + type: graphql + seq: 1 +} + +post { + url: {{gql_host}}:{{gql_port}}/gql + body: graphql + auth: none +} + +body:graphql { + query GetBrand { + getBrand { + name + } + } + +} diff --git a/tololo/priv/schema.graphql b/tololo/priv/schema.graphql index 3ad7f29a..263c955e 100644 --- a/tololo/priv/schema.graphql +++ b/tololo/priv/schema.graphql @@ -391,6 +391,89 @@ type Cart { ): [CartLine!]! } +input BranchFilterBrandId { + isNil: Boolean + eq: ID + notEq: ID + in: [ID] + lessThan: ID + greaterThan: ID + lessThanOrEqual: ID + greaterThanOrEqual: ID +} + +input BranchFilterLongitude { + isNil: Boolean + eq: Float + notEq: Float + in: [Float!] + lessThan: Float + greaterThan: Float + lessThanOrEqual: Float + greaterThanOrEqual: Float +} + +input BranchFilterLatitude { + isNil: Boolean + eq: Float + notEq: Float + in: [Float!] + lessThan: Float + greaterThan: Float + lessThanOrEqual: Float + greaterThanOrEqual: Float +} + +input BranchFilterAddress { + isNil: Boolean + eq: String + notEq: String + in: [String!] + lessThan: String + greaterThan: String + lessThanOrEqual: String + greaterThanOrEqual: String + like: String + ilike: String +} + +input BranchFilterName { + isNil: Boolean + eq: String + notEq: String + in: [String!] + lessThan: String + greaterThan: String + lessThanOrEqual: String + greaterThanOrEqual: String + like: String + ilike: String +} + +input BranchFilterId { + isNil: Boolean + eq: ID + notEq: ID + in: [ID!] + lessThan: ID + greaterThan: ID + lessThanOrEqual: ID + greaterThanOrEqual: ID +} + +input BranchFilterInput { + and: [BranchFilterInput!] + or: [BranchFilterInput!] + not: [BranchFilterInput!] + id: BranchFilterId + name: BranchFilterName + address: BranchFilterAddress + latitude: BranchFilterLatitude + longitude: BranchFilterLongitude + brandId: BranchFilterBrandId + brand: BrandFilterInput +} + type Branch { id: ID! name: String! @@ -401,6 +484,39 @@ type Branch { brand: Brand } +input BrandFilterName { + isNil: Boolean + eq: String + notEq: String + in: [String!] + lessThan: String + greaterThan: String + lessThanOrEqual: String + greaterThanOrEqual: String + like: String + ilike: String +} + +input BrandFilterId { + isNil: Boolean + eq: ID + notEq: ID + in: [ID!] + lessThan: ID + greaterThan: ID + lessThanOrEqual: ID + greaterThanOrEqual: ID +} + +input BrandFilterInput { + and: [BrandFilterInput!] + or: [BrandFilterInput!] + not: [BrandFilterInput!] + id: BrandFilterId + name: BrandFilterName + branch: BranchFilterInput +} + type Brand { id: ID! name: String! @@ -1177,13 +1293,13 @@ type RootQueryType { ): Collection getBrand( - "The id of the record" - id: ID! + "A filter to limit the results" + filter: BrandFilterInput ): Brand getBranch( - "The id of the record" - id: ID! + "A filter to limit the results" + filter: BranchFilterInput ): Branch getCart( diff --git a/tololo/test/tololo/products/product_test.exs b/tololo/test/tololo/products/product_test.exs index b923ba2c..cd6698aa 100644 --- a/tololo/test/tololo/products/product_test.exs +++ b/tololo/test/tololo/products/product_test.exs @@ -13,7 +13,7 @@ defmodule ProductTest do state: :enabled, sku: "TEST_SKU", discount_rules: [ - %{discount: 50000, method: :fixed} + %{discount: 50_000, method: :fixed} ] }, authorize?: false @@ -23,7 +23,7 @@ defmodule ProductTest do assert [%{method: :fixed}] = product.discount_rules product = Product.update_price!(product, %{amount: 20, currency: :USD}, authorize?: false) - product = Product.update_price!(product, %{amount: 20000, currency: :CLP}, authorize?: false) + product = Product.update_price!(product, %{amount: 20_000, currency: :CLP}, authorize?: false) assert Enum.count(product.prices) == 2 end