> ## Documentation Index
> Fetch the complete documentation index at: https://sonamu.cartanova.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Generated Files

> Complete list of files auto-generated from Entity definitions by Sonamu

Sonamu automatically generates TypeScript types, Zod schemas, API clients, React components, and more from Entity definitions. This document describes the types and purposes of all generated files.

## Generated Files Overview

<CardGroup cols={2}>
  <Card title="Types & Schemas" icon="brackets-curly">
    TypeScript types and Zod schemas \*.types.ts, sonamu.generated.ts
  </Card>

  <Card title="API Clients" icon="code">
    HTTP client functions services.generated.ts
  </Card>

  <Card title="Query Helpers" icon="database">
    Subset query functions sonamu.generated.sso.ts
  </Card>

  <Card title="React Components" icon="react">
    Form, List, Select components view\_\*.tsx
  </Card>
</CardGroup>

## Core Generated Files

### 1. Entity Types (`{entity}.types.ts`)

TypeScript types and Zod schemas are generated per Entity.

```typescript title="api/src/application/user/user.types.ts (auto-generated)" theme={null}
import { z } from "zod";

// Base type
export type User = {
  id: number;
  email: string;
  username: string;
  role: "admin" | "normal";
  created_at: Date;
};

// Zod schema
export const User = z.object({
  id: z.number(),
  email: z.string(),
  username: z.string(),
  role: z.enum(["admin", "normal"]),
  created_at: z.date(),
});

// List parameters
export const UserListParams = z.object({
  num: z.number().optional(),
  page: z.number().optional(),
  search: UserSearchField.optional(),
  keyword: z.string().optional(),
  orderBy: UserOrderBy.optional(),
});

// Save parameters
export const UserSaveParams = User.partial({ id: true });
```

**Generated when**: Entity save or `pnpm sonamu sync`

**Editable**: ❌ Auto-regenerated (custom types in separate file)

### 2. Generated Base (`sonamu.generated.ts`)

Base types and Enums for the entire project.

```typescript title="api/src/application/sonamu.generated.ts (auto-generated)" theme={null}
import { z } from "zod";

// All Entity Enums
export const UserRole = z.enum(["admin", "normal"]);
export type UserRole = z.infer<typeof UserRole>;

export const UserSearchField = z.enum(["id", "email", "username"]);
export const UserOrderBy = z.enum(["id-desc", "id-asc", "created_at-desc"]);

// Subset types
export type UserSubsetKey = "A" | "P" | "SS";
export type UserSubsetMapping = {
  A: UserA;
  P: UserP;
  SS: UserSS;
};

// Enum label helpers
export function userRoleLabel(role: UserRole): string {
  return {
    admin: "Administrator",
    normal: "Normal User",
  }[role];
}

// Export all models
export * from "./user/user.model";
export * from "./post/post.model";
```

**Generated when**: Entity save or `pnpm sonamu sync`

**Editable**: ❌ Auto-regenerated

### 3. Subset Queries (`sonamu.generated.sso.ts`)

Query functions per Subset.

```typescript title="api/src/application/sonamu.generated.sso.ts (auto-generated)" theme={null}
import type { PuriWrapper } from "sonamu";

// Subset query functions
export const userSubsetQueries = {
  A: (puri: PuriWrapper) =>
    puri
      .table("users")
      .select(["users.id", "users.email", "users.username", "users.role", "users.created_at"]),

  P: (puri: PuriWrapper) =>
    puri
      .table("users")
      .select(["users.id", "users.email", "users.username"])
      .leftJoin("employees", "employees.user_id", "users.id")
      .select([
        "employees.id as employee__id",
        "employees.department_id as employee__department_id",
      ]),

  SS: (puri: PuriWrapper) => puri.table("users").select(["users.id", "users.email"]),
};

// Loader query functions (HasMany, ManyToMany)
export const userLoaderQueries = {
  P: [
    {
      as: "posts",
      refId: "id",
      qb: (puri: PuriWrapper, ids: number[]) =>
        puri
          .table("posts")
          .whereIn("posts.user_id", ids)
          .select(["posts.id", "posts.user_id as refId", "posts.title"]),
    },
  ],
};
```

