## Overview

`duck-gen` emits `.d.ts` files that export types for API routes and message registries.
This page lists **every exported type** with a usage example.

Import generated types from the framework entrypoint:

```ts
import type {
  // API route types
  ApiRoutes,
  RoutePath,
  RouteReq,
  RouteRes,
  RouteMethod,
  RouteMethods,
  PathsByMethod,
  DuckFetcher,
  DuckClient,
  GetBody,
  GetQuery,
  GetParams,
  GetHeaders,
  GetRes,
  GetReq,
  // Message types
  DuckgenMessageSources,
  DuckgenMessageGroup,
  DuckgenMessageKey,
  DuckgenMessageDictionary,
  DuckgenMessageDictionaryByGroup,
  DuckGenI18nMessages,
  DuckgenI18n,
  DuckgenI18nByGroup,
  DuckgenScopedI18nByGroup,
} from '@gentleduck/gen/nestjs'
```

## API route types

Generated from NestJS controllers.

### ApiRoutes

The main route map. Each key is a route path; the value describes method, request shape,
and response type.

```ts
// The generated interface looks like:
interface ApiRoutes {
  '/api/auth/signin': {
    body: SigninDto
    query: never
    params: never
    headers: never
    res: AuthSession
    method: 'POST'
  }
  '/api/users/:id': {
    body: never
    query: never
    params: { id: string }
    headers: never
    res: UserDto
    method: 'GET'
  }
}
```

Pass `ApiRoutes` as the generic when creating a Duck Query client:

```ts
import { createDuckQueryClient } from '@gentleduck/query'
import type { ApiRoutes } from '@gentleduck/gen/nestjs'

const client = createDuckQueryClient<ApiRoutes>({
  baseURL: 'http://localhost:3000',
})
```

### RoutePath

A union of all route path strings.

```ts
type RoutePath = '/api/auth/signin' | '/api/users/:id' | '/api/users'
```

Use it to restrict a variable or parameter to valid route paths:

```ts
function logRoute(path: RoutePath) {
  console.log(`Calling ${path}`)
}

logRoute('/api/auth/signin') // ok
logRoute('/api/unknown')     // error: type error
```

### RouteReq

The request shape for a route. An object with `body`, `query`, `params`, and `headers`,
filtered to the fields that are **not `never`** for that route.

```ts
type SigninReq = RouteReq<'/api/auth/signin'>
// => { body: SigninDto }

type UserReq = RouteReq<'/api/users/:id'>
// => { params: { id: string } }

type SearchReq = RouteReq<'/api/users'>
// => { query: PaginationDto }
```

The type you'll reach for most often when building request payloads:

```ts
function buildSigninPayload(): RouteReq<'/api/auth/signin'> {
  return {
    body: {
      username: 'duck',
      password: '123456',
    },
  }
}
```

### RouteRes

The response type for a given route path.

```ts
type SigninRes = RouteRes<'/api/auth/signin'>
// => AuthSession

type UserRes = RouteRes<'/api/users/:id'>
// => UserDto
```

Use it to type response handlers:

```ts
function handleSignin(response: RouteRes<'/api/auth/signin'>) {
  console.log('Signed in as', response.username)
}
```

### RouteMethod

The HTTP method for a given route path.

```ts
type SigninMethod = RouteMethod<'/api/auth/signin'>
// => 'POST'

type UserMethod = RouteMethod<'/api/users/:id'>
// => 'GET'
```

### RouteMethods

A union of all HTTP methods used across all routes.

```ts
type AllMethods = RouteMethods
// => 'GET' | 'POST' | 'PUT' | 'DELETE' | ...
```

### PathsByMethod

Filters route paths by HTTP method — returns only paths using that method.

```ts
type GetPaths = PathsByMethod<'GET'>
// => '/api/users/:id' | '/api/users'

type PostPaths = PathsByMethod<'POST'>
// => '/api/auth/signin' | '/api/users'
```

Useful for method-specific helpers:

```ts
async function fetchAll<P extends PathsByMethod<'GET'>>(
  client: DuckQueryClient<ApiRoutes>,
  path: P,
) {
  return client.get(path)
}
```

### GetBody, GetQuery, GetParams, GetHeaders

Individual type extractors for each request component:

```ts
type SigninBody = GetBody<'/api/auth/signin'>
// => SigninDto

type UserParams = GetParams<'/api/users/:id'>
// => { id: string }

type SearchQuery = GetQuery<'/api/users'>
// => PaginationDto

type AuthHeaders = GetHeaders<'/api/me'>
// => { authorization: string }
```

### GetRes

Alias for `RouteRes`. Pick whichever name reads better:

```ts
type SigninResponse = GetRes<'/api/auth/signin'>
// => AuthSession
```

### GetReq

Alias for `RouteReq`:

```ts
type SigninRequest = GetReq<'/api/auth/signin'>
// => { body: SigninDto }
```

### DuckFetcher

A typed fetcher function signature for a route path:

```ts
type Fetcher = DuckFetcher<'/api/auth/signin'>
// => (req: { body: SigninDto }) => Promise<AuthSession>
```

### DuckClient

A typed client helper with `request` and `byMethod` methods:

```ts
type Client = DuckClient
// => { request: ...; byMethod: ... }
```

## Message types

Generated from `@duckgen` tagged constants.

### DuckgenMessageSources

Maps group keys to their source types — the raw registry:

```ts
type DuckgenMessageSources = {
  auth: typeof AuthMessages       // from @duckgen messages auth
  payments: typeof PaymentMessages // from @duckgen messages payments
}
```

