# Named setters on direct builders

Available since `0.1.0-alpha.2`. Use [matching published packages](/mimlet/guide/getting-started.md)
and declare a builder beside your test; no builder file or code generation is required.

Generated ordinary-record builders already have named methods such as
`withName()`. For direct builders, opt into the fields you want:

```ts
import { fluent } from '@mimlet/core';
import { fromZod } from '@mimlet/zod';
import { z } from 'zod';

const User = z.object({ name: z.string(), age: z.string().transform(Number) });
const users = fluent(fromZod(User), ['name', 'age']);

export const input = users.withName('Ada').withAge('42').build();
export const output = users.withName('Ada').withAge('42').buildValidated();
// input.age is a string; output.age is a number. No builder file is generated.
// Async transitions retain setters and remove synchronous build methods.
export const asynchronous = await users
  .transformAsync(async (value) => value)
  .withName('Grace')
  .withAge('24')
  .buildValidatedAsync();
```

The setters use the schema's **input** types. Validation returns its native output
type, and async transformations remove synchronous build methods while preserving
the named setters. The wrapper uses the existing immutable class facade; choosing
fields does not execute the factory or inspect a native schema.

For a custom spelling, pass a literal method-to-field map:

```ts
const named = fluent(builder, { withUserName: 'user_name' });
```

Literal field tuples and alias maps are checked against finite, ordinary object
records. Runtime-length inventories, index signatures, atomic values, arrays,
nullable root objects and root object unions cannot acquire unsound partial setters.
Use `.replace()` for variant transitions. For typed nested updates, use
[`setPath` inside `.transform()`](/mimlet/guide/generated-facades-and-paths.md#typed-nested-changes).
Names that collide with builder/prototype methods, `then` or `toJSON` are rejected.

Automatic names capitalize alphanumeric segments, matching standalone codegen.
Selections contain 1–1,000 fields. Automatic field names allow up to 64 characters;
explicit aliases allow a 1,024-character field and a 128-character method name.
Duplicate fields, colliding names, getters and sparse arrays are rejected before
factory execution.

For classes that should be checked into a project, use
[generated facades](/mimlet/guide/generated-facades-and-paths.md). Generic `.with()` remains the
smallest API when named methods do not make a test clearer.