**Generated when**: Entity Subset changes

**Editable**: ❌ Auto-regenerated

### 4. API Services (`services.generated.ts`)

API client functions.

```typescript title="web/src/services/services.generated.ts (auto-generated)" theme={null}
import axios from "axios";
import type { ListResult } from "./sonamu.shared";
import type { User, UserListParams, UserSaveParams } from "./user/user.types";

// Axios clients
export async function findUserById(id: number): Promise<User> {
  const { data } = await axios.get("/user/findById", { params: { id } });
  return data;
}

export async function findManyUsers(
  params?: UserListParams,
): Promise<ListResult<UserListParams, User>> {
  const { data } = await axios.get("/user/findMany", { params });
  return data;
}

export async function saveUser(params: UserSaveParams[]): Promise<number[]> {
  const { data } = await axios.post("/user/save", { params });
  return data;
}

// TanStack Query Hooks
export function useUserById(id: number) {
  return useQuery({
    queryKey: ["User", "findById", id],
    queryFn: () => findUserById(id),
  });
}

export function useUsers(params?: UserListParams) {
  return useQuery({
    queryKey: ["Users", "findMany", params],
    queryFn: () => findManyUsers(params),
  });
}

// TanStack Mutation Hooks
export function useSaveUser() {
  return useMutation({
    mutationFn: (params: UserSaveParams[]) => saveUser(params),
  });
}
```

**Generated when**: Model's `@api` decorator changes

**Editable**: ❌ Auto-regenerated

<Info>
  **Target-specific generation**: Copied to each target specified in `sync.targets` in
  `sonamu.config.ts` (`web`, `app`, etc.).
</Info>

### 5. HTTP Test File (`sonamu.generated.http`)

HTTP test file for REST Client.

```http title="api/sonamu.generated.http (auto-generated)" theme={null}
@baseUrl = http://localhost:3000

### User.findById
GET {{baseUrl}}/user/findById?id=1

### User.findMany
GET {{baseUrl}}/user/findMany?num=10&page=1

### User.save
POST {{baseUrl}}/user/save
Content-Type: application/json

{
  "params": [
    {
      "email": "test@test.com",
      "username": "Test User"
    }
  ]
}

### User.del
DELETE {{baseUrl}}/user/del
Content-Type: application/json

{
  "ids": [1, 2, 3]
}
```

**Generated when**: Model file changes

**Editable**: ❌ Auto-regenerated

**Usage**: Install VS Code's REST Client extension and execute requests

## React Components

React UI components can be generated via Scaffold.

### 6. List Component

<CodeGroup>
  ```tsx title="web/src/pages/user/UserList.tsx" theme={null}
  import { useUsers } from "@/services/services.generated";

  export function UserList() {
    const [params, setParams] = useState({ num: 20, page: 1 });
    const { data, isLoading } = useUsers(params);

  return (

  <div>
  <table>
  <thead>
  <tr>
  <th>ID</th>
  <th>Email</th>
  <th>Username</th>
  </tr>
  </thead>
  <tbody>
  {data?.rows.map((user) => (
  <tr key={user.id}>
  <td>{user.id}</td>
  <td>{user.email}</td>
  <td>{user.username}</td>
  </tr>
  ))}
  </tbody>
  </table>

        <Pagination
          total={data?.total ?? 0}
          page={params.page}
          onChange={(page) => setParams({ ...params, page })}
        />
      </div>

  );
  }

  ```

  ```tsx title="web/src/pages/user/UserSearchInput.tsx" theme={null}
  export function UserSearchInput({
    value,
    onChange,
  }: {
    value: UserSearchField;
    onChange: (value: UserSearchField) => void;
  }) {
    return (
      <select value={value} onChange={(e) => onChange(e.target.value)}>
        <option value="id">ID</option>
        <option value="email">Email</option>
        <option value="username">Username</option>
      </select>
    );
  }
  ```
</CodeGroup>

