defmodule NPM.Validator do @moduledoc """ Validate `package.json` fields. """ @doc """ Validate a package name according to npm naming rules. Returns `:ok` or `{:error, reason}`. """ @spec validate_name(String.t()) :: :ok | {:error, String.t()} def validate_name(name) do cond do name == "" -> {:error, "name cannot be empty"} byte_size(name) > 214 -> {:error, "name cannot exceed 214 characters"} String.starts_with?(name, ".") -> {:error, "name cannot start with a period"} String.starts_with?(name, "_") -> {:error, "name cannot start with an underscore"} name != String.downcase(name) and not String.starts_with?(name, "@") -> {:error, "name must be lowercase"} String.contains?(name, " ") -> {:error, "name cannot contain spaces"} true -> :ok end end @doc """ Validate a version range string. Returns `:ok` or `{:error, reason}`. """ @spec validate_range(String.t()) :: :ok | {:error, String.t()} def validate_range(""), do: {:error, "version range cannot be empty"} def validate_range("*"), do: :ok def validate_range("latest"), do: :ok def validate_range(range) do case NPMSemver.to_hex_constraint(range) do {:ok, _} -> :ok :error -> {:error, "invalid version range: #{range}"} end end end