# @xemahq/api-client-generator

> Central OpenAPI + Orval client generator for Xema services.

## Overview

Generates typed API clients for NestJS services. It extracts one OpenAPI
document per API surface (public, internal, operator) from decorator metadata,
then generates one Orval client package per non-empty surface, all sharing one
derived version. A route ships in a surface only when it, or its controller, is
explicitly classified.

## When to use it

- Use it to generate a service's client packages instead of maintaining
  per-service generator scripts.

## Installation

```bash
pnpm add -D @xemahq/api-client-generator
```

## Usage

```bash
xema-openapi            # one OpenAPI document per classified API surface
xema-client-generate    # one Orval client package per non-empty surface
```

When regeneration changes the output, the client version advances by a class the
generator derives from the published surface (break, additive, fix). If it
cannot classify a change it refuses and names what it could not decide; state
the class and re-run:

```bash
xema-client-generate --bump-class=minor
# or: XEMA_CLIENT_BUMP_CLASS=minor (the flag wins)
```

A turbo task that runs the generator must pass `XEMA_CLIENT_BUMP_CLASS` through
(`passThroughEnv` or `env`).

## Configuration

Clients in a customer-owned repository are configured in the `client` block of
`tooling/ci/release.config.mjs`:

| Option | Meaning |
| --- | --- |
| `client.packageScope` | Scope for client names (`@acme`), or `""` for unscoped names. Required outside first-party Xema repositories. |
| `client.private` | `true` for workspace-only clients: no banner, publish config or changeset. |
| `client.license` | SPDX or reserved licence stated in the generated README. |
| `client.copyrightHolder` | Legal owner stated in the generated README; there is no default. |

## Repository layout

- **Repository root**: the nearest ancestor that is a git checkout (holds
  `.git`). A `git archive` export or tarball tree is not supported.
- **Package manager**: the root `package.json#packageManager` (`pnpm` or `npm`),
  else the single lockfile present; a repository that says neither, or holds both
  lockfiles, is refused. It decides how the client compiles (`pnpm exec tsc` /
  `npx --no-install tsc`), the README install line, and the client's
  `typescript` devDependency: `catalog:` under pnpm, and under npm the range in
  the repository's own root `package.json` (refused when absent).
- **Changesets**: a repository without `.changeset/` versions its packages by
  its own flow, so the generator records no changeset there (it still never
  writes a version).

## Peer requirements

`@nestjs/common`, `@nestjs/core`, `@nestjs/swagger`, `@nestjs/testing`,
`@xemahq/xema-decorators`, `orval`, `reflect-metadata`, `ts-node`,
`tsconfig-paths`, `typescript`.

## License

Apache-2.0 &copy; Xema — [xema.dev](https://xema.dev)
