Skip to content

Regenerate the API Client ​

When you add or change API endpoints, regenerate the typed frontend SDK so the client stays in sync.

When to regenerate ​

Regenerate the SDK whenever you:

  • Add a new controller or endpoint
  • Change a DTO (request or response shape)
  • Rename or delete an endpoint
  • Add new query parameters or path parameters

How to regenerate ​

From the repo root:

bash
pnpm openapi

This is a two-step pipeline that needs no already-running API:

  1. @tt/api openapi:export boots the API under the Nest CLI (nest start with EXPORT_SWAGGER=openapi.json), writes services/api/openapi.json, and exits.
  2. openapi-ts reads that services/api/openapi.json and writes the generated files to services/client/src/api/.

Must run under the Nest CLI

The @nestjs/swagger plugin (configured in services/api/nest-cli.json) only runs when the API is compiled by the Nest CLI. If you export the spec from an API started with tsx (e.g. the old tsx watch src/main.ts) or from node dist/main.js built by plain tsc, request-body DTOs come out empty (body?: never) and every Create*Dto/Update*Dto disappears from the generated client. That's why dev, start:debug, build, and openapi:export all go through nest.

Generate without re-exporting

If services/api/openapi.json is already current (you just exported it), skip the export step:

bash
pnpm --filter @tt/client openapi:generate   # reads services/api/openapi.json only

services/api/openapi.json is a build artifact and is gitignored — it's produced on demand by the export step, not committed.

What changes ​

The generator rewrites files in src/api/. The main file you'll use is src/api/sdk.gen.ts, which exports one namespace per API tag (e.g. Notes, Entries, Invoices).

Using the generated SDK ​

typescript
import { Notes } from '@/api/sdk.gen'

// GET /tenants/:tenantId/notes
const { data } = await Notes.noteControllerFindAll({
  path: { tenantId: 'abc' },
})

// POST /tenants/:tenantId/notes
await Notes.noteControllerCreate({
  path: { tenantId: 'abc' },
  body: { content: 'Hello' },
})

Every call automatically includes the session cookie (credentials: 'include' is set in the base client configuration at src/api/client.ts).

Never hand-edit generated files ​

Files in src/api/ ending in .gen.ts are overwritten every time you regenerate. Put any customization in wrapper composables or utility functions outside that directory.

TT Time Tracker — Internal Documentation