# `Arc.ProxyGenerator`
[🔗](https://github.com/Cratis/Arc.Elixir/blob/main/lib/arc/proxy_generator.ex#L4)

Generates TypeScript proxies for the React frontend packages (`@cratis/arc`, `@cratis/arc.react`)
from the commands and read models of an `Arc.Application`.

Proxy generation is **opt-in**. Nothing is generated unless you run `mix arc.gen.proxies` or
configure the `:arc` compiler. A backend serving LiveView or an API to another client never
generates TypeScript.

    # mix.exs
    def project do
      [
        # ...
        compilers: Mix.compilers() ++ [:arc],
        arc: [application: MyApp.Arc, output: "assets/src/arc"]
      ]
    end

## What is generated

One file per artifact, in a folder that mirrors the module namespace after the leading
`segments_to_skip` segments:

  * a command module becomes a `Command` class with its interface, route, roles, property
    descriptors, client-side validator and a `use` hook
  * each query of a read model becomes a `QueryFor` (or `ObservableQueryFor`) class with
    parameters, sorting helpers and the `use`, `useWithPaging`, `useSuspense` and `when` hooks
  * each model and nested schema becomes a class with `@field` decorators
  * the identity provider's details type becomes a class too, to pass to `IdentityProvider.getCurrent`
    or `useIdentity`
  * an `index.ts` per folder re-exports the generated files

The output follows the C# proxy generator's templates, so the frontend packages consume it
unchanged.

## Safety

Every generated file starts with `// @generated by Cratis. Source: <module>. Hash: <sha256>`.
A file without that marker is never overwritten, and stale cleanup deletes only files that
carry it. Output is deterministic: generating twice produces identical bytes, and an unchanged
file is not rewritten.

## Options

Read from `arc:` in `mix.exs`, or given as flags to `mix arc.gen.proxies`.

  * `:application` - the `Arc.Application` module (required)
  * `:output` - the directory to generate into (required)
  * `:layout` - `:namespace` (default) mirrors the module namespace under `:output`;
    `:colocated` writes each proxy beside the source file of its module, so `:output` is the
    root that holds your Elixir and your React code, for example `"lib"`. See
    [Vertical slices](vertical-slices.md)
  * `:remove_stale` - delete generated files for artifacts that no longer exist; default `true`

# `result`

```elixir
@type result() :: %{
  written: [String.t()],
  unchanged: [String.t()],
  removed: [String.t()]
}
```

# `generate`

```elixir
@spec generate(module(), keyword()) :: {:ok, result()} | {:error, [String.t()]}
```

Generates proxies into `output`.

## Options

  * `:output` - the directory (required)
  * `:layout` - `:namespace` (default) or `:colocated`
  * `:root` - for `:colocated`, the directory source folders are relative to; defaults to `:output`
  * `:remove_stale` - default `true`
  * `:dry_run` - report what would change without writing

# `render`

```elixir
@spec render(module(), keyword()) :: [Arc.ProxyGenerator.Artifact.t()]
```

Renders every proxy without touching the file system. Returns files with a path relative to the output
directory, the source module, and the TypeScript body.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