**Generated when**: `pnpm sonamu generate view_list --entity User`

**Editable**: ✅ Editable after initial generation

### 7. Form Component

```tsx title="web/src/pages/user/UserForm.tsx" theme={null}
import { useSaveUser } from "@/services/services.generated";
import { UserSaveParams } from "@/services/user/user.types";

export function UserForm({ userId }: { userId?: number }) {
  const { data: user } = useUserById(userId);
  const { mutate: save } = useSaveUser();

  const handleSubmit = (values: UserSaveParams) => {
    save([values], {
      onSuccess: () => {
        alert("Saved");
      },
    });
  };

  return (
    <form onSubmit={handleSubmit}>
      <input name="email" type="email" defaultValue={user?.email} required />
      <input name="username" defaultValue={user?.username} required />
      <select name="role" defaultValue={user?.role ?? "normal"}>
        <option value="admin">Administrator</option>
        <option value="normal">Normal User</option>
      </select>
      <button type="submit">Save</button>
    </form>
  );
}
```

**Generated when**: `pnpm sonamu generate view_form --entity User`

**Editable**: ✅ Editable after initial generation

### 8. Select Components

<CodeGroup>
  ```tsx title="web/src/components/user/UserIdAsyncSelect.tsx" theme={null}
  // Async Select (searchable)
  export function UserIdAsyncSelect({
    value,
    onChange,
  }: {
    value?: number;
    onChange: (value: number) => void;
  }) {
    const [keyword, setKeyword] = useState("");
    const { data } = useUsers({ keyword, num: 10 });

  return (

  <AsyncSelect
  value={value}
  onChange={onChange}
  onSearch={setKeyword}
  options={data?.rows.map((u) => ({
  value: u.id,
  label: u.email,
  }))}
  />
  );
  }

  ```

  ```tsx title="web/src/components/user/UserRoleSelect.tsx" theme={null}
  // Enum Select
  export function UserRoleSelect({
    value,
    onChange,
  }: {
    value?: UserRole;
    onChange: (value: UserRole) => void;
  }) {
    return (
      <select value={value} onChange={(e) => onChange(e.target.value)}>
        <option value="admin">Administrator</option>
        <option value="normal">Normal User</option>
      </select>
    );
  }
  ```
</CodeGroup>

## SSR Related Files

Files for Server-Side Rendering are auto-generated.

### 9. Queries (`queries.generated.ts`)

For APIs with the `tanstack-query` client enabled, this file exports SSR-side descriptors (`SSRQuery`) grouped by model namespace. The api-side `ssr/routes.ts` uses these descriptors via `registerSSR(...)` to compose preload configs.

```typescript title="api/src/application/queries.generated.ts (auto-generated)" theme={null}
import type { SSRQuery } from "sonamu/ssr";

function createSSRQuery(
  modelName: string,
  methodName: string,
  params: any[],
  serviceKey: [string, string],
): SSRQuery {
  return { modelName, methodName, params, serviceKey, __brand: "SSRQuery" } as SSRQuery;
}

export namespace UserService {
  export const findById = (id: number): SSRQuery =>
    createSSRQuery("UserModel", "findById", [id], ["User", "findById"]);
}
```

**Generated when**: Model file changes

**Editable**: ❌ Auto-regenerated

**Location**: An api-only asset. It is not copied into target (web/app) and is never imported directly from target code. The SSR renderer executes the descriptor server-side and only the result is hydrated on the client.

### 10. Entry Server (`entry-server.generated.tsx`)

TanStack Router-based SSR entry point. It exports a `render(url, preloadedData)` function called by the web side, not a per-route `loader`. Data prefetched during SSR (`preloadedData`) is injected via `queryClient.setQueryData(queryKey, data)`, then `dehydrate`d for client hydration.

