defmodule Facturx.MixProject do use Mix.Project @version "0.7.0" @source_url "https://github.com/nseaSeb/facturx" def project do [ app: :facturx, version: @version, elixir: "~> 1.15", elixirc_paths: elixirc_paths(Mix.env()), start_permanent: Mix.env() == :prod, deps: deps(), description: description(), package: package(), docs: docs(), dialyzer: dialyzer(), test_coverage: [tool: ExCoveralls], name: "Facturx", source_url: @source_url ] end # test/support holds Facturx.TestPDF, which builds synthetic PDF/A bases so the # Embed / Extract paths run in CI without the private fixtures. package/0 does # not ship test/, so nothing of it reaches Hex. defp elixirc_paths(:test), do: ["lib", "test/support"] # dev/ holds `mix facturx.harness`, the veraPDF + Python-parity oracle. It is # compiled here and nowhere else, so package/0 shipping all of lib/ cannot # carry a task that needs fixtures nobody else has. defp elixirc_paths(:dev), do: ["lib", "dev"] defp elixirc_paths(_), do: ["lib"] def application do [ # :xmerl (OTP) powers Facturx.XSD — pure-BEAM XSD validation, no external tool. extra_applications: [:logger, :xmerl], # Facturx.XSD.Cache compiles bundled schemas once and shares them. mod: {Facturx.Application, []} ] end # The coveralls tasks only exist in :test, so they have to select it themselves. def cli do [ preferred_envs: [ coveralls: :test, "coveralls.html": :test, "coveralls.github": :test ] ] end defp deps do [ # Pure-Elixir XML parsing/building for the CII core. {:saxy, "~> 1.6"}, # Exact decimal arithmetic for monetary amounts (prices, VAT, totals). # 3.0 is the floor, not a preference: every 2.x is affected by # CVE-2026-32686, and `parse/1` hands amounts straight from an untrusted # invoice to the caller. See the note in Facturx.CII. {:decimal, "~> 3.0"}, # Optional: only needed by Facturx.Validate (Schematron over HTTP). # Callers that don't validate don't pull an HTTP client. {:req, "~> 0.5", optional: true}, # Dev / docs only. {:ex_doc, "~> 0.34", only: :dev, runtime: false}, # Quality gates. The public API is almost fully @spec'd; until dialyxir # arrived nothing checked those specs against the code. {:dialyxir, "~> 1.4", only: [:dev, :test], runtime: false}, {:credo, "~> 1.7", only: [:dev, :test], runtime: false}, {:stream_data, "~> 1.1", only: [:dev, :test]}, {:excoveralls, "~> 0.18", only: :test} ] end defp dialyzer do [ # Facturx.XSD calls :xmerl_xsd and :xmerl_xpath directly, and OTP apps are # not in the PLT unless named here. plt_add_apps: [:xmerl], # Never priv/: package/0 ships priv/ to Hex, and a PLT is machine-local. plt_local_path: "_build/plts", plt_core_path: "_build/plts", # No :underspecs. The public specs are deliberately wider than the success # typing — `{:error, term()}` is what lets a new error atom ship without # breaking the contract — so every one of them would be reported. flags: [:error_handling, :extra_return, :missing_return] ] end defp description do "Pure-Elixir Factur-X / ZUGFeRD e-invoicing: generate and extract hybrid " <> "PDF/A-3 + CII XML invoices (EN 16931), with optional Schematron validation." end defp package do [ licenses: ["MIT"], links: %{"GitHub" => @source_url}, files: ~w(lib priv docs mix.exs README.md CHANGELOG.md LICENSE) ] end defp docs do [ main: "readme", # Without this, the "source" links on hexdocs follow the default branch # rather than the tag the published docs were built from. source_ref: "v#{@version}", extras: [ "README.md", "CHANGELOG.md", "docs/reference/reforme-fr.md", "docs/reference/mapping-cii-flux1.md", "docs/adr/0001-perimetre-et-architecture.md", "docs/adr/0002-conformite-reforme-fr.md", # Declared so the README's links to them resolve in the docs. "priv/NOTICE.md": [title: "Third-party notices"], LICENSE: [title: "License"] ], groups_for_extras: [ Référence: ~r/docs\/reference\//, "Décisions d'architecture": ~r/docs\/adr\//, Licences: ~r/(LICENSE|NOTICE)/ ] ] end end