Packages
surface
0.8.0
0.12.3
0.12.2
0.12.1
0.12.0
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.1
0.2.0
0.1.1
0.1.0
0.1.0-alpha.2
0.1.0-alpha.1
0.1.0-alpha.0
A component based library for Phoenix LiveView
Current section
Files
Jump to
Current section
Files
lib/mix/tasks/surface/surface.init/file_patchers/phoenix.ex
defmodule Mix.Tasks.Surface.Init.FilePatchers.Phoenix do
@moduledoc false
# Common patches for phoenix files
alias Mix.Tasks.Surface.Init.ExPatcher
import ExPatcher
def add_import_to_view_macro(code, module, web_module) do
import_str = "import #{inspect(module)}"
append_code_to_view_macro(code, import_str, import_str, web_module)
end
def append_code_to_view_macro(code, text_to_append, already_patched_text, web_module) do
code
|> parse_string!()
|> enter_defmodule(web_module)
|> enter_def(:view)
|> enter_call(:quote)
|> halt_if(&find_code_containing(&1, already_patched_text), :already_patched)
|> append_child_code(text_to_append)
end
def add_import_to_router(code, module, web_module) do
import_str = "import #{inspect(module)}"
code
|> parse_string!()
|> enter_defmodule(Module.concat(web_module, Router))
|> halt_if(&find_code_containing(&1, import_str), :already_patched)
|> find_call_with_args(:use, fn args -> args == [inspect(web_module), ":router"] end)
|> append_code("\n#{import_str}")
end
def append_route(code, route, web_module, route_code) do
code
|> parse_string!()
|> enter_defmodule(Module.concat(web_module, Router))
|> halt_if(&find_code(&1, route), :already_patched)
|> append_child_code("\n#{route_code}")
end
def append_route_to_main_scope(code, route, web_module, route_code) do
web_module_str = inspect(web_module)
code
|> parse_string!()
|> enter_defmodule(Module.concat(web_module, Router))
|> halt_if(&find_code(&1, route), :already_patched)
|> find_call_with_args(:scope, &match?([~S("/"), ^web_module_str | _], &1))
|> body()
|> append_child_code(route_code)
end
def add_reloadable_compiler_to_endpoint_config(code, compiler, context_app, web_module) do
reloadable_compilers = Module.concat(web_module, Endpoint).config(:reloadable_compilers)
patcher =
code
|> parse_string!()
|> find_endpoint_config_with_live_reload(context_app, web_module)
case find_keyword(patcher, :reloadable_compilers) do
%ExPatcher{node: nil} ->
value = inspect(reloadable_compilers ++ [compiler])
insert_keyword(patcher, :reloadable_compilers, value)
list_patcher ->
list_patcher
|> value()
|> halt_if(&find_list_item_with_code(&1, inspect(compiler)), :already_patched)
|> append_list_item(inspect(compiler))
end
end
def add_live_reload_pattern_to_endpoint_config(code, pattern, already_patched_text, context_app, web_module) do
code
|> parse_string!()
|> find_endpoint_config_with_live_reload(context_app, web_module)
|> find_keyword_value([:live_reload, :patterns])
|> halt_if(&find_code_containing(&1, already_patched_text), :already_patched)
# Could not use `append_list_item` as it messes with the indentation of the parent node
|> down()
|> last_child()
|> replace_code(&"#{&1},\n #{pattern}")
end
def replace_live_reload_pattern_in_endpoint_config(
code,
pattern,
replacement,
already_patched_text,
context_app,
web_module
) do
code
|> parse_string!()
|> find_endpoint_config_with_live_reload(context_app, web_module)
|> find_keyword_value([:live_reload, :patterns])
|> halt_if(&find_code_containing(&1, already_patched_text), :already_patched)
|> find_list_item_with_code(pattern)
|> replace(replacement)
end
def add_esbuild_entry_to_config(code, key, value) do
patcher =
code
|> parse_string!()
|> find_call_with_args(:config, &match?([":esbuild", _], &1))
|> last_arg()
case patcher do
%ExPatcher{node: nil} ->
code
|> parse_string!()
|> find_call_with_args(:import, &(&1 == ["Config"]))
|> append_code("""
config :esbuild,
#{key}: #{value}\
""")
esbuild_patcher ->
esbuild_patcher
|> halt_if(&find_keyword(&1, [:catalogue]), :already_patched)
|> find_keyword_value([:default])
|> replace_code(
&"""
#{&1},
#{key}: #{value}\
"""
)
end
end
def add_watcher_to_endpoint_config(code, key, value, already_patched_text, context_app, web_module) do
args = [inspect(context_app), "#{inspect(web_module)}.Endpoint"]
code
|> parse_string!()
|> find_call_with_args_and_opt(:config, args, :watchers)
|> last_arg()
|> find_keyword_value([:watchers])
|> halt_if(&find_code_containing(&1, already_patched_text), :already_patched)
|> last_arg()
|> last_child()
|> replace_code(
&"""
#{&1},
#{key}: #{value}\
"""
)
end
defp find_endpoint_config_with_live_reload(patcher, context_app, web_module) do
args = [inspect(context_app), "#{inspect(web_module)}.Endpoint"]
patcher
|> find_call_with_args_and_opt(:config, args, :live_reload)
|> last_arg()
end
end