Current section

Files

Jump to
Raw

mix.exs

# SPDX-FileCopyrightText: 2025 ash_typescript contributors <https://github.com/ash-project/ash_typescript/graphs/contributors>
#
# SPDX-License-Identifier: MIT

defmodule AshTypescript.MixProject do
  use Mix.Project

  @version "0.19.0"

  @description """
  Generate type-safe TypeScript clients directly from your Ash resources and actions, ensuring end-to-end type safety between your backend and frontend.
  """

  def project do
    [
      app: :ash_typescript,
      version: @version,
      elixir: "~> 1.15",
      start_permanent: Mix.env() == :prod,
      elixirc_paths: elixirc_paths(Mix.env()),
      package: package(),
      deps: deps(),
      aliases: aliases(),
      docs: &docs/0,
      description: @description,
      source_url: "https://github.com/ash-project/ash_typescript",
      homepage_url: "https://github.com/ash-project/ash_typescript",
      dialyzer: [
        plt_add_apps: [:mix]
      ],
      usage_rules: usage_rules(),
      consolidate_protocols: Mix.env() != :test
    ]
  end

  # Read by `mix usage_rules.sync` (and its `--check` run in `mix check`):
  # link every dependency's usage rules into AGENTS.md as `@deps/...` references.
  defp usage_rules do
    [
      file: "AGENTS.md",
      usage_rules: {:all, link: :at}
    ]
  end

  def cli do
    [
      preferred_envs: [
        "test.codegen": :test,
        "test.test_valibot": :test,
        tidewave: :test
      ]
    ]
  end

  def ash_version(default_version) do
    case System.get_env("ASH_VERSION") do
      nil -> default_version
      "local" -> [path: "../ash", override: true]
      "main" -> [git: "https://github.com/ash-project/ash.git", override: true]
      version -> "~> #{version}"
    end
  end

  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(_), do: ["lib"]

  def application do
    application(Mix.env())
  end

  defp application(:test) do
    [
      mod: {AshTypescript.TestApp, []},
      extra_applications: [:logger]
    ]
  end

  defp application(_) do
    [
      extra_applications: [:logger]
    ]
  end

  defp package do
    [
      maintainers: [
        "Torkild Kjevik <torkild.kjevik@boitano.no>"
      ],
      licenses: ["MIT"],
      files: ~w(lib .formatter.exs mix.exs README*
        CHANGELOG* documentation usage-rules.md LICENSES priv),
      links: %{
        "GitHub" => "https://github.com/ash-project/ash_typescript",
        "Changelog" => "https://github.com/ash-project/ash_typescript/blob/main/CHANGELOG.md",
        "Discord" => "https://discord.gg/HTHRaaVPUc",
        "Website" => "https://ash-hq.org",
        "Forum" => "https://elixirforum.com/c/elixir-framework-forums/ash-framework-forum",
        "REUSE Compliance" =>
          "https://api.reuse.software/info/github.com/ash-project/ash_typescript"
      }
    ]
  end

  defp docs do
    [
      main: "readme",
      source_ref: "v#{@version}",
      logo: "logos/small-logo.png",
      extra_section: "GUIDES",
      extras: [
        # Home
        {"README.md", title: "Home"},

        # Getting Started
        "documentation/getting-started/installation.md",
        "documentation/getting-started/first-rpc-action.md",
        "documentation/getting-started/frontend-frameworks.md",

        # Guides
        "documentation/guides/crud-operations.md",
        "documentation/guides/field-selection.md",
        "documentation/guides/querying-data.md",
        "documentation/guides/typed-queries.md",
        "documentation/guides/error-handling.md",
        "documentation/guides/form-validation.md",
        "documentation/guides/typed-controllers.md",
        "documentation/guides/typed-channels.md",

        # Features
        "documentation/features/rpc-action-options.md",
        "documentation/features/phoenix-channels.md",
        "documentation/features/lifecycle-hooks.md",
        "documentation/features/multitenancy.md",
        "documentation/features/action-metadata.md",
        "documentation/features/developer-experience.md",

        # Advanced
        "documentation/advanced/union-types.md",
        "documentation/advanced/embedded-resources.md",
        "documentation/advanced/custom-fetch.md",
        "documentation/advanced/custom-types.md",
        "documentation/advanced/field-name-mapping.md",

        # Reference
        "documentation/reference/configuration.md",
        "documentation/reference/mix-tasks.md",
        "documentation/reference/troubleshooting.md",

        # DSLs
        {"documentation/dsls/DSL-AshTypescript.Rpc.md",
         search_data: Spark.Docs.search_data_for(AshTypescript.Rpc)},
        {"documentation/dsls/DSL-AshTypescript.Resource.md",
         search_data: Spark.Docs.search_data_for(AshTypescript.Resource)},
        {"documentation/dsls/DSL-AshTypescript.TypedController.md",
         search_data: Spark.Docs.search_data_for(AshTypescript.TypedController.Dsl)},
        {"documentation/dsls/DSL-AshTypescript.TypedChannel.md",
         search_data: Spark.Docs.search_data_for(AshTypescript.TypedChannel.Dsl)},

        # About
        "CHANGELOG.md"
      ],
      groups_for_extras: [
        "Getting Started": ~r'documentation/getting-started',
        Guides: ~r'documentation/guides',
        Features: ~r'documentation/features',
        Advanced: ~r'documentation/advanced',
        Reference: ~r'documentation/reference',
        DSLs: ~r'documentation/dsls',
        "About AshTypescript": [
          "CHANGELOG.md"
        ]
      ],
      before_closing_head_tag: fn type ->
        if type == :html do
          """
          <script>
            if (location.hostname === "hexdocs.pm") {
              var script = document.createElement("script");
              script.src = "https://plausible.io/js/script.js";
              script.setAttribute("defer", "defer")
              script.setAttribute("data-domain", "ashhexdocs")
              document.head.appendChild(script);
            }
          </script>
          """
        end
      end
    ]
  end

  # Run "mix help deps" to learn about dependencies.
  defp deps do
    [
      {:ash, ash_version("~> 3.27")},
      {:ash_authentication, "~> 4.0", optional: true},
      {:ash_phoenix, "~> 2.0"},
      {:ash_postgres, "~> 2.0", only: [:dev, :test]},
      {:git_ops, "~> 2.0", only: [:dev], runtime: false},
      {:spark, "~> 2.0"},
      {:sourceror, "~> 1.7", only: [:dev, :test]},
      {:faker, "~> 0.19", only: :test},
      {:credo, ">= 0.0.0", only: [:dev, :test], runtime: false},
      {:dialyxir, ">= 0.0.0", only: [:dev, :test], runtime: false},
      {:igniter, "~> 0.7", only: [:dev, :test]},
      {:ex_doc, "~> 0.37", only: [:dev, :test], runtime: false},
      {:makeup_syntect, "~> 0.1", only: [:dev, :test], runtime: false},
      {:sobelow, ">= 0.0.0", only: [:dev, :test], runtime: false},
      {:picosat_elixir, "~> 0.2", only: [:dev, :test]},
      {:mix_audit, ">= 0.0.0", only: [:dev, :test], runtime: false},
      {:usage_rules, "~> 1.2", only: [:dev]},
      {:tidewave, "~> 0.5", only: [:dev, :test]},
      {:ex_check, "~> 0.12", only: [:dev, :test]},
      {:bandit, "~> 1.0", only: [:dev, :test]},
      {:benchee, "~> 1.3", only: [:dev, :test]}
    ]
  end

  defp aliases do
    [
      "test.codegen": "ash_typescript.codegen",
      "test.compile_generated": "cmd cd test/ts && npm run compileGenerated",
      "test.compile_should_pass": "cmd cd test/ts && npm run compileShouldPass",
      "test.compile_should_fail": "cmd cd test/ts && npm run compileShouldFail",
      "test.test_zod": "cmd cd test/ts && npm run testZod",
      "test.test_valibot": "cmd cd test/ts && npm run testValibot",
      tidewave:
        "run --no-halt -e 'port = String.to_integer(System.get_env(\"TIDEWAVE_PORT\") || \"4012\"); Agent.start(fn -> Bandit.start_link(plug: Tidewave, port: port) end)'",
      sobelow: "sobelow --skip",
      docs: [
        "spark.cheat_sheets",
        "docs",
        "spark.replace_doc_links"
      ],
      sync_usage_rules: ["usage_rules.sync"],
      credo: "credo --strict",
      "spark.formatter":
        "spark.formatter --extensions AshTypescript.Rpc,AshTypescript.Resource,AshTypescript.TypedController.Dsl,AshTypescript.TypedChannel.Dsl",
      "spark.cheat_sheets":
        "spark.cheat_sheets --extensions AshTypescript.Rpc,AshTypescript.Resource,AshTypescript.TypedController.Dsl,AshTypescript.TypedChannel.Dsl"
    ]
  end
end