```tsx title="web/src/entry-server.generated.tsx (auto-generated)" theme={null}
import { QueryClient, dehydrate } from "@tanstack/react-query";
import { createMemoryHistory, createRouter, RouterProvider } from "@tanstack/react-router";
import { Suspense } from "react";
import { renderToString } from "react-dom/server";
import { routeTree } from "./routeTree.gen";

export type PreloadedData = {
  queryKey: any[];
  data: any;
};

export async function render(url: string, preloadedData: PreloadedData[] = []) {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: { staleTime: 5000, retry: false },
    },
  });

  // Inject results pre-invoked during SSR into queryClient
  for (const { queryKey, data } of preloadedData) {
    queryClient.setQueryData(queryKey, data);
  }

  const dehydratedState = dehydrate(queryClient);

  const memoryHistory = createMemoryHistory({ initialEntries: [url] });
  const router = createRouter({
    routeTree,
    context: { queryClient },
    history: memoryHistory,
    defaultPreload: "intent",
  });
  await router.load();

  const appHtml = renderToString(
    <Suspense fallback={null}>
      <RouterProvider router={router} />
    </Suspense>,
  );

  return { html: appHtml, dehydratedState };
}
```

**Generated when**: Once on first sync (static bootstrap asset, does not depend on inputs)

**Editable**: ❌ Auto-regenerated

## Internationalization Files

Generated when i18n configuration exists.

### 11. Sonamu Dictionary (`sd.generated.ts`)

```typescript title="api/src/sd.generated.ts (auto-generated)" theme={null}
export const SD = {
  User: "User",
  user: {
    id: "ID",
    email: "Email",
    username: "Username",
    role: "Role",
    created_at: "Created At",
  },
  UserRole: {
    admin: "Administrator",
    normal: "Normal User",
  },
} as const;
```

**Generated when**: Entity or i18n file changes

**Editable**: ❌ Auto-regenerated

**Targets**: Generated for `api`, `web`, `app` each

## Generated Files Summary Table

| File                         | Location                           | Generated When     | Editable |
| ---------------------------- | ---------------------------------- | ------------------ | -------- |
| `{entity}.types.ts`          | `api/src/application/{entity}/`    | Entity save        | ❌        |
| `sonamu.generated.ts`        | `api/src/application/`             | Entity save        | ❌        |
| `sonamu.generated.sso.ts`    | `api/src/application/`             | Entity save        | ❌        |
| `services.generated.ts`      | `web/src/services/`                | Model change       | ❌        |
| `sonamu.generated.http`      | `api/`                             | Model change       | ❌        |
| `queries.generated.ts`       | `api/src/application/`             | Model change       | ❌        |
| `entry-server.generated.tsx` | `web/src/`                         | Once on first sync | ✅        |
| `sd.generated.ts`            | `api/src/`, `web/src/`, `app/src/` | Entity/i18n change | ❌        |
| `{Entity}List.tsx`           | `web/src/pages/{entity}/`          | Scaffold           | ✅        |
| `{Entity}Form.tsx`           | `web/src/pages/{entity}/`          | Scaffold           | ✅        |
| `{Entity}SearchInput.tsx`    | `web/src/pages/{entity}/`          | Scaffold           | ✅        |
| `{Entity}IdAsyncSelect.tsx`  | `web/src/components/{entity}/`     | Scaffold           | ✅        |
| `{EnumId}Select.tsx`         | `web/src/components/{entity}/`     | Scaffold           | ✅        |

<Warning>
  **Auto-regenerated files**: Never modify `*.generated.*` files. Changes will be automatically
  overwritten.
</Warning>

## Next Steps

<CardGroup cols={2}>
  <Card title="Syncer" icon="rotate" href="/en/core-concepts/auto-generation/syncer">
    Understanding the core Syncer system
  </Card>

  <Card title="When Files Regenerate" icon="clock" href="/en/core-concepts/auto-generation/when-files-regenerate">
    Learn when files are regenerated
  </Card>

  <Card title="Customizing Generated Code" icon="pen-to-square" href="/en/core-concepts/auto-generation/customizing-generated-code">
    How to customize generated code
  </Card>

  <Card title="Creating Entities" icon="plus" href="/en/core-concepts/entity/defining-entities">
    Define Entities and generate files
  </Card>
</CardGroup>
