Skip to content

Commit d3583d9

Browse files
committed
Initial commit
0 parents  commit d3583d9

File tree

9 files changed

+191
-0
lines changed

9 files changed

+191
-0
lines changed

.formatter.exs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Used by "mix format"
2+
[
3+
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
4+
]

.gitignore

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# The directory Mix will write compiled artifacts to.
2+
/_build/
3+
4+
# If you run "mix test --cover", coverage assets end up here.
5+
/cover/
6+
7+
# The directory Mix downloads your dependencies sources to.
8+
/deps/
9+
10+
# Where third-party dependencies like ExDoc output generated docs.
11+
/doc/
12+
13+
# Ignore .fetch files in case you like to edit your project deps locally.
14+
/.fetch
15+
16+
# If the VM crashes, it generates a dump, let's ignore it too.
17+
erl_crash.dump
18+
19+
# Also ignore archive artifacts (built via "mix archive.build").
20+
*.ez
21+
22+
# Ignore package tarball (built via "mix hex.build").
23+
phoenix_importmap-*.tar
24+
25+
# Temporary files, for example, from tests.
26+
/tmp/
27+
/priv/static/assets

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# PhoenixImportmap
2+
3+
**TODO: Add description**
4+
5+
## Installation
6+
7+
If [available in Hex](https://hex.pm/docs/publish), the package can be installed
8+
by adding `phoenix_importmap` to your list of dependencies in `mix.exs`:
9+
10+
```elixir
11+
def deps do
12+
[
13+
{:phoenix_importmap, "~> 0.1.0"}
14+
]
15+
end
16+
```
17+
18+
Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
19+
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
20+
be found at <https://hexdocs.pm/phoenix_importmap>.
21+

assets/js/app.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// Fixture for testing purposes

lib/phoenix_importmap.ex

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
defmodule PhoenixImportmap do
2+
@moduledoc """
3+
Documentation for `PhoenixImportmap`.
4+
"""
5+
6+
@copy_destination_path "/priv/static/assets"
7+
@public_asset_path_prefix "/priv/static"
8+
9+
def copy(importmap = %{}) do
10+
importmap
11+
|> Map.values()
12+
|> Enum.map(fn source_path ->
13+
full_source_path = "#{File.cwd!()}#{source_path}"
14+
dest_path = dest_path_for_asset(source_path)
15+
maybe_copy_asset(full_source_path, dest_path)
16+
end)
17+
18+
:ok
19+
end
20+
21+
def importmap_json(importmap = %{}) do
22+
%{
23+
imports:
24+
importmap
25+
|> Enum.reduce(%{}, fn {name, path}, acc ->
26+
Map.put(
27+
acc,
28+
name,
29+
dest_path_for_asset(path) |> String.replace(@public_asset_path_prefix, "")
30+
)
31+
end)
32+
}
33+
|> Jason.encode!()
34+
|> Phoenix.HTML.raw()
35+
end
36+
37+
def dest_path_for_asset("//:" <> _), do: nil
38+
def dest_path_for_asset("http://" <> _), do: nil
39+
def dest_path_for_asset("https://" <> _), do: nil
40+
41+
def dest_path_for_asset("/assets" <> _ = full_path) do
42+
"#{@copy_destination_path}/#{filename(full_path)}"
43+
end
44+
45+
def dest_path_for_asset("/deps" <> _ = full_path) do
46+
"#{@copy_destination_path}/#{filename(full_path)}"
47+
end
48+
49+
defp maybe_copy_asset(_source, nil), do: {:ok, 0}
50+
51+
defp maybe_copy_asset(source, dest) do
52+
source
53+
|> File.copy!(File.cwd!() <> dest)
54+
end
55+
56+
defp filename(full_path) do
57+
String.split(full_path, "/")
58+
|> Enum.take(-1)
59+
end
60+
end

mix.exs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
defmodule PhoenixImportmap.MixProject do
2+
use Mix.Project
3+
4+
def project do
5+
[
6+
app: :phoenix_importmap,
7+
version: "0.1.0",
8+
elixir: "~> 1.17",
9+
start_permanent: Mix.env() == :prod,
10+
deps: deps()
11+
]
12+
end
13+
14+
# Run "mix help compile.app" to learn about applications.
15+
def application do
16+
[
17+
extra_applications: [:logger]
18+
]
19+
end
20+
21+
# Run "mix help deps" to learn about dependencies.
22+
defp deps do
23+
[
24+
{:jason, "~> 1.4.4"},
25+
{:phoenix_html, "~> 4.1.1"}
26+
]
27+
end
28+
end

mix.lock

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
%{
2+
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
3+
"phoenix_html": {:hex, :phoenix_html, "4.1.1", "4c064fd3873d12ebb1388425a8f2a19348cef56e7289e1998e2d2fa758aa982e", [:mix], [], "hexpm", "f2f2df5a72bc9a2f510b21497fd7d2b86d932ec0598f0210fed4114adc546c6f"},
4+
}

test/phoenix_importmap_test.exs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
defmodule PhoenixImportmapTest do
2+
use ExUnit.Case
3+
doctest PhoenixImportmap
4+
5+
@example_importmap %{
6+
app: "/assets/js/app.js",
7+
phoenix_html: "/deps/phoenix_html/priv/static/phoenix_html.js"
8+
}
9+
10+
@example_missing_file_importmap %{
11+
app: "/assets/js/missing.js"
12+
}
13+
14+
test "copy succeeds" do
15+
%{app: app_js_path, phoenix_html: dep_js_path} = @example_importmap
16+
17+
app_js_full_path = File.cwd!() <> PhoenixImportmap.dest_path_for_asset(app_js_path)
18+
dep_js_full_path = File.cwd!() <> PhoenixImportmap.dest_path_for_asset(dep_js_path)
19+
20+
assert File.exists?(app_js_full_path) == false
21+
assert File.exists?(dep_js_full_path) == false
22+
23+
assert PhoenixImportmap.copy(@example_importmap) == :ok
24+
25+
assert File.exists?(app_js_full_path)
26+
assert File.exists?(dep_js_full_path)
27+
28+
File.rm!(app_js_full_path)
29+
File.rm!(dep_js_full_path)
30+
end
31+
32+
test "copy fails on missing file" do
33+
assert_raise(File.CopyError, fn ->
34+
PhoenixImportmap.copy(@example_missing_file_importmap)
35+
end)
36+
end
37+
38+
test "importmap_json" do
39+
assert PhoenixImportmap.importmap_json(@example_importmap) ==
40+
{:safe,
41+
"{\"imports\":{\"app\":\"/assets/app.js\",\"phoenix_html\":\"/assets/phoenix_html.js\"}}"}
42+
end
43+
end

test/test_helper.exs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
File.rm_rf!(File.cwd!() <> "/priv/static/assets")
2+
File.mkdir_p!(File.cwd!() <> "/priv/static/assets")
3+
ExUnit.start()

0 commit comments

Comments
 (0)