defmodule NPM.Registry.URL do
@moduledoc """
Constructs registry API URLs for package operations.
"""
@default_registry "https://registry.npmjs.org"
@doc """
Returns the package metadata URL.
"""
@spec package_url(String.t(), String.t()) :: String.t()
def package_url(name, registry \\ @default_registry) do
"#{normalize(registry)}/#{encode_name(name)}"
end
@doc """
Returns the URL for a specific version.
"""
@spec version_url(String.t(), String.t(), String.t()) :: String.t()
def version_url(name, version, registry \\ @default_registry) do
"#{package_url(name, registry)}/#{version}"
end
@doc """
Returns the tarball URL.
"""
@spec tarball_url(String.t(), String.t(), String.t()) :: String.t()
def tarball_url(name, version, registry \\ @default_registry) do
base = normalize(registry)
basename = Path.basename(name)
"#{base}/#{encode_name(name)}/-/#{basename}-#{version}.tgz"
end
@doc """
Returns the search API URL.
"""
@spec search_url(String.t(), keyword()) :: String.t()
def search_url(query, opts \\ []) do
registry = Keyword.get(opts, :registry, @default_registry)
size = Keyword.get(opts, :size, 20)
"#{normalize(registry)}/-/v1/search?text=#{URI.encode(query)}&size=#{size}"
end
@doc """
Returns the abbreviated (corgi) metadata URL.
"""
@spec abbreviated_url(String.t(), String.t()) :: String.t()
def abbreviated_url(name, registry \\ @default_registry) do
package_url(name, registry)
end
@doc """
Checks if a URL points to the default npm registry.
"""
@spec default_registry?(String.t()) :: boolean()
def default_registry?(url) do
normalized = normalize(url)
normalized == @default_registry or normalized == "https://registry.npmmirror.com"
end
@doc """
Returns the default registry URL.
"""
@spec default_registry :: String.t()
def default_registry, do: @default_registry
defp normalize(url), do: String.trim_trailing(url, "/")
defp encode_name(name) do
if NPM.Scope.scoped?(name) do
name |> String.replace("/", "%2f")
else
name
end
end
end