mirror of
https://github.com/wanderer-industries/wanderer
synced 2025-11-02 07:27:04 +00:00
Compare commits
2 Commits
v1.75.0
...
audit-pagi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cee545cfd9 | ||
|
|
9612cda72b |
@@ -75,6 +75,17 @@ config :phoenix_ddos,
|
||||
request_paths: ["/auth/eve"], allowed: 20, period: {1, :minute}}
|
||||
]
|
||||
|
||||
config :ash_pagify,
|
||||
default_limit: 50,
|
||||
max_limit: 1000,
|
||||
scopes: %{
|
||||
role: []
|
||||
},
|
||||
reset_on_filter?: true,
|
||||
replace_invalid_params?: true,
|
||||
pagination: [opts: {WandererAppWeb.CoreComponents, :pagination_opts}],
|
||||
table: [opts: {WandererAppWeb.CoreComponents, :table_opts}]
|
||||
|
||||
# Configures Elixir's Logger
|
||||
config :logger, :console,
|
||||
format: "$time $metadata[$level] $message\n",
|
||||
|
||||
11
lib/wanderer_app/api/preparations/load_character.ex
Normal file
11
lib/wanderer_app/api/preparations/load_character.ex
Normal file
@@ -0,0 +1,11 @@
|
||||
defmodule WandererApp.Api.Preparations.LoadCharacter do
|
||||
@moduledoc false
|
||||
|
||||
use Ash.Resource.Preparation
|
||||
require Ash.Query
|
||||
|
||||
def prepare(query, _params, _) do
|
||||
query
|
||||
|> Ash.Query.load([:character])
|
||||
end
|
||||
end
|
||||
@@ -5,6 +5,16 @@ defmodule WandererApp.Api.UserActivity do
|
||||
domain: WandererApp.Api,
|
||||
data_layer: AshPostgres.DataLayer
|
||||
|
||||
require Ash.Expr
|
||||
|
||||
@ash_pagify_options %{
|
||||
default_limit: 15,
|
||||
scopes: %{
|
||||
role: []
|
||||
}
|
||||
}
|
||||
def ash_pagify_options, do: @ash_pagify_options
|
||||
|
||||
postgres do
|
||||
repo(WandererApp.Repo)
|
||||
table("user_activity_v1")
|
||||
@@ -31,7 +41,13 @@ defmodule WandererApp.Api.UserActivity do
|
||||
|
||||
read :read do
|
||||
primary?(true)
|
||||
pagination(offset?: true, keyset?: true)
|
||||
|
||||
pagination offset?: true,
|
||||
default_limit: @ash_pagify_options.default_limit,
|
||||
countable: true,
|
||||
required?: false
|
||||
|
||||
prepare WandererApp.Api.Preparations.LoadCharacter
|
||||
end
|
||||
|
||||
create :new do
|
||||
|
||||
@@ -39,7 +39,7 @@ defmodule WandererApp.Map.Audit do
|
||||
:ok
|
||||
end
|
||||
|
||||
def get_activity_page(map_id, page, per_page, period, activity) do
|
||||
def get_activity_query(map_id, period, activity) do
|
||||
{from, to} = period |> get_period()
|
||||
|
||||
query =
|
||||
@@ -65,10 +65,6 @@ defmodule WandererApp.Map.Audit do
|
||||
|
||||
query
|
||||
|> Ash.Query.sort(inserted_at: :desc)
|
||||
|> WandererApp.Api.read(
|
||||
page: [limit: per_page, offset: (page - 1) * per_page],
|
||||
load: [:character]
|
||||
)
|
||||
end
|
||||
|
||||
def track_acl_event(
|
||||
|
||||
1318
lib/wanderer_app_web/components/components.ex
Normal file
1318
lib/wanderer_app_web/components/components.ex
Normal file
File diff suppressed because it is too large
Load Diff
@@ -951,4 +951,64 @@ defmodule WandererAppWeb.CoreComponents do
|
||||
when is_binary(eve_alliance_id) or is_integer(eve_alliance_id) do
|
||||
"#{@image_base_url}/alliances/#{eve_alliance_id}/logo?size=32"
|
||||
end
|
||||
|
||||
def pagination_opts do
|
||||
[
|
||||
ellipsis_attrs: [class: "ellipsis"],
|
||||
ellipsis_content: "‥",
|
||||
next_link_content: next_icon(),
|
||||
page_links: {:ellipsis, 7},
|
||||
previous_link_content: previous_icon(),
|
||||
current_link_attrs: [
|
||||
class:
|
||||
"relative z-10 inline-flex items-center bg-indigo-600 px-4 py-2 text-sm font-semibold text-white focus:z-20 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600",
|
||||
aria: [current: "page"]
|
||||
],
|
||||
next_link_attrs: [
|
||||
aria: [label: "Go to next page"],
|
||||
class: ""
|
||||
],
|
||||
pagination_link_attrs: [
|
||||
class:
|
||||
"relative z-10 inline-flex items-center px-4 py-2 text-sm font-semibold text-white focus:z-20 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
|
||||
],
|
||||
previous_link_attrs: [
|
||||
aria: [label: "Go to previous page"],
|
||||
class: ""
|
||||
]
|
||||
]
|
||||
end
|
||||
|
||||
defp next_icon do
|
||||
assigns = %{}
|
||||
|
||||
~H"""
|
||||
<.icon name="hero-chevron-right" class="h-5 w-5" />
|
||||
"""
|
||||
end
|
||||
|
||||
defp previous_icon do
|
||||
assigns = %{}
|
||||
|
||||
~H"""
|
||||
<.icon name="hero-chevron-left" class="h-5 w-5" />
|
||||
"""
|
||||
end
|
||||
|
||||
def table_opts do
|
||||
[
|
||||
container: true,
|
||||
container_attrs: [class: "table-container"],
|
||||
no_results_content: no_results_content(),
|
||||
table_attrs: [class: "table"]
|
||||
]
|
||||
end
|
||||
|
||||
defp no_results_content do
|
||||
assigns = %{}
|
||||
|
||||
~H"""
|
||||
<p>Nothing found.</p>
|
||||
"""
|
||||
end
|
||||
end
|
||||
|
||||
115
lib/wanderer_app_web/components/pagination.ex
Normal file
115
lib/wanderer_app_web/components/pagination.ex
Normal file
@@ -0,0 +1,115 @@
|
||||
defmodule WandererAppWeb.Components.Pagination do
|
||||
@moduledoc """
|
||||
Pagination component for AshPagify.
|
||||
"""
|
||||
|
||||
alias WandererAppWeb.Components
|
||||
alias AshPagify.Meta
|
||||
alias AshPagify.Misc
|
||||
|
||||
@spec default_opts() :: [Components.pagination_option()]
|
||||
def default_opts do
|
||||
[
|
||||
current_link_attrs: [
|
||||
class: "pagination-link is-current",
|
||||
aria: [current: "page"]
|
||||
],
|
||||
disabled_class: "disabled",
|
||||
ellipsis_attrs: [class: "pagination-ellipsis"],
|
||||
ellipsis_content: Phoenix.HTML.raw("…"),
|
||||
next_link_attrs: [
|
||||
aria: [label: "Go to next page"],
|
||||
class: "pagination-next"
|
||||
],
|
||||
next_link_content: "Next",
|
||||
page_links: :all,
|
||||
pagination_link_aria_label: &"Go to page #{&1}",
|
||||
pagination_link_attrs: [class: "pagination-link"],
|
||||
previous_link_attrs: [
|
||||
aria: [label: "Go to previous page"],
|
||||
class: "pagination-previous"
|
||||
],
|
||||
previous_link_content: "Previous",
|
||||
wrapper_attrs: [
|
||||
class: "pagination",
|
||||
role: "navigation",
|
||||
aria: [label: "pagination"]
|
||||
]
|
||||
]
|
||||
end
|
||||
|
||||
def merge_opts(opts) do
|
||||
default_opts()
|
||||
|> Misc.list_merge(Misc.global_option(:pagination) || [])
|
||||
|> Misc.list_merge(opts)
|
||||
end
|
||||
|
||||
def max_pages(:all, total_pages), do: total_pages
|
||||
def max_pages(:hide, _), do: 0
|
||||
def max_pages({:ellipsis, max_pages}, _), do: max_pages
|
||||
|
||||
def show_pagination(nil), do: false
|
||||
|
||||
def show_pagination?(%Meta{errors: [], total_pages: total_pages}) do
|
||||
total_pages > 1
|
||||
end
|
||||
|
||||
def show_pagination?(_), do: false
|
||||
|
||||
def get_page_link_range(current_page, max_pages, total_pages) do
|
||||
# number of additional pages to show before or after current page
|
||||
additional = ceil(max_pages / 2)
|
||||
|
||||
cond do
|
||||
max_pages >= total_pages ->
|
||||
1..total_pages
|
||||
|
||||
current_page + additional > total_pages ->
|
||||
(total_pages - max_pages + 1)..total_pages
|
||||
|
||||
true ->
|
||||
first = max(current_page - additional + 1, 1)
|
||||
last = min(first + max_pages - 1, total_pages)
|
||||
first..last
|
||||
end
|
||||
end
|
||||
|
||||
@spec build_page_link_helper(Meta.t(), Components.pagination_path()) ::
|
||||
(integer() -> String.t() | nil)
|
||||
def build_page_link_helper(_meta, nil), do: fn _offset -> nil end
|
||||
|
||||
def build_page_link_helper(%Meta{} = meta, path) do
|
||||
query_params = build_query_params(meta)
|
||||
|
||||
fn offset ->
|
||||
params = maybe_put_offset(query_params, offset)
|
||||
Components.build_path(path, params)
|
||||
end
|
||||
end
|
||||
|
||||
defp build_query_params(%Meta{} = meta) do
|
||||
Components.to_query(meta.ash_pagify, for: meta.resource, default_scopes: meta.default_scopes)
|
||||
end
|
||||
|
||||
defp maybe_put_offset(params, 0), do: Keyword.delete(params, :offset)
|
||||
defp maybe_put_offset(params, offset), do: Keyword.put(params, :offset, offset)
|
||||
|
||||
def attrs_for_page_link(page, %{current_page: page}, opts) do
|
||||
add_page_link_aria_label(opts[:current_link_attrs], page, opts)
|
||||
end
|
||||
|
||||
def attrs_for_page_link(page, _meta, opts) do
|
||||
add_page_link_aria_label(opts[:pagination_link_attrs], page, opts)
|
||||
end
|
||||
|
||||
defp add_page_link_aria_label(attrs, page, opts) do
|
||||
aria_label = opts[:pagination_link_aria_label].(page)
|
||||
|
||||
Keyword.update(
|
||||
attrs,
|
||||
:aria,
|
||||
[label: aria_label],
|
||||
&Keyword.put(&1, :label, aria_label)
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -25,31 +25,11 @@ defmodule WandererAppWeb.UserActivity do
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<div id={@id}>
|
||||
<span
|
||||
:if={@page > 1}
|
||||
class="text-1xl fixed bottom-10 right-10 bg-zinc-700 text-white rounded-lg p-1 text-center min-w-[65px] z-50 opacity-70"
|
||||
>
|
||||
<%= @page %>
|
||||
</span>
|
||||
<ul
|
||||
id="events"
|
||||
class="space-y-4"
|
||||
phx-update="stream"
|
||||
phx-viewport-top={@page > 1 && "prev-page"}
|
||||
phx-viewport-bottom={!@end_of_stream? && "next-page"}
|
||||
phx-page-loading
|
||||
class={[
|
||||
if(@end_of_stream?, do: "pb-10", else: "pb-[calc(200vh)]"),
|
||||
if(@page == 1, do: "pt-10", else: "pt-[calc(200vh)]")
|
||||
]}
|
||||
>
|
||||
<ul id="events" class="space-y-4" phx-update="stream" phx-page-loading class={["pt-10"]}>
|
||||
<li :for={{dom_id, activity} <- @stream} id={dom_id}>
|
||||
<.activity_entry activity={activity} can_undo_types={@can_undo_types} />
|
||||
</li>
|
||||
</ul>
|
||||
<div :if={@end_of_stream?} class="mt-5 text-center">
|
||||
No more activity
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
@@ -52,7 +52,7 @@ defmodule WandererAppWeb.MapAuditLive do
|
||||
|
||||
@impl true
|
||||
def handle_params(params, _url, socket) do
|
||||
{:noreply, apply_action(socket, socket.assigns.live_action, params)}
|
||||
apply_action(socket, socket.assigns.live_action, params)
|
||||
end
|
||||
|
||||
@impl true
|
||||
@@ -83,26 +83,6 @@ defmodule WandererAppWeb.MapAuditLive do
|
||||
|> push_navigate(to: ~p"/#{map_slug}/audit?period=#{period}&activity=#{activity}")}
|
||||
end
|
||||
|
||||
def handle_event("top", _, socket) do
|
||||
{:noreply, socket |> load_activity(1)}
|
||||
end
|
||||
|
||||
def handle_event("next-page", _, socket) do
|
||||
{:noreply, load_activity(socket, socket.assigns.page + 1)}
|
||||
end
|
||||
|
||||
def handle_event("prev-page", %{"_overran" => true}, socket) do
|
||||
{:noreply, load_activity(socket, 1)}
|
||||
end
|
||||
|
||||
def handle_event("prev-page", _, socket) do
|
||||
if socket.assigns.page > 1 do
|
||||
{:noreply, load_activity(socket, socket.assigns.page - 1)}
|
||||
else
|
||||
{:noreply, socket}
|
||||
end
|
||||
end
|
||||
|
||||
def handle_event(
|
||||
"undo",
|
||||
%{"event-data" => event_data, "event-type" => "systems_removed"},
|
||||
@@ -138,7 +118,7 @@ defmodule WandererAppWeb.MapAuditLive do
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
defp apply_action(socket, :index, _params) do
|
||||
defp apply_action(socket, :index, params) do
|
||||
socket
|
||||
|> assign(:active_page, :audit)
|
||||
|> assign(:page_title, "Map - Audit")
|
||||
@@ -158,45 +138,29 @@ defmodule WandererAppWeb.MapAuditLive do
|
||||
{"Signatures Added", :signatures_added},
|
||||
{"Signatures Removed", :signatures_removed}
|
||||
])
|
||||
|> load_activity(1)
|
||||
|> list_activity(params)
|
||||
end
|
||||
|
||||
defp load_activity(socket, new_page) when new_page >= 1 do
|
||||
defp list_activity(socket, params, opts \\ []) do
|
||||
%{
|
||||
activity: activity,
|
||||
per_page: per_page,
|
||||
page: cur_page,
|
||||
map_id: map_id,
|
||||
map_slug: map_slug,
|
||||
map_subscription_active: map_subscription_active,
|
||||
period: period
|
||||
} =
|
||||
socket.assigns
|
||||
|
||||
period = get_valid_period(period, map_subscription_active)
|
||||
query = WandererApp.Map.Audit.get_activity_query(map_id, period, activity)
|
||||
|
||||
with {:ok, page} <-
|
||||
WandererApp.Map.Audit.get_activity_page(map_id, new_page, per_page, period, activity) do
|
||||
{activity, at, limit} =
|
||||
if new_page >= cur_page do
|
||||
{page.results, -1, per_page * 3 * -1}
|
||||
else
|
||||
{Enum.reverse(page.results), 0, per_page * 3}
|
||||
end
|
||||
AshPagify.validate_and_run(query, params, opts)
|
||||
|> case do
|
||||
{:ok, {activity, meta}} ->
|
||||
{:noreply, socket |> assign(:meta, meta) |> stream(:activity, activity, reset: true)}
|
||||
|
||||
case activity do
|
||||
[] ->
|
||||
socket
|
||||
|> assign(end_of_stream?: at == -1)
|
||||
|> stream(:activity, [])
|
||||
|
||||
[_ | _] = _ ->
|
||||
socket
|
||||
|> assign(end_of_stream?: false)
|
||||
|> assign(page: if(activity == [], do: cur_page, else: new_page))
|
||||
|> stream(:activity, activity, at: at, limit: limit)
|
||||
end
|
||||
else
|
||||
_ -> socket
|
||||
{:error, meta} ->
|
||||
valid_path = AshPagify.Components.build_path(~p"/#{map_slug}/audit", meta.params)
|
||||
{:noreply, socket |> push_navigate(to: valid_path)}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -101,6 +101,10 @@
|
||||
class="pt-20 w-full h-full col-span-2 lg:col-span-1 p-4 pl-20 pb-20 overflow-auto"
|
||||
>
|
||||
<div class="flex flex-col gap-4 w-full">
|
||||
<div class="flex justify-between w-full">
|
||||
<div />
|
||||
<WandererAppWeb.Components.pagination meta={@meta} path={~p"/#{@map_slug}/audit?period=#{@period}&activity=#{@activity}"} />
|
||||
</div>
|
||||
<.live_component
|
||||
module={UserActivity}
|
||||
id="user-activity"
|
||||
@@ -111,5 +115,10 @@
|
||||
end_of_stream?={@end_of_stream?}
|
||||
event_name="activity_event"
|
||||
/>
|
||||
|
||||
<div class="flex justify-between w-full">
|
||||
<div />
|
||||
<WandererAppWeb.Components.pagination meta={@meta} path={~p"/#{@map_slug}/audit?period=#{@period}&activity=#{@activity}"} />
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
5
mix.exs
5
mix.exs
@@ -50,7 +50,7 @@ defmodule WandererApp.MixProject do
|
||||
{:credo, "~> 1.7", only: [:dev, :test], runtime: false},
|
||||
{:dialyxir, ">= 0.0.0", only: [:dev], runtime: false},
|
||||
{:doctor, ">= 0.0.0", only: [:dev], runtime: false},
|
||||
{:ex_doc, ">= 0.0.0", only: [:dev], runtime: false},
|
||||
{:ex_doc, "~> 0.37", runtime: false},
|
||||
{:sobelow, ">= 0.0.0", only: [:dev], runtime: false},
|
||||
{:mix_audit, ">= 0.0.0", only: [:dev], runtime: false},
|
||||
{:ex_check, "~> 0.14.0", only: [:dev], runtime: false},
|
||||
@@ -117,7 +117,8 @@ defmodule WandererApp.MixProject do
|
||||
{:version_tasks, "~> 0.12.0"},
|
||||
{:error_tracker, "~> 0.2"},
|
||||
{:ddrt, "~> 0.2.1"},
|
||||
{:live_view_events, "~> 0.1.0"}
|
||||
{:live_view_events, "~> 0.1.0"},
|
||||
{:ash_pagify, "~> 1.4.1"}
|
||||
]
|
||||
end
|
||||
|
||||
|
||||
5
mix.lock
5
mix.lock
@@ -1,6 +1,7 @@
|
||||
%{
|
||||
"ash": {:hex, :ash, "3.4.15", "0b8a0ae9bc543267380ffdacfeb1bc8d1bc831c1acb58b923ac0285464d5badd", [: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.3.36 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: false]}, {: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", [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", "3647184d23c40a8d4d381c3616b5c5c783d4d2e969918b6fd36aa171fede9cfa"},
|
||||
"ash_cloak": {:hex, :ash_cloak, "0.1.2", "d70338491ad8b6a18c691c25a2a236e18bb726c551642f56d996d25a9f1e779b", [:mix], [{:ash, "~> 3.0", [hex: :ash, repo: "hexpm", optional: false]}], "hexpm", "8b13dc44d8c58a7a876e537b3eab03672ac04f442568b4f9c1d70ccd9522812f"},
|
||||
"ash_pagify": {:hex, :ash_pagify, "1.4.1", "af25d5f68b6df84ed5388dd4688658fd08fa59e99f70361a0497c376b50ac115", [:mix], [{:ash, "~> 3.3", [hex: :ash, repo: "hexpm", optional: false]}, {:ash_phoenix, "~> 2.1", [hex: :ash_phoenix, repo: "hexpm", optional: false]}, {:ash_postgres, "~> 2.1", [hex: :ash_postgres, repo: "hexpm", optional: false]}, {:ex_doc, "~> 0.37", [hex: :ex_doc, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.7", [hex: :phoenix, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}], "hexpm", "5b7f771c5a76f92d120536cd87fb25b7321a681482aeaf127b7202bd18552c84"},
|
||||
"ash_phoenix": {:hex, :ash_phoenix, "2.1.2", "7215cf3a1ebc82ca0e5317a8449e1725fa753354674a0e8cd7fc1c8ffd1181c7", [: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", "b591bd731a0855f670b5bc3f48c364b1694d508071f44d57bcd508c82817c51e"},
|
||||
"ash_postgres": {:hex, :ash_postgres, "2.4.1", "6fa9bbb40e9d4a73bcdd2403e036874421e8c919dc57338eb6476cc8a82fa112", [:mix], [{:ash, ">= 3.4.9 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ash_sql, ">= 0.2.30 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.3.36 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: false]}, {: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", "9419993fe7f200db7230c372f5aa280f8bebb175501c9e8d58703c9054006c7b"},
|
||||
"ash_sql": {:hex, :ash_sql, "0.2.32", "de99255becfb9daa7991c18c870e9f276bb372acda7eda3e05c3e2ff2ca8922e", [: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", "43773bcd33d21319c11804d76fe11f1a1b7c8faba7aaedeab6f55fde3d2405db"},
|
||||
@@ -27,7 +28,7 @@
|
||||
"dns_cluster": {:hex, :dns_cluster, "0.1.3", "0bc20a2c88ed6cc494f2964075c359f8c2d00e1bf25518a6a6c7fd277c9b0c66", [:mix], [], "hexpm", "46cb7c4a1b3e52c7ad4cbe33ca5079fbde4840dedeafca2baf77996c2da1bc33"},
|
||||
"doctor": {:hex, :doctor, "0.21.0", "20ef89355c67778e206225fe74913e96141c4d001cb04efdeba1a2a9704f1ab5", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "a227831daa79784eb24cdeedfa403c46a4cb7d0eab0e31232ec654314447e4e0"},
|
||||
"earmark": {:hex, :earmark, "1.4.46", "8c7287bd3137e99d26ae4643e5b7ef2129a260e3dcf41f251750cb4563c8fb81", [:mix], [], "hexpm", "798d86db3d79964e759ddc0c077d5eb254968ed426399fbf5a62de2b5ff8910a"},
|
||||
"earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"},
|
||||
"earmark_parser": {:hex, :earmark_parser, "1.4.43", "34b2f401fe473080e39ff2b90feb8ddfeef7639f8ee0bbf71bb41911831d77c5", [:mix], [], "hexpm", "970a3cd19503f5e8e527a190662be2cee5d98eed1ff72ed9b3d1a3d466692de8"},
|
||||
"ecto": {:hex, :ecto, "3.12.5", "4a312960ce612e17337e7cefcf9be45b95a3be6b36b6f94dfb3d8c361d631866", [: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", "6eb18e80bef8bb57e17f5a7f068a1719fbda384d40fc37acb8eb8aeca493b6ea"},
|
||||
"ecto_sql": {:hex, :ecto_sql, "3.12.0", "73cea17edfa54bde76ee8561b30d29ea08f630959685006d9c6e7d1e59113b7d", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.12", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 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", "dc9e4d206f274f3947e96142a8fdc5f69a2a6a9abb4649ef5c882323b6d512f0"},
|
||||
"erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"},
|
||||
@@ -36,7 +37,7 @@
|
||||
"ets": {:hex, :ets, "0.9.0", "79c6a6c205436780486f72d84230c6cba2f8a9920456750ddd1e47389107d5fd", [:mix], [], "hexpm", "2861fdfb04bcaeff370f1a5904eec864f0a56dcfebe5921ea9aadf2a481c822b"},
|
||||
"ex2ms": {:hex, :ex2ms, "1.7.0", "45b9f523d0b777667ded60070d82d871a37e294f0b6c5b8eca86771f00f82ee1", [:mix], [], "hexpm", "2589eee51f81f1b1caa6d08c990b1ad409215fe6f64c73f73c67d36ed10be827"},
|
||||
"ex_check": {:hex, :ex_check, "0.14.0", "d6fbe0bcc51cf38fea276f5bc2af0c9ae0a2bb059f602f8de88709421dae4f0e", [:mix], [], "hexpm", "8a602e98c66e6a4be3a639321f1f545292042f290f91fa942a285888c6868af0"},
|
||||
"ex_doc": {:hex, :ex_doc, "0.34.1", "9751a0419bc15bc7580c73fde506b17b07f6402a1e5243be9e0f05a68c723368", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "d441f1a86a235f59088978eff870de2e815e290e44a8bd976fe5d64470a4c9d2"},
|
||||
"ex_doc": {:hex, :ex_doc, "0.37.3", "f7816881a443cd77872b7d6118e8a55f547f49903aef8747dbcb345a75b462f9", [:mix], [{:earmark_parser, "~> 1.4.42", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "e6aebca7156e7c29b5da4daa17f6361205b2ae5f26e5c7d8ca0d3f7e18972233"},
|
||||
"ex_rated": {:hex, :ex_rated, "2.1.0", "d40e6fe35097b10222df2db7bb5dd801d57211bac65f29063de5f201c2a6aebc", [:mix], [{:ex2ms, "~> 1.5", [hex: :ex2ms, repo: "hexpm", optional: false]}], "hexpm", "936c155337253ed6474f06d941999dd3a9cf0fe767ec99a59f2d2989dc2cc13f"},
|
||||
"expo": {:hex, :expo, "0.5.2", "beba786aab8e3c5431813d7a44b828e7b922bfa431d6bfbada0904535342efe2", [:mix], [], "hexpm", "8c9bfa06ca017c9cb4020fabe980bc7fdb1aaec059fd004c2ab3bff03b1c599c"},
|
||||
"exsync": {:hex, :exsync, "0.4.1", "0a14fe4bfcb80a509d8a0856be3dd070fffe619b9ba90fec13c58b316c176594", [:mix], [{:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm", "cefb22aa805ec97ffc5b75a4e1dc54bcaf781e8b32564bf74abbe5803d1b5178"},
|
||||
|
||||
Reference in New Issue
Block a user