""" Form role output schemas — the wire shapes the schema/validate/submit roles emit. These mirror the Django adapter's `mizan.forms.schemas` field-for-field (FormMeta, FieldSchema, FormSchema, FormValidation, FormSubmitPass/Fail) so the generated client is identical regardless of which backend authored the form. The only difference is the source: Django builds these from `forms.Field` introspection; this builds them from Pydantic `FieldInfo`. """ from __future__ import annotations from typing import Any, Optional from pydantic import BaseModel class FormMeta(BaseModel): """Frontend behavior flags (parity with the Django adapter).""" refetch_schema_on_validate: bool = False live_validation: bool = True live_form_errors: bool = False class FieldChoice(BaseModel): value: str label: str class FieldError(BaseModel): message: str code: Optional[str] = None class FieldErrorList(BaseModel): field: str errors: list[FieldError] class FieldSchema(BaseModel): name: str label: str type: str widget: str required: bool disabled: bool help_text: str initial: Any = None max_length: Optional[int] = None min_length: Optional[int] = None choices: Optional[list[FieldChoice]] = None class FormSchema(BaseModel): """Schema returned by the `.schema` role: form metadata + field definitions.""" name: str title: str subtitle: Optional[str] = None submit_label: str fields: list[FieldSchema] meta: FormMeta = FormMeta() class FormValidation(BaseModel): errors: list[FieldErrorList] class FormSubmitPass(BaseModel): success: bool data: Optional[dict] = None class FormSubmitFail(BaseModel): success: bool errors: FormValidation