### DuckgenMessageGroup

A union of all group keys:

```ts
type DuckgenMessageGroup = 'auth' | 'payments'
```

Use it for group-aware functions:

```ts
function getTranslations(group: DuckgenMessageGroup, lang: string) {
  return i18n[lang].server[group]
}
```

### DuckgenMessageKey

A union of message keys, optionally scoped to a group:

```ts
// All keys across all groups
type AllKeys = DuckgenMessageKey
// => 'AUTH_SIGNIN_SUCCESS' | 'AUTH_SIGNIN_FAILED' | 'PAYMENT_SUCCESS' | ...

// Keys for a specific group
type AuthKeys = DuckgenMessageKey<'auth'>
// => 'AUTH_SIGNIN_SUCCESS' | 'AUTH_SIGNIN_FAILED' | ...
```

Type-safe error handling:

```ts
function showError(key: DuckgenMessageKey<'auth'>, lang: 'en' | 'ar') {
  const message = i18n[lang].server.AuthMessages[key]
  toast.error(message)
}

showError('AUTH_SIGNIN_FAILED', 'en')  // ok
showError('UNKNOWN_KEY', 'en')          // error: type error
```

### DuckgenMessageDictionary

A record mapping message keys to string values for a group — the shape of one
translation file:

```ts
type AuthDict = DuckgenMessageDictionary<'auth'>
// => {
//     AUTH_SIGNIN_SUCCESS: string
//     AUTH_SIGNIN_FAILED: string
//     AUTH_USERNAME_INVALID: string
//     AUTH_PASSWORD_INVALID: string
//   }
```

Use it to type translation objects:

```ts
const authEn: DuckgenMessageDictionary<'auth'> = {
  AUTH_SIGNIN_SUCCESS: 'Signed in successfully',
  AUTH_SIGNIN_FAILED: 'Sign in failed',
  AUTH_USERNAME_INVALID: 'Invalid username',
  AUTH_PASSWORD_INVALID: 'Invalid password',
}
```

A missing key or an unknown key triggers a TypeScript error.

### DuckgenMessageDictionaryByGroup

All groups mapped to their dictionaries in one object:

```ts
type AllDicts = DuckgenMessageDictionaryByGroup
// => {
//     auth: { AUTH_SIGNIN_SUCCESS: string; ... }
//     payments: { PAYMENT_SUCCESS: string; ... }
//   }
```

### DuckGenI18nMessages

Alias for `DuckgenMessageDictionaryByGroup`. Pick whichever name reads better:

```ts
type Messages = DuckGenI18nMessages
// Same as DuckgenMessageDictionaryByGroup
```

### DuckgenI18n

Maps language codes to message dictionaries. Takes a language union and an optional
group:

```ts
type AuthI18n = DuckgenI18n<'en' | 'ar', 'auth'>
// => {
//     en: { AUTH_SIGNIN_SUCCESS: string; ... }
//     ar: { AUTH_SIGNIN_SUCCESS: string; ... }
//   }
```

### DuckgenI18nByGroup

Maps language codes to all group dictionaries:

```ts
type FullI18n = DuckgenI18nByGroup<'en' | 'ar'>
// => {
//     en: { auth: { ... }; payments: { ... } }
//     ar: { auth: { ... }; payments: { ... } }
//   }
```

### DuckgenScopedI18nByGroup

The most common i18n type. Wraps all groups under a `server` scope, separating
server-generated messages from client-only translations:

```ts
type ScopedI18n = DuckgenScopedI18nByGroup<'en' | 'ar', DuckGenI18nMessages>
// => {
//     en: {
//       server: {
//         AuthMessages: { AUTH_SIGNIN_SUCCESS: string; ... }
//         PaymentMessages: { PAYMENT_SUCCESS: string; ... }
//       }
//     }
//     ar: {
//       server: {
//         AuthMessages: { AUTH_SIGNIN_SUCCESS: string; ... }
//         PaymentMessages: { PAYMENT_SUCCESS: string; ... }
//       }
//     }
//   }
```

Full usage example:

```ts
import type { DuckgenScopedI18nByGroup, DuckGenI18nMessages } from '@gentleduck/gen/nestjs'

type Lang = 'en' | 'ar'
type I18n = DuckgenScopedI18nByGroup<Lang, DuckGenI18nMessages>

const i18n: I18n = {
  en: {
    server: {
      AuthMessages: {
        AUTH_SIGNIN_SUCCESS: 'Signed in successfully',
        AUTH_SIGNIN_FAILED: 'Sign in failed',
        // ... TypeScript enforces all keys are present
      },
      PaymentMessages: {
        PAYMENT_SUCCESS: 'Payment processed',
        PAYMENT_DECLINED: 'Payment declined',
      },
    },
  },
  ar: {
    server: {
      AuthMessages: {
        AUTH_SIGNIN_SUCCESS: 'تم تسجيل الدخول بنجاح',
        AUTH_SIGNIN_FAILED: 'فشل تسجيل الدخول',
      },
      PaymentMessages: {
        PAYMENT_SUCCESS: 'تم الدفع بنجاح',
        PAYMENT_DECLINED: 'تم رفض الدفع',
      },
    },
  },
}
```

## Next steps

* [API Routes guide](/duck-gen/api-routes): how routes are scanned and generated.
* [Messages guide](/duck-gen/messages): how message tags work.
* [Duck Query](/duck-query): use these types with a type-safe HTTP client.
* [Templates](/duck-gen/templates): complete working example.