defmodule Mix.Tasks.LiveState.Gen.Element do
@shortdoc "Generates a Phoenix channel"
@moduledoc """
Generates a Livestate channel.
$ mix live_state.gen.channel Todo
Accepts the module name for the channel
The generated files will contain:
For a regular application:
* a channel in `lib/my_app_web/channels`
* a channel test in `test/my_app_web/channels`
"""
use Mix.Task
alias Mix.Tasks.Phx.Gen
@doc false
def run(args) do
[channel_name, tag_name] = validate_args!(args)
binding = [
channel_name: channel_name |> Phoenix.Naming.underscore(),
tag_name: tag_name,
element_class: element_class(tag_name)
]
Mix.shell().cmd("npm install --prefix assets lit phx-live-state")
element_contents =
EEx.eval_file(Path.join(__DIR__, "../../../priv/templates/custom-element.ts"), binding)
File.write!("assets/js/#{tag_name}.ts", element_contents)
end
@spec raise_with_help() :: no_return()
defp raise_with_help do
Mix.raise("""
mix live_state.gen.channel expects the channel name and tag name
mix live_state.gen.element ContactForm contact-form
""")
end
defp validate_args!(args) do
unless length(args) == 2 and args |> Enum.at(1) |> valid_tag_name?() do
raise_with_help()
end
args
end
defp element_class(tag_name),
do: tag_name |> String.split("-") |> Enum.concat(["element"]) |> Enum.map(&String.capitalize/1) |> Enum.join("")
defp valid_tag_name?(name) do
name =~ ~r/^[a-z]*\-/
end
end