/**
* `@nifrajs/web/forms` - a typed form ↔ backend-schema binding. The three artifacts that must agree -
* a form's ``, the action's `formData.get`, and the typed-client payload - all key off the
* ONE route body schema, derived purely from `typeof backend`. A typo'd field name, or a field the
* schema doesn't have, becomes a COMPILE error instead of a silent runtime empty.
*
* import type { backend } from "../backend"
* import { formFor } from "@nifrajs/web/forms"
*
* const f = formFor() // method defaults to "post"
* // In the component (any framework - spread the props onto an input):
* // "text" ∈ the body's keys, else a compile error
* // In the action:
* const text = f.read(await request.formData(), "text") // an orphan key won't compile
* await api.todos.post({ text }) // payload already typed by nifra
*
* Framework-agnostic + dependency-free: no codegen, no schema is bundled into the client, and the
* runtime is a trivial pass-through - all the work is in the types. It checks the field KEY, never the
* MEANING (a `field("email")` collecting a phone is still valid here); that stays an app/AI concern.
*/
import type { RouteInfo, Server } from "@nifrajs/core/server";
type FormEntry = ReturnType;
type FormEntries = ReturnType;
/** The route registry baked into a server's type (`typeof app`). */
type RegistryOf = App extends Server ? R : never;
/** Every route path the app declares - constrains `Path`, so a wrong path is itself a type error. */
export type RoutePaths = keyof RegistryOf & string;
/** The body object type of `App`'s `Method Path` route (`never` when the route declares no body). */
export type RouteBody = Path extends keyof RegistryOf ? Uppercase extends keyof RegistryOf[Path] ? (RegistryOf[Path][Uppercase] & RouteInfo)["body"] : never : never;
/** The valid field names for that route's body - the schema's keys as a string union. */
export type FieldKey = [
RouteBody
] extends [never] ? never : keyof RouteBody & string;
/** Extra attributes merged into the returned input props (id, type, defaultValue, placeholder, …). */
export type FieldProps = Record;
export interface FormHandle {
/** Input props for a schema field. `name` is constrained to the body's keys - a typo, or a field the
* schema doesn't have, is a COMPILE error. Spread onto an element: ``. */
field>(name: K, props?: FieldProps): FieldProps & {
name: K;
};
/** `formData.get`, key-constrained to the body's fields - reading an orphan key won't compile. */
read>(form: FormData, name: K): FormEntry;
/** `formData.getAll`, key-checked the same way. */
readAll>(form: FormData, name: K): FormEntries;
}
/**
* Bind a form to a backend route's body schema at the type level. `App` is `typeof backend`; `Path` is
* constrained to the app's real routes (a wrong path is a type error); `Method` defaults to `"post"`.
*/
export declare function formFor, Method extends string = "post">(): FormHandle;
export {};
//# sourceMappingURL=forms.d.ts.map