@buildnbuzz/buzzform 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -37,7 +37,7 @@ npx shadcn@latest add https://form.buildnbuzz.com/r/starter
37
37
  ```tsx
38
38
  "use client";
39
39
 
40
- import { createSchema, type InferSchema } from "@buildnbuzz/buzzform";
40
+ import { createSchema, type InferType } from "@buildnbuzz/buzzform";
41
41
  import { Form } from "@/components/buzzform/form";
42
42
 
43
43
  const schema = createSchema([
@@ -46,7 +46,7 @@ const schema = createSchema([
46
46
  { type: "password", name: "password", label: "Password", minLength: 8 },
47
47
  ]);
48
48
 
49
- type FormData = InferSchema<typeof schema>;
49
+ type FormData = InferType<typeof schema>;
50
50
 
51
51
  export function LoginForm() {
52
52
  const handleSubmit = async (data: FormData) => {
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { F as Field, a as FormConfig, U as UseFormOptions, b as FormAdapter } from './adapter-nQW28cyO.mjs';
2
2
  export { g as AdapterFactory, f as AdapterOptions, y as ArrayField, A as ArrayHelpers, B as BaseField, O as BuzzFormSchema, s as CheckboxField, J as CollapsibleField, C as ConditionContext, L as DataField, D as DateField, p as DatetimeField, E as EmailField, k as FieldComponentProps, j as FieldCondition, d as FieldError, l as FieldInputProps, m as FieldInputRenderFn, n as FieldStyle, K as FieldType, Q as FormSettings, c as FormState, G as GroupField, M as LayoutField, N as NumberField, P as PasswordField, u as RadioField, e as Resolver, R as ResolverResult, z as RowField, r as SelectField, q as SelectOption, S as SetValueOptions, t as SwitchField, H as Tab, I as TabsField, w as TagsField, T as TextField, o as TextareaField, x as UploadField, V as ValidationContext, i as ValidationFn, h as ValidationResult, v as validateAdapter } from './adapter-nQW28cyO.mjs';
3
- export { F as FieldToZod, a as FieldsToShape, I as InferSchema, S as SchemaBuilder, b as SchemaBuilderMap, g as coerceToDate, d as coerceToNumber, k as createArrayHelpers, c as createSchema, e as extractValidationConfig, f as fieldsToZodSchema, o as formatBytes, l as generateFieldId, n as getNestedValue, h as getPatternErrorMessage, i as isFileLike, j as isFileTypeAccepted, m as makeOptional, s as setNestedValue } from './utils-Dzp_68i3.mjs';
3
+ export { F as FieldToZod, a as FieldsToShape, c as InferSchema, I as InferType, S as SchemaBuilder, b as SchemaBuilderMap, h as coerceToDate, g as coerceToNumber, l as createArrayHelpers, d as createSchema, e as extractValidationConfig, f as fieldsToZodSchema, p as formatBytes, n as generateFieldId, o as getNestedValue, i as getPatternErrorMessage, j as isFileLike, k as isFileTypeAccepted, m as makeOptional, s as setNestedValue } from './utils-BRY27BLX.mjs';
4
4
  import * as React from 'react';
5
5
  import React__default, { ReactNode } from 'react';
6
6
  import 'zod';
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { F as Field, a as FormConfig, U as UseFormOptions, b as FormAdapter } from './adapter-nQW28cyO.js';
2
2
  export { g as AdapterFactory, f as AdapterOptions, y as ArrayField, A as ArrayHelpers, B as BaseField, O as BuzzFormSchema, s as CheckboxField, J as CollapsibleField, C as ConditionContext, L as DataField, D as DateField, p as DatetimeField, E as EmailField, k as FieldComponentProps, j as FieldCondition, d as FieldError, l as FieldInputProps, m as FieldInputRenderFn, n as FieldStyle, K as FieldType, Q as FormSettings, c as FormState, G as GroupField, M as LayoutField, N as NumberField, P as PasswordField, u as RadioField, e as Resolver, R as ResolverResult, z as RowField, r as SelectField, q as SelectOption, S as SetValueOptions, t as SwitchField, H as Tab, I as TabsField, w as TagsField, T as TextField, o as TextareaField, x as UploadField, V as ValidationContext, i as ValidationFn, h as ValidationResult, v as validateAdapter } from './adapter-nQW28cyO.js';
3
- export { F as FieldToZod, a as FieldsToShape, I as InferSchema, S as SchemaBuilder, b as SchemaBuilderMap, g as coerceToDate, d as coerceToNumber, k as createArrayHelpers, c as createSchema, e as extractValidationConfig, f as fieldsToZodSchema, o as formatBytes, l as generateFieldId, n as getNestedValue, h as getPatternErrorMessage, i as isFileLike, j as isFileTypeAccepted, m as makeOptional, s as setNestedValue } from './utils-CS2VrTJU.js';
3
+ export { F as FieldToZod, a as FieldsToShape, c as InferSchema, I as InferType, S as SchemaBuilder, b as SchemaBuilderMap, h as coerceToDate, g as coerceToNumber, l as createArrayHelpers, d as createSchema, e as extractValidationConfig, f as fieldsToZodSchema, p as formatBytes, n as generateFieldId, o as getNestedValue, i as getPatternErrorMessage, j as isFileLike, k as isFileTypeAccepted, m as makeOptional, s as setNestedValue } from './utils-DgwUn6tN.js';
4
4
  import * as React from 'react';
5
5
  import React__default, { ReactNode } from 'react';
6
6
  import 'zod';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/types/adapter.ts","../src/schema/fields-to-schema.ts","../src/schema/builders/text.ts","../src/schema/helpers.ts","../src/schema/builders/number.ts","../src/schema/builders/date.ts","../src/schema/builders/select.ts","../src/schema/builders/boolean.ts","../src/schema/builders/upload.ts","../src/schema/builders/tags.ts","../src/schema/builders/composite.ts","../src/schema/create-schema.ts","../src/utils/array.ts","../src/lib/utils.ts","../src/lib/field.ts","../src/context/form-context.ts","../src/providers/form-provider.tsx","../src/hooks/use-form.ts"],"sourcesContent":["// =============================================================================\n// @buildnbuzz/buzzform\n// =============================================================================\n\n// =============================================================================\n// TYPES - Adapter Interface\n// =============================================================================\nexport type {\n FormState,\n SetValueOptions,\n FieldError,\n ResolverResult,\n Resolver,\n ArrayHelpers,\n AdapterOptions,\n FormAdapter,\n AdapterFactory,\n} from './types';\n\n// Adapter validation helper (for custom adapter authors)\nexport { validateAdapter } from './types';\n\n// =============================================================================\n// TYPES - Field Definitions\n// =============================================================================\nexport type {\n // Validation\n ValidationContext,\n ValidationResult,\n ValidationFn,\n\n // Conditional\n ConditionContext,\n FieldCondition,\n\n // Custom rendering\n FieldComponentProps,\n FieldInputProps,\n FieldInputRenderFn,\n\n // Styling\n FieldStyle,\n\n // Base\n BaseField,\n\n // Data fields\n TextField,\n EmailField,\n PasswordField,\n TextareaField,\n NumberField,\n DateField,\n DatetimeField,\n SelectOption,\n SelectField,\n CheckboxField,\n SwitchField,\n RadioField,\n TagsField,\n UploadField,\n\n // Layout fields\n GroupField,\n ArrayField,\n RowField,\n Tab,\n TabsField,\n CollapsibleField,\n\n // Union types\n Field,\n FieldType,\n DataField,\n LayoutField,\n} from './types';\n\n// =============================================================================\n// TYPES - Form Configuration\n// =============================================================================\nexport type {\n BuzzFormSchema,\n FormSettings,\n FormConfig,\n UseFormOptions,\n} from './types';\n\n// =============================================================================\n// TYPES - Schema Utilities\n// =============================================================================\nexport type {\n FieldToZod,\n FieldsToShape,\n SchemaBuilder,\n SchemaBuilderMap,\n InferSchema,\n} from './types';\n\n// =============================================================================\n// SCHEMA\n// =============================================================================\nexport { createSchema, fieldsToZodSchema } from './schema';\n\n// Re-export schema helpers for advanced usage (custom field builders)\nexport {\n extractValidationConfig,\n makeOptional,\n coerceToNumber,\n coerceToDate,\n getPatternErrorMessage,\n isFileLike,\n isFileTypeAccepted,\n} from './schema';\n\n// =============================================================================\n// UTILITIES\n// =============================================================================\nexport { createArrayHelpers } from './utils';\n\n// Common utilities for registry components\nexport { generateFieldId, getNestedValue, setNestedValue, formatBytes } from './lib';\n\n// Field utilities for nested fields, error counting, and dynamic state\nexport {\n getNestedFieldPaths,\n countNestedErrors,\n resolveFieldState,\n getArrayRowLabel,\n} from './lib';\n\n// Field style utilities\nexport { getFieldWidthStyle } from './lib';\n\n// Select option utilities\nexport {\n normalizeSelectOption,\n getSelectOptionValue,\n getSelectOptionLabel,\n getSelectOptionLabelString,\n isSelectOptionDisabled,\n} from './lib';\n\n// Number utilities\nexport {\n clampNumber,\n applyNumericPrecision,\n formatNumberWithSeparator,\n parseFormattedNumber,\n} from './lib';\n\n// Date utilities\nexport { parseToDate } from './lib';\n\n// =============================================================================\n// CONTEXT & PROVIDERS\n// =============================================================================\nexport { FormProvider } from './providers/form-provider';\nexport { FormConfigContext } from './context/form-context';\n\n// =============================================================================\n// HOOKS\n// =============================================================================\nexport { useForm } from './hooks/use-form';\n","import type { FormEvent } from 'react';\nimport type { FormSettings } from './form';\n\n// =============================================================================\n// FORM STATE\n// =============================================================================\n\n/**\n * Represents the current reactive state of a form.\n * Adapters must ensure this triggers re-renders when values change.\n * \n * This is the MINIMUM state required for BuzzForm to work.\n * Custom adapters must provide all these properties.\n */\nexport interface FormState {\n /** True while the form is being submitted */\n isSubmitting: boolean;\n\n /** True while validation is running (async validators) */\n isValidating: boolean;\n\n /** True if any field has been modified from its default value */\n isDirty: boolean;\n\n /** True if all validations pass (no errors) */\n isValid: boolean;\n\n /** True while async default values are being resolved */\n isLoading: boolean;\n\n /** \n * Field-level errors.\n * Key is the field path (e.g., \"email\", \"address.city\", \"items.0.name\")\n * Value is the error message(s)\n * \n * NOTE: Path format uses dot notation. Array indices use numbers (items.0.name).\n */\n errors: Record<string, string | string[] | undefined>;\n\n /** Map of field paths to whether they've been modified */\n dirtyFields: Record<string, boolean>;\n\n /** Map of field paths to whether they've been touched (blurred) */\n touchedFields: Record<string, boolean>;\n\n /** Number of times the form has been submitted */\n submitCount: number;\n}\n\n// =============================================================================\n// VALUE MANAGEMENT\n// =============================================================================\n\n/**\n * Options when programmatically setting a field value.\n */\nexport interface SetValueOptions {\n /** Run validation after setting the value (default: adapter-specific) */\n shouldValidate?: boolean;\n\n /** Mark the field as dirty (default: true) */\n shouldDirty?: boolean;\n\n /** Mark the field as touched (default: false) */\n shouldTouch?: boolean;\n}\n\n// =============================================================================\n// VALIDATION\n// =============================================================================\n\n/**\n * Represents a field-level error.\n */\nexport interface FieldError {\n /** Error type (e.g., 'required', 'pattern', 'server', 'custom') */\n type?: string;\n\n /** Human-readable error message */\n message: string;\n}\n\n/**\n * Result from a validation resolver.\n */\nexport interface ResolverResult<TData> {\n /** Parsed/transformed values (if validation passes) */\n values?: TData;\n\n /** Field errors (if validation fails) */\n errors?: Record<string, FieldError>;\n}\n\n/**\n * A validation resolver function.\n * Adapters use this to validate form values against a schema.\n * \n * @example\n * // Zod resolver\n * const zodResolver = (schema) => async (values) => {\n * const result = schema.safeParse(values);\n * if (result.success) return { values: result.data };\n * return { errors: mapZodErrors(result.error) };\n * };\n */\nexport type Resolver<TData> = (\n values: TData\n) => Promise<ResolverResult<TData>> | ResolverResult<TData>;\n\n// =============================================================================\n// ARRAY HELPERS\n// =============================================================================\n\n/**\n * Helper methods for manipulating array fields.\n * All methods operate on a field path (e.g., \"items\", \"users.0.tags\").\n * \n * This is REQUIRED for ArrayField to work. If your custom adapter doesn't\n * support arrays, you can implement these as no-ops or throw errors.\n */\nexport interface ArrayHelpers {\n /**\n * Get array items with stable IDs for React keys.\n * @param path - Field path to the array\n * @returns Array of items, each with an `id` property for React keys\n */\n fields: <T = unknown>(path: string) => Array<T & { id: string }>;\n\n /**\n * Add an item to the end of the array.\n */\n append: (path: string, value: unknown) => void;\n\n /**\n * Add an item to the beginning of the array.\n */\n prepend: (path: string, value: unknown) => void;\n\n /**\n * Insert an item at a specific index.\n */\n insert: (path: string, index: number, value: unknown) => void;\n\n /**\n * Remove an item at a specific index.\n */\n remove: (path: string, index: number) => void;\n\n /**\n * Move an item from one index to another.\n * Used for drag-and-drop reordering.\n */\n move: (path: string, from: number, to: number) => void;\n\n /**\n * Swap two items by their indices.\n */\n swap: (path: string, indexA: number, indexB: number) => void;\n\n /**\n * Replace the entire array with new values.\n */\n replace: (path: string, values: unknown[]) => void;\n\n /**\n * Update an item at a specific index.\n */\n update: (path: string, index: number, value: unknown) => void;\n}\n\n// =============================================================================\n// ADAPTER OPTIONS\n// =============================================================================\n\n/**\n * Base options passed to any adapter when creating a form instance.\n * Adapters can extend this with library-specific options.\n * \n * @typeParam TData - The shape of form data\n */\nexport interface AdapterOptions<TData = Record<string, unknown>> {\n /**\n * Initial values for the form.\n * Can be:\n * - A static object\n * - A sync function returning values\n * - An async function returning values (form shows loading state)\n */\n defaultValues?: TData | (() => TData) | (() => Promise<TData>);\n\n /**\n * Controlled values - when provided, form becomes controlled.\n * Changes to this prop will update form values.\n */\n values?: TData;\n\n /**\n * Validation resolver.\n * Called to validate form values before submission and optionally on change/blur.\n */\n resolver?: Resolver<TData>;\n\n /**\n * When to run validation.\n * - 'onChange': Validate on every value change\n * - 'onBlur': Validate when fields lose focus\n * - 'onSubmit': Validate only on submit\n * - 'all': Validate on all events\n * \n * NOTE: Not all adapters support all modes. Check adapter documentation.\n */\n mode?: 'onChange' | 'onBlur' | 'onSubmit' | 'all';\n\n /**\n * When to re-validate after initial error.\n * NOTE: This is optional. Some form libraries don't have this concept.\n */\n reValidateMode?: 'onChange' | 'onBlur' | 'onSubmit';\n\n /**\n * Callback when form is submitted (after validation passes).\n */\n onSubmit?: (values: TData) => Promise<void> | void;\n}\n\n// =============================================================================\n// FORM ADAPTER INTERFACE\n// =============================================================================\n\n/**\n * The contract any form adapter must fulfill.\n * \n * ## Required vs Optional\n * \n * **Required methods** are the building blocks that BuzzForm needs to function.\n * If any are missing, forms will break.\n * \n * **Optional methods** (marked with `?`) provide enhanced functionality but\n * are not required. BuzzForm will gracefully degrade without them.\n * \n * ## Creating a Custom Adapter\n * \n * To create a custom adapter (e.g., for useActionState, Formik, or vanilla React):\n * \n * 1. Implement all required properties and methods\n * 2. Optionally implement enhanced features\n * 3. Return the adapter from a hook (factory function)\n * \n * @example\n * // Minimal custom adapter skeleton\n * function useMyAdapter<T>(options: AdapterOptions<T>): FormAdapter<T> {\n * const [values, setValues] = useState(options.defaultValues ?? {});\n * const [errors, setErrors] = useState({});\n * const [isSubmitting, setIsSubmitting] = useState(false);\n * \n * return {\n * control: null, // Your state/context\n * get formState() { return { ... } },\n * handleSubmit: async (e) => { ... },\n * getValues: () => values,\n * setValue: (name, value) => { ... },\n * reset: (vals) => setValues(vals ?? {}),\n * watch: (name) => name ? values[name] : values,\n * validate: async () => true,\n * setError: (name, error) => { ... },\n * clearErrors: () => setErrors({}),\n * array: createArrayHelpers(...),\n * };\n * }\n * \n * @typeParam TData - The shape of form data\n */\nexport interface FormAdapter<TData = Record<string, unknown>> {\n // =========================================================================\n // CORE PROPERTIES (Required)\n // =========================================================================\n\n /**\n * Form-level behavior settings.\n * Set by useForm after applying FormSettings.\n */\n settings?: FormSettings;\n\n /**\n * The underlying form library's control/instance.\n * \n * This is passed to field components that need direct access to the form\n * library (e.g., for React Hook Form's Controller).\n * \n * For custom adapters, this can be:\n * - Your state object\n * - A context value\n * - null (if not needed)\n */\n control: unknown;\n\n /**\n * Current form state.\n * MUST be implemented as a getter to ensure reactivity.\n * \n * @example\n * get formState() {\n * return {\n * isSubmitting: this._isSubmitting,\n * isValidating: false,\n * isDirty: Object.keys(this._touched).length > 0,\n * isValid: Object.keys(this._errors).length === 0,\n * isLoading: false,\n * errors: this._errors,\n * dirtyFields: this._dirty,\n * touchedFields: this._touched,\n * submitCount: this._submitCount,\n * };\n * }\n */\n formState: FormState;\n\n /**\n * Submit handler to attach to a form element.\n * Should prevent default, run validation, and call onSubmit if valid.\n * \n * @example\n * <form onSubmit={adapter.handleSubmit}>\n */\n handleSubmit: (e?: FormEvent) => Promise<void> | void;\n\n // =========================================================================\n // VALUE MANAGEMENT (Required)\n // =========================================================================\n\n /**\n * Get all current form values.\n */\n getValues: () => TData;\n\n /**\n * Set a single field's value.\n * \n * @param name - Field path (e.g., \"email\", \"address.city\", \"items.0.name\")\n * @param value - New value\n * @param options - Additional options\n */\n setValue: (\n name: string,\n value: unknown,\n options?: SetValueOptions\n ) => void;\n\n /**\n * Reset form to default values or provided values.\n * \n * @param values - Optional new values to reset to\n */\n reset: (values?: Partial<TData>) => void;\n\n /**\n * Watch one or more field values reactively.\n * Returns current value(s) and causes re-render when they change.\n * \n * @param name - Field path to watch, or undefined for all values\n * @returns Current value(s)\n */\n watch: <T = unknown>(name?: string) => T;\n\n // =========================================================================\n // VALIDATION (Required)\n // =========================================================================\n\n /**\n * Manually trigger validation.\n * \n * @param name - Field(s) to validate, or undefined for entire form\n * @returns True if validation passes\n */\n validate: (name?: string | string[]) => Promise<boolean>;\n\n /**\n * Set a field error programmatically.\n * Useful for server-side validation errors.\n * \n * @param name - Field path\n * @param error - Error details\n */\n setError: (name: string, error: FieldError) => void;\n\n /**\n * Clear validation errors.\n * \n * @param name - Field(s) to clear, or undefined for all errors\n */\n clearErrors: (name?: string | string[]) => void;\n\n // =========================================================================\n // ARRAYS (Required for ArrayField)\n // =========================================================================\n\n /**\n * Helpers for manipulating array fields.\n * Required if you use ArrayField component.\n */\n array: ArrayHelpers;\n\n // =========================================================================\n // OPTIONAL ENHANCED FEATURES\n // These provide better UX but are not required for basic functionality.\n // =========================================================================\n\n /**\n * Handle field blur event.\n * Triggers validation if mode is 'onBlur'.\n * \n * If not provided, BuzzForm will not trigger blur-based validation.\n * \n * @param name - Field path\n */\n onBlur?: (name: string) => void;\n\n /**\n * Get the state of a specific field.\n * More efficient than accessing the entire formState for single fields.\n * \n * @param name - Field path\n */\n getFieldState?: (name: string) => {\n isDirty: boolean;\n isTouched: boolean;\n invalid: boolean;\n error?: string;\n };\n\n /**\n * Programmatically focus a field.\n * Useful for accessibility and after adding array items.\n * \n * @param name - Field path\n * @param options - Focus options\n */\n setFocus?: (name: string, options?: { shouldSelect?: boolean }) => void;\n\n /**\n * Unregister a field from the form.\n * Called when conditional fields are hidden.\n * \n * If not provided, hidden fields will retain their values.\n * \n * @param name - Field path(s) to unregister\n */\n unregister?: (name: string | string[]) => void;\n}\n\n// =============================================================================\n// ADAPTER FACTORY TYPE\n// =============================================================================\n\n/**\n * Type for an adapter factory function (hook).\n * \n * @example\n * // Using the adapter\n * function MyApp() {\n * return (\n * <FormProvider adapter={useRhfAdapter}>\n * <MyForm />\n * </FormProvider>\n * );\n * }\n */\nexport type AdapterFactory<TData = Record<string, unknown>> = (\n options: AdapterOptions<TData>\n) => FormAdapter<TData>;\n\n// =============================================================================\n// VALIDATION HELPERS FOR CUSTOM ADAPTERS\n// =============================================================================\n\n/**\n * Validates that a FormAdapter has all required methods.\n * Call this in development to catch missing implementations early.\n * \n * @param adapter - The adapter to validate\n * @param adapterName - Name for error messages\n * @throws Error if required methods are missing\n */\nexport function validateAdapter(adapter: FormAdapter, adapterName = 'adapter'): void {\n const required = [\n 'control',\n 'formState',\n 'handleSubmit',\n 'getValues',\n 'setValue',\n 'reset',\n 'watch',\n 'validate',\n 'setError',\n 'clearErrors',\n 'array',\n ] as const;\n\n for (const key of required) {\n if (adapter[key] === undefined) {\n throw new Error(\n `Invalid FormAdapter: \"${adapterName}\" is missing required property \"${key}\". ` +\n `See FormAdapter interface for implementation requirements.`\n );\n }\n }\n\n // Validate array helpers\n const arrayMethods = [\n 'fields', 'append', 'prepend', 'insert',\n 'remove', 'move', 'swap', 'replace', 'update'\n ] as const;\n\n for (const method of arrayMethods) {\n if (typeof adapter.array[method] !== 'function') {\n throw new Error(\n `Invalid FormAdapter: \"${adapterName}.array.${method}\" must be a function.`\n );\n }\n }\n}\n","import { z } from 'zod';\nimport type {\n Field,\n TabsField,\n TextField,\n EmailField,\n PasswordField,\n TextareaField,\n NumberField,\n DateField,\n DatetimeField,\n SelectField,\n RadioField,\n CheckboxField,\n SwitchField,\n UploadField,\n TagsField,\n ArrayField,\n GroupField,\n FieldsToShape,\n} from '../types';\nimport {\n createTextFieldSchema,\n createEmailFieldSchema,\n createPasswordFieldSchema,\n createNumberFieldSchema,\n createDateFieldSchema,\n createSelectFieldSchema,\n createRadioFieldSchema,\n createCheckboxFieldSchema,\n createSwitchFieldSchema,\n createUploadFieldSchema,\n createTagsFieldSchema,\n createArrayFieldSchema,\n createGroupFieldSchema,\n} from './builders';\n\nfunction fieldToZod(field: Field): z.ZodTypeAny {\n if ('schema' in field && field.schema) {\n return field.schema as z.ZodTypeAny;\n }\n\n switch (field.type) {\n case 'text':\n return createTextFieldSchema(field as TextField);\n case 'email':\n return createEmailFieldSchema(field as EmailField);\n case 'password':\n return createPasswordFieldSchema(field as PasswordField);\n case 'textarea':\n return createTextFieldSchema(field as TextareaField);\n case 'number':\n return createNumberFieldSchema(field as NumberField);\n case 'date':\n case 'datetime':\n return createDateFieldSchema(field as DateField | DatetimeField);\n case 'select':\n return createSelectFieldSchema(field as SelectField);\n case 'radio':\n return createRadioFieldSchema(field as RadioField);\n case 'checkbox':\n return createCheckboxFieldSchema(field as CheckboxField);\n case 'switch':\n return createSwitchFieldSchema(field as SwitchField);\n case 'upload':\n return createUploadFieldSchema(field as UploadField);\n case 'tags':\n return createTagsFieldSchema(field as TagsField);\n case 'array':\n return createArrayFieldSchema(field as ArrayField, fieldsToZodSchema);\n case 'group':\n return createGroupFieldSchema(field as GroupField, fieldsToZodSchema);\n case 'row':\n case 'collapsible':\n case 'tabs':\n return z.any();\n default:\n return z.any();\n }\n}\n\nfunction processTabsField(field: TabsField): Record<string, z.ZodTypeAny> {\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const tab of field.tabs) {\n if (tab.name) {\n const tabSchema = fieldsToZodSchema(tab.fields);\n shape[tab.name] = tabSchema;\n } else {\n const tabFieldsSchema = fieldsToZodSchema(tab.fields);\n if (tabFieldsSchema instanceof z.ZodObject) {\n Object.assign(shape, tabFieldsSchema.shape);\n }\n }\n }\n\n return shape;\n}\n\n/**\n * Converts field definitions to a Zod schema.\n * \n * Note: Custom validation (field.validate) is handled by the zodResolver,\n * not at the schema level. This ensures custom validators run even when\n * other fields have errors.\n */\nexport function fieldsToZodSchema<T extends readonly Field[]>(\n fields: T\n): z.ZodObject<FieldsToShape<T>> {\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const field of fields) {\n if ('name' in field && field.name) {\n shape[field.name] = fieldToZod(field);\n } else if (field.type === 'tabs') {\n const tabsShape = processTabsField(field);\n Object.assign(shape, tabsShape);\n } else if (field.type === 'row' || field.type === 'collapsible') {\n const nestedSchema = fieldsToZodSchema(field.fields);\n if (nestedSchema instanceof z.ZodObject) {\n Object.assign(shape, nestedSchema.shape);\n }\n }\n }\n\n return z.object(shape) as z.ZodObject<FieldsToShape<T>>;\n}\n","import { z } from 'zod';\nimport type { TextField, EmailField, TextareaField, PasswordField } from '../../types';\nimport { makeOptional, getPatternErrorMessage } from '../helpers';\n\nexport function createTextFieldSchema(field: TextField | TextareaField): z.ZodTypeAny {\n let schema = z.string({ error: 'This field is required' });\n\n if ('pattern' in field && field.pattern) {\n const pattern = typeof field.pattern === 'string'\n ? new RegExp(field.pattern)\n : field.pattern;\n\n schema = schema.regex(pattern, {\n error: getPatternErrorMessage(field.pattern),\n });\n }\n\n if (field.minLength) {\n schema = schema.min(field.minLength, {\n error: `Must be at least ${field.minLength} characters`,\n });\n }\n if (field.maxLength) {\n schema = schema.max(field.maxLength, {\n error: `Must be no more than ${field.maxLength} characters`,\n });\n }\n\n if (field.required) {\n schema = schema.min(1, { error: 'This field is required' });\n }\n\n let finalSchema: z.ZodTypeAny = schema;\n if ('trim' in field && field.trim) {\n finalSchema = z.preprocess((val) => {\n return typeof val === 'string' ? val.trim() : val;\n }, schema);\n }\n\n if (!field.required) {\n return makeOptional(finalSchema, field.type);\n }\n\n return finalSchema;\n}\n\nexport function createEmailFieldSchema(field: EmailField): z.ZodTypeAny {\n // Zod v4: z.email() for email validation with custom error\n let schema = z.email({ error: 'Invalid email address' });\n\n if (field.minLength) {\n schema = schema.min(field.minLength, {\n error: `Must be at least ${field.minLength} characters`,\n });\n }\n if (field.maxLength) {\n schema = schema.max(field.maxLength, {\n error: `Must be no more than ${field.maxLength} characters`,\n });\n }\n\n if (field.required) {\n schema = schema.min(1, { error: 'Email is required' });\n }\n\n if (!field.required) {\n return makeOptional(schema, 'email');\n }\n\n return schema;\n}\n\nexport function createPasswordFieldSchema(field: PasswordField): z.ZodTypeAny {\n // Zod v4: provide error message for invalid_type\n let schema = z.string({ error: 'Password is required' });\n\n if (field.minLength) {\n schema = schema.min(field.minLength, {\n error: `Password must be at least ${field.minLength} characters`,\n });\n }\n if (field.maxLength) {\n schema = schema.max(field.maxLength, {\n error: `Password must be no more than ${field.maxLength} characters`,\n });\n }\n if (field.required) {\n schema = schema.min(1, { error: 'Password is required' });\n }\n\n if (!field.required) {\n return makeOptional(schema, 'password');\n }\n\n return schema;\n}\n","import { z } from 'zod';\nimport type { Field, FieldType, ValidationContext, ValidationFn } from '../types';\n\n// =============================================================================\n// VALIDATION CONFIG EXTRACTION\n// =============================================================================\n\ntype ExtractableValidationFn = (\n value: unknown,\n context: ValidationContext\n) => true | string | Promise<true | string>;\n\nexport interface ExtractedValidationConfig {\n fn?: ExtractableValidationFn;\n isLive: boolean;\n debounceMs?: number;\n}\n\nexport function extractValidationConfig(\n validate?: unknown\n): ExtractedValidationConfig {\n if (!validate) {\n return { fn: undefined, isLive: false };\n }\n\n if (typeof validate === 'function') {\n return { fn: validate as ExtractableValidationFn, isLive: false };\n }\n\n if (typeof validate === 'object' && 'fn' in validate) {\n const obj = validate as { fn?: unknown; live?: boolean | { debounceMs?: number } };\n const fn = typeof obj.fn === 'function' ? obj.fn as ExtractableValidationFn : undefined;\n\n if (!obj.live) {\n return { fn, isLive: false };\n }\n\n const debounceMs = typeof obj.live === 'object' ? obj.live.debounceMs : undefined;\n return { fn, isLive: true, debounceMs };\n }\n\n return { fn: undefined, isLive: false };\n}\n\n// =============================================================================\n// FIELD VALIDATOR COLLECTION\n// =============================================================================\n\nexport interface FieldValidator {\n path: string;\n fn: ValidationFn;\n}\n\n/**\n * Recursively collects all field validators from a field array.\n */\nexport function collectFieldValidators(\n fields: readonly Field[],\n basePath: string = ''\n): FieldValidator[] {\n const validators: FieldValidator[] = [];\n\n for (const field of fields) {\n if ('name' in field && field.name) {\n const fieldPath = basePath ? `${basePath}.${field.name}` : field.name;\n\n if ('validate' in field && field.validate) {\n const config = extractValidationConfig(field.validate);\n if (config.fn) {\n validators.push({\n path: fieldPath,\n fn: config.fn as ValidationFn,\n });\n }\n }\n\n if (field.type === 'group' && 'fields' in field) {\n validators.push(...collectFieldValidators(field.fields, fieldPath));\n }\n }\n\n // Layout fields pass through without adding to path\n if (field.type === 'row' && 'fields' in field) {\n validators.push(...collectFieldValidators(field.fields, basePath));\n }\n if (field.type === 'collapsible' && 'fields' in field) {\n validators.push(...collectFieldValidators(field.fields, basePath));\n }\n if (field.type === 'tabs' && 'tabs' in field) {\n for (const tab of field.tabs) {\n const tabPath = tab.name\n ? (basePath ? `${basePath}.${tab.name}` : tab.name)\n : basePath;\n validators.push(...collectFieldValidators(tab.fields, tabPath));\n }\n }\n }\n\n return validators;\n}\n\n// =============================================================================\n// SIBLING DATA EXTRACTION\n// =============================================================================\n\n/**\n * Gets the parent object containing the field at the given path.\n */\nexport function getSiblingData(\n data: Record<string, unknown>,\n path: string\n): Record<string, unknown> {\n const parts = path.split('.');\n\n if (parts.length <= 1) {\n return data;\n }\n\n const parentParts = parts.slice(0, -1);\n let current: unknown = data;\n\n for (const part of parentParts) {\n if (current && typeof current === 'object' && current !== null) {\n current = (current as Record<string, unknown>)[part];\n } else {\n return {};\n }\n }\n\n if (current && typeof current === 'object' && current !== null) {\n return current as Record<string, unknown>;\n }\n\n return {};\n}\n\n/**\n * Gets a value at a dot-notation path.\n */\nexport function getValueByPath(\n data: Record<string, unknown>,\n path: string\n): unknown {\n const parts = path.split('.');\n let current: unknown = data;\n\n for (const part of parts) {\n if (current && typeof current === 'object' && current !== null) {\n current = (current as Record<string, unknown>)[part];\n } else {\n return undefined;\n }\n }\n\n return current;\n}\n\n/**\n * Creates a superRefine that runs all field validators with full form context.\n */\nexport function createRootValidationRefinement(\n validators: FieldValidator[]\n): (data: Record<string, unknown>, ctx: z.RefinementCtx) => Promise<void> {\n return async (data, ctx) => {\n const validationPromises = validators.map(async ({ path, fn }) => {\n const value = getValueByPath(data, path);\n const siblingData = getSiblingData(data, path);\n\n try {\n const result = await fn(value, {\n data,\n siblingData,\n path: path.split('.'),\n });\n\n if (result !== true) {\n ctx.addIssue({\n code: 'custom',\n path: path.split('.'),\n message: typeof result === 'string' ? result : 'Validation failed',\n });\n }\n } catch (error) {\n ctx.addIssue({\n code: 'custom',\n path: path.split('.'),\n message: error instanceof Error ? error.message : 'Validation error',\n });\n }\n });\n\n await Promise.all(validationPromises);\n };\n}\n\n// =============================================================================\n// OPTIONAL HANDLING\n// =============================================================================\n\nexport function makeOptional(\n schema: z.ZodTypeAny,\n fieldType: FieldType\n): z.ZodTypeAny {\n switch (fieldType) {\n case 'text':\n case 'textarea':\n case 'email':\n case 'password':\n return schema.optional().or(z.literal(''));\n\n case 'number':\n case 'date':\n case 'select':\n case 'radio':\n return schema.optional().nullable();\n\n case 'checkbox':\n case 'switch':\n return schema;\n\n case 'tags':\n case 'array':\n return schema.optional().default([]);\n\n case 'upload':\n return schema.optional().nullable();\n\n default:\n return schema.optional();\n }\n}\n\n// =============================================================================\n// COERCION HELPERS\n// =============================================================================\n\nexport function coerceToNumber(val: unknown): number | undefined {\n if (val === '' || val === null || val === undefined) {\n return undefined;\n }\n const num = Number(val);\n return isNaN(num) ? undefined : num;\n}\n\nexport function coerceToDate(val: unknown): Date | undefined {\n if (val === '' || val === null || val === undefined) {\n return undefined;\n }\n if (val instanceof Date) {\n return isNaN(val.getTime()) ? undefined : val;\n }\n if (typeof val === 'string' || typeof val === 'number') {\n const d = new Date(val);\n return isNaN(d.getTime()) ? undefined : d;\n }\n return undefined;\n}\n\n// =============================================================================\n// PATTERN VALIDATION\n// =============================================================================\n\nconst PATTERN_MESSAGES: Record<string, string> = {\n '^[a-zA-Z0-9_]+$': 'Only letters, numbers, and underscores allowed',\n '^[a-z0-9-]+$': 'Only lowercase letters, numbers, and hyphens allowed',\n '^\\\\S+@\\\\S+\\\\.\\\\S+$': 'Invalid email format',\n '^https?://': 'Must start with http:// or https://',\n};\n\nexport function getPatternErrorMessage(pattern: string | RegExp): string {\n const patternStr = typeof pattern === 'string' ? pattern : pattern.source;\n return PATTERN_MESSAGES[patternStr] || `Must match pattern: ${patternStr}`;\n}\n\n// =============================================================================\n// FILE VALIDATION HELPERS\n// =============================================================================\n\nexport function isFileLike(value: unknown): value is File {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'name' in value &&\n 'size' in value &&\n 'type' in value\n );\n}\n\nexport function isFileTypeAccepted(\n file: File,\n accept: string\n): boolean {\n if (accept === '*' || !accept) return true;\n\n const acceptTypes = accept.split(',').map(t => t.trim().toLowerCase());\n const fileType = file.type.toLowerCase();\n const fileName = file.name.toLowerCase();\n\n return acceptTypes.some(acceptType => {\n if (acceptType.endsWith('/*')) {\n const category = acceptType.replace('/*', '');\n return fileType.startsWith(category + '/');\n }\n if (acceptType.startsWith('.')) {\n return fileName.endsWith(acceptType);\n }\n return fileType === acceptType;\n });\n}\n","import { z } from 'zod';\nimport type { NumberField } from '../../types';\nimport { coerceToNumber, makeOptional } from '../helpers';\n\n/**\n * Creates Zod schema for number fields.\n * Note: Custom validation (field.validate) is handled at root schema level.\n */\nexport function createNumberFieldSchema(field: NumberField): z.ZodTypeAny {\n let numSchema = z.number({ error: 'Must be a number' });\n\n // Min/max constraints\n if (field.min !== undefined) {\n numSchema = numSchema.min(field.min, `Must be at least ${field.min}`);\n }\n if (field.max !== undefined) {\n numSchema = numSchema.max(field.max, `Must be at most ${field.max}`);\n }\n\n // Coercion: empty/null/undefined → undefined, otherwise Number()\n const schema: z.ZodTypeAny = z.preprocess(coerceToNumber, numSchema);\n\n if (field.required) {\n return schema;\n }\n\n return makeOptional(schema, 'number');\n}\n","import { z } from 'zod';\nimport type { DateField, DatetimeField } from '../../types';\nimport { coerceToDate, makeOptional } from '../helpers';\n\n/**\n * Parse a value to a Date object for constraint checking.\n */\nfunction toDate(value?: string | Date): Date | undefined {\n if (!value) return undefined;\n if (value instanceof Date) return isNaN(value.getTime()) ? undefined : value;\n const parsed = new Date(value);\n return isNaN(parsed.getTime()) ? undefined : parsed;\n}\n\n/**\n * Creates Zod schema for date and datetime fields.\n * Note: Custom validation (field.validate) is handled at root schema level.\n */\nexport function createDateFieldSchema(field: DateField | DatetimeField): z.ZodTypeAny {\n const isDatetime = field.type === 'datetime';\n\n // Parse min/max dates from field config\n const minDate = toDate(field.minDate);\n const maxDate = toDate(field.maxDate);\n\n // Build base date schema\n let dateSchema = z.date({ error: 'Please enter a valid date' });\n\n // Add min date constraint\n if (minDate) {\n const formattedDate = isDatetime ? minDate.toLocaleString() : minDate.toDateString();\n dateSchema = dateSchema.min(minDate, {\n error: `Date must be on or after ${formattedDate}`,\n });\n }\n\n // Add max date constraint\n if (maxDate) {\n const formattedDate = isDatetime ? maxDate.toLocaleString() : maxDate.toDateString();\n dateSchema = dateSchema.max(maxDate, {\n error: `Date must be on or before ${formattedDate}`,\n });\n }\n\n // Coercion from various input types\n const schema: z.ZodTypeAny = z.preprocess(coerceToDate, dateSchema);\n\n if (field.required) {\n return schema.refine(\n (val) => val instanceof Date && !isNaN(val.getTime()),\n 'Date is required'\n );\n }\n\n return makeOptional(schema, 'date');\n}\n","import { z } from 'zod';\nimport type { SelectField, RadioField } from '../../types';\nimport { makeOptional } from '../helpers';\n\n// Base schema for select/radio values with user-friendly error messages\nconst selectValueSchema = z.union([\n z.string({ error: 'Please select an option' }),\n z.number({ error: 'Please select an option' }),\n z.boolean({ error: 'Please select an option' }),\n], { error: 'Please select an option' });\n\nexport function createSelectFieldSchema(field: SelectField): z.ZodTypeAny {\n if (field.hasMany) {\n let arraySchema = z.array(selectValueSchema, { error: 'Invalid selection' });\n\n if (field.required) {\n arraySchema = arraySchema.min(1, 'Select at least one option');\n }\n\n if (!field.required) {\n return arraySchema.optional().default([]);\n }\n return arraySchema;\n }\n\n let schema: z.ZodTypeAny = selectValueSchema;\n\n if (field.required) {\n schema = selectValueSchema.refine(\n (val) => val !== '' && val !== null && val !== undefined,\n 'Please select an option'\n );\n }\n\n if (!field.required) {\n return makeOptional(schema, 'select');\n }\n\n return schema;\n}\n\nexport function createRadioFieldSchema(field: RadioField): z.ZodTypeAny {\n let schema: z.ZodTypeAny = selectValueSchema;\n\n if (field.required) {\n schema = selectValueSchema.refine(\n (val) => val !== '' && val !== null && val !== undefined,\n 'Please select an option'\n );\n }\n\n if (!field.required) {\n return makeOptional(schema, 'radio');\n }\n\n return schema;\n}\n","import { z } from 'zod';\nimport type { CheckboxField, SwitchField } from '../../types';\n\nexport function createCheckboxFieldSchema(field: CheckboxField): z.ZodTypeAny {\n let schema: z.ZodTypeAny = z.boolean({ error: 'Invalid value' });\n\n if (field.required) {\n schema = z.boolean({ error: 'This field is required' }).refine(val => val === true, {\n error: 'This field is required',\n });\n }\n\n return schema;\n}\n\nexport function createSwitchFieldSchema(field: SwitchField): z.ZodTypeAny {\n let schema: z.ZodTypeAny = z.boolean({ error: 'Invalid value' });\n\n if (field.required) {\n schema = z.boolean({ error: 'This field is required' }).refine(val => val === true, {\n error: 'This field is required',\n });\n }\n\n return schema;\n}\n","import { z } from 'zod';\nimport type { UploadField } from '../../types';\n\nfunction matchesMimePattern(fileType: string, pattern: string): boolean {\n const normalizedPattern = pattern.toLowerCase().trim();\n const normalizedType = fileType.toLowerCase();\n\n if (normalizedPattern.endsWith('/*')) {\n const category = normalizedPattern.replace('/*', '');\n return normalizedType.startsWith(category + '/');\n }\n\n if (normalizedPattern.startsWith('.')) {\n return true;\n }\n\n return normalizedType === normalizedPattern;\n}\n\nfunction isFileTypeAccepted(file: File, acceptPatterns: string[]): boolean {\n if (!file.type) return true;\n return acceptPatterns.some(pattern => matchesMimePattern(file.type, pattern));\n}\n\nexport function createUploadFieldSchema(field: UploadField): z.ZodTypeAny {\n let fileSchema: z.ZodTypeAny = z.file({ error: 'Please select a file' });\n\n if (field.maxSize) {\n const sizeMB = (field.maxSize / 1024 / 1024).toFixed(1);\n fileSchema = (fileSchema as z.ZodFile).max(field.maxSize, {\n error: `File must be smaller than ${sizeMB}MB`,\n });\n }\n\n const accept = field.ui?.accept;\n if (accept && accept !== '*') {\n const acceptPatterns = accept.split(',').map(t => t.trim());\n const hasWildcard = acceptPatterns.some(p => p.includes('*') || p.startsWith('.'));\n\n if (hasWildcard) {\n fileSchema = fileSchema.refine(\n (file) => isFileTypeAccepted(file as File, acceptPatterns),\n `File type not allowed. Accepted: ${accept}`\n );\n } else {\n fileSchema = (fileSchema as z.ZodFile).mime(acceptPatterns, {\n error: `File type not allowed. Accepted: ${accept}`,\n });\n }\n }\n\n const fileOrUrl = z.union([\n fileSchema,\n z.string({ error: 'Invalid file' }),\n ], { error: 'Please select a file' });\n\n if (field.hasMany) {\n let arraySchema = z.array(fileOrUrl, { error: 'Invalid files' });\n\n if (field.minFiles !== undefined && field.minFiles > 0) {\n arraySchema = arraySchema.min(field.minFiles, {\n error: `At least ${field.minFiles} file(s) required`,\n });\n }\n\n if (field.maxFiles !== undefined) {\n arraySchema = arraySchema.max(field.maxFiles, {\n error: `Maximum ${field.maxFiles} file(s) allowed`,\n });\n }\n\n if (field.required) {\n arraySchema = arraySchema.min(1, {\n error: 'At least one file is required',\n });\n return arraySchema;\n }\n\n return arraySchema.optional().default([]);\n }\n\n if (field.required) {\n return fileOrUrl;\n }\n\n return fileOrUrl.optional().nullable();\n}\n","import { z } from 'zod';\nimport type { TagsField } from '../../types';\n\nexport function createTagsFieldSchema(field: TagsField): z.ZodTypeAny {\n const tagSchema = z.string({ error: 'Invalid tag' });\n let schema = z.array(tagSchema, { error: 'Invalid tags' });\n\n if (field.minTags !== undefined) {\n schema = schema.min(field.minTags, `At least ${field.minTags} tag(s) required`);\n }\n if (field.maxTags !== undefined) {\n schema = schema.max(field.maxTags, `Maximum ${field.maxTags} tag(s) allowed`);\n }\n\n if (field.required) {\n return schema.refine(\n (arr) => Array.isArray(arr) && arr.length > 0,\n 'At least one tag is required'\n );\n }\n\n return schema.optional().default([]);\n}\n","import { z } from 'zod';\nimport type { ArrayField, GroupField, Field } from '../../types';\n\n// Note: These import from the parent module to avoid circular deps\n// The fieldsToZodSchema function is passed as a parameter\n\ntype SchemaGenerator = (fields: readonly Field[]) => z.ZodObject<z.ZodRawShape>;\n\n/**\n * Creates Zod schema for array fields.\n * Uses passed-in schema generator to handle nested fields.\n */\nexport function createArrayFieldSchema(\n field: ArrayField,\n fieldsToZodSchema: SchemaGenerator\n): z.ZodTypeAny {\n const itemSchema = fieldsToZodSchema(field.fields);\n let schema = z.array(itemSchema);\n\n if (field.minRows !== undefined) {\n schema = schema.min(\n field.minRows,\n `At least ${field.minRows} row${field.minRows !== 1 ? 's' : ''} required`\n );\n }\n if (field.maxRows !== undefined) {\n schema = schema.max(\n field.maxRows,\n `Maximum ${field.maxRows} row${field.maxRows !== 1 ? 's' : ''} allowed`\n );\n }\n\n if (field.required) {\n return schema;\n }\n\n return schema.optional().default([]);\n}\n\n/**\n * Creates Zod schema for group fields.\n * Uses passed-in schema generator to handle nested fields.\n */\nexport function createGroupFieldSchema(\n field: GroupField,\n fieldsToZodSchema: SchemaGenerator\n): z.ZodTypeAny {\n const schema = fieldsToZodSchema(field.fields);\n\n if (!field.required) {\n return schema.optional();\n }\n\n return schema;\n}","import { type z } from 'zod';\nimport type { Field, FieldsToShape } from '../types';\nimport type { StrictFieldArray } from '../types/strict-fields';\nimport { fieldsToZodSchema } from './fields-to-schema';\n\n/**\n * Creates a Zod schema from field definitions with strict type validation.\n *\n * @example\n * const schema = createSchema([\n * { type: 'email', name: 'email', required: true },\n * { type: 'password', name: 'password', minLength: 8 },\n * ]);\n *\n * type FormData = z.infer<typeof schema>;\n */\nexport function createSchema<const T extends readonly Field[]>(\n fields: StrictFieldArray<T> & T\n): z.ZodObject<FieldsToShape<T>> & { fields: T } {\n const schema = fieldsToZodSchema(fields as unknown as T);\n return Object.assign(schema, { fields }) as z.ZodObject<FieldsToShape<T>> & { fields: T };\n}\n","import { nanoid } from 'nanoid';\nimport type { ArrayHelpers } from '../types';\n\n/**\n * Creates a standardized set of array field manipulation methods.\n * Abstracts the difference between getting/setting values in different form libraries.\n * \n * @param getArray - Function to get current array value at a path\n * @param setArray - Function to set array value at a path\n */\nexport function createArrayHelpers(\n getArray: (path: string) => unknown[],\n setArray: (path: string, value: unknown[]) => void\n): ArrayHelpers {\n return {\n fields: <T = unknown>(path: string): Array<T & { id: string }> => {\n const arr = getArray(path);\n if (!Array.isArray(arr)) return [];\n return arr.map((item, index) => ({\n id: (item as Record<string, unknown>)?.id as string || `${path}-${index}`,\n ...item as T,\n }));\n },\n\n append: (path: string, value: unknown) => {\n const current = getArray(path) || [];\n const itemWithId = ensureId(value);\n setArray(path, [...current, itemWithId]);\n },\n\n prepend: (path: string, value: unknown) => {\n const current = getArray(path) || [];\n const itemWithId = ensureId(value);\n setArray(path, [itemWithId, ...current]);\n },\n\n insert: (path: string, index: number, value: unknown) => {\n const current = [...(getArray(path) || [])];\n const itemWithId = ensureId(value);\n current.splice(index, 0, itemWithId);\n setArray(path, current);\n },\n\n remove: (path: string, index: number) => {\n const current = [...(getArray(path) || [])];\n current.splice(index, 1);\n setArray(path, current);\n },\n\n move: (path: string, from: number, to: number) => {\n const current = [...(getArray(path) || [])];\n const [item] = current.splice(from, 1);\n current.splice(to, 0, item);\n setArray(path, current);\n },\n\n swap: (path: string, indexA: number, indexB: number) => {\n const current = [...(getArray(path) || [])];\n const temp = current[indexA];\n current[indexA] = current[indexB];\n current[indexB] = temp;\n setArray(path, current);\n },\n\n replace: (path: string, values: unknown[]) => {\n const itemsWithIds = values.map(ensureId);\n setArray(path, itemsWithIds);\n },\n\n update: (path: string, index: number, value: unknown) => {\n const current = [...(getArray(path) || [])];\n // Preserve existing ID if present\n const existingId = (current[index] as Record<string, unknown>)?.id;\n current[index] = {\n ...(typeof value === 'object' && value !== null ? value : {}),\n id: existingId || nanoid(),\n };\n setArray(path, current);\n },\n };\n}\n\n/**\n * Ensures an item has a unique ID for React keys.\n */\nfunction ensureId(value: unknown): unknown {\n if (typeof value === 'object' && value !== null) {\n const obj = value as Record<string, unknown>;\n if (!obj.id) {\n return { ...obj, id: nanoid() };\n }\n return obj;\n }\n return { value, id: nanoid() };\n}\n","// =============================================================================\n// COMMON UTILITIES\n// These are used by both the core package and registry field components.\n// =============================================================================\n\n/**\n * Generate a unique field ID from the field path.\n * Converts dot notation to dashes and prefixes with 'field-'.\n * Used for accessibility (htmlFor, id attributes).\n * \n * @example\n * generateFieldId('user.profile.email') => 'field-user-profile-email'\n * generateFieldId('items[0].name') => 'field-items-0-name'\n */\nexport function generateFieldId(path: string): string {\n return `field-${path.replace(/\\./g, \"-\").replace(/\\[/g, \"-\").replace(/\\]/g, \"\")}`;\n}\n\n/**\n * Safely retrieve a nested value from an object using a dot-notation path.\n * \n * @example\n * getNestedValue({ user: { name: 'John' } }, 'user.name') => 'John'\n * getNestedValue({ items: [{ id: 1 }] }, 'items.0.id') => 1\n */\nexport function getNestedValue(obj: unknown, path: string): unknown {\n if (!obj || !path) return undefined;\n return path.split(\".\").reduce<unknown>((acc: unknown, key: string) => {\n if (acc && typeof acc === \"object\" && acc !== null) {\n return (acc as Record<string, unknown>)[key];\n }\n return undefined;\n }, obj);\n}\n\n/**\n * Set a nested value in an object using a dot-notation path.\n * Creates intermediate objects/arrays as needed.\n * \n * @example\n * setNestedValue({}, 'user.name', 'John') => { user: { name: 'John' } }\n */\nexport function setNestedValue<T extends Record<string, unknown>>(\n obj: T,\n path: string,\n value: unknown\n): T {\n const keys = path.split(\".\");\n const result = { ...obj } as Record<string, unknown>;\n let current = result;\n\n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i];\n if (!(key in current) || typeof current[key] !== \"object\") {\n // Check if next key is numeric (array index)\n const nextKey = keys[i + 1];\n current[key] = /^\\d+$/.test(nextKey) ? [] : {};\n } else {\n current[key] = Array.isArray(current[key])\n ? [...(current[key] as unknown[])]\n : { ...(current[key] as Record<string, unknown>) };\n }\n current = current[key] as Record<string, unknown>;\n }\n\n current[keys[keys.length - 1]] = value;\n return result as T;\n}\n\n/**\n * Format bytes into a human-readable string.\n * \n * @example\n * formatBytes(1024) => '1 KB'\n * formatBytes(1234567) => '1.18 MB'\n */\nexport function formatBytes(bytes: number, decimals = 2): string {\n if (bytes === 0) return '0 Bytes';\n\n const k = 1024;\n const dm = decimals < 0 ? 0 : decimals;\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];\n\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;\n}\n\n/**\n * Flatten a nested object to dot-notation paths.\n * Useful for converting form library state (like dirtyFields, touchedFields)\n * to the flat format expected by FormState.\n * \n * @example\n * flattenNestedObject({ user: { name: true, email: true } })\n * // => { 'user.name': true, 'user.email': true }\n * \n * flattenNestedObject({ items: { 0: { title: true } } })\n * // => { 'items.0.title': true }\n */\nexport function flattenNestedObject(\n obj: Record<string, unknown>,\n prefix = ''\n): Record<string, boolean> {\n const result: Record<string, boolean> = {};\n\n for (const key in obj) {\n const path = prefix ? `${prefix}.${key}` : key;\n const value = obj[key];\n\n if (typeof value === 'boolean') {\n result[path] = value;\n } else if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n Object.assign(result, flattenNestedObject(value as Record<string, unknown>, path));\n }\n }\n\n return result;\n}\n\n","import type { ReactNode } from 'react';\nimport type { Field } from '../types';\n\n// =============================================================================\n// FIELD PATH UTILITIES\n// These utilities help work with nested field definitions and form data.\n// =============================================================================\n\n/**\n * Recursively extracts all field paths from a field definition tree.\n * Handles nested groups, arrays, and layout fields (rows, tabs, collapsibles).\n * \n * @param fields - Array of field definitions\n * @param basePath - Base path prefix (e.g., \"contacts.0\" for array items)\n * @returns Array of all field paths\n * \n * @example\n * const fields = [\n * { type: 'text', name: 'name' },\n * { type: 'group', name: 'address', fields: [\n * { type: 'text', name: 'city' },\n * { type: 'text', name: 'zip' }\n * ]}\n * ];\n * getNestedFieldPaths(fields, 'contact')\n * // => ['contact.name', 'contact.address', 'contact.address.city', 'contact.address.zip']\n */\nexport function getNestedFieldPaths(fields: Field[], basePath: string): string[] {\n const paths: string[] = [];\n\n for (const field of fields) {\n // Data fields with names\n if ('name' in field && field.name) {\n const fieldPath = basePath ? `${basePath}.${field.name}` : field.name;\n paths.push(fieldPath);\n\n // Recurse into group/array fields\n if (field.type === 'group' && 'fields' in field) {\n paths.push(...getNestedFieldPaths(field.fields, fieldPath));\n }\n if (field.type === 'array' && 'fields' in field) {\n paths.push(...getNestedFieldPaths(field.fields, fieldPath));\n }\n }\n\n // Layout fields (row, tabs, collapsible) - pass through without adding to path\n if ('fields' in field && field.type !== 'group' && field.type !== 'array') {\n const layoutField = field as Field & { fields: Field[] };\n paths.push(...getNestedFieldPaths(layoutField.fields, basePath));\n }\n\n // Tabs field - iterate through tabs\n if (field.type === 'tabs' && 'tabs' in field) {\n for (const tab of field.tabs) {\n const tabPath = tab.name ? (basePath ? `${basePath}.${tab.name}` : tab.name) : basePath;\n paths.push(...getNestedFieldPaths(tab.fields, tabPath));\n }\n }\n }\n\n return paths;\n}\n\n/**\n * Count validation errors in nested fields.\n * Useful for showing error badges on collapsible sections, array rows, tabs, etc.\n * \n * @param errors - Form errors object from FormAdapter.formState.errors\n * @param fields - Field definitions to check\n * @param basePath - Base path for the fields\n * @returns Number of fields with errors\n * \n * @example\n * const errorCount = countNestedErrors(form.formState.errors, arrayField.fields, `items.0`);\n */\nexport function countNestedErrors(\n errors: Record<string, unknown>,\n fields: Field[],\n basePath: string\n): number {\n const paths = getNestedFieldPaths(fields, basePath);\n return paths.filter((path) => errors[path]).length;\n}\n\n/**\n * Resolve a potentially dynamic field property (disabled, readOnly, hidden).\n * These properties can be boolean or a function that receives form data.\n * \n * @param value - The property value (boolean or function)\n * @param formData - Current form data\n * @param siblingData - Data at the same level (for arrays, this is the row data)\n * @returns Resolved boolean value\n * \n * @example\n * const isDisabled = resolveFieldState(field.disabled, formData, siblingData);\n */\nexport function resolveFieldState<TData = Record<string, unknown>>(\n value: boolean | ((data: TData, siblingData: Record<string, unknown>) => boolean) | undefined,\n formData: TData,\n siblingData: Record<string, unknown> = formData as Record<string, unknown>\n): boolean {\n if (typeof value === 'function') {\n return value(formData, siblingData);\n }\n return Boolean(value);\n}\n\n/**\n * Get the label value for an array row based on field configuration.\n * First checks for a specific rowLabelField in ui options, then falls back\n * to the first named field's value.\n * \n * @param rowData - Data for the row\n * @param fields - Field definitions for the array\n * @param uiOptions - UI options that may contain rowLabelField\n * @param fallbackLabel - Default label if no value found\n * @returns Label string for the row\n * \n * @example\n * const label = getArrayRowLabel(rowData, field.fields, field.ui, `Item ${index + 1}`);\n */\nexport function getArrayRowLabel(\n rowData: Record<string, unknown> | undefined,\n fields: Field[],\n uiOptions: { rowLabelField?: string } | undefined,\n fallbackLabel: string\n): string {\n // First try explicit rowLabelField\n if (uiOptions?.rowLabelField && rowData?.[uiOptions.rowLabelField]) {\n return String(rowData[uiOptions.rowLabelField]);\n }\n\n // Fall back to first named field\n const firstNamedField = fields.find((f) => 'name' in f && f.name);\n if (firstNamedField && 'name' in firstNamedField) {\n const value = rowData?.[firstNamedField.name];\n if (value) {\n return String(value);\n }\n }\n\n return fallbackLabel;\n}\n\n// =============================================================================\n// FIELD STYLE UTILITIES\n// Helpers for computing field styling props.\n// =============================================================================\n\n/**\n * Compute the inline style object for a field's width.\n * Handles both numeric (px) and string (CSS) width values.\n * \n * @param style - Field style configuration\n * @returns CSS properties object or undefined if no width specified\n * \n * @example\n * <Field style={getFieldWidthStyle(field.style)}>\n * ...\n * </Field>\n */\nexport function getFieldWidthStyle(\n style: { width?: number | string } | undefined\n): { width: string } | undefined {\n if (!style?.width) return undefined;\n return {\n width: typeof style.width === 'number'\n ? `${style.width}px`\n : style.width,\n };\n}\n\n// =============================================================================\n// SELECT OPTION UTILITIES\n// Helpers for normalizing and extracting data from SelectOption | string.\n// =============================================================================\n\ntype SelectOptionLike = { value: string | number | boolean; label?: ReactNode; description?: ReactNode; icon?: ReactNode; disabled?: boolean } | string;\n\n/**\n * Normalize a select option to always be an object.\n * Converts string options to { value, label } objects.\n * \n * @param option - String or SelectOption object\n * @returns Normalized SelectOption object\n * \n * @example\n * normalizeSelectOption('foo') // => { value: 'foo', label: 'foo' }\n * normalizeSelectOption({ value: 'bar', label: 'Bar' }) // => { value: 'bar', label: 'Bar' }\n */\nexport function normalizeSelectOption(option: SelectOptionLike): {\n value: string | number | boolean;\n label: ReactNode;\n description?: ReactNode;\n icon?: ReactNode;\n disabled?: boolean;\n} {\n if (typeof option === 'string') {\n return { value: option, label: option };\n }\n return {\n value: option.value,\n label: option.label ?? String(option.value),\n description: option.description,\n icon: option.icon,\n disabled: option.disabled,\n };\n}\n\n/**\n * Get the value from a select option (handles string or object).\n * \n * @param option - String or SelectOption object\n * @returns The option's value as a string\n * \n * @example\n * getSelectOptionValue('foo') // => 'foo'\n * getSelectOptionValue({ value: 123, label: 'One Two Three' }) // => '123'\n */\nexport function getSelectOptionValue(option: SelectOptionLike): string {\n if (typeof option === 'string') return option;\n const val = option.value;\n if (typeof val === 'boolean') return val ? 'true' : 'false';\n return String(val);\n}\n\n/**\n * Get the label from a select option (handles string or object).\n * Returns ReactNode to support JSX labels.\n * \n * @param option - String or SelectOption object\n * @returns The option's label for display\n * \n * @example\n * getSelectOptionLabel('foo') // => 'foo'\n * getSelectOptionLabel({ value: 'bar', label: <strong>Bar</strong> }) // => <strong>Bar</strong>\n */\nexport function getSelectOptionLabel(option: SelectOptionLike): ReactNode {\n if (typeof option === 'string') return option;\n return option.label ?? String(option.value);\n}\n\n/**\n * Get the string label from a select option (for filtering/comparison).\n * Always returns a string, not ReactNode.\n * \n * @param option - String or SelectOption object\n * @returns The option's label as a string\n */\nexport function getSelectOptionLabelString(option: SelectOptionLike): string {\n if (typeof option === 'string') return option;\n if (typeof option.label === 'string') return option.label;\n return String(option.value);\n}\n\n/**\n * Check if a select option is disabled.\n * \n * @param option - String or SelectOption object\n * @returns true if option is disabled\n */\nexport function isSelectOptionDisabled(option: SelectOptionLike): boolean {\n if (typeof option === 'string') return false;\n return option.disabled === true;\n}\n\n// =============================================================================\n// NUMBER UTILITIES\n// Helpers for number field operations.\n// =============================================================================\n\n/**\n * Clamp a number between min and max bounds.\n * \n * @param value - The number to clamp\n * @param min - Minimum bound (optional)\n * @param max - Maximum bound (optional)\n * @returns Clamped number\n * \n * @example\n * clampNumber(5, 0, 10) // => 5\n * clampNumber(-5, 0, 10) // => 0\n * clampNumber(15, 0, 10) // => 10\n */\nexport function clampNumber(value: number, min?: number, max?: number): number {\n let result = value;\n if (min !== undefined && result < min) result = min;\n if (max !== undefined && result > max) result = max;\n return result;\n}\n\n/**\n * Apply numeric precision (decimal places) to a number.\n * \n * @param value - The number to format\n * @param precision - Number of decimal places\n * @returns Formatted number or undefined if input is undefined\n * \n * @example\n * applyNumericPrecision(3.14159, 2) // => 3.14\n * applyNumericPrecision(10, 2) // => 10\n */\nexport function applyNumericPrecision(\n value: number | undefined,\n precision?: number\n): number | undefined {\n if (value === undefined || precision === undefined) return value;\n return parseFloat(value.toFixed(precision));\n}\n\n/**\n * Format a number with thousand separators.\n * \n * @param value - The number to format\n * @param separator - Separator character (default: ',')\n * @returns Formatted string or empty string if value is undefined/NaN\n * \n * @example\n * formatNumberWithSeparator(1234567.89) // => '1,234,567.89'\n * formatNumberWithSeparator(1234567, ' ') // => '1 234 567'\n */\nexport function formatNumberWithSeparator(\n value: number | undefined,\n separator: string = ','\n): string {\n if (value === undefined || value === null || isNaN(value)) return '';\n const [intPart, decPart] = value.toString().split('.');\n const formattedInt = intPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, separator);\n return decPart !== undefined ? `${formattedInt}.${decPart}` : formattedInt;\n}\n\n/**\n * Parse a formatted number string back to a number.\n * \n * @param str - Formatted string with separators\n * @param separator - Separator character to remove\n * @returns Parsed number or undefined if invalid\n * \n * @example\n * parseFormattedNumber('1,234,567.89') // => 1234567.89\n * parseFormattedNumber('1 234 567', ' ') // => 1234567\n */\nexport function parseFormattedNumber(\n str: string,\n separator: string = ','\n): number | undefined {\n if (!str || str === '') return undefined;\n const cleaned = str.split(separator).join('');\n const num = parseFloat(cleaned);\n return isNaN(num) ? undefined : num;\n}\n\n// =============================================================================\n// DATE UTILITIES\n// Helpers for date field operations.\n// =============================================================================\n\n/**\n * Safely parse a value to a Date object.\n * Handles Date objects, ISO strings, and timestamps.\n * \n * @param value - Value to parse (Date, string, number, or unknown)\n * @returns Date object or undefined if invalid\n * \n * @example\n * parseToDate(new Date()) // => Date\n * parseToDate('2024-01-15') // => Date\n * parseToDate(null) // => undefined\n */\nexport function parseToDate(value: unknown): Date | undefined {\n if (!value) return undefined;\n if (value instanceof Date) {\n return isNaN(value.getTime()) ? undefined : value;\n }\n if (typeof value === 'number') {\n const date = new Date(value);\n return isNaN(date.getTime()) ? undefined : date;\n }\n if (typeof value === 'string') {\n const date = new Date(value);\n return isNaN(date.getTime()) ? undefined : date;\n }\n return undefined;\n}\n","'use client';\n\nimport { createContext } from 'react';\nimport type { FormConfig } from '../types';\n\n/**\n * Context for global form configuration.\n * Set via FormProvider, consumed by useForm.\n */\nexport const FormConfigContext = createContext<FormConfig | null>(null);\n","\"use client\";\n\nimport React from \"react\";\nimport { FormConfigContext } from \"../context/form-context\";\nimport type { FormConfig } from \"../types\";\n\n/**\n * Provider for global form configuration.\n * Set the adapter, resolver, and default mode for all forms in the app.\n *\n * @example\n * import { FormProvider } from '@buildnbuzz/buzzform';\n * import { useRhfAdapter } from '@buildnbuzz/buzzform/rhf';\n * import { zodResolver } from '@buildnbuzz/buzzform/resolvers/zod';\n *\n * <FormProvider\n * adapter={useRhfAdapter}\n * resolver={zodResolver}\n * mode=\"onBlur\"\n * >\n * <App />\n * </FormProvider>\n */\nexport const FormProvider: React.FC<\n FormConfig & { children: React.ReactNode }\n> = ({ children, ...config }) => {\n return (\n <FormConfigContext.Provider value={config}>\n {children}\n </FormConfigContext.Provider>\n );\n};\n","'use client';\n\nimport { useContext, useMemo } from 'react';\nimport { FormConfigContext } from '../context/form-context';\nimport type { UseFormOptions, FormAdapter, AdapterOptions, Field, FormSettings } from '../types';\n\n/**\n * Extract default values from field definitions.\n */\nfunction extractDefaultsFromFields(fields?: Field[]): Record<string, unknown> | undefined {\n if (!fields || fields.length === 0) return undefined;\n\n const defaults: Record<string, unknown> = {};\n let hasDefaults = false;\n\n for (const field of fields) {\n if ('name' in field && 'defaultValue' in field && field.defaultValue !== undefined) {\n defaults[field.name] = field.defaultValue;\n hasDefaults = true;\n }\n // Handle nested fields (group, array)\n if ('fields' in field && Array.isArray(field.fields)) {\n const nestedDefaults = extractDefaultsFromFields(field.fields);\n if (nestedDefaults) {\n Object.assign(defaults, nestedDefaults);\n hasDefaults = true;\n }\n }\n }\n\n return hasDefaults ? defaults : undefined;\n}\n\n/**\n * Apply FormSettings to a FormAdapter.\n * Wraps handleSubmit to implement settings like submitOnlyWhenDirty.\n */\nfunction applySettings<TData>(\n form: FormAdapter<TData>,\n settings?: FormSettings\n): FormAdapter<TData> {\n if (!settings) return form;\n\n // Wrap handleSubmit if submitOnlyWhenDirty is enabled\n if (settings.submitOnlyWhenDirty) {\n const originalHandleSubmit = form.handleSubmit;\n\n form.handleSubmit = (e?: React.FormEvent) => {\n // Check if form is dirty before submitting\n if (!form.formState.isDirty) {\n e?.preventDefault?.();\n return;\n }\n return originalHandleSubmit(e);\n };\n }\n\n // Note: autoFocus is a hint for the renderer component\n // We attach it to the form for the renderer to read\n if (settings) {\n form.settings = settings;\n }\n\n return form;\n}\n\n/**\n * Create a form instance with the specified options.\n * Uses adapter and resolver from FormProvider context unless overridden.\n * \n * @example\n * const loginSchema = createSchema([\n * { type: 'email', name: 'email', required: true },\n * { type: 'password', name: 'password', required: true },\n * ]);\n * \n * const form = useForm({\n * schema: loginSchema,\n * onSubmit: async (data) => {\n * await auth.login(data);\n * },\n * settings: {\n * submitOnlyWhenDirty: true,\n * },\n * });\n * \n * return (\n * <form onSubmit={form.handleSubmit}>\n * ...\n * </form>\n * );\n */\nexport function useForm<TData extends Record<string, unknown> = Record<string, unknown>>(\n options: UseFormOptions<TData>\n): FormAdapter<TData> {\n const globalConfig = useContext(FormConfigContext);\n\n // Validate required options\n if (!options.schema) {\n throw new Error(\n 'useForm: schema is required. ' +\n 'Use createSchema([...]) to create a schema from fields, or pass a Zod schema directly.'\n );\n }\n\n // Merge global config with per-form overrides\n const adapter = options.adapter ?? globalConfig?.adapter;\n const resolverFn = globalConfig?.resolver;\n const mode = options.mode ?? globalConfig?.mode ?? 'onChange';\n const reValidateMode = options.reValidateMode ?? globalConfig?.reValidateMode ?? 'onChange';\n\n // Validate adapter is available\n if (!adapter) {\n throw new Error(\n 'useForm: No adapter configured. ' +\n 'Either wrap your app in <FormProvider adapter={...}> or pass adapter in options.'\n );\n }\n\n // Create resolver from schema\n const resolver = resolverFn ? resolverFn(options.schema) : undefined;\n\n // Extract default values\n // Priority: explicit defaultValues > field defaultValues\n const schemaWithFields = options.schema as typeof options.schema & { fields?: Field[] };\n const fieldDefaults = useMemo(\n () => extractDefaultsFromFields(schemaWithFields.fields),\n [schemaWithFields.fields]\n );\n const defaultValues = options.defaultValues ?? fieldDefaults;\n\n // Call the adapter\n const form = adapter({\n defaultValues,\n resolver,\n mode,\n reValidateMode,\n onSubmit: options.onSubmit,\n } as AdapterOptions) as FormAdapter<TData>;\n\n // Apply settings (submitOnlyWhenDirty, etc.)\n return applySettings(form, options.settings);\n}\n"],"mappings":"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","names":["import_zod","import_zod","import_zod","import_zod","import_zod","import_zod","import_zod","isFileTypeAccepted","import_zod","import_zod","fieldsToZodSchema","import_react"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/types/adapter.ts","../src/schema/fields-to-schema.ts","../src/schema/builders/text.ts","../src/schema/helpers.ts","../src/schema/builders/number.ts","../src/schema/builders/date.ts","../src/schema/builders/select.ts","../src/schema/builders/boolean.ts","../src/schema/builders/upload.ts","../src/schema/builders/tags.ts","../src/schema/builders/composite.ts","../src/schema/create-schema.ts","../src/utils/array.ts","../src/lib/utils.ts","../src/lib/field.ts","../src/context/form-context.ts","../src/providers/form-provider.tsx","../src/hooks/use-form.ts"],"sourcesContent":["// =============================================================================\n// @buildnbuzz/buzzform\n// =============================================================================\n\n// =============================================================================\n// TYPES - Adapter Interface\n// =============================================================================\nexport type {\n FormState,\n SetValueOptions,\n FieldError,\n ResolverResult,\n Resolver,\n ArrayHelpers,\n AdapterOptions,\n FormAdapter,\n AdapterFactory,\n} from './types';\n\n// Adapter validation helper (for custom adapter authors)\nexport { validateAdapter } from './types';\n\n// =============================================================================\n// TYPES - Field Definitions\n// =============================================================================\nexport type {\n // Validation\n ValidationContext,\n ValidationResult,\n ValidationFn,\n\n // Conditional\n ConditionContext,\n FieldCondition,\n\n // Custom rendering\n FieldComponentProps,\n FieldInputProps,\n FieldInputRenderFn,\n\n // Styling\n FieldStyle,\n\n // Base\n BaseField,\n\n // Data fields\n TextField,\n EmailField,\n PasswordField,\n TextareaField,\n NumberField,\n DateField,\n DatetimeField,\n SelectOption,\n SelectField,\n CheckboxField,\n SwitchField,\n RadioField,\n TagsField,\n UploadField,\n\n // Layout fields\n GroupField,\n ArrayField,\n RowField,\n Tab,\n TabsField,\n CollapsibleField,\n\n // Union types\n Field,\n FieldType,\n DataField,\n LayoutField,\n} from './types';\n\n// =============================================================================\n// TYPES - Form Configuration\n// =============================================================================\nexport type {\n BuzzFormSchema,\n FormSettings,\n FormConfig,\n UseFormOptions,\n} from './types';\n\n// =============================================================================\n// TYPES - Schema Utilities\n// =============================================================================\nexport type {\n FieldToZod,\n FieldsToShape,\n SchemaBuilder,\n SchemaBuilderMap,\n InferType,\n InferSchema,\n} from './types';\n\n// =============================================================================\n// SCHEMA\n// =============================================================================\nexport { createSchema, fieldsToZodSchema } from './schema';\n\n// Re-export schema helpers for advanced usage (custom field builders)\nexport {\n extractValidationConfig,\n makeOptional,\n coerceToNumber,\n coerceToDate,\n getPatternErrorMessage,\n isFileLike,\n isFileTypeAccepted,\n} from './schema';\n\n// =============================================================================\n// UTILITIES\n// =============================================================================\nexport { createArrayHelpers } from './utils';\n\n// Common utilities for registry components\nexport { generateFieldId, getNestedValue, setNestedValue, formatBytes } from './lib';\n\n// Field utilities for nested fields, error counting, and dynamic state\nexport {\n getNestedFieldPaths,\n countNestedErrors,\n resolveFieldState,\n getArrayRowLabel,\n} from './lib';\n\n// Field style utilities\nexport { getFieldWidthStyle } from './lib';\n\n// Select option utilities\nexport {\n normalizeSelectOption,\n getSelectOptionValue,\n getSelectOptionLabel,\n getSelectOptionLabelString,\n isSelectOptionDisabled,\n} from './lib';\n\n// Number utilities\nexport {\n clampNumber,\n applyNumericPrecision,\n formatNumberWithSeparator,\n parseFormattedNumber,\n} from './lib';\n\n// Date utilities\nexport { parseToDate } from './lib';\n\n// =============================================================================\n// CONTEXT & PROVIDERS\n// =============================================================================\nexport { FormProvider } from './providers/form-provider';\nexport { FormConfigContext } from './context/form-context';\n\n// =============================================================================\n// HOOKS\n// =============================================================================\nexport { useForm } from './hooks/use-form';\n","import type { FormEvent } from 'react';\nimport type { FormSettings } from './form';\n\n// =============================================================================\n// FORM STATE\n// =============================================================================\n\n/**\n * Represents the current reactive state of a form.\n * Adapters must ensure this triggers re-renders when values change.\n * \n * This is the MINIMUM state required for BuzzForm to work.\n * Custom adapters must provide all these properties.\n */\nexport interface FormState {\n /** True while the form is being submitted */\n isSubmitting: boolean;\n\n /** True while validation is running (async validators) */\n isValidating: boolean;\n\n /** True if any field has been modified from its default value */\n isDirty: boolean;\n\n /** True if all validations pass (no errors) */\n isValid: boolean;\n\n /** True while async default values are being resolved */\n isLoading: boolean;\n\n /** \n * Field-level errors.\n * Key is the field path (e.g., \"email\", \"address.city\", \"items.0.name\")\n * Value is the error message(s)\n * \n * NOTE: Path format uses dot notation. Array indices use numbers (items.0.name).\n */\n errors: Record<string, string | string[] | undefined>;\n\n /** Map of field paths to whether they've been modified */\n dirtyFields: Record<string, boolean>;\n\n /** Map of field paths to whether they've been touched (blurred) */\n touchedFields: Record<string, boolean>;\n\n /** Number of times the form has been submitted */\n submitCount: number;\n}\n\n// =============================================================================\n// VALUE MANAGEMENT\n// =============================================================================\n\n/**\n * Options when programmatically setting a field value.\n */\nexport interface SetValueOptions {\n /** Run validation after setting the value (default: adapter-specific) */\n shouldValidate?: boolean;\n\n /** Mark the field as dirty (default: true) */\n shouldDirty?: boolean;\n\n /** Mark the field as touched (default: false) */\n shouldTouch?: boolean;\n}\n\n// =============================================================================\n// VALIDATION\n// =============================================================================\n\n/**\n * Represents a field-level error.\n */\nexport interface FieldError {\n /** Error type (e.g., 'required', 'pattern', 'server', 'custom') */\n type?: string;\n\n /** Human-readable error message */\n message: string;\n}\n\n/**\n * Result from a validation resolver.\n */\nexport interface ResolverResult<TData> {\n /** Parsed/transformed values (if validation passes) */\n values?: TData;\n\n /** Field errors (if validation fails) */\n errors?: Record<string, FieldError>;\n}\n\n/**\n * A validation resolver function.\n * Adapters use this to validate form values against a schema.\n * \n * @example\n * // Zod resolver\n * const zodResolver = (schema) => async (values) => {\n * const result = schema.safeParse(values);\n * if (result.success) return { values: result.data };\n * return { errors: mapZodErrors(result.error) };\n * };\n */\nexport type Resolver<TData> = (\n values: TData\n) => Promise<ResolverResult<TData>> | ResolverResult<TData>;\n\n// =============================================================================\n// ARRAY HELPERS\n// =============================================================================\n\n/**\n * Helper methods for manipulating array fields.\n * All methods operate on a field path (e.g., \"items\", \"users.0.tags\").\n * \n * This is REQUIRED for ArrayField to work. If your custom adapter doesn't\n * support arrays, you can implement these as no-ops or throw errors.\n */\nexport interface ArrayHelpers {\n /**\n * Get array items with stable IDs for React keys.\n * @param path - Field path to the array\n * @returns Array of items, each with an `id` property for React keys\n */\n fields: <T = unknown>(path: string) => Array<T & { id: string }>;\n\n /**\n * Add an item to the end of the array.\n */\n append: (path: string, value: unknown) => void;\n\n /**\n * Add an item to the beginning of the array.\n */\n prepend: (path: string, value: unknown) => void;\n\n /**\n * Insert an item at a specific index.\n */\n insert: (path: string, index: number, value: unknown) => void;\n\n /**\n * Remove an item at a specific index.\n */\n remove: (path: string, index: number) => void;\n\n /**\n * Move an item from one index to another.\n * Used for drag-and-drop reordering.\n */\n move: (path: string, from: number, to: number) => void;\n\n /**\n * Swap two items by their indices.\n */\n swap: (path: string, indexA: number, indexB: number) => void;\n\n /**\n * Replace the entire array with new values.\n */\n replace: (path: string, values: unknown[]) => void;\n\n /**\n * Update an item at a specific index.\n */\n update: (path: string, index: number, value: unknown) => void;\n}\n\n// =============================================================================\n// ADAPTER OPTIONS\n// =============================================================================\n\n/**\n * Base options passed to any adapter when creating a form instance.\n * Adapters can extend this with library-specific options.\n * \n * @typeParam TData - The shape of form data\n */\nexport interface AdapterOptions<TData = Record<string, unknown>> {\n /**\n * Initial values for the form.\n * Can be:\n * - A static object\n * - A sync function returning values\n * - An async function returning values (form shows loading state)\n */\n defaultValues?: TData | (() => TData) | (() => Promise<TData>);\n\n /**\n * Controlled values - when provided, form becomes controlled.\n * Changes to this prop will update form values.\n */\n values?: TData;\n\n /**\n * Validation resolver.\n * Called to validate form values before submission and optionally on change/blur.\n */\n resolver?: Resolver<TData>;\n\n /**\n * When to run validation.\n * - 'onChange': Validate on every value change\n * - 'onBlur': Validate when fields lose focus\n * - 'onSubmit': Validate only on submit\n * - 'all': Validate on all events\n * \n * NOTE: Not all adapters support all modes. Check adapter documentation.\n */\n mode?: 'onChange' | 'onBlur' | 'onSubmit' | 'all';\n\n /**\n * When to re-validate after initial error.\n * NOTE: This is optional. Some form libraries don't have this concept.\n */\n reValidateMode?: 'onChange' | 'onBlur' | 'onSubmit';\n\n /**\n * Callback when form is submitted (after validation passes).\n */\n onSubmit?: (values: TData) => Promise<void> | void;\n}\n\n// =============================================================================\n// FORM ADAPTER INTERFACE\n// =============================================================================\n\n/**\n * The contract any form adapter must fulfill.\n * \n * ## Required vs Optional\n * \n * **Required methods** are the building blocks that BuzzForm needs to function.\n * If any are missing, forms will break.\n * \n * **Optional methods** (marked with `?`) provide enhanced functionality but\n * are not required. BuzzForm will gracefully degrade without them.\n * \n * ## Creating a Custom Adapter\n * \n * To create a custom adapter (e.g., for useActionState, Formik, or vanilla React):\n * \n * 1. Implement all required properties and methods\n * 2. Optionally implement enhanced features\n * 3. Return the adapter from a hook (factory function)\n * \n * @example\n * // Minimal custom adapter skeleton\n * function useMyAdapter<T>(options: AdapterOptions<T>): FormAdapter<T> {\n * const [values, setValues] = useState(options.defaultValues ?? {});\n * const [errors, setErrors] = useState({});\n * const [isSubmitting, setIsSubmitting] = useState(false);\n * \n * return {\n * control: null, // Your state/context\n * get formState() { return { ... } },\n * handleSubmit: async (e) => { ... },\n * getValues: () => values,\n * setValue: (name, value) => { ... },\n * reset: (vals) => setValues(vals ?? {}),\n * watch: (name) => name ? values[name] : values,\n * validate: async () => true,\n * setError: (name, error) => { ... },\n * clearErrors: () => setErrors({}),\n * array: createArrayHelpers(...),\n * };\n * }\n * \n * @typeParam TData - The shape of form data\n */\nexport interface FormAdapter<TData = Record<string, unknown>> {\n // =========================================================================\n // CORE PROPERTIES (Required)\n // =========================================================================\n\n /**\n * Form-level behavior settings.\n * Set by useForm after applying FormSettings.\n */\n settings?: FormSettings;\n\n /**\n * The underlying form library's control/instance.\n * \n * This is passed to field components that need direct access to the form\n * library (e.g., for React Hook Form's Controller).\n * \n * For custom adapters, this can be:\n * - Your state object\n * - A context value\n * - null (if not needed)\n */\n control: unknown;\n\n /**\n * Current form state.\n * MUST be implemented as a getter to ensure reactivity.\n * \n * @example\n * get formState() {\n * return {\n * isSubmitting: this._isSubmitting,\n * isValidating: false,\n * isDirty: Object.keys(this._touched).length > 0,\n * isValid: Object.keys(this._errors).length === 0,\n * isLoading: false,\n * errors: this._errors,\n * dirtyFields: this._dirty,\n * touchedFields: this._touched,\n * submitCount: this._submitCount,\n * };\n * }\n */\n formState: FormState;\n\n /**\n * Submit handler to attach to a form element.\n * Should prevent default, run validation, and call onSubmit if valid.\n * \n * @example\n * <form onSubmit={adapter.handleSubmit}>\n */\n handleSubmit: (e?: FormEvent) => Promise<void> | void;\n\n // =========================================================================\n // VALUE MANAGEMENT (Required)\n // =========================================================================\n\n /**\n * Get all current form values.\n */\n getValues: () => TData;\n\n /**\n * Set a single field's value.\n * \n * @param name - Field path (e.g., \"email\", \"address.city\", \"items.0.name\")\n * @param value - New value\n * @param options - Additional options\n */\n setValue: (\n name: string,\n value: unknown,\n options?: SetValueOptions\n ) => void;\n\n /**\n * Reset form to default values or provided values.\n * \n * @param values - Optional new values to reset to\n */\n reset: (values?: Partial<TData>) => void;\n\n /**\n * Watch one or more field values reactively.\n * Returns current value(s) and causes re-render when they change.\n * \n * @param name - Field path to watch, or undefined for all values\n * @returns Current value(s)\n */\n watch: <T = unknown>(name?: string) => T;\n\n // =========================================================================\n // VALIDATION (Required)\n // =========================================================================\n\n /**\n * Manually trigger validation.\n * \n * @param name - Field(s) to validate, or undefined for entire form\n * @returns True if validation passes\n */\n validate: (name?: string | string[]) => Promise<boolean>;\n\n /**\n * Set a field error programmatically.\n * Useful for server-side validation errors.\n * \n * @param name - Field path\n * @param error - Error details\n */\n setError: (name: string, error: FieldError) => void;\n\n /**\n * Clear validation errors.\n * \n * @param name - Field(s) to clear, or undefined for all errors\n */\n clearErrors: (name?: string | string[]) => void;\n\n // =========================================================================\n // ARRAYS (Required for ArrayField)\n // =========================================================================\n\n /**\n * Helpers for manipulating array fields.\n * Required if you use ArrayField component.\n */\n array: ArrayHelpers;\n\n // =========================================================================\n // OPTIONAL ENHANCED FEATURES\n // These provide better UX but are not required for basic functionality.\n // =========================================================================\n\n /**\n * Handle field blur event.\n * Triggers validation if mode is 'onBlur'.\n * \n * If not provided, BuzzForm will not trigger blur-based validation.\n * \n * @param name - Field path\n */\n onBlur?: (name: string) => void;\n\n /**\n * Get the state of a specific field.\n * More efficient than accessing the entire formState for single fields.\n * \n * @param name - Field path\n */\n getFieldState?: (name: string) => {\n isDirty: boolean;\n isTouched: boolean;\n invalid: boolean;\n error?: string;\n };\n\n /**\n * Programmatically focus a field.\n * Useful for accessibility and after adding array items.\n * \n * @param name - Field path\n * @param options - Focus options\n */\n setFocus?: (name: string, options?: { shouldSelect?: boolean }) => void;\n\n /**\n * Unregister a field from the form.\n * Called when conditional fields are hidden.\n * \n * If not provided, hidden fields will retain their values.\n * \n * @param name - Field path(s) to unregister\n */\n unregister?: (name: string | string[]) => void;\n}\n\n// =============================================================================\n// ADAPTER FACTORY TYPE\n// =============================================================================\n\n/**\n * Type for an adapter factory function (hook).\n * \n * @example\n * // Using the adapter\n * function MyApp() {\n * return (\n * <FormProvider adapter={useRhfAdapter}>\n * <MyForm />\n * </FormProvider>\n * );\n * }\n */\nexport type AdapterFactory<TData = Record<string, unknown>> = (\n options: AdapterOptions<TData>\n) => FormAdapter<TData>;\n\n// =============================================================================\n// VALIDATION HELPERS FOR CUSTOM ADAPTERS\n// =============================================================================\n\n/**\n * Validates that a FormAdapter has all required methods.\n * Call this in development to catch missing implementations early.\n * \n * @param adapter - The adapter to validate\n * @param adapterName - Name for error messages\n * @throws Error if required methods are missing\n */\nexport function validateAdapter(adapter: FormAdapter, adapterName = 'adapter'): void {\n const required = [\n 'control',\n 'formState',\n 'handleSubmit',\n 'getValues',\n 'setValue',\n 'reset',\n 'watch',\n 'validate',\n 'setError',\n 'clearErrors',\n 'array',\n ] as const;\n\n for (const key of required) {\n if (adapter[key] === undefined) {\n throw new Error(\n `Invalid FormAdapter: \"${adapterName}\" is missing required property \"${key}\". ` +\n `See FormAdapter interface for implementation requirements.`\n );\n }\n }\n\n // Validate array helpers\n const arrayMethods = [\n 'fields', 'append', 'prepend', 'insert',\n 'remove', 'move', 'swap', 'replace', 'update'\n ] as const;\n\n for (const method of arrayMethods) {\n if (typeof adapter.array[method] !== 'function') {\n throw new Error(\n `Invalid FormAdapter: \"${adapterName}.array.${method}\" must be a function.`\n );\n }\n }\n}\n","import { z } from 'zod';\nimport type {\n Field,\n TabsField,\n TextField,\n EmailField,\n PasswordField,\n TextareaField,\n NumberField,\n DateField,\n DatetimeField,\n SelectField,\n RadioField,\n CheckboxField,\n SwitchField,\n UploadField,\n TagsField,\n ArrayField,\n GroupField,\n FieldsToShape,\n} from '../types';\nimport {\n createTextFieldSchema,\n createEmailFieldSchema,\n createPasswordFieldSchema,\n createNumberFieldSchema,\n createDateFieldSchema,\n createSelectFieldSchema,\n createRadioFieldSchema,\n createCheckboxFieldSchema,\n createSwitchFieldSchema,\n createUploadFieldSchema,\n createTagsFieldSchema,\n createArrayFieldSchema,\n createGroupFieldSchema,\n} from './builders';\n\nfunction fieldToZod(field: Field): z.ZodTypeAny {\n if ('schema' in field && field.schema) {\n return field.schema as z.ZodTypeAny;\n }\n\n switch (field.type) {\n case 'text':\n return createTextFieldSchema(field as TextField);\n case 'email':\n return createEmailFieldSchema(field as EmailField);\n case 'password':\n return createPasswordFieldSchema(field as PasswordField);\n case 'textarea':\n return createTextFieldSchema(field as TextareaField);\n case 'number':\n return createNumberFieldSchema(field as NumberField);\n case 'date':\n case 'datetime':\n return createDateFieldSchema(field as DateField | DatetimeField);\n case 'select':\n return createSelectFieldSchema(field as SelectField);\n case 'radio':\n return createRadioFieldSchema(field as RadioField);\n case 'checkbox':\n return createCheckboxFieldSchema(field as CheckboxField);\n case 'switch':\n return createSwitchFieldSchema(field as SwitchField);\n case 'upload':\n return createUploadFieldSchema(field as UploadField);\n case 'tags':\n return createTagsFieldSchema(field as TagsField);\n case 'array':\n return createArrayFieldSchema(field as ArrayField, fieldsToZodSchema);\n case 'group':\n return createGroupFieldSchema(field as GroupField, fieldsToZodSchema);\n case 'row':\n case 'collapsible':\n case 'tabs':\n return z.any();\n default:\n return z.any();\n }\n}\n\nfunction processTabsField(field: TabsField): Record<string, z.ZodTypeAny> {\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const tab of field.tabs) {\n if (tab.name) {\n const tabSchema = fieldsToZodSchema(tab.fields);\n shape[tab.name] = tabSchema;\n } else {\n const tabFieldsSchema = fieldsToZodSchema(tab.fields);\n if (tabFieldsSchema instanceof z.ZodObject) {\n Object.assign(shape, tabFieldsSchema.shape);\n }\n }\n }\n\n return shape;\n}\n\n/**\n * Converts field definitions to a Zod schema.\n * \n * Note: Custom validation (field.validate) is handled by the zodResolver,\n * not at the schema level. This ensures custom validators run even when\n * other fields have errors.\n */\nexport function fieldsToZodSchema<T extends readonly Field[]>(\n fields: T\n): z.ZodObject<FieldsToShape<T>> {\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const field of fields) {\n if ('name' in field && field.name) {\n shape[field.name] = fieldToZod(field);\n } else if (field.type === 'tabs') {\n const tabsShape = processTabsField(field);\n Object.assign(shape, tabsShape);\n } else if (field.type === 'row' || field.type === 'collapsible') {\n const nestedSchema = fieldsToZodSchema(field.fields);\n if (nestedSchema instanceof z.ZodObject) {\n Object.assign(shape, nestedSchema.shape);\n }\n }\n }\n\n return z.object(shape) as z.ZodObject<FieldsToShape<T>>;\n}\n","import { z } from 'zod';\nimport type { TextField, EmailField, TextareaField, PasswordField } from '../../types';\nimport { makeOptional, getPatternErrorMessage } from '../helpers';\n\nexport function createTextFieldSchema(field: TextField | TextareaField): z.ZodTypeAny {\n let schema = z.string({ error: 'This field is required' });\n\n if ('pattern' in field && field.pattern) {\n const pattern = typeof field.pattern === 'string'\n ? new RegExp(field.pattern)\n : field.pattern;\n\n schema = schema.regex(pattern, {\n error: getPatternErrorMessage(field.pattern),\n });\n }\n\n if (field.minLength) {\n schema = schema.min(field.minLength, {\n error: `Must be at least ${field.minLength} characters`,\n });\n }\n if (field.maxLength) {\n schema = schema.max(field.maxLength, {\n error: `Must be no more than ${field.maxLength} characters`,\n });\n }\n\n if (field.required) {\n schema = schema.min(1, { error: 'This field is required' });\n }\n\n let finalSchema: z.ZodTypeAny = schema;\n if ('trim' in field && field.trim) {\n finalSchema = z.preprocess((val) => {\n return typeof val === 'string' ? val.trim() : val;\n }, schema);\n }\n\n if (!field.required) {\n return makeOptional(finalSchema, field.type);\n }\n\n return finalSchema;\n}\n\nexport function createEmailFieldSchema(field: EmailField): z.ZodTypeAny {\n // Zod v4: z.email() for email validation with custom error\n let schema = z.email({ error: 'Invalid email address' });\n\n if (field.minLength) {\n schema = schema.min(field.minLength, {\n error: `Must be at least ${field.minLength} characters`,\n });\n }\n if (field.maxLength) {\n schema = schema.max(field.maxLength, {\n error: `Must be no more than ${field.maxLength} characters`,\n });\n }\n\n if (field.required) {\n schema = schema.min(1, { error: 'Email is required' });\n }\n\n if (!field.required) {\n return makeOptional(schema, 'email');\n }\n\n return schema;\n}\n\nexport function createPasswordFieldSchema(field: PasswordField): z.ZodTypeAny {\n // Zod v4: provide error message for invalid_type\n let schema = z.string({ error: 'Password is required' });\n\n if (field.minLength) {\n schema = schema.min(field.minLength, {\n error: `Password must be at least ${field.minLength} characters`,\n });\n }\n if (field.maxLength) {\n schema = schema.max(field.maxLength, {\n error: `Password must be no more than ${field.maxLength} characters`,\n });\n }\n if (field.required) {\n schema = schema.min(1, { error: 'Password is required' });\n }\n\n if (!field.required) {\n return makeOptional(schema, 'password');\n }\n\n return schema;\n}\n","import { z } from 'zod';\nimport type { Field, FieldType, ValidationContext, ValidationFn } from '../types';\n\n// =============================================================================\n// VALIDATION CONFIG EXTRACTION\n// =============================================================================\n\ntype ExtractableValidationFn = (\n value: unknown,\n context: ValidationContext\n) => true | string | Promise<true | string>;\n\nexport interface ExtractedValidationConfig {\n fn?: ExtractableValidationFn;\n isLive: boolean;\n debounceMs?: number;\n}\n\nexport function extractValidationConfig(\n validate?: unknown\n): ExtractedValidationConfig {\n if (!validate) {\n return { fn: undefined, isLive: false };\n }\n\n if (typeof validate === 'function') {\n return { fn: validate as ExtractableValidationFn, isLive: false };\n }\n\n if (typeof validate === 'object' && 'fn' in validate) {\n const obj = validate as { fn?: unknown; live?: boolean | { debounceMs?: number } };\n const fn = typeof obj.fn === 'function' ? obj.fn as ExtractableValidationFn : undefined;\n\n if (!obj.live) {\n return { fn, isLive: false };\n }\n\n const debounceMs = typeof obj.live === 'object' ? obj.live.debounceMs : undefined;\n return { fn, isLive: true, debounceMs };\n }\n\n return { fn: undefined, isLive: false };\n}\n\n// =============================================================================\n// FIELD VALIDATOR COLLECTION\n// =============================================================================\n\nexport interface FieldValidator {\n path: string;\n fn: ValidationFn;\n}\n\n/**\n * Recursively collects all field validators from a field array.\n */\nexport function collectFieldValidators(\n fields: readonly Field[],\n basePath: string = ''\n): FieldValidator[] {\n const validators: FieldValidator[] = [];\n\n for (const field of fields) {\n if ('name' in field && field.name) {\n const fieldPath = basePath ? `${basePath}.${field.name}` : field.name;\n\n if ('validate' in field && field.validate) {\n const config = extractValidationConfig(field.validate);\n if (config.fn) {\n validators.push({\n path: fieldPath,\n fn: config.fn as ValidationFn,\n });\n }\n }\n\n if (field.type === 'group' && 'fields' in field) {\n validators.push(...collectFieldValidators(field.fields, fieldPath));\n }\n }\n\n // Layout fields pass through without adding to path\n if (field.type === 'row' && 'fields' in field) {\n validators.push(...collectFieldValidators(field.fields, basePath));\n }\n if (field.type === 'collapsible' && 'fields' in field) {\n validators.push(...collectFieldValidators(field.fields, basePath));\n }\n if (field.type === 'tabs' && 'tabs' in field) {\n for (const tab of field.tabs) {\n const tabPath = tab.name\n ? (basePath ? `${basePath}.${tab.name}` : tab.name)\n : basePath;\n validators.push(...collectFieldValidators(tab.fields, tabPath));\n }\n }\n }\n\n return validators;\n}\n\n// =============================================================================\n// SIBLING DATA EXTRACTION\n// =============================================================================\n\n/**\n * Gets the parent object containing the field at the given path.\n */\nexport function getSiblingData(\n data: Record<string, unknown>,\n path: string\n): Record<string, unknown> {\n const parts = path.split('.');\n\n if (parts.length <= 1) {\n return data;\n }\n\n const parentParts = parts.slice(0, -1);\n let current: unknown = data;\n\n for (const part of parentParts) {\n if (current && typeof current === 'object' && current !== null) {\n current = (current as Record<string, unknown>)[part];\n } else {\n return {};\n }\n }\n\n if (current && typeof current === 'object' && current !== null) {\n return current as Record<string, unknown>;\n }\n\n return {};\n}\n\n/**\n * Gets a value at a dot-notation path.\n */\nexport function getValueByPath(\n data: Record<string, unknown>,\n path: string\n): unknown {\n const parts = path.split('.');\n let current: unknown = data;\n\n for (const part of parts) {\n if (current && typeof current === 'object' && current !== null) {\n current = (current as Record<string, unknown>)[part];\n } else {\n return undefined;\n }\n }\n\n return current;\n}\n\n/**\n * Creates a superRefine that runs all field validators with full form context.\n */\nexport function createRootValidationRefinement(\n validators: FieldValidator[]\n): (data: Record<string, unknown>, ctx: z.RefinementCtx) => Promise<void> {\n return async (data, ctx) => {\n const validationPromises = validators.map(async ({ path, fn }) => {\n const value = getValueByPath(data, path);\n const siblingData = getSiblingData(data, path);\n\n try {\n const result = await fn(value, {\n data,\n siblingData,\n path: path.split('.'),\n });\n\n if (result !== true) {\n ctx.addIssue({\n code: 'custom',\n path: path.split('.'),\n message: typeof result === 'string' ? result : 'Validation failed',\n });\n }\n } catch (error) {\n ctx.addIssue({\n code: 'custom',\n path: path.split('.'),\n message: error instanceof Error ? error.message : 'Validation error',\n });\n }\n });\n\n await Promise.all(validationPromises);\n };\n}\n\n// =============================================================================\n// OPTIONAL HANDLING\n// =============================================================================\n\nexport function makeOptional(\n schema: z.ZodTypeAny,\n fieldType: FieldType\n): z.ZodTypeAny {\n switch (fieldType) {\n case 'text':\n case 'textarea':\n case 'email':\n case 'password':\n return schema.optional().or(z.literal(''));\n\n case 'number':\n case 'date':\n case 'select':\n case 'radio':\n return schema.optional().nullable();\n\n case 'checkbox':\n case 'switch':\n return schema;\n\n case 'tags':\n case 'array':\n return schema.optional().default([]);\n\n case 'upload':\n return schema.optional().nullable();\n\n default:\n return schema.optional();\n }\n}\n\n// =============================================================================\n// COERCION HELPERS\n// =============================================================================\n\nexport function coerceToNumber(val: unknown): number | undefined {\n if (val === '' || val === null || val === undefined) {\n return undefined;\n }\n const num = Number(val);\n return isNaN(num) ? undefined : num;\n}\n\nexport function coerceToDate(val: unknown): Date | undefined {\n if (val === '' || val === null || val === undefined) {\n return undefined;\n }\n if (val instanceof Date) {\n return isNaN(val.getTime()) ? undefined : val;\n }\n if (typeof val === 'string' || typeof val === 'number') {\n const d = new Date(val);\n return isNaN(d.getTime()) ? undefined : d;\n }\n return undefined;\n}\n\n// =============================================================================\n// PATTERN VALIDATION\n// =============================================================================\n\nconst PATTERN_MESSAGES: Record<string, string> = {\n '^[a-zA-Z0-9_]+$': 'Only letters, numbers, and underscores allowed',\n '^[a-z0-9-]+$': 'Only lowercase letters, numbers, and hyphens allowed',\n '^\\\\S+@\\\\S+\\\\.\\\\S+$': 'Invalid email format',\n '^https?://': 'Must start with http:// or https://',\n};\n\nexport function getPatternErrorMessage(pattern: string | RegExp): string {\n const patternStr = typeof pattern === 'string' ? pattern : pattern.source;\n return PATTERN_MESSAGES[patternStr] || `Must match pattern: ${patternStr}`;\n}\n\n// =============================================================================\n// FILE VALIDATION HELPERS\n// =============================================================================\n\nexport function isFileLike(value: unknown): value is File {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'name' in value &&\n 'size' in value &&\n 'type' in value\n );\n}\n\nexport function isFileTypeAccepted(\n file: File,\n accept: string\n): boolean {\n if (accept === '*' || !accept) return true;\n\n const acceptTypes = accept.split(',').map(t => t.trim().toLowerCase());\n const fileType = file.type.toLowerCase();\n const fileName = file.name.toLowerCase();\n\n return acceptTypes.some(acceptType => {\n if (acceptType.endsWith('/*')) {\n const category = acceptType.replace('/*', '');\n return fileType.startsWith(category + '/');\n }\n if (acceptType.startsWith('.')) {\n return fileName.endsWith(acceptType);\n }\n return fileType === acceptType;\n });\n}\n","import { z } from 'zod';\nimport type { NumberField } from '../../types';\nimport { coerceToNumber, makeOptional } from '../helpers';\n\n/**\n * Creates Zod schema for number fields.\n * Note: Custom validation (field.validate) is handled at root schema level.\n */\nexport function createNumberFieldSchema(field: NumberField): z.ZodTypeAny {\n let numSchema = z.number({ error: 'Must be a number' });\n\n // Min/max constraints\n if (field.min !== undefined) {\n numSchema = numSchema.min(field.min, `Must be at least ${field.min}`);\n }\n if (field.max !== undefined) {\n numSchema = numSchema.max(field.max, `Must be at most ${field.max}`);\n }\n\n // Coercion: empty/null/undefined → undefined, otherwise Number()\n const schema: z.ZodTypeAny = z.preprocess(coerceToNumber, numSchema);\n\n if (field.required) {\n return schema;\n }\n\n return makeOptional(schema, 'number');\n}\n","import { z } from 'zod';\nimport type { DateField, DatetimeField } from '../../types';\nimport { coerceToDate, makeOptional } from '../helpers';\n\n/**\n * Parse a value to a Date object for constraint checking.\n */\nfunction toDate(value?: string | Date): Date | undefined {\n if (!value) return undefined;\n if (value instanceof Date) return isNaN(value.getTime()) ? undefined : value;\n const parsed = new Date(value);\n return isNaN(parsed.getTime()) ? undefined : parsed;\n}\n\n/**\n * Creates Zod schema for date and datetime fields.\n * Note: Custom validation (field.validate) is handled at root schema level.\n */\nexport function createDateFieldSchema(field: DateField | DatetimeField): z.ZodTypeAny {\n const isDatetime = field.type === 'datetime';\n\n // Parse min/max dates from field config\n const minDate = toDate(field.minDate);\n const maxDate = toDate(field.maxDate);\n\n // Build base date schema\n let dateSchema = z.date({ error: 'Please enter a valid date' });\n\n // Add min date constraint\n if (minDate) {\n const formattedDate = isDatetime ? minDate.toLocaleString() : minDate.toDateString();\n dateSchema = dateSchema.min(minDate, {\n error: `Date must be on or after ${formattedDate}`,\n });\n }\n\n // Add max date constraint\n if (maxDate) {\n const formattedDate = isDatetime ? maxDate.toLocaleString() : maxDate.toDateString();\n dateSchema = dateSchema.max(maxDate, {\n error: `Date must be on or before ${formattedDate}`,\n });\n }\n\n // Coercion from various input types\n const schema: z.ZodTypeAny = z.preprocess(coerceToDate, dateSchema);\n\n if (field.required) {\n return schema.refine(\n (val) => val instanceof Date && !isNaN(val.getTime()),\n 'Date is required'\n );\n }\n\n return makeOptional(schema, 'date');\n}\n","import { z } from 'zod';\nimport type { SelectField, RadioField } from '../../types';\nimport { makeOptional } from '../helpers';\n\n// Base schema for select/radio values with user-friendly error messages\nconst selectValueSchema = z.union([\n z.string({ error: 'Please select an option' }),\n z.number({ error: 'Please select an option' }),\n z.boolean({ error: 'Please select an option' }),\n], { error: 'Please select an option' });\n\nexport function createSelectFieldSchema(field: SelectField): z.ZodTypeAny {\n if (field.hasMany) {\n let arraySchema = z.array(selectValueSchema, { error: 'Invalid selection' });\n\n if (field.required) {\n arraySchema = arraySchema.min(1, 'Select at least one option');\n }\n\n if (!field.required) {\n return arraySchema.optional().default([]);\n }\n return arraySchema;\n }\n\n let schema: z.ZodTypeAny = selectValueSchema;\n\n if (field.required) {\n schema = selectValueSchema.refine(\n (val) => val !== '' && val !== null && val !== undefined,\n 'Please select an option'\n );\n }\n\n if (!field.required) {\n return makeOptional(schema, 'select');\n }\n\n return schema;\n}\n\nexport function createRadioFieldSchema(field: RadioField): z.ZodTypeAny {\n let schema: z.ZodTypeAny = selectValueSchema;\n\n if (field.required) {\n schema = selectValueSchema.refine(\n (val) => val !== '' && val !== null && val !== undefined,\n 'Please select an option'\n );\n }\n\n if (!field.required) {\n return makeOptional(schema, 'radio');\n }\n\n return schema;\n}\n","import { z } from 'zod';\nimport type { CheckboxField, SwitchField } from '../../types';\n\nexport function createCheckboxFieldSchema(field: CheckboxField): z.ZodTypeAny {\n let schema: z.ZodTypeAny = z.boolean({ error: 'Invalid value' });\n\n if (field.required) {\n schema = z.boolean({ error: 'This field is required' }).refine(val => val === true, {\n error: 'This field is required',\n });\n }\n\n return schema;\n}\n\nexport function createSwitchFieldSchema(field: SwitchField): z.ZodTypeAny {\n let schema: z.ZodTypeAny = z.boolean({ error: 'Invalid value' });\n\n if (field.required) {\n schema = z.boolean({ error: 'This field is required' }).refine(val => val === true, {\n error: 'This field is required',\n });\n }\n\n return schema;\n}\n","import { z } from 'zod';\nimport type { UploadField } from '../../types';\n\nfunction matchesMimePattern(fileType: string, pattern: string): boolean {\n const normalizedPattern = pattern.toLowerCase().trim();\n const normalizedType = fileType.toLowerCase();\n\n if (normalizedPattern.endsWith('/*')) {\n const category = normalizedPattern.replace('/*', '');\n return normalizedType.startsWith(category + '/');\n }\n\n if (normalizedPattern.startsWith('.')) {\n return true;\n }\n\n return normalizedType === normalizedPattern;\n}\n\nfunction isFileTypeAccepted(file: File, acceptPatterns: string[]): boolean {\n if (!file.type) return true;\n return acceptPatterns.some(pattern => matchesMimePattern(file.type, pattern));\n}\n\nexport function createUploadFieldSchema(field: UploadField): z.ZodTypeAny {\n let fileSchema: z.ZodTypeAny = z.file({ error: 'Please select a file' });\n\n if (field.maxSize) {\n const sizeMB = (field.maxSize / 1024 / 1024).toFixed(1);\n fileSchema = (fileSchema as z.ZodFile).max(field.maxSize, {\n error: `File must be smaller than ${sizeMB}MB`,\n });\n }\n\n const accept = field.ui?.accept;\n if (accept && accept !== '*') {\n const acceptPatterns = accept.split(',').map(t => t.trim());\n const hasWildcard = acceptPatterns.some(p => p.includes('*') || p.startsWith('.'));\n\n if (hasWildcard) {\n fileSchema = fileSchema.refine(\n (file) => isFileTypeAccepted(file as File, acceptPatterns),\n `File type not allowed. Accepted: ${accept}`\n );\n } else {\n fileSchema = (fileSchema as z.ZodFile).mime(acceptPatterns, {\n error: `File type not allowed. Accepted: ${accept}`,\n });\n }\n }\n\n const fileOrUrl = z.union([\n fileSchema,\n z.string({ error: 'Invalid file' }),\n ], { error: 'Please select a file' });\n\n if (field.hasMany) {\n let arraySchema = z.array(fileOrUrl, { error: 'Invalid files' });\n\n if (field.minFiles !== undefined && field.minFiles > 0) {\n arraySchema = arraySchema.min(field.minFiles, {\n error: `At least ${field.minFiles} file(s) required`,\n });\n }\n\n if (field.maxFiles !== undefined) {\n arraySchema = arraySchema.max(field.maxFiles, {\n error: `Maximum ${field.maxFiles} file(s) allowed`,\n });\n }\n\n if (field.required) {\n arraySchema = arraySchema.min(1, {\n error: 'At least one file is required',\n });\n return arraySchema;\n }\n\n return arraySchema.optional().default([]);\n }\n\n if (field.required) {\n return fileOrUrl;\n }\n\n return fileOrUrl.optional().nullable();\n}\n","import { z } from 'zod';\nimport type { TagsField } from '../../types';\n\nexport function createTagsFieldSchema(field: TagsField): z.ZodTypeAny {\n const tagSchema = z.string({ error: 'Invalid tag' });\n let schema = z.array(tagSchema, { error: 'Invalid tags' });\n\n if (field.minTags !== undefined) {\n schema = schema.min(field.minTags, `At least ${field.minTags} tag(s) required`);\n }\n if (field.maxTags !== undefined) {\n schema = schema.max(field.maxTags, `Maximum ${field.maxTags} tag(s) allowed`);\n }\n\n if (field.required) {\n return schema.refine(\n (arr) => Array.isArray(arr) && arr.length > 0,\n 'At least one tag is required'\n );\n }\n\n return schema.optional().default([]);\n}\n","import { z } from 'zod';\nimport type { ArrayField, GroupField, Field } from '../../types';\n\n// Note: These import from the parent module to avoid circular deps\n// The fieldsToZodSchema function is passed as a parameter\n\ntype SchemaGenerator = (fields: readonly Field[]) => z.ZodObject<z.ZodRawShape>;\n\n/**\n * Creates Zod schema for array fields.\n * Uses passed-in schema generator to handle nested fields.\n */\nexport function createArrayFieldSchema(\n field: ArrayField,\n fieldsToZodSchema: SchemaGenerator\n): z.ZodTypeAny {\n const itemSchema = fieldsToZodSchema(field.fields);\n let schema = z.array(itemSchema);\n\n if (field.minRows !== undefined) {\n schema = schema.min(\n field.minRows,\n `At least ${field.minRows} row${field.minRows !== 1 ? 's' : ''} required`\n );\n }\n if (field.maxRows !== undefined) {\n schema = schema.max(\n field.maxRows,\n `Maximum ${field.maxRows} row${field.maxRows !== 1 ? 's' : ''} allowed`\n );\n }\n\n if (field.required) {\n return schema;\n }\n\n return schema.optional().default([]);\n}\n\n/**\n * Creates Zod schema for group fields.\n * Uses passed-in schema generator to handle nested fields.\n */\nexport function createGroupFieldSchema(\n field: GroupField,\n fieldsToZodSchema: SchemaGenerator\n): z.ZodTypeAny {\n const schema = fieldsToZodSchema(field.fields);\n\n if (!field.required) {\n return schema.optional();\n }\n\n return schema;\n}","import { type z } from 'zod';\nimport type { Field, FieldsToShape } from '../types';\nimport type { StrictFieldArray } from '../types/strict-fields';\nimport { fieldsToZodSchema } from './fields-to-schema';\n\n/**\n * Creates a Zod schema from field definitions with strict type validation.\n *\n * @example\n * const schema = createSchema([\n * { type: 'email', name: 'email', required: true },\n * { type: 'password', name: 'password', minLength: 8 },\n * ]);\n *\n * type FormData = z.infer<typeof schema>;\n */\nexport function createSchema<const T extends readonly Field[]>(\n fields: StrictFieldArray<T> & T\n): z.ZodObject<FieldsToShape<T>> & { fields: T } {\n const schema = fieldsToZodSchema(fields as unknown as T);\n return Object.assign(schema, { fields }) as z.ZodObject<FieldsToShape<T>> & { fields: T };\n}\n","import { nanoid } from 'nanoid';\nimport type { ArrayHelpers } from '../types';\n\n/**\n * Creates a standardized set of array field manipulation methods.\n * Abstracts the difference between getting/setting values in different form libraries.\n * \n * @param getArray - Function to get current array value at a path\n * @param setArray - Function to set array value at a path\n */\nexport function createArrayHelpers(\n getArray: (path: string) => unknown[],\n setArray: (path: string, value: unknown[]) => void\n): ArrayHelpers {\n return {\n fields: <T = unknown>(path: string): Array<T & { id: string }> => {\n const arr = getArray(path);\n if (!Array.isArray(arr)) return [];\n return arr.map((item, index) => ({\n id: (item as Record<string, unknown>)?.id as string || `${path}-${index}`,\n ...item as T,\n }));\n },\n\n append: (path: string, value: unknown) => {\n const current = getArray(path) || [];\n const itemWithId = ensureId(value);\n setArray(path, [...current, itemWithId]);\n },\n\n prepend: (path: string, value: unknown) => {\n const current = getArray(path) || [];\n const itemWithId = ensureId(value);\n setArray(path, [itemWithId, ...current]);\n },\n\n insert: (path: string, index: number, value: unknown) => {\n const current = [...(getArray(path) || [])];\n const itemWithId = ensureId(value);\n current.splice(index, 0, itemWithId);\n setArray(path, current);\n },\n\n remove: (path: string, index: number) => {\n const current = [...(getArray(path) || [])];\n current.splice(index, 1);\n setArray(path, current);\n },\n\n move: (path: string, from: number, to: number) => {\n const current = [...(getArray(path) || [])];\n const [item] = current.splice(from, 1);\n current.splice(to, 0, item);\n setArray(path, current);\n },\n\n swap: (path: string, indexA: number, indexB: number) => {\n const current = [...(getArray(path) || [])];\n const temp = current[indexA];\n current[indexA] = current[indexB];\n current[indexB] = temp;\n setArray(path, current);\n },\n\n replace: (path: string, values: unknown[]) => {\n const itemsWithIds = values.map(ensureId);\n setArray(path, itemsWithIds);\n },\n\n update: (path: string, index: number, value: unknown) => {\n const current = [...(getArray(path) || [])];\n // Preserve existing ID if present\n const existingId = (current[index] as Record<string, unknown>)?.id;\n current[index] = {\n ...(typeof value === 'object' && value !== null ? value : {}),\n id: existingId || nanoid(),\n };\n setArray(path, current);\n },\n };\n}\n\n/**\n * Ensures an item has a unique ID for React keys.\n */\nfunction ensureId(value: unknown): unknown {\n if (typeof value === 'object' && value !== null) {\n const obj = value as Record<string, unknown>;\n if (!obj.id) {\n return { ...obj, id: nanoid() };\n }\n return obj;\n }\n return { value, id: nanoid() };\n}\n","// =============================================================================\n// COMMON UTILITIES\n// These are used by both the core package and registry field components.\n// =============================================================================\n\n/**\n * Generate a unique field ID from the field path.\n * Converts dot notation to dashes and prefixes with 'field-'.\n * Used for accessibility (htmlFor, id attributes).\n * \n * @example\n * generateFieldId('user.profile.email') => 'field-user-profile-email'\n * generateFieldId('items[0].name') => 'field-items-0-name'\n */\nexport function generateFieldId(path: string): string {\n return `field-${path.replace(/\\./g, \"-\").replace(/\\[/g, \"-\").replace(/\\]/g, \"\")}`;\n}\n\n/**\n * Safely retrieve a nested value from an object using a dot-notation path.\n * \n * @example\n * getNestedValue({ user: { name: 'John' } }, 'user.name') => 'John'\n * getNestedValue({ items: [{ id: 1 }] }, 'items.0.id') => 1\n */\nexport function getNestedValue(obj: unknown, path: string): unknown {\n if (!obj || !path) return undefined;\n return path.split(\".\").reduce<unknown>((acc: unknown, key: string) => {\n if (acc && typeof acc === \"object\" && acc !== null) {\n return (acc as Record<string, unknown>)[key];\n }\n return undefined;\n }, obj);\n}\n\n/**\n * Set a nested value in an object using a dot-notation path.\n * Creates intermediate objects/arrays as needed.\n * \n * @example\n * setNestedValue({}, 'user.name', 'John') => { user: { name: 'John' } }\n */\nexport function setNestedValue<T extends Record<string, unknown>>(\n obj: T,\n path: string,\n value: unknown\n): T {\n const keys = path.split(\".\");\n const result = { ...obj } as Record<string, unknown>;\n let current = result;\n\n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i];\n if (!(key in current) || typeof current[key] !== \"object\") {\n // Check if next key is numeric (array index)\n const nextKey = keys[i + 1];\n current[key] = /^\\d+$/.test(nextKey) ? [] : {};\n } else {\n current[key] = Array.isArray(current[key])\n ? [...(current[key] as unknown[])]\n : { ...(current[key] as Record<string, unknown>) };\n }\n current = current[key] as Record<string, unknown>;\n }\n\n current[keys[keys.length - 1]] = value;\n return result as T;\n}\n\n/**\n * Format bytes into a human-readable string.\n * \n * @example\n * formatBytes(1024) => '1 KB'\n * formatBytes(1234567) => '1.18 MB'\n */\nexport function formatBytes(bytes: number, decimals = 2): string {\n if (bytes === 0) return '0 Bytes';\n\n const k = 1024;\n const dm = decimals < 0 ? 0 : decimals;\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];\n\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;\n}\n\n/**\n * Flatten a nested object to dot-notation paths.\n * Useful for converting form library state (like dirtyFields, touchedFields)\n * to the flat format expected by FormState.\n * \n * @example\n * flattenNestedObject({ user: { name: true, email: true } })\n * // => { 'user.name': true, 'user.email': true }\n * \n * flattenNestedObject({ items: { 0: { title: true } } })\n * // => { 'items.0.title': true }\n */\nexport function flattenNestedObject(\n obj: Record<string, unknown>,\n prefix = ''\n): Record<string, boolean> {\n const result: Record<string, boolean> = {};\n\n for (const key in obj) {\n const path = prefix ? `${prefix}.${key}` : key;\n const value = obj[key];\n\n if (typeof value === 'boolean') {\n result[path] = value;\n } else if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n Object.assign(result, flattenNestedObject(value as Record<string, unknown>, path));\n }\n }\n\n return result;\n}\n\n","import type { ReactNode } from 'react';\nimport type { Field } from '../types';\n\n// =============================================================================\n// FIELD PATH UTILITIES\n// These utilities help work with nested field definitions and form data.\n// =============================================================================\n\n/**\n * Recursively extracts all field paths from a field definition tree.\n * Handles nested groups, arrays, and layout fields (rows, tabs, collapsibles).\n * \n * @param fields - Array of field definitions\n * @param basePath - Base path prefix (e.g., \"contacts.0\" for array items)\n * @returns Array of all field paths\n * \n * @example\n * const fields = [\n * { type: 'text', name: 'name' },\n * { type: 'group', name: 'address', fields: [\n * { type: 'text', name: 'city' },\n * { type: 'text', name: 'zip' }\n * ]}\n * ];\n * getNestedFieldPaths(fields, 'contact')\n * // => ['contact.name', 'contact.address', 'contact.address.city', 'contact.address.zip']\n */\nexport function getNestedFieldPaths(fields: Field[], basePath: string): string[] {\n const paths: string[] = [];\n\n for (const field of fields) {\n // Data fields with names\n if ('name' in field && field.name) {\n const fieldPath = basePath ? `${basePath}.${field.name}` : field.name;\n paths.push(fieldPath);\n\n // Recurse into group/array fields\n if (field.type === 'group' && 'fields' in field) {\n paths.push(...getNestedFieldPaths(field.fields, fieldPath));\n }\n if (field.type === 'array' && 'fields' in field) {\n paths.push(...getNestedFieldPaths(field.fields, fieldPath));\n }\n }\n\n // Layout fields (row, tabs, collapsible) - pass through without adding to path\n if ('fields' in field && field.type !== 'group' && field.type !== 'array') {\n const layoutField = field as Field & { fields: Field[] };\n paths.push(...getNestedFieldPaths(layoutField.fields, basePath));\n }\n\n // Tabs field - iterate through tabs\n if (field.type === 'tabs' && 'tabs' in field) {\n for (const tab of field.tabs) {\n const tabPath = tab.name ? (basePath ? `${basePath}.${tab.name}` : tab.name) : basePath;\n paths.push(...getNestedFieldPaths(tab.fields, tabPath));\n }\n }\n }\n\n return paths;\n}\n\n/**\n * Count validation errors in nested fields.\n * Useful for showing error badges on collapsible sections, array rows, tabs, etc.\n * \n * @param errors - Form errors object from FormAdapter.formState.errors\n * @param fields - Field definitions to check\n * @param basePath - Base path for the fields\n * @returns Number of fields with errors\n * \n * @example\n * const errorCount = countNestedErrors(form.formState.errors, arrayField.fields, `items.0`);\n */\nexport function countNestedErrors(\n errors: Record<string, unknown>,\n fields: Field[],\n basePath: string\n): number {\n const paths = getNestedFieldPaths(fields, basePath);\n return paths.filter((path) => errors[path]).length;\n}\n\n/**\n * Resolve a potentially dynamic field property (disabled, readOnly, hidden).\n * These properties can be boolean or a function that receives form data.\n * \n * @param value - The property value (boolean or function)\n * @param formData - Current form data\n * @param siblingData - Data at the same level (for arrays, this is the row data)\n * @returns Resolved boolean value\n * \n * @example\n * const isDisabled = resolveFieldState(field.disabled, formData, siblingData);\n */\nexport function resolveFieldState<TData = Record<string, unknown>>(\n value: boolean | ((data: TData, siblingData: Record<string, unknown>) => boolean) | undefined,\n formData: TData,\n siblingData: Record<string, unknown> = formData as Record<string, unknown>\n): boolean {\n if (typeof value === 'function') {\n return value(formData, siblingData);\n }\n return Boolean(value);\n}\n\n/**\n * Get the label value for an array row based on field configuration.\n * First checks for a specific rowLabelField in ui options, then falls back\n * to the first named field's value.\n * \n * @param rowData - Data for the row\n * @param fields - Field definitions for the array\n * @param uiOptions - UI options that may contain rowLabelField\n * @param fallbackLabel - Default label if no value found\n * @returns Label string for the row\n * \n * @example\n * const label = getArrayRowLabel(rowData, field.fields, field.ui, `Item ${index + 1}`);\n */\nexport function getArrayRowLabel(\n rowData: Record<string, unknown> | undefined,\n fields: Field[],\n uiOptions: { rowLabelField?: string } | undefined,\n fallbackLabel: string\n): string {\n // First try explicit rowLabelField\n if (uiOptions?.rowLabelField && rowData?.[uiOptions.rowLabelField]) {\n return String(rowData[uiOptions.rowLabelField]);\n }\n\n // Fall back to first named field\n const firstNamedField = fields.find((f) => 'name' in f && f.name);\n if (firstNamedField && 'name' in firstNamedField) {\n const value = rowData?.[firstNamedField.name];\n if (value) {\n return String(value);\n }\n }\n\n return fallbackLabel;\n}\n\n// =============================================================================\n// FIELD STYLE UTILITIES\n// Helpers for computing field styling props.\n// =============================================================================\n\n/**\n * Compute the inline style object for a field's width.\n * Handles both numeric (px) and string (CSS) width values.\n * \n * @param style - Field style configuration\n * @returns CSS properties object or undefined if no width specified\n * \n * @example\n * <Field style={getFieldWidthStyle(field.style)}>\n * ...\n * </Field>\n */\nexport function getFieldWidthStyle(\n style: { width?: number | string } | undefined\n): { width: string } | undefined {\n if (!style?.width) return undefined;\n return {\n width: typeof style.width === 'number'\n ? `${style.width}px`\n : style.width,\n };\n}\n\n// =============================================================================\n// SELECT OPTION UTILITIES\n// Helpers for normalizing and extracting data from SelectOption | string.\n// =============================================================================\n\ntype SelectOptionLike = { value: string | number | boolean; label?: ReactNode; description?: ReactNode; icon?: ReactNode; disabled?: boolean } | string;\n\n/**\n * Normalize a select option to always be an object.\n * Converts string options to { value, label } objects.\n * \n * @param option - String or SelectOption object\n * @returns Normalized SelectOption object\n * \n * @example\n * normalizeSelectOption('foo') // => { value: 'foo', label: 'foo' }\n * normalizeSelectOption({ value: 'bar', label: 'Bar' }) // => { value: 'bar', label: 'Bar' }\n */\nexport function normalizeSelectOption(option: SelectOptionLike): {\n value: string | number | boolean;\n label: ReactNode;\n description?: ReactNode;\n icon?: ReactNode;\n disabled?: boolean;\n} {\n if (typeof option === 'string') {\n return { value: option, label: option };\n }\n return {\n value: option.value,\n label: option.label ?? String(option.value),\n description: option.description,\n icon: option.icon,\n disabled: option.disabled,\n };\n}\n\n/**\n * Get the value from a select option (handles string or object).\n * \n * @param option - String or SelectOption object\n * @returns The option's value as a string\n * \n * @example\n * getSelectOptionValue('foo') // => 'foo'\n * getSelectOptionValue({ value: 123, label: 'One Two Three' }) // => '123'\n */\nexport function getSelectOptionValue(option: SelectOptionLike): string {\n if (typeof option === 'string') return option;\n const val = option.value;\n if (typeof val === 'boolean') return val ? 'true' : 'false';\n return String(val);\n}\n\n/**\n * Get the label from a select option (handles string or object).\n * Returns ReactNode to support JSX labels.\n * \n * @param option - String or SelectOption object\n * @returns The option's label for display\n * \n * @example\n * getSelectOptionLabel('foo') // => 'foo'\n * getSelectOptionLabel({ value: 'bar', label: <strong>Bar</strong> }) // => <strong>Bar</strong>\n */\nexport function getSelectOptionLabel(option: SelectOptionLike): ReactNode {\n if (typeof option === 'string') return option;\n return option.label ?? String(option.value);\n}\n\n/**\n * Get the string label from a select option (for filtering/comparison).\n * Always returns a string, not ReactNode.\n * \n * @param option - String or SelectOption object\n * @returns The option's label as a string\n */\nexport function getSelectOptionLabelString(option: SelectOptionLike): string {\n if (typeof option === 'string') return option;\n if (typeof option.label === 'string') return option.label;\n return String(option.value);\n}\n\n/**\n * Check if a select option is disabled.\n * \n * @param option - String or SelectOption object\n * @returns true if option is disabled\n */\nexport function isSelectOptionDisabled(option: SelectOptionLike): boolean {\n if (typeof option === 'string') return false;\n return option.disabled === true;\n}\n\n// =============================================================================\n// NUMBER UTILITIES\n// Helpers for number field operations.\n// =============================================================================\n\n/**\n * Clamp a number between min and max bounds.\n * \n * @param value - The number to clamp\n * @param min - Minimum bound (optional)\n * @param max - Maximum bound (optional)\n * @returns Clamped number\n * \n * @example\n * clampNumber(5, 0, 10) // => 5\n * clampNumber(-5, 0, 10) // => 0\n * clampNumber(15, 0, 10) // => 10\n */\nexport function clampNumber(value: number, min?: number, max?: number): number {\n let result = value;\n if (min !== undefined && result < min) result = min;\n if (max !== undefined && result > max) result = max;\n return result;\n}\n\n/**\n * Apply numeric precision (decimal places) to a number.\n * \n * @param value - The number to format\n * @param precision - Number of decimal places\n * @returns Formatted number or undefined if input is undefined\n * \n * @example\n * applyNumericPrecision(3.14159, 2) // => 3.14\n * applyNumericPrecision(10, 2) // => 10\n */\nexport function applyNumericPrecision(\n value: number | undefined,\n precision?: number\n): number | undefined {\n if (value === undefined || precision === undefined) return value;\n return parseFloat(value.toFixed(precision));\n}\n\n/**\n * Format a number with thousand separators.\n * \n * @param value - The number to format\n * @param separator - Separator character (default: ',')\n * @returns Formatted string or empty string if value is undefined/NaN\n * \n * @example\n * formatNumberWithSeparator(1234567.89) // => '1,234,567.89'\n * formatNumberWithSeparator(1234567, ' ') // => '1 234 567'\n */\nexport function formatNumberWithSeparator(\n value: number | undefined,\n separator: string = ','\n): string {\n if (value === undefined || value === null || isNaN(value)) return '';\n const [intPart, decPart] = value.toString().split('.');\n const formattedInt = intPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, separator);\n return decPart !== undefined ? `${formattedInt}.${decPart}` : formattedInt;\n}\n\n/**\n * Parse a formatted number string back to a number.\n * \n * @param str - Formatted string with separators\n * @param separator - Separator character to remove\n * @returns Parsed number or undefined if invalid\n * \n * @example\n * parseFormattedNumber('1,234,567.89') // => 1234567.89\n * parseFormattedNumber('1 234 567', ' ') // => 1234567\n */\nexport function parseFormattedNumber(\n str: string,\n separator: string = ','\n): number | undefined {\n if (!str || str === '') return undefined;\n const cleaned = str.split(separator).join('');\n const num = parseFloat(cleaned);\n return isNaN(num) ? undefined : num;\n}\n\n// =============================================================================\n// DATE UTILITIES\n// Helpers for date field operations.\n// =============================================================================\n\n/**\n * Safely parse a value to a Date object.\n * Handles Date objects, ISO strings, and timestamps.\n * \n * @param value - Value to parse (Date, string, number, or unknown)\n * @returns Date object or undefined if invalid\n * \n * @example\n * parseToDate(new Date()) // => Date\n * parseToDate('2024-01-15') // => Date\n * parseToDate(null) // => undefined\n */\nexport function parseToDate(value: unknown): Date | undefined {\n if (!value) return undefined;\n if (value instanceof Date) {\n return isNaN(value.getTime()) ? undefined : value;\n }\n if (typeof value === 'number') {\n const date = new Date(value);\n return isNaN(date.getTime()) ? undefined : date;\n }\n if (typeof value === 'string') {\n const date = new Date(value);\n return isNaN(date.getTime()) ? undefined : date;\n }\n return undefined;\n}\n","'use client';\n\nimport { createContext } from 'react';\nimport type { FormConfig } from '../types';\n\n/**\n * Context for global form configuration.\n * Set via FormProvider, consumed by useForm.\n */\nexport const FormConfigContext = createContext<FormConfig | null>(null);\n","\"use client\";\n\nimport React from \"react\";\nimport { FormConfigContext } from \"../context/form-context\";\nimport type { FormConfig } from \"../types\";\n\n/**\n * Provider for global form configuration.\n * Set the adapter, resolver, and default mode for all forms in the app.\n *\n * @example\n * import { FormProvider } from '@buildnbuzz/buzzform';\n * import { useRhfAdapter } from '@buildnbuzz/buzzform/rhf';\n * import { zodResolver } from '@buildnbuzz/buzzform/resolvers/zod';\n *\n * <FormProvider\n * adapter={useRhfAdapter}\n * resolver={zodResolver}\n * mode=\"onBlur\"\n * >\n * <App />\n * </FormProvider>\n */\nexport const FormProvider: React.FC<\n FormConfig & { children: React.ReactNode }\n> = ({ children, ...config }) => {\n return (\n <FormConfigContext.Provider value={config}>\n {children}\n </FormConfigContext.Provider>\n );\n};\n","'use client';\n\nimport { useContext, useMemo } from 'react';\nimport { FormConfigContext } from '../context/form-context';\nimport type { UseFormOptions, FormAdapter, AdapterOptions, Field, FormSettings } from '../types';\n\n/**\n * Extract default values from field definitions.\n */\nfunction extractDefaultsFromFields(fields?: Field[]): Record<string, unknown> | undefined {\n if (!fields || fields.length === 0) return undefined;\n\n const defaults: Record<string, unknown> = {};\n let hasDefaults = false;\n\n for (const field of fields) {\n if ('name' in field && 'defaultValue' in field && field.defaultValue !== undefined) {\n defaults[field.name] = field.defaultValue;\n hasDefaults = true;\n }\n // Handle nested fields (group, array)\n if ('fields' in field && Array.isArray(field.fields)) {\n const nestedDefaults = extractDefaultsFromFields(field.fields);\n if (nestedDefaults) {\n Object.assign(defaults, nestedDefaults);\n hasDefaults = true;\n }\n }\n }\n\n return hasDefaults ? defaults : undefined;\n}\n\n/**\n * Apply FormSettings to a FormAdapter.\n * Wraps handleSubmit to implement settings like submitOnlyWhenDirty.\n */\nfunction applySettings<TData>(\n form: FormAdapter<TData>,\n settings?: FormSettings\n): FormAdapter<TData> {\n if (!settings) return form;\n\n // Wrap handleSubmit if submitOnlyWhenDirty is enabled\n if (settings.submitOnlyWhenDirty) {\n const originalHandleSubmit = form.handleSubmit;\n\n form.handleSubmit = (e?: React.FormEvent) => {\n // Check if form is dirty before submitting\n if (!form.formState.isDirty) {\n e?.preventDefault?.();\n return;\n }\n return originalHandleSubmit(e);\n };\n }\n\n // Note: autoFocus is a hint for the renderer component\n // We attach it to the form for the renderer to read\n if (settings) {\n form.settings = settings;\n }\n\n return form;\n}\n\n/**\n * Create a form instance with the specified options.\n * Uses adapter and resolver from FormProvider context unless overridden.\n * \n * @example\n * const loginSchema = createSchema([\n * { type: 'email', name: 'email', required: true },\n * { type: 'password', name: 'password', required: true },\n * ]);\n * \n * const form = useForm({\n * schema: loginSchema,\n * onSubmit: async (data) => {\n * await auth.login(data);\n * },\n * settings: {\n * submitOnlyWhenDirty: true,\n * },\n * });\n * \n * return (\n * <form onSubmit={form.handleSubmit}>\n * ...\n * </form>\n * );\n */\nexport function useForm<TData extends Record<string, unknown> = Record<string, unknown>>(\n options: UseFormOptions<TData>\n): FormAdapter<TData> {\n const globalConfig = useContext(FormConfigContext);\n\n // Validate required options\n if (!options.schema) {\n throw new Error(\n 'useForm: schema is required. ' +\n 'Use createSchema([...]) to create a schema from fields, or pass a Zod schema directly.'\n );\n }\n\n // Merge global config with per-form overrides\n const adapter = options.adapter ?? globalConfig?.adapter;\n const resolverFn = globalConfig?.resolver;\n const mode = options.mode ?? globalConfig?.mode ?? 'onChange';\n const reValidateMode = options.reValidateMode ?? globalConfig?.reValidateMode ?? 'onChange';\n\n // Validate adapter is available\n if (!adapter) {\n throw new Error(\n 'useForm: No adapter configured. ' +\n 'Either wrap your app in <FormProvider adapter={...}> or pass adapter in options.'\n );\n }\n\n // Create resolver from schema\n const resolver = resolverFn ? resolverFn(options.schema) : undefined;\n\n // Extract default values\n // Priority: explicit defaultValues > field defaultValues\n const schemaWithFields = options.schema as typeof options.schema & { fields?: Field[] };\n const fieldDefaults = useMemo(\n () => extractDefaultsFromFields(schemaWithFields.fields),\n [schemaWithFields.fields]\n );\n const defaultValues = options.defaultValues ?? fieldDefaults;\n\n // Call the adapter\n const form = adapter({\n defaultValues,\n resolver,\n mode,\n reValidateMode,\n onSubmit: options.onSubmit,\n } as AdapterOptions) as FormAdapter<TData>;\n\n // Apply settings (submitOnlyWhenDirty, etc.)\n return applySettings(form, options.settings);\n}\n"],"mappings":"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","names":["import_zod","import_zod","import_zod","import_zod","import_zod","import_zod","import_zod","isFileTypeAccepted","import_zod","import_zod","fieldsToZodSchema","import_react"]}
package/dist/schema.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { T as TextField, o as TextareaField, E as EmailField, P as PasswordField, N as NumberField, D as DateField, p as DatetimeField, r as SelectField, u as RadioField, s as CheckboxField, t as SwitchField, x as UploadField, w as TagsField, y as ArrayField, F as Field, G as GroupField } from './adapter-nQW28cyO.mjs';
2
2
  export { g as AdapterFactory, f as AdapterOptions, A as ArrayHelpers, B as BaseField, O as BuzzFormSchema, J as CollapsibleField, C as ConditionContext, L as DataField, k as FieldComponentProps, j as FieldCondition, d as FieldError, l as FieldInputProps, m as FieldInputRenderFn, n as FieldStyle, K as FieldType, b as FormAdapter, a as FormConfig, Q as FormSettings, c as FormState, M as LayoutField, e as Resolver, R as ResolverResult, z as RowField, q as SelectOption, S as SetValueOptions, H as Tab, I as TabsField, U as UseFormOptions, V as ValidationContext, i as ValidationFn, h as ValidationResult } from './adapter-nQW28cyO.mjs';
3
- export { F as FieldToZod, t as FieldValidator, a as FieldsToShape, I as InferSchema, S as SchemaBuilder, b as SchemaBuilderMap, g as coerceToDate, d as coerceToNumber, p as collectFieldValidators, k as createArrayHelpers, c as createSchema, e as extractValidationConfig, f as fieldsToZodSchema, o as formatBytes, l as generateFieldId, n as getNestedValue, h as getPatternErrorMessage, q as getSiblingData, r as getValueByPath, i as isFileLike, j as isFileTypeAccepted, m as makeOptional, s as setNestedValue } from './utils-Dzp_68i3.mjs';
3
+ export { F as FieldToZod, u as FieldValidator, a as FieldsToShape, c as InferSchema, I as InferType, S as SchemaBuilder, b as SchemaBuilderMap, h as coerceToDate, g as coerceToNumber, q as collectFieldValidators, l as createArrayHelpers, d as createSchema, e as extractValidationConfig, f as fieldsToZodSchema, p as formatBytes, n as generateFieldId, o as getNestedValue, i as getPatternErrorMessage, r as getSiblingData, t as getValueByPath, j as isFileLike, k as isFileTypeAccepted, m as makeOptional, s as setNestedValue } from './utils-BRY27BLX.mjs';
4
4
  import { z } from 'zod';
5
5
  import 'react';
6
6
 
package/dist/schema.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { T as TextField, o as TextareaField, E as EmailField, P as PasswordField, N as NumberField, D as DateField, p as DatetimeField, r as SelectField, u as RadioField, s as CheckboxField, t as SwitchField, x as UploadField, w as TagsField, y as ArrayField, F as Field, G as GroupField } from './adapter-nQW28cyO.js';
2
2
  export { g as AdapterFactory, f as AdapterOptions, A as ArrayHelpers, B as BaseField, O as BuzzFormSchema, J as CollapsibleField, C as ConditionContext, L as DataField, k as FieldComponentProps, j as FieldCondition, d as FieldError, l as FieldInputProps, m as FieldInputRenderFn, n as FieldStyle, K as FieldType, b as FormAdapter, a as FormConfig, Q as FormSettings, c as FormState, M as LayoutField, e as Resolver, R as ResolverResult, z as RowField, q as SelectOption, S as SetValueOptions, H as Tab, I as TabsField, U as UseFormOptions, V as ValidationContext, i as ValidationFn, h as ValidationResult } from './adapter-nQW28cyO.js';
3
- export { F as FieldToZod, t as FieldValidator, a as FieldsToShape, I as InferSchema, S as SchemaBuilder, b as SchemaBuilderMap, g as coerceToDate, d as coerceToNumber, p as collectFieldValidators, k as createArrayHelpers, c as createSchema, e as extractValidationConfig, f as fieldsToZodSchema, o as formatBytes, l as generateFieldId, n as getNestedValue, h as getPatternErrorMessage, q as getSiblingData, r as getValueByPath, i as isFileLike, j as isFileTypeAccepted, m as makeOptional, s as setNestedValue } from './utils-CS2VrTJU.js';
3
+ export { F as FieldToZod, u as FieldValidator, a as FieldsToShape, c as InferSchema, I as InferType, S as SchemaBuilder, b as SchemaBuilderMap, h as coerceToDate, g as coerceToNumber, q as collectFieldValidators, l as createArrayHelpers, d as createSchema, e as extractValidationConfig, f as fieldsToZodSchema, p as formatBytes, n as generateFieldId, o as getNestedValue, i as getPatternErrorMessage, r as getSiblingData, t as getValueByPath, j as isFileLike, k as isFileTypeAccepted, m as makeOptional, s as setNestedValue } from './utils-DgwUn6tN.js';
4
4
  import { z } from 'zod';
5
5
  import 'react';
6
6
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/schema/index.ts","../src/schema/fields-to-schema.ts","../src/schema/builders/text.ts","../src/schema/helpers.ts","../src/schema/builders/number.ts","../src/schema/builders/date.ts","../src/schema/builders/select.ts","../src/schema/builders/boolean.ts","../src/schema/builders/upload.ts","../src/schema/builders/tags.ts","../src/schema/builders/composite.ts","../src/schema/create-schema.ts","../src/utils/array.ts","../src/lib/utils.ts"],"sourcesContent":["/**\n * Schema utilities for BuzzForm.\n *\n * @example\n * import { createSchema } from '@buildnbuzz/buzzform';\n *\n * const loginSchema = createSchema([\n * { type: 'email', name: 'email', required: true },\n * { type: 'password', name: 'password', minLength: 8 },\n * ]);\n *\n * type LoginData = z.infer<typeof loginSchema>;\n */\n\n// =============================================================================\n// TYPES - Adapter Interface (no runtime code, just types)\n// =============================================================================\nexport type {\n FormState,\n SetValueOptions,\n FieldError,\n ResolverResult,\n Resolver,\n ArrayHelpers,\n AdapterOptions,\n FormAdapter,\n AdapterFactory,\n} from '../types';\n\n// =============================================================================\n// TYPES - Field Definitions\n// =============================================================================\nexport type {\n // Validation\n ValidationContext,\n ValidationResult,\n ValidationFn,\n\n // Conditional\n ConditionContext,\n FieldCondition,\n\n // Custom rendering\n FieldComponentProps,\n FieldInputProps,\n FieldInputRenderFn,\n\n // Styling\n FieldStyle,\n\n // Base\n BaseField,\n\n // Data fields\n TextField,\n EmailField,\n PasswordField,\n TextareaField,\n NumberField,\n DateField,\n DatetimeField,\n SelectOption,\n SelectField,\n CheckboxField,\n SwitchField,\n RadioField,\n TagsField,\n UploadField,\n\n // Layout fields\n GroupField,\n ArrayField,\n RowField,\n Tab,\n TabsField,\n CollapsibleField,\n\n // Union types\n Field,\n FieldType,\n DataField,\n LayoutField,\n} from '../types';\n\n// =============================================================================\n// TYPES - Form Configuration\n// =============================================================================\nexport type {\n BuzzFormSchema,\n FormSettings,\n FormConfig,\n UseFormOptions,\n} from '../types';\n\n// =============================================================================\n// TYPES - Schema Utilities\n// =============================================================================\nexport type {\n FieldToZod,\n FieldsToShape,\n SchemaBuilder,\n SchemaBuilderMap,\n InferSchema,\n} from '../types';\n\n// =============================================================================\n// SCHEMA\n// =============================================================================\nexport { createSchema } from './create-schema';\nexport { fieldsToZodSchema } from './fields-to-schema';\n\n// Re-export schema helpers for advanced usage (custom field builders)\nexport {\n extractValidationConfig,\n makeOptional,\n coerceToNumber,\n coerceToDate,\n getPatternErrorMessage,\n isFileLike,\n isFileTypeAccepted,\n // Helpers for cross-field validation (used by zodResolver)\n collectFieldValidators,\n getSiblingData,\n getValueByPath,\n type FieldValidator,\n} from './helpers';\n\n// Individual builders for registry integration\nexport * from './builders';\n\n// =============================================================================\n// UTILITIES (Server-safe - no React imports)\n// =============================================================================\nexport { createArrayHelpers } from '../utils';\n\n// Add common utilities that registry components will need\nexport { generateFieldId, getNestedValue, setNestedValue, formatBytes } from '../lib';","import { z } from 'zod';\nimport type {\n Field,\n TabsField,\n TextField,\n EmailField,\n PasswordField,\n TextareaField,\n NumberField,\n DateField,\n DatetimeField,\n SelectField,\n RadioField,\n CheckboxField,\n SwitchField,\n UploadField,\n TagsField,\n ArrayField,\n GroupField,\n FieldsToShape,\n} from '../types';\nimport {\n createTextFieldSchema,\n createEmailFieldSchema,\n createPasswordFieldSchema,\n createNumberFieldSchema,\n createDateFieldSchema,\n createSelectFieldSchema,\n createRadioFieldSchema,\n createCheckboxFieldSchema,\n createSwitchFieldSchema,\n createUploadFieldSchema,\n createTagsFieldSchema,\n createArrayFieldSchema,\n createGroupFieldSchema,\n} from './builders';\n\nfunction fieldToZod(field: Field): z.ZodTypeAny {\n if ('schema' in field && field.schema) {\n return field.schema as z.ZodTypeAny;\n }\n\n switch (field.type) {\n case 'text':\n return createTextFieldSchema(field as TextField);\n case 'email':\n return createEmailFieldSchema(field as EmailField);\n case 'password':\n return createPasswordFieldSchema(field as PasswordField);\n case 'textarea':\n return createTextFieldSchema(field as TextareaField);\n case 'number':\n return createNumberFieldSchema(field as NumberField);\n case 'date':\n case 'datetime':\n return createDateFieldSchema(field as DateField | DatetimeField);\n case 'select':\n return createSelectFieldSchema(field as SelectField);\n case 'radio':\n return createRadioFieldSchema(field as RadioField);\n case 'checkbox':\n return createCheckboxFieldSchema(field as CheckboxField);\n case 'switch':\n return createSwitchFieldSchema(field as SwitchField);\n case 'upload':\n return createUploadFieldSchema(field as UploadField);\n case 'tags':\n return createTagsFieldSchema(field as TagsField);\n case 'array':\n return createArrayFieldSchema(field as ArrayField, fieldsToZodSchema);\n case 'group':\n return createGroupFieldSchema(field as GroupField, fieldsToZodSchema);\n case 'row':\n case 'collapsible':\n case 'tabs':\n return z.any();\n default:\n return z.any();\n }\n}\n\nfunction processTabsField(field: TabsField): Record<string, z.ZodTypeAny> {\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const tab of field.tabs) {\n if (tab.name) {\n const tabSchema = fieldsToZodSchema(tab.fields);\n shape[tab.name] = tabSchema;\n } else {\n const tabFieldsSchema = fieldsToZodSchema(tab.fields);\n if (tabFieldsSchema instanceof z.ZodObject) {\n Object.assign(shape, tabFieldsSchema.shape);\n }\n }\n }\n\n return shape;\n}\n\n/**\n * Converts field definitions to a Zod schema.\n * \n * Note: Custom validation (field.validate) is handled by the zodResolver,\n * not at the schema level. This ensures custom validators run even when\n * other fields have errors.\n */\nexport function fieldsToZodSchema<T extends readonly Field[]>(\n fields: T\n): z.ZodObject<FieldsToShape<T>> {\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const field of fields) {\n if ('name' in field && field.name) {\n shape[field.name] = fieldToZod(field);\n } else if (field.type === 'tabs') {\n const tabsShape = processTabsField(field);\n Object.assign(shape, tabsShape);\n } else if (field.type === 'row' || field.type === 'collapsible') {\n const nestedSchema = fieldsToZodSchema(field.fields);\n if (nestedSchema instanceof z.ZodObject) {\n Object.assign(shape, nestedSchema.shape);\n }\n }\n }\n\n return z.object(shape) as z.ZodObject<FieldsToShape<T>>;\n}\n","import { z } from 'zod';\nimport type { TextField, EmailField, TextareaField, PasswordField } from '../../types';\nimport { makeOptional, getPatternErrorMessage } from '../helpers';\n\nexport function createTextFieldSchema(field: TextField | TextareaField): z.ZodTypeAny {\n let schema = z.string({ error: 'This field is required' });\n\n if ('pattern' in field && field.pattern) {\n const pattern = typeof field.pattern === 'string'\n ? new RegExp(field.pattern)\n : field.pattern;\n\n schema = schema.regex(pattern, {\n error: getPatternErrorMessage(field.pattern),\n });\n }\n\n if (field.minLength) {\n schema = schema.min(field.minLength, {\n error: `Must be at least ${field.minLength} characters`,\n });\n }\n if (field.maxLength) {\n schema = schema.max(field.maxLength, {\n error: `Must be no more than ${field.maxLength} characters`,\n });\n }\n\n if (field.required) {\n schema = schema.min(1, { error: 'This field is required' });\n }\n\n let finalSchema: z.ZodTypeAny = schema;\n if ('trim' in field && field.trim) {\n finalSchema = z.preprocess((val) => {\n return typeof val === 'string' ? val.trim() : val;\n }, schema);\n }\n\n if (!field.required) {\n return makeOptional(finalSchema, field.type);\n }\n\n return finalSchema;\n}\n\nexport function createEmailFieldSchema(field: EmailField): z.ZodTypeAny {\n // Zod v4: z.email() for email validation with custom error\n let schema = z.email({ error: 'Invalid email address' });\n\n if (field.minLength) {\n schema = schema.min(field.minLength, {\n error: `Must be at least ${field.minLength} characters`,\n });\n }\n if (field.maxLength) {\n schema = schema.max(field.maxLength, {\n error: `Must be no more than ${field.maxLength} characters`,\n });\n }\n\n if (field.required) {\n schema = schema.min(1, { error: 'Email is required' });\n }\n\n if (!field.required) {\n return makeOptional(schema, 'email');\n }\n\n return schema;\n}\n\nexport function createPasswordFieldSchema(field: PasswordField): z.ZodTypeAny {\n // Zod v4: provide error message for invalid_type\n let schema = z.string({ error: 'Password is required' });\n\n if (field.minLength) {\n schema = schema.min(field.minLength, {\n error: `Password must be at least ${field.minLength} characters`,\n });\n }\n if (field.maxLength) {\n schema = schema.max(field.maxLength, {\n error: `Password must be no more than ${field.maxLength} characters`,\n });\n }\n if (field.required) {\n schema = schema.min(1, { error: 'Password is required' });\n }\n\n if (!field.required) {\n return makeOptional(schema, 'password');\n }\n\n return schema;\n}\n","import { z } from 'zod';\nimport type { Field, FieldType, ValidationContext, ValidationFn } from '../types';\n\n// =============================================================================\n// VALIDATION CONFIG EXTRACTION\n// =============================================================================\n\ntype ExtractableValidationFn = (\n value: unknown,\n context: ValidationContext\n) => true | string | Promise<true | string>;\n\nexport interface ExtractedValidationConfig {\n fn?: ExtractableValidationFn;\n isLive: boolean;\n debounceMs?: number;\n}\n\nexport function extractValidationConfig(\n validate?: unknown\n): ExtractedValidationConfig {\n if (!validate) {\n return { fn: undefined, isLive: false };\n }\n\n if (typeof validate === 'function') {\n return { fn: validate as ExtractableValidationFn, isLive: false };\n }\n\n if (typeof validate === 'object' && 'fn' in validate) {\n const obj = validate as { fn?: unknown; live?: boolean | { debounceMs?: number } };\n const fn = typeof obj.fn === 'function' ? obj.fn as ExtractableValidationFn : undefined;\n\n if (!obj.live) {\n return { fn, isLive: false };\n }\n\n const debounceMs = typeof obj.live === 'object' ? obj.live.debounceMs : undefined;\n return { fn, isLive: true, debounceMs };\n }\n\n return { fn: undefined, isLive: false };\n}\n\n// =============================================================================\n// FIELD VALIDATOR COLLECTION\n// =============================================================================\n\nexport interface FieldValidator {\n path: string;\n fn: ValidationFn;\n}\n\n/**\n * Recursively collects all field validators from a field array.\n */\nexport function collectFieldValidators(\n fields: readonly Field[],\n basePath: string = ''\n): FieldValidator[] {\n const validators: FieldValidator[] = [];\n\n for (const field of fields) {\n if ('name' in field && field.name) {\n const fieldPath = basePath ? `${basePath}.${field.name}` : field.name;\n\n if ('validate' in field && field.validate) {\n const config = extractValidationConfig(field.validate);\n if (config.fn) {\n validators.push({\n path: fieldPath,\n fn: config.fn as ValidationFn,\n });\n }\n }\n\n if (field.type === 'group' && 'fields' in field) {\n validators.push(...collectFieldValidators(field.fields, fieldPath));\n }\n }\n\n // Layout fields pass through without adding to path\n if (field.type === 'row' && 'fields' in field) {\n validators.push(...collectFieldValidators(field.fields, basePath));\n }\n if (field.type === 'collapsible' && 'fields' in field) {\n validators.push(...collectFieldValidators(field.fields, basePath));\n }\n if (field.type === 'tabs' && 'tabs' in field) {\n for (const tab of field.tabs) {\n const tabPath = tab.name\n ? (basePath ? `${basePath}.${tab.name}` : tab.name)\n : basePath;\n validators.push(...collectFieldValidators(tab.fields, tabPath));\n }\n }\n }\n\n return validators;\n}\n\n// =============================================================================\n// SIBLING DATA EXTRACTION\n// =============================================================================\n\n/**\n * Gets the parent object containing the field at the given path.\n */\nexport function getSiblingData(\n data: Record<string, unknown>,\n path: string\n): Record<string, unknown> {\n const parts = path.split('.');\n\n if (parts.length <= 1) {\n return data;\n }\n\n const parentParts = parts.slice(0, -1);\n let current: unknown = data;\n\n for (const part of parentParts) {\n if (current && typeof current === 'object' && current !== null) {\n current = (current as Record<string, unknown>)[part];\n } else {\n return {};\n }\n }\n\n if (current && typeof current === 'object' && current !== null) {\n return current as Record<string, unknown>;\n }\n\n return {};\n}\n\n/**\n * Gets a value at a dot-notation path.\n */\nexport function getValueByPath(\n data: Record<string, unknown>,\n path: string\n): unknown {\n const parts = path.split('.');\n let current: unknown = data;\n\n for (const part of parts) {\n if (current && typeof current === 'object' && current !== null) {\n current = (current as Record<string, unknown>)[part];\n } else {\n return undefined;\n }\n }\n\n return current;\n}\n\n/**\n * Creates a superRefine that runs all field validators with full form context.\n */\nexport function createRootValidationRefinement(\n validators: FieldValidator[]\n): (data: Record<string, unknown>, ctx: z.RefinementCtx) => Promise<void> {\n return async (data, ctx) => {\n const validationPromises = validators.map(async ({ path, fn }) => {\n const value = getValueByPath(data, path);\n const siblingData = getSiblingData(data, path);\n\n try {\n const result = await fn(value, {\n data,\n siblingData,\n path: path.split('.'),\n });\n\n if (result !== true) {\n ctx.addIssue({\n code: 'custom',\n path: path.split('.'),\n message: typeof result === 'string' ? result : 'Validation failed',\n });\n }\n } catch (error) {\n ctx.addIssue({\n code: 'custom',\n path: path.split('.'),\n message: error instanceof Error ? error.message : 'Validation error',\n });\n }\n });\n\n await Promise.all(validationPromises);\n };\n}\n\n// =============================================================================\n// OPTIONAL HANDLING\n// =============================================================================\n\nexport function makeOptional(\n schema: z.ZodTypeAny,\n fieldType: FieldType\n): z.ZodTypeAny {\n switch (fieldType) {\n case 'text':\n case 'textarea':\n case 'email':\n case 'password':\n return schema.optional().or(z.literal(''));\n\n case 'number':\n case 'date':\n case 'select':\n case 'radio':\n return schema.optional().nullable();\n\n case 'checkbox':\n case 'switch':\n return schema;\n\n case 'tags':\n case 'array':\n return schema.optional().default([]);\n\n case 'upload':\n return schema.optional().nullable();\n\n default:\n return schema.optional();\n }\n}\n\n// =============================================================================\n// COERCION HELPERS\n// =============================================================================\n\nexport function coerceToNumber(val: unknown): number | undefined {\n if (val === '' || val === null || val === undefined) {\n return undefined;\n }\n const num = Number(val);\n return isNaN(num) ? undefined : num;\n}\n\nexport function coerceToDate(val: unknown): Date | undefined {\n if (val === '' || val === null || val === undefined) {\n return undefined;\n }\n if (val instanceof Date) {\n return isNaN(val.getTime()) ? undefined : val;\n }\n if (typeof val === 'string' || typeof val === 'number') {\n const d = new Date(val);\n return isNaN(d.getTime()) ? undefined : d;\n }\n return undefined;\n}\n\n// =============================================================================\n// PATTERN VALIDATION\n// =============================================================================\n\nconst PATTERN_MESSAGES: Record<string, string> = {\n '^[a-zA-Z0-9_]+$': 'Only letters, numbers, and underscores allowed',\n '^[a-z0-9-]+$': 'Only lowercase letters, numbers, and hyphens allowed',\n '^\\\\S+@\\\\S+\\\\.\\\\S+$': 'Invalid email format',\n '^https?://': 'Must start with http:// or https://',\n};\n\nexport function getPatternErrorMessage(pattern: string | RegExp): string {\n const patternStr = typeof pattern === 'string' ? pattern : pattern.source;\n return PATTERN_MESSAGES[patternStr] || `Must match pattern: ${patternStr}`;\n}\n\n// =============================================================================\n// FILE VALIDATION HELPERS\n// =============================================================================\n\nexport function isFileLike(value: unknown): value is File {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'name' in value &&\n 'size' in value &&\n 'type' in value\n );\n}\n\nexport function isFileTypeAccepted(\n file: File,\n accept: string\n): boolean {\n if (accept === '*' || !accept) return true;\n\n const acceptTypes = accept.split(',').map(t => t.trim().toLowerCase());\n const fileType = file.type.toLowerCase();\n const fileName = file.name.toLowerCase();\n\n return acceptTypes.some(acceptType => {\n if (acceptType.endsWith('/*')) {\n const category = acceptType.replace('/*', '');\n return fileType.startsWith(category + '/');\n }\n if (acceptType.startsWith('.')) {\n return fileName.endsWith(acceptType);\n }\n return fileType === acceptType;\n });\n}\n","import { z } from 'zod';\nimport type { NumberField } from '../../types';\nimport { coerceToNumber, makeOptional } from '../helpers';\n\n/**\n * Creates Zod schema for number fields.\n * Note: Custom validation (field.validate) is handled at root schema level.\n */\nexport function createNumberFieldSchema(field: NumberField): z.ZodTypeAny {\n let numSchema = z.number({ error: 'Must be a number' });\n\n // Min/max constraints\n if (field.min !== undefined) {\n numSchema = numSchema.min(field.min, `Must be at least ${field.min}`);\n }\n if (field.max !== undefined) {\n numSchema = numSchema.max(field.max, `Must be at most ${field.max}`);\n }\n\n // Coercion: empty/null/undefined → undefined, otherwise Number()\n const schema: z.ZodTypeAny = z.preprocess(coerceToNumber, numSchema);\n\n if (field.required) {\n return schema;\n }\n\n return makeOptional(schema, 'number');\n}\n","import { z } from 'zod';\nimport type { DateField, DatetimeField } from '../../types';\nimport { coerceToDate, makeOptional } from '../helpers';\n\n/**\n * Parse a value to a Date object for constraint checking.\n */\nfunction toDate(value?: string | Date): Date | undefined {\n if (!value) return undefined;\n if (value instanceof Date) return isNaN(value.getTime()) ? undefined : value;\n const parsed = new Date(value);\n return isNaN(parsed.getTime()) ? undefined : parsed;\n}\n\n/**\n * Creates Zod schema for date and datetime fields.\n * Note: Custom validation (field.validate) is handled at root schema level.\n */\nexport function createDateFieldSchema(field: DateField | DatetimeField): z.ZodTypeAny {\n const isDatetime = field.type === 'datetime';\n\n // Parse min/max dates from field config\n const minDate = toDate(field.minDate);\n const maxDate = toDate(field.maxDate);\n\n // Build base date schema\n let dateSchema = z.date({ error: 'Please enter a valid date' });\n\n // Add min date constraint\n if (minDate) {\n const formattedDate = isDatetime ? minDate.toLocaleString() : minDate.toDateString();\n dateSchema = dateSchema.min(minDate, {\n error: `Date must be on or after ${formattedDate}`,\n });\n }\n\n // Add max date constraint\n if (maxDate) {\n const formattedDate = isDatetime ? maxDate.toLocaleString() : maxDate.toDateString();\n dateSchema = dateSchema.max(maxDate, {\n error: `Date must be on or before ${formattedDate}`,\n });\n }\n\n // Coercion from various input types\n const schema: z.ZodTypeAny = z.preprocess(coerceToDate, dateSchema);\n\n if (field.required) {\n return schema.refine(\n (val) => val instanceof Date && !isNaN(val.getTime()),\n 'Date is required'\n );\n }\n\n return makeOptional(schema, 'date');\n}\n","import { z } from 'zod';\nimport type { SelectField, RadioField } from '../../types';\nimport { makeOptional } from '../helpers';\n\n// Base schema for select/radio values with user-friendly error messages\nconst selectValueSchema = z.union([\n z.string({ error: 'Please select an option' }),\n z.number({ error: 'Please select an option' }),\n z.boolean({ error: 'Please select an option' }),\n], { error: 'Please select an option' });\n\nexport function createSelectFieldSchema(field: SelectField): z.ZodTypeAny {\n if (field.hasMany) {\n let arraySchema = z.array(selectValueSchema, { error: 'Invalid selection' });\n\n if (field.required) {\n arraySchema = arraySchema.min(1, 'Select at least one option');\n }\n\n if (!field.required) {\n return arraySchema.optional().default([]);\n }\n return arraySchema;\n }\n\n let schema: z.ZodTypeAny = selectValueSchema;\n\n if (field.required) {\n schema = selectValueSchema.refine(\n (val) => val !== '' && val !== null && val !== undefined,\n 'Please select an option'\n );\n }\n\n if (!field.required) {\n return makeOptional(schema, 'select');\n }\n\n return schema;\n}\n\nexport function createRadioFieldSchema(field: RadioField): z.ZodTypeAny {\n let schema: z.ZodTypeAny = selectValueSchema;\n\n if (field.required) {\n schema = selectValueSchema.refine(\n (val) => val !== '' && val !== null && val !== undefined,\n 'Please select an option'\n );\n }\n\n if (!field.required) {\n return makeOptional(schema, 'radio');\n }\n\n return schema;\n}\n","import { z } from 'zod';\nimport type { CheckboxField, SwitchField } from '../../types';\n\nexport function createCheckboxFieldSchema(field: CheckboxField): z.ZodTypeAny {\n let schema: z.ZodTypeAny = z.boolean({ error: 'Invalid value' });\n\n if (field.required) {\n schema = z.boolean({ error: 'This field is required' }).refine(val => val === true, {\n error: 'This field is required',\n });\n }\n\n return schema;\n}\n\nexport function createSwitchFieldSchema(field: SwitchField): z.ZodTypeAny {\n let schema: z.ZodTypeAny = z.boolean({ error: 'Invalid value' });\n\n if (field.required) {\n schema = z.boolean({ error: 'This field is required' }).refine(val => val === true, {\n error: 'This field is required',\n });\n }\n\n return schema;\n}\n","import { z } from 'zod';\nimport type { UploadField } from '../../types';\n\nfunction matchesMimePattern(fileType: string, pattern: string): boolean {\n const normalizedPattern = pattern.toLowerCase().trim();\n const normalizedType = fileType.toLowerCase();\n\n if (normalizedPattern.endsWith('/*')) {\n const category = normalizedPattern.replace('/*', '');\n return normalizedType.startsWith(category + '/');\n }\n\n if (normalizedPattern.startsWith('.')) {\n return true;\n }\n\n return normalizedType === normalizedPattern;\n}\n\nfunction isFileTypeAccepted(file: File, acceptPatterns: string[]): boolean {\n if (!file.type) return true;\n return acceptPatterns.some(pattern => matchesMimePattern(file.type, pattern));\n}\n\nexport function createUploadFieldSchema(field: UploadField): z.ZodTypeAny {\n let fileSchema: z.ZodTypeAny = z.file({ error: 'Please select a file' });\n\n if (field.maxSize) {\n const sizeMB = (field.maxSize / 1024 / 1024).toFixed(1);\n fileSchema = (fileSchema as z.ZodFile).max(field.maxSize, {\n error: `File must be smaller than ${sizeMB}MB`,\n });\n }\n\n const accept = field.ui?.accept;\n if (accept && accept !== '*') {\n const acceptPatterns = accept.split(',').map(t => t.trim());\n const hasWildcard = acceptPatterns.some(p => p.includes('*') || p.startsWith('.'));\n\n if (hasWildcard) {\n fileSchema = fileSchema.refine(\n (file) => isFileTypeAccepted(file as File, acceptPatterns),\n `File type not allowed. Accepted: ${accept}`\n );\n } else {\n fileSchema = (fileSchema as z.ZodFile).mime(acceptPatterns, {\n error: `File type not allowed. Accepted: ${accept}`,\n });\n }\n }\n\n const fileOrUrl = z.union([\n fileSchema,\n z.string({ error: 'Invalid file' }),\n ], { error: 'Please select a file' });\n\n if (field.hasMany) {\n let arraySchema = z.array(fileOrUrl, { error: 'Invalid files' });\n\n if (field.minFiles !== undefined && field.minFiles > 0) {\n arraySchema = arraySchema.min(field.minFiles, {\n error: `At least ${field.minFiles} file(s) required`,\n });\n }\n\n if (field.maxFiles !== undefined) {\n arraySchema = arraySchema.max(field.maxFiles, {\n error: `Maximum ${field.maxFiles} file(s) allowed`,\n });\n }\n\n if (field.required) {\n arraySchema = arraySchema.min(1, {\n error: 'At least one file is required',\n });\n return arraySchema;\n }\n\n return arraySchema.optional().default([]);\n }\n\n if (field.required) {\n return fileOrUrl;\n }\n\n return fileOrUrl.optional().nullable();\n}\n","import { z } from 'zod';\nimport type { TagsField } from '../../types';\n\nexport function createTagsFieldSchema(field: TagsField): z.ZodTypeAny {\n const tagSchema = z.string({ error: 'Invalid tag' });\n let schema = z.array(tagSchema, { error: 'Invalid tags' });\n\n if (field.minTags !== undefined) {\n schema = schema.min(field.minTags, `At least ${field.minTags} tag(s) required`);\n }\n if (field.maxTags !== undefined) {\n schema = schema.max(field.maxTags, `Maximum ${field.maxTags} tag(s) allowed`);\n }\n\n if (field.required) {\n return schema.refine(\n (arr) => Array.isArray(arr) && arr.length > 0,\n 'At least one tag is required'\n );\n }\n\n return schema.optional().default([]);\n}\n","import { z } from 'zod';\nimport type { ArrayField, GroupField, Field } from '../../types';\n\n// Note: These import from the parent module to avoid circular deps\n// The fieldsToZodSchema function is passed as a parameter\n\ntype SchemaGenerator = (fields: readonly Field[]) => z.ZodObject<z.ZodRawShape>;\n\n/**\n * Creates Zod schema for array fields.\n * Uses passed-in schema generator to handle nested fields.\n */\nexport function createArrayFieldSchema(\n field: ArrayField,\n fieldsToZodSchema: SchemaGenerator\n): z.ZodTypeAny {\n const itemSchema = fieldsToZodSchema(field.fields);\n let schema = z.array(itemSchema);\n\n if (field.minRows !== undefined) {\n schema = schema.min(\n field.minRows,\n `At least ${field.minRows} row${field.minRows !== 1 ? 's' : ''} required`\n );\n }\n if (field.maxRows !== undefined) {\n schema = schema.max(\n field.maxRows,\n `Maximum ${field.maxRows} row${field.maxRows !== 1 ? 's' : ''} allowed`\n );\n }\n\n if (field.required) {\n return schema;\n }\n\n return schema.optional().default([]);\n}\n\n/**\n * Creates Zod schema for group fields.\n * Uses passed-in schema generator to handle nested fields.\n */\nexport function createGroupFieldSchema(\n field: GroupField,\n fieldsToZodSchema: SchemaGenerator\n): z.ZodTypeAny {\n const schema = fieldsToZodSchema(field.fields);\n\n if (!field.required) {\n return schema.optional();\n }\n\n return schema;\n}","import { type z } from 'zod';\nimport type { Field, FieldsToShape } from '../types';\nimport type { StrictFieldArray } from '../types/strict-fields';\nimport { fieldsToZodSchema } from './fields-to-schema';\n\n/**\n * Creates a Zod schema from field definitions with strict type validation.\n *\n * @example\n * const schema = createSchema([\n * { type: 'email', name: 'email', required: true },\n * { type: 'password', name: 'password', minLength: 8 },\n * ]);\n *\n * type FormData = z.infer<typeof schema>;\n */\nexport function createSchema<const T extends readonly Field[]>(\n fields: StrictFieldArray<T> & T\n): z.ZodObject<FieldsToShape<T>> & { fields: T } {\n const schema = fieldsToZodSchema(fields as unknown as T);\n return Object.assign(schema, { fields }) as z.ZodObject<FieldsToShape<T>> & { fields: T };\n}\n","import { nanoid } from 'nanoid';\nimport type { ArrayHelpers } from '../types';\n\n/**\n * Creates a standardized set of array field manipulation methods.\n * Abstracts the difference between getting/setting values in different form libraries.\n * \n * @param getArray - Function to get current array value at a path\n * @param setArray - Function to set array value at a path\n */\nexport function createArrayHelpers(\n getArray: (path: string) => unknown[],\n setArray: (path: string, value: unknown[]) => void\n): ArrayHelpers {\n return {\n fields: <T = unknown>(path: string): Array<T & { id: string }> => {\n const arr = getArray(path);\n if (!Array.isArray(arr)) return [];\n return arr.map((item, index) => ({\n id: (item as Record<string, unknown>)?.id as string || `${path}-${index}`,\n ...item as T,\n }));\n },\n\n append: (path: string, value: unknown) => {\n const current = getArray(path) || [];\n const itemWithId = ensureId(value);\n setArray(path, [...current, itemWithId]);\n },\n\n prepend: (path: string, value: unknown) => {\n const current = getArray(path) || [];\n const itemWithId = ensureId(value);\n setArray(path, [itemWithId, ...current]);\n },\n\n insert: (path: string, index: number, value: unknown) => {\n const current = [...(getArray(path) || [])];\n const itemWithId = ensureId(value);\n current.splice(index, 0, itemWithId);\n setArray(path, current);\n },\n\n remove: (path: string, index: number) => {\n const current = [...(getArray(path) || [])];\n current.splice(index, 1);\n setArray(path, current);\n },\n\n move: (path: string, from: number, to: number) => {\n const current = [...(getArray(path) || [])];\n const [item] = current.splice(from, 1);\n current.splice(to, 0, item);\n setArray(path, current);\n },\n\n swap: (path: string, indexA: number, indexB: number) => {\n const current = [...(getArray(path) || [])];\n const temp = current[indexA];\n current[indexA] = current[indexB];\n current[indexB] = temp;\n setArray(path, current);\n },\n\n replace: (path: string, values: unknown[]) => {\n const itemsWithIds = values.map(ensureId);\n setArray(path, itemsWithIds);\n },\n\n update: (path: string, index: number, value: unknown) => {\n const current = [...(getArray(path) || [])];\n // Preserve existing ID if present\n const existingId = (current[index] as Record<string, unknown>)?.id;\n current[index] = {\n ...(typeof value === 'object' && value !== null ? value : {}),\n id: existingId || nanoid(),\n };\n setArray(path, current);\n },\n };\n}\n\n/**\n * Ensures an item has a unique ID for React keys.\n */\nfunction ensureId(value: unknown): unknown {\n if (typeof value === 'object' && value !== null) {\n const obj = value as Record<string, unknown>;\n if (!obj.id) {\n return { ...obj, id: nanoid() };\n }\n return obj;\n }\n return { value, id: nanoid() };\n}\n","// =============================================================================\n// COMMON UTILITIES\n// These are used by both the core package and registry field components.\n// =============================================================================\n\n/**\n * Generate a unique field ID from the field path.\n * Converts dot notation to dashes and prefixes with 'field-'.\n * Used for accessibility (htmlFor, id attributes).\n * \n * @example\n * generateFieldId('user.profile.email') => 'field-user-profile-email'\n * generateFieldId('items[0].name') => 'field-items-0-name'\n */\nexport function generateFieldId(path: string): string {\n return `field-${path.replace(/\\./g, \"-\").replace(/\\[/g, \"-\").replace(/\\]/g, \"\")}`;\n}\n\n/**\n * Safely retrieve a nested value from an object using a dot-notation path.\n * \n * @example\n * getNestedValue({ user: { name: 'John' } }, 'user.name') => 'John'\n * getNestedValue({ items: [{ id: 1 }] }, 'items.0.id') => 1\n */\nexport function getNestedValue(obj: unknown, path: string): unknown {\n if (!obj || !path) return undefined;\n return path.split(\".\").reduce<unknown>((acc: unknown, key: string) => {\n if (acc && typeof acc === \"object\" && acc !== null) {\n return (acc as Record<string, unknown>)[key];\n }\n return undefined;\n }, obj);\n}\n\n/**\n * Set a nested value in an object using a dot-notation path.\n * Creates intermediate objects/arrays as needed.\n * \n * @example\n * setNestedValue({}, 'user.name', 'John') => { user: { name: 'John' } }\n */\nexport function setNestedValue<T extends Record<string, unknown>>(\n obj: T,\n path: string,\n value: unknown\n): T {\n const keys = path.split(\".\");\n const result = { ...obj } as Record<string, unknown>;\n let current = result;\n\n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i];\n if (!(key in current) || typeof current[key] !== \"object\") {\n // Check if next key is numeric (array index)\n const nextKey = keys[i + 1];\n current[key] = /^\\d+$/.test(nextKey) ? [] : {};\n } else {\n current[key] = Array.isArray(current[key])\n ? [...(current[key] as unknown[])]\n : { ...(current[key] as Record<string, unknown>) };\n }\n current = current[key] as Record<string, unknown>;\n }\n\n current[keys[keys.length - 1]] = value;\n return result as T;\n}\n\n/**\n * Format bytes into a human-readable string.\n * \n * @example\n * formatBytes(1024) => '1 KB'\n * formatBytes(1234567) => '1.18 MB'\n */\nexport function formatBytes(bytes: number, decimals = 2): string {\n if (bytes === 0) return '0 Bytes';\n\n const k = 1024;\n const dm = decimals < 0 ? 0 : decimals;\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];\n\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;\n}\n\n/**\n * Flatten a nested object to dot-notation paths.\n * Useful for converting form library state (like dirtyFields, touchedFields)\n * to the flat format expected by FormState.\n * \n * @example\n * flattenNestedObject({ user: { name: true, email: true } })\n * // => { 'user.name': true, 'user.email': true }\n * \n * flattenNestedObject({ items: { 0: { title: true } } })\n * // => { 'items.0.title': true }\n */\nexport function flattenNestedObject(\n obj: Record<string, unknown>,\n prefix = ''\n): Record<string, boolean> {\n const result: Record<string, boolean> = {};\n\n for (const key in obj) {\n const path = prefix ? `${prefix}.${key}` : key;\n const value = obj[key];\n\n if (typeof value === 'boolean') {\n result[path] = value;\n } else if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n Object.assign(result, flattenNestedObject(value as Record<string, unknown>, path));\n }\n }\n\n return result;\n}\n\n"],"mappings":"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","names":["import_zod","import_zod","import_zod","import_zod","import_zod","import_zod","import_zod","isFileTypeAccepted","import_zod","import_zod","fieldsToZodSchema"]}
1
+ {"version":3,"sources":["../src/schema/index.ts","../src/schema/fields-to-schema.ts","../src/schema/builders/text.ts","../src/schema/helpers.ts","../src/schema/builders/number.ts","../src/schema/builders/date.ts","../src/schema/builders/select.ts","../src/schema/builders/boolean.ts","../src/schema/builders/upload.ts","../src/schema/builders/tags.ts","../src/schema/builders/composite.ts","../src/schema/create-schema.ts","../src/utils/array.ts","../src/lib/utils.ts"],"sourcesContent":["/**\n * Schema utilities for BuzzForm.\n *\n * @example\n * import { createSchema } from '@buildnbuzz/buzzform';\n *\n * const loginSchema = createSchema([\n * { type: 'email', name: 'email', required: true },\n * { type: 'password', name: 'password', minLength: 8 },\n * ]);\n *\n * type LoginData = z.infer<typeof loginSchema>;\n */\n\n// =============================================================================\n// TYPES - Adapter Interface (no runtime code, just types)\n// =============================================================================\nexport type {\n FormState,\n SetValueOptions,\n FieldError,\n ResolverResult,\n Resolver,\n ArrayHelpers,\n AdapterOptions,\n FormAdapter,\n AdapterFactory,\n} from '../types';\n\n// =============================================================================\n// TYPES - Field Definitions\n// =============================================================================\nexport type {\n // Validation\n ValidationContext,\n ValidationResult,\n ValidationFn,\n\n // Conditional\n ConditionContext,\n FieldCondition,\n\n // Custom rendering\n FieldComponentProps,\n FieldInputProps,\n FieldInputRenderFn,\n\n // Styling\n FieldStyle,\n\n // Base\n BaseField,\n\n // Data fields\n TextField,\n EmailField,\n PasswordField,\n TextareaField,\n NumberField,\n DateField,\n DatetimeField,\n SelectOption,\n SelectField,\n CheckboxField,\n SwitchField,\n RadioField,\n TagsField,\n UploadField,\n\n // Layout fields\n GroupField,\n ArrayField,\n RowField,\n Tab,\n TabsField,\n CollapsibleField,\n\n // Union types\n Field,\n FieldType,\n DataField,\n LayoutField,\n} from '../types';\n\n// =============================================================================\n// TYPES - Form Configuration\n// =============================================================================\nexport type {\n BuzzFormSchema,\n FormSettings,\n FormConfig,\n UseFormOptions,\n} from '../types';\n\n// =============================================================================\n// TYPES - Schema Utilities\n// =============================================================================\nexport type {\n FieldToZod,\n FieldsToShape,\n SchemaBuilder,\n SchemaBuilderMap,\n InferType,\n InferSchema,\n} from '../types';\n\n// =============================================================================\n// SCHEMA\n// =============================================================================\nexport { createSchema } from './create-schema';\nexport { fieldsToZodSchema } from './fields-to-schema';\n\n// Re-export schema helpers for advanced usage (custom field builders)\nexport {\n extractValidationConfig,\n makeOptional,\n coerceToNumber,\n coerceToDate,\n getPatternErrorMessage,\n isFileLike,\n isFileTypeAccepted,\n // Helpers for cross-field validation (used by zodResolver)\n collectFieldValidators,\n getSiblingData,\n getValueByPath,\n type FieldValidator,\n} from './helpers';\n\n// Individual builders for registry integration\nexport * from './builders';\n\n// =============================================================================\n// UTILITIES (Server-safe - no React imports)\n// =============================================================================\nexport { createArrayHelpers } from '../utils';\n\n// Add common utilities that registry components will need\nexport { generateFieldId, getNestedValue, setNestedValue, formatBytes } from '../lib';","import { z } from 'zod';\nimport type {\n Field,\n TabsField,\n TextField,\n EmailField,\n PasswordField,\n TextareaField,\n NumberField,\n DateField,\n DatetimeField,\n SelectField,\n RadioField,\n CheckboxField,\n SwitchField,\n UploadField,\n TagsField,\n ArrayField,\n GroupField,\n FieldsToShape,\n} from '../types';\nimport {\n createTextFieldSchema,\n createEmailFieldSchema,\n createPasswordFieldSchema,\n createNumberFieldSchema,\n createDateFieldSchema,\n createSelectFieldSchema,\n createRadioFieldSchema,\n createCheckboxFieldSchema,\n createSwitchFieldSchema,\n createUploadFieldSchema,\n createTagsFieldSchema,\n createArrayFieldSchema,\n createGroupFieldSchema,\n} from './builders';\n\nfunction fieldToZod(field: Field): z.ZodTypeAny {\n if ('schema' in field && field.schema) {\n return field.schema as z.ZodTypeAny;\n }\n\n switch (field.type) {\n case 'text':\n return createTextFieldSchema(field as TextField);\n case 'email':\n return createEmailFieldSchema(field as EmailField);\n case 'password':\n return createPasswordFieldSchema(field as PasswordField);\n case 'textarea':\n return createTextFieldSchema(field as TextareaField);\n case 'number':\n return createNumberFieldSchema(field as NumberField);\n case 'date':\n case 'datetime':\n return createDateFieldSchema(field as DateField | DatetimeField);\n case 'select':\n return createSelectFieldSchema(field as SelectField);\n case 'radio':\n return createRadioFieldSchema(field as RadioField);\n case 'checkbox':\n return createCheckboxFieldSchema(field as CheckboxField);\n case 'switch':\n return createSwitchFieldSchema(field as SwitchField);\n case 'upload':\n return createUploadFieldSchema(field as UploadField);\n case 'tags':\n return createTagsFieldSchema(field as TagsField);\n case 'array':\n return createArrayFieldSchema(field as ArrayField, fieldsToZodSchema);\n case 'group':\n return createGroupFieldSchema(field as GroupField, fieldsToZodSchema);\n case 'row':\n case 'collapsible':\n case 'tabs':\n return z.any();\n default:\n return z.any();\n }\n}\n\nfunction processTabsField(field: TabsField): Record<string, z.ZodTypeAny> {\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const tab of field.tabs) {\n if (tab.name) {\n const tabSchema = fieldsToZodSchema(tab.fields);\n shape[tab.name] = tabSchema;\n } else {\n const tabFieldsSchema = fieldsToZodSchema(tab.fields);\n if (tabFieldsSchema instanceof z.ZodObject) {\n Object.assign(shape, tabFieldsSchema.shape);\n }\n }\n }\n\n return shape;\n}\n\n/**\n * Converts field definitions to a Zod schema.\n * \n * Note: Custom validation (field.validate) is handled by the zodResolver,\n * not at the schema level. This ensures custom validators run even when\n * other fields have errors.\n */\nexport function fieldsToZodSchema<T extends readonly Field[]>(\n fields: T\n): z.ZodObject<FieldsToShape<T>> {\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const field of fields) {\n if ('name' in field && field.name) {\n shape[field.name] = fieldToZod(field);\n } else if (field.type === 'tabs') {\n const tabsShape = processTabsField(field);\n Object.assign(shape, tabsShape);\n } else if (field.type === 'row' || field.type === 'collapsible') {\n const nestedSchema = fieldsToZodSchema(field.fields);\n if (nestedSchema instanceof z.ZodObject) {\n Object.assign(shape, nestedSchema.shape);\n }\n }\n }\n\n return z.object(shape) as z.ZodObject<FieldsToShape<T>>;\n}\n","import { z } from 'zod';\nimport type { TextField, EmailField, TextareaField, PasswordField } from '../../types';\nimport { makeOptional, getPatternErrorMessage } from '../helpers';\n\nexport function createTextFieldSchema(field: TextField | TextareaField): z.ZodTypeAny {\n let schema = z.string({ error: 'This field is required' });\n\n if ('pattern' in field && field.pattern) {\n const pattern = typeof field.pattern === 'string'\n ? new RegExp(field.pattern)\n : field.pattern;\n\n schema = schema.regex(pattern, {\n error: getPatternErrorMessage(field.pattern),\n });\n }\n\n if (field.minLength) {\n schema = schema.min(field.minLength, {\n error: `Must be at least ${field.minLength} characters`,\n });\n }\n if (field.maxLength) {\n schema = schema.max(field.maxLength, {\n error: `Must be no more than ${field.maxLength} characters`,\n });\n }\n\n if (field.required) {\n schema = schema.min(1, { error: 'This field is required' });\n }\n\n let finalSchema: z.ZodTypeAny = schema;\n if ('trim' in field && field.trim) {\n finalSchema = z.preprocess((val) => {\n return typeof val === 'string' ? val.trim() : val;\n }, schema);\n }\n\n if (!field.required) {\n return makeOptional(finalSchema, field.type);\n }\n\n return finalSchema;\n}\n\nexport function createEmailFieldSchema(field: EmailField): z.ZodTypeAny {\n // Zod v4: z.email() for email validation with custom error\n let schema = z.email({ error: 'Invalid email address' });\n\n if (field.minLength) {\n schema = schema.min(field.minLength, {\n error: `Must be at least ${field.minLength} characters`,\n });\n }\n if (field.maxLength) {\n schema = schema.max(field.maxLength, {\n error: `Must be no more than ${field.maxLength} characters`,\n });\n }\n\n if (field.required) {\n schema = schema.min(1, { error: 'Email is required' });\n }\n\n if (!field.required) {\n return makeOptional(schema, 'email');\n }\n\n return schema;\n}\n\nexport function createPasswordFieldSchema(field: PasswordField): z.ZodTypeAny {\n // Zod v4: provide error message for invalid_type\n let schema = z.string({ error: 'Password is required' });\n\n if (field.minLength) {\n schema = schema.min(field.minLength, {\n error: `Password must be at least ${field.minLength} characters`,\n });\n }\n if (field.maxLength) {\n schema = schema.max(field.maxLength, {\n error: `Password must be no more than ${field.maxLength} characters`,\n });\n }\n if (field.required) {\n schema = schema.min(1, { error: 'Password is required' });\n }\n\n if (!field.required) {\n return makeOptional(schema, 'password');\n }\n\n return schema;\n}\n","import { z } from 'zod';\nimport type { Field, FieldType, ValidationContext, ValidationFn } from '../types';\n\n// =============================================================================\n// VALIDATION CONFIG EXTRACTION\n// =============================================================================\n\ntype ExtractableValidationFn = (\n value: unknown,\n context: ValidationContext\n) => true | string | Promise<true | string>;\n\nexport interface ExtractedValidationConfig {\n fn?: ExtractableValidationFn;\n isLive: boolean;\n debounceMs?: number;\n}\n\nexport function extractValidationConfig(\n validate?: unknown\n): ExtractedValidationConfig {\n if (!validate) {\n return { fn: undefined, isLive: false };\n }\n\n if (typeof validate === 'function') {\n return { fn: validate as ExtractableValidationFn, isLive: false };\n }\n\n if (typeof validate === 'object' && 'fn' in validate) {\n const obj = validate as { fn?: unknown; live?: boolean | { debounceMs?: number } };\n const fn = typeof obj.fn === 'function' ? obj.fn as ExtractableValidationFn : undefined;\n\n if (!obj.live) {\n return { fn, isLive: false };\n }\n\n const debounceMs = typeof obj.live === 'object' ? obj.live.debounceMs : undefined;\n return { fn, isLive: true, debounceMs };\n }\n\n return { fn: undefined, isLive: false };\n}\n\n// =============================================================================\n// FIELD VALIDATOR COLLECTION\n// =============================================================================\n\nexport interface FieldValidator {\n path: string;\n fn: ValidationFn;\n}\n\n/**\n * Recursively collects all field validators from a field array.\n */\nexport function collectFieldValidators(\n fields: readonly Field[],\n basePath: string = ''\n): FieldValidator[] {\n const validators: FieldValidator[] = [];\n\n for (const field of fields) {\n if ('name' in field && field.name) {\n const fieldPath = basePath ? `${basePath}.${field.name}` : field.name;\n\n if ('validate' in field && field.validate) {\n const config = extractValidationConfig(field.validate);\n if (config.fn) {\n validators.push({\n path: fieldPath,\n fn: config.fn as ValidationFn,\n });\n }\n }\n\n if (field.type === 'group' && 'fields' in field) {\n validators.push(...collectFieldValidators(field.fields, fieldPath));\n }\n }\n\n // Layout fields pass through without adding to path\n if (field.type === 'row' && 'fields' in field) {\n validators.push(...collectFieldValidators(field.fields, basePath));\n }\n if (field.type === 'collapsible' && 'fields' in field) {\n validators.push(...collectFieldValidators(field.fields, basePath));\n }\n if (field.type === 'tabs' && 'tabs' in field) {\n for (const tab of field.tabs) {\n const tabPath = tab.name\n ? (basePath ? `${basePath}.${tab.name}` : tab.name)\n : basePath;\n validators.push(...collectFieldValidators(tab.fields, tabPath));\n }\n }\n }\n\n return validators;\n}\n\n// =============================================================================\n// SIBLING DATA EXTRACTION\n// =============================================================================\n\n/**\n * Gets the parent object containing the field at the given path.\n */\nexport function getSiblingData(\n data: Record<string, unknown>,\n path: string\n): Record<string, unknown> {\n const parts = path.split('.');\n\n if (parts.length <= 1) {\n return data;\n }\n\n const parentParts = parts.slice(0, -1);\n let current: unknown = data;\n\n for (const part of parentParts) {\n if (current && typeof current === 'object' && current !== null) {\n current = (current as Record<string, unknown>)[part];\n } else {\n return {};\n }\n }\n\n if (current && typeof current === 'object' && current !== null) {\n return current as Record<string, unknown>;\n }\n\n return {};\n}\n\n/**\n * Gets a value at a dot-notation path.\n */\nexport function getValueByPath(\n data: Record<string, unknown>,\n path: string\n): unknown {\n const parts = path.split('.');\n let current: unknown = data;\n\n for (const part of parts) {\n if (current && typeof current === 'object' && current !== null) {\n current = (current as Record<string, unknown>)[part];\n } else {\n return undefined;\n }\n }\n\n return current;\n}\n\n/**\n * Creates a superRefine that runs all field validators with full form context.\n */\nexport function createRootValidationRefinement(\n validators: FieldValidator[]\n): (data: Record<string, unknown>, ctx: z.RefinementCtx) => Promise<void> {\n return async (data, ctx) => {\n const validationPromises = validators.map(async ({ path, fn }) => {\n const value = getValueByPath(data, path);\n const siblingData = getSiblingData(data, path);\n\n try {\n const result = await fn(value, {\n data,\n siblingData,\n path: path.split('.'),\n });\n\n if (result !== true) {\n ctx.addIssue({\n code: 'custom',\n path: path.split('.'),\n message: typeof result === 'string' ? result : 'Validation failed',\n });\n }\n } catch (error) {\n ctx.addIssue({\n code: 'custom',\n path: path.split('.'),\n message: error instanceof Error ? error.message : 'Validation error',\n });\n }\n });\n\n await Promise.all(validationPromises);\n };\n}\n\n// =============================================================================\n// OPTIONAL HANDLING\n// =============================================================================\n\nexport function makeOptional(\n schema: z.ZodTypeAny,\n fieldType: FieldType\n): z.ZodTypeAny {\n switch (fieldType) {\n case 'text':\n case 'textarea':\n case 'email':\n case 'password':\n return schema.optional().or(z.literal(''));\n\n case 'number':\n case 'date':\n case 'select':\n case 'radio':\n return schema.optional().nullable();\n\n case 'checkbox':\n case 'switch':\n return schema;\n\n case 'tags':\n case 'array':\n return schema.optional().default([]);\n\n case 'upload':\n return schema.optional().nullable();\n\n default:\n return schema.optional();\n }\n}\n\n// =============================================================================\n// COERCION HELPERS\n// =============================================================================\n\nexport function coerceToNumber(val: unknown): number | undefined {\n if (val === '' || val === null || val === undefined) {\n return undefined;\n }\n const num = Number(val);\n return isNaN(num) ? undefined : num;\n}\n\nexport function coerceToDate(val: unknown): Date | undefined {\n if (val === '' || val === null || val === undefined) {\n return undefined;\n }\n if (val instanceof Date) {\n return isNaN(val.getTime()) ? undefined : val;\n }\n if (typeof val === 'string' || typeof val === 'number') {\n const d = new Date(val);\n return isNaN(d.getTime()) ? undefined : d;\n }\n return undefined;\n}\n\n// =============================================================================\n// PATTERN VALIDATION\n// =============================================================================\n\nconst PATTERN_MESSAGES: Record<string, string> = {\n '^[a-zA-Z0-9_]+$': 'Only letters, numbers, and underscores allowed',\n '^[a-z0-9-]+$': 'Only lowercase letters, numbers, and hyphens allowed',\n '^\\\\S+@\\\\S+\\\\.\\\\S+$': 'Invalid email format',\n '^https?://': 'Must start with http:// or https://',\n};\n\nexport function getPatternErrorMessage(pattern: string | RegExp): string {\n const patternStr = typeof pattern === 'string' ? pattern : pattern.source;\n return PATTERN_MESSAGES[patternStr] || `Must match pattern: ${patternStr}`;\n}\n\n// =============================================================================\n// FILE VALIDATION HELPERS\n// =============================================================================\n\nexport function isFileLike(value: unknown): value is File {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'name' in value &&\n 'size' in value &&\n 'type' in value\n );\n}\n\nexport function isFileTypeAccepted(\n file: File,\n accept: string\n): boolean {\n if (accept === '*' || !accept) return true;\n\n const acceptTypes = accept.split(',').map(t => t.trim().toLowerCase());\n const fileType = file.type.toLowerCase();\n const fileName = file.name.toLowerCase();\n\n return acceptTypes.some(acceptType => {\n if (acceptType.endsWith('/*')) {\n const category = acceptType.replace('/*', '');\n return fileType.startsWith(category + '/');\n }\n if (acceptType.startsWith('.')) {\n return fileName.endsWith(acceptType);\n }\n return fileType === acceptType;\n });\n}\n","import { z } from 'zod';\nimport type { NumberField } from '../../types';\nimport { coerceToNumber, makeOptional } from '../helpers';\n\n/**\n * Creates Zod schema for number fields.\n * Note: Custom validation (field.validate) is handled at root schema level.\n */\nexport function createNumberFieldSchema(field: NumberField): z.ZodTypeAny {\n let numSchema = z.number({ error: 'Must be a number' });\n\n // Min/max constraints\n if (field.min !== undefined) {\n numSchema = numSchema.min(field.min, `Must be at least ${field.min}`);\n }\n if (field.max !== undefined) {\n numSchema = numSchema.max(field.max, `Must be at most ${field.max}`);\n }\n\n // Coercion: empty/null/undefined → undefined, otherwise Number()\n const schema: z.ZodTypeAny = z.preprocess(coerceToNumber, numSchema);\n\n if (field.required) {\n return schema;\n }\n\n return makeOptional(schema, 'number');\n}\n","import { z } from 'zod';\nimport type { DateField, DatetimeField } from '../../types';\nimport { coerceToDate, makeOptional } from '../helpers';\n\n/**\n * Parse a value to a Date object for constraint checking.\n */\nfunction toDate(value?: string | Date): Date | undefined {\n if (!value) return undefined;\n if (value instanceof Date) return isNaN(value.getTime()) ? undefined : value;\n const parsed = new Date(value);\n return isNaN(parsed.getTime()) ? undefined : parsed;\n}\n\n/**\n * Creates Zod schema for date and datetime fields.\n * Note: Custom validation (field.validate) is handled at root schema level.\n */\nexport function createDateFieldSchema(field: DateField | DatetimeField): z.ZodTypeAny {\n const isDatetime = field.type === 'datetime';\n\n // Parse min/max dates from field config\n const minDate = toDate(field.minDate);\n const maxDate = toDate(field.maxDate);\n\n // Build base date schema\n let dateSchema = z.date({ error: 'Please enter a valid date' });\n\n // Add min date constraint\n if (minDate) {\n const formattedDate = isDatetime ? minDate.toLocaleString() : minDate.toDateString();\n dateSchema = dateSchema.min(minDate, {\n error: `Date must be on or after ${formattedDate}`,\n });\n }\n\n // Add max date constraint\n if (maxDate) {\n const formattedDate = isDatetime ? maxDate.toLocaleString() : maxDate.toDateString();\n dateSchema = dateSchema.max(maxDate, {\n error: `Date must be on or before ${formattedDate}`,\n });\n }\n\n // Coercion from various input types\n const schema: z.ZodTypeAny = z.preprocess(coerceToDate, dateSchema);\n\n if (field.required) {\n return schema.refine(\n (val) => val instanceof Date && !isNaN(val.getTime()),\n 'Date is required'\n );\n }\n\n return makeOptional(schema, 'date');\n}\n","import { z } from 'zod';\nimport type { SelectField, RadioField } from '../../types';\nimport { makeOptional } from '../helpers';\n\n// Base schema for select/radio values with user-friendly error messages\nconst selectValueSchema = z.union([\n z.string({ error: 'Please select an option' }),\n z.number({ error: 'Please select an option' }),\n z.boolean({ error: 'Please select an option' }),\n], { error: 'Please select an option' });\n\nexport function createSelectFieldSchema(field: SelectField): z.ZodTypeAny {\n if (field.hasMany) {\n let arraySchema = z.array(selectValueSchema, { error: 'Invalid selection' });\n\n if (field.required) {\n arraySchema = arraySchema.min(1, 'Select at least one option');\n }\n\n if (!field.required) {\n return arraySchema.optional().default([]);\n }\n return arraySchema;\n }\n\n let schema: z.ZodTypeAny = selectValueSchema;\n\n if (field.required) {\n schema = selectValueSchema.refine(\n (val) => val !== '' && val !== null && val !== undefined,\n 'Please select an option'\n );\n }\n\n if (!field.required) {\n return makeOptional(schema, 'select');\n }\n\n return schema;\n}\n\nexport function createRadioFieldSchema(field: RadioField): z.ZodTypeAny {\n let schema: z.ZodTypeAny = selectValueSchema;\n\n if (field.required) {\n schema = selectValueSchema.refine(\n (val) => val !== '' && val !== null && val !== undefined,\n 'Please select an option'\n );\n }\n\n if (!field.required) {\n return makeOptional(schema, 'radio');\n }\n\n return schema;\n}\n","import { z } from 'zod';\nimport type { CheckboxField, SwitchField } from '../../types';\n\nexport function createCheckboxFieldSchema(field: CheckboxField): z.ZodTypeAny {\n let schema: z.ZodTypeAny = z.boolean({ error: 'Invalid value' });\n\n if (field.required) {\n schema = z.boolean({ error: 'This field is required' }).refine(val => val === true, {\n error: 'This field is required',\n });\n }\n\n return schema;\n}\n\nexport function createSwitchFieldSchema(field: SwitchField): z.ZodTypeAny {\n let schema: z.ZodTypeAny = z.boolean({ error: 'Invalid value' });\n\n if (field.required) {\n schema = z.boolean({ error: 'This field is required' }).refine(val => val === true, {\n error: 'This field is required',\n });\n }\n\n return schema;\n}\n","import { z } from 'zod';\nimport type { UploadField } from '../../types';\n\nfunction matchesMimePattern(fileType: string, pattern: string): boolean {\n const normalizedPattern = pattern.toLowerCase().trim();\n const normalizedType = fileType.toLowerCase();\n\n if (normalizedPattern.endsWith('/*')) {\n const category = normalizedPattern.replace('/*', '');\n return normalizedType.startsWith(category + '/');\n }\n\n if (normalizedPattern.startsWith('.')) {\n return true;\n }\n\n return normalizedType === normalizedPattern;\n}\n\nfunction isFileTypeAccepted(file: File, acceptPatterns: string[]): boolean {\n if (!file.type) return true;\n return acceptPatterns.some(pattern => matchesMimePattern(file.type, pattern));\n}\n\nexport function createUploadFieldSchema(field: UploadField): z.ZodTypeAny {\n let fileSchema: z.ZodTypeAny = z.file({ error: 'Please select a file' });\n\n if (field.maxSize) {\n const sizeMB = (field.maxSize / 1024 / 1024).toFixed(1);\n fileSchema = (fileSchema as z.ZodFile).max(field.maxSize, {\n error: `File must be smaller than ${sizeMB}MB`,\n });\n }\n\n const accept = field.ui?.accept;\n if (accept && accept !== '*') {\n const acceptPatterns = accept.split(',').map(t => t.trim());\n const hasWildcard = acceptPatterns.some(p => p.includes('*') || p.startsWith('.'));\n\n if (hasWildcard) {\n fileSchema = fileSchema.refine(\n (file) => isFileTypeAccepted(file as File, acceptPatterns),\n `File type not allowed. Accepted: ${accept}`\n );\n } else {\n fileSchema = (fileSchema as z.ZodFile).mime(acceptPatterns, {\n error: `File type not allowed. Accepted: ${accept}`,\n });\n }\n }\n\n const fileOrUrl = z.union([\n fileSchema,\n z.string({ error: 'Invalid file' }),\n ], { error: 'Please select a file' });\n\n if (field.hasMany) {\n let arraySchema = z.array(fileOrUrl, { error: 'Invalid files' });\n\n if (field.minFiles !== undefined && field.minFiles > 0) {\n arraySchema = arraySchema.min(field.minFiles, {\n error: `At least ${field.minFiles} file(s) required`,\n });\n }\n\n if (field.maxFiles !== undefined) {\n arraySchema = arraySchema.max(field.maxFiles, {\n error: `Maximum ${field.maxFiles} file(s) allowed`,\n });\n }\n\n if (field.required) {\n arraySchema = arraySchema.min(1, {\n error: 'At least one file is required',\n });\n return arraySchema;\n }\n\n return arraySchema.optional().default([]);\n }\n\n if (field.required) {\n return fileOrUrl;\n }\n\n return fileOrUrl.optional().nullable();\n}\n","import { z } from 'zod';\nimport type { TagsField } from '../../types';\n\nexport function createTagsFieldSchema(field: TagsField): z.ZodTypeAny {\n const tagSchema = z.string({ error: 'Invalid tag' });\n let schema = z.array(tagSchema, { error: 'Invalid tags' });\n\n if (field.minTags !== undefined) {\n schema = schema.min(field.minTags, `At least ${field.minTags} tag(s) required`);\n }\n if (field.maxTags !== undefined) {\n schema = schema.max(field.maxTags, `Maximum ${field.maxTags} tag(s) allowed`);\n }\n\n if (field.required) {\n return schema.refine(\n (arr) => Array.isArray(arr) && arr.length > 0,\n 'At least one tag is required'\n );\n }\n\n return schema.optional().default([]);\n}\n","import { z } from 'zod';\nimport type { ArrayField, GroupField, Field } from '../../types';\n\n// Note: These import from the parent module to avoid circular deps\n// The fieldsToZodSchema function is passed as a parameter\n\ntype SchemaGenerator = (fields: readonly Field[]) => z.ZodObject<z.ZodRawShape>;\n\n/**\n * Creates Zod schema for array fields.\n * Uses passed-in schema generator to handle nested fields.\n */\nexport function createArrayFieldSchema(\n field: ArrayField,\n fieldsToZodSchema: SchemaGenerator\n): z.ZodTypeAny {\n const itemSchema = fieldsToZodSchema(field.fields);\n let schema = z.array(itemSchema);\n\n if (field.minRows !== undefined) {\n schema = schema.min(\n field.minRows,\n `At least ${field.minRows} row${field.minRows !== 1 ? 's' : ''} required`\n );\n }\n if (field.maxRows !== undefined) {\n schema = schema.max(\n field.maxRows,\n `Maximum ${field.maxRows} row${field.maxRows !== 1 ? 's' : ''} allowed`\n );\n }\n\n if (field.required) {\n return schema;\n }\n\n return schema.optional().default([]);\n}\n\n/**\n * Creates Zod schema for group fields.\n * Uses passed-in schema generator to handle nested fields.\n */\nexport function createGroupFieldSchema(\n field: GroupField,\n fieldsToZodSchema: SchemaGenerator\n): z.ZodTypeAny {\n const schema = fieldsToZodSchema(field.fields);\n\n if (!field.required) {\n return schema.optional();\n }\n\n return schema;\n}","import { type z } from 'zod';\nimport type { Field, FieldsToShape } from '../types';\nimport type { StrictFieldArray } from '../types/strict-fields';\nimport { fieldsToZodSchema } from './fields-to-schema';\n\n/**\n * Creates a Zod schema from field definitions with strict type validation.\n *\n * @example\n * const schema = createSchema([\n * { type: 'email', name: 'email', required: true },\n * { type: 'password', name: 'password', minLength: 8 },\n * ]);\n *\n * type FormData = z.infer<typeof schema>;\n */\nexport function createSchema<const T extends readonly Field[]>(\n fields: StrictFieldArray<T> & T\n): z.ZodObject<FieldsToShape<T>> & { fields: T } {\n const schema = fieldsToZodSchema(fields as unknown as T);\n return Object.assign(schema, { fields }) as z.ZodObject<FieldsToShape<T>> & { fields: T };\n}\n","import { nanoid } from 'nanoid';\nimport type { ArrayHelpers } from '../types';\n\n/**\n * Creates a standardized set of array field manipulation methods.\n * Abstracts the difference between getting/setting values in different form libraries.\n * \n * @param getArray - Function to get current array value at a path\n * @param setArray - Function to set array value at a path\n */\nexport function createArrayHelpers(\n getArray: (path: string) => unknown[],\n setArray: (path: string, value: unknown[]) => void\n): ArrayHelpers {\n return {\n fields: <T = unknown>(path: string): Array<T & { id: string }> => {\n const arr = getArray(path);\n if (!Array.isArray(arr)) return [];\n return arr.map((item, index) => ({\n id: (item as Record<string, unknown>)?.id as string || `${path}-${index}`,\n ...item as T,\n }));\n },\n\n append: (path: string, value: unknown) => {\n const current = getArray(path) || [];\n const itemWithId = ensureId(value);\n setArray(path, [...current, itemWithId]);\n },\n\n prepend: (path: string, value: unknown) => {\n const current = getArray(path) || [];\n const itemWithId = ensureId(value);\n setArray(path, [itemWithId, ...current]);\n },\n\n insert: (path: string, index: number, value: unknown) => {\n const current = [...(getArray(path) || [])];\n const itemWithId = ensureId(value);\n current.splice(index, 0, itemWithId);\n setArray(path, current);\n },\n\n remove: (path: string, index: number) => {\n const current = [...(getArray(path) || [])];\n current.splice(index, 1);\n setArray(path, current);\n },\n\n move: (path: string, from: number, to: number) => {\n const current = [...(getArray(path) || [])];\n const [item] = current.splice(from, 1);\n current.splice(to, 0, item);\n setArray(path, current);\n },\n\n swap: (path: string, indexA: number, indexB: number) => {\n const current = [...(getArray(path) || [])];\n const temp = current[indexA];\n current[indexA] = current[indexB];\n current[indexB] = temp;\n setArray(path, current);\n },\n\n replace: (path: string, values: unknown[]) => {\n const itemsWithIds = values.map(ensureId);\n setArray(path, itemsWithIds);\n },\n\n update: (path: string, index: number, value: unknown) => {\n const current = [...(getArray(path) || [])];\n // Preserve existing ID if present\n const existingId = (current[index] as Record<string, unknown>)?.id;\n current[index] = {\n ...(typeof value === 'object' && value !== null ? value : {}),\n id: existingId || nanoid(),\n };\n setArray(path, current);\n },\n };\n}\n\n/**\n * Ensures an item has a unique ID for React keys.\n */\nfunction ensureId(value: unknown): unknown {\n if (typeof value === 'object' && value !== null) {\n const obj = value as Record<string, unknown>;\n if (!obj.id) {\n return { ...obj, id: nanoid() };\n }\n return obj;\n }\n return { value, id: nanoid() };\n}\n","// =============================================================================\n// COMMON UTILITIES\n// These are used by both the core package and registry field components.\n// =============================================================================\n\n/**\n * Generate a unique field ID from the field path.\n * Converts dot notation to dashes and prefixes with 'field-'.\n * Used for accessibility (htmlFor, id attributes).\n * \n * @example\n * generateFieldId('user.profile.email') => 'field-user-profile-email'\n * generateFieldId('items[0].name') => 'field-items-0-name'\n */\nexport function generateFieldId(path: string): string {\n return `field-${path.replace(/\\./g, \"-\").replace(/\\[/g, \"-\").replace(/\\]/g, \"\")}`;\n}\n\n/**\n * Safely retrieve a nested value from an object using a dot-notation path.\n * \n * @example\n * getNestedValue({ user: { name: 'John' } }, 'user.name') => 'John'\n * getNestedValue({ items: [{ id: 1 }] }, 'items.0.id') => 1\n */\nexport function getNestedValue(obj: unknown, path: string): unknown {\n if (!obj || !path) return undefined;\n return path.split(\".\").reduce<unknown>((acc: unknown, key: string) => {\n if (acc && typeof acc === \"object\" && acc !== null) {\n return (acc as Record<string, unknown>)[key];\n }\n return undefined;\n }, obj);\n}\n\n/**\n * Set a nested value in an object using a dot-notation path.\n * Creates intermediate objects/arrays as needed.\n * \n * @example\n * setNestedValue({}, 'user.name', 'John') => { user: { name: 'John' } }\n */\nexport function setNestedValue<T extends Record<string, unknown>>(\n obj: T,\n path: string,\n value: unknown\n): T {\n const keys = path.split(\".\");\n const result = { ...obj } as Record<string, unknown>;\n let current = result;\n\n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i];\n if (!(key in current) || typeof current[key] !== \"object\") {\n // Check if next key is numeric (array index)\n const nextKey = keys[i + 1];\n current[key] = /^\\d+$/.test(nextKey) ? [] : {};\n } else {\n current[key] = Array.isArray(current[key])\n ? [...(current[key] as unknown[])]\n : { ...(current[key] as Record<string, unknown>) };\n }\n current = current[key] as Record<string, unknown>;\n }\n\n current[keys[keys.length - 1]] = value;\n return result as T;\n}\n\n/**\n * Format bytes into a human-readable string.\n * \n * @example\n * formatBytes(1024) => '1 KB'\n * formatBytes(1234567) => '1.18 MB'\n */\nexport function formatBytes(bytes: number, decimals = 2): string {\n if (bytes === 0) return '0 Bytes';\n\n const k = 1024;\n const dm = decimals < 0 ? 0 : decimals;\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];\n\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;\n}\n\n/**\n * Flatten a nested object to dot-notation paths.\n * Useful for converting form library state (like dirtyFields, touchedFields)\n * to the flat format expected by FormState.\n * \n * @example\n * flattenNestedObject({ user: { name: true, email: true } })\n * // => { 'user.name': true, 'user.email': true }\n * \n * flattenNestedObject({ items: { 0: { title: true } } })\n * // => { 'items.0.title': true }\n */\nexport function flattenNestedObject(\n obj: Record<string, unknown>,\n prefix = ''\n): Record<string, boolean> {\n const result: Record<string, boolean> = {};\n\n for (const key in obj) {\n const path = prefix ? `${prefix}.${key}` : key;\n const value = obj[key];\n\n if (typeof value === 'boolean') {\n result[path] = value;\n } else if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n Object.assign(result, flattenNestedObject(value as Record<string, unknown>, path));\n }\n }\n\n return result;\n}\n\n"],"mappings":"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","names":["import_zod","import_zod","import_zod","import_zod","import_zod","import_zod","import_zod","isFileTypeAccepted","import_zod","import_zod","fieldsToZodSchema"]}
@@ -1,108 +1,85 @@
1
1
  import { z } from 'zod';
2
2
  import { F as Field, T as TextField, E as EmailField, P as PasswordField, o as TextareaField, N as NumberField, D as DateField, p as DatetimeField, r as SelectField, s as CheckboxField, t as SwitchField, u as RadioField, w as TagsField, x as UploadField, G as GroupField, y as ArrayField, z as RowField, I as TabsField, J as CollapsibleField, V as ValidationContext, K as FieldType, i as ValidationFn, A as ArrayHelpers } from './adapter-nQW28cyO.mjs';
3
3
 
4
- /**
5
- * Maps a BuzzForm field definition to its corresponding Zod type.
6
- * Used for type inference in createSchema.
7
- *
8
- * Order matters for conditional types - more specific matches first.
9
- */
10
- type FieldToZod<F extends Field> = F extends {
4
+ type ExtractL1<F> = F extends {
5
+ type: "row" | "collapsible";
6
+ fields: infer Nested extends readonly Field[];
7
+ } ? Nested[number] : F extends {
8
+ type: "tabs";
9
+ tabs: readonly (infer T)[];
10
+ } ? T extends {
11
+ fields: infer TabFields extends readonly Field[];
12
+ } ? TabFields[number] : never : F;
13
+ type ExtractL2<F> = ExtractL1<ExtractL1<F>>;
14
+ type ExtractL3<F> = ExtractL1<ExtractL2<F>>;
15
+ type ExtractL4<F> = ExtractL1<ExtractL3<F>>;
16
+ type FlattenedFields<F> = ExtractL4<F>;
17
+ type MakeOptional<T extends z.ZodTypeAny, F extends Field> = F extends {
18
+ required: true;
19
+ } ? T : z.ZodOptional<T>;
20
+ type InnerFieldsShape<T extends readonly Field[]> = {
21
+ [K in FlattenedFields<T[number]> as K extends {
22
+ name: infer N extends string;
23
+ } ? N : never]: K extends Field ? InnerFieldToZod<K> : never;
24
+ };
25
+ type InnerFieldToZod<F extends Field> = MakeOptional<InnerBaseFieldType<F>, F>;
26
+ type InnerBaseFieldType<F extends Field> = F extends {
11
27
  schema: infer S extends z.ZodTypeAny;
12
28
  } ? S : F extends {
13
- type: 'text';
14
- hasMany: true;
15
- } ? z.ZodArray<z.ZodString> : F extends {
16
- type: 'email';
17
- hasMany: true;
18
- } ? z.ZodArray<z.ZodString> : F extends {
19
- type: 'text';
29
+ type: "text";
20
30
  } ? z.ZodString : F extends {
21
- type: 'email';
31
+ type: "email";
22
32
  } ? z.ZodString : F extends {
23
- type: 'password';
33
+ type: "password";
24
34
  } ? z.ZodString : F extends {
25
- type: 'textarea';
35
+ type: "textarea";
26
36
  } ? z.ZodString : F extends {
27
- type: 'number';
37
+ type: "number";
28
38
  } ? z.ZodNumber : F extends {
29
- type: 'date';
39
+ type: "date";
30
40
  } ? z.ZodDate : F extends {
31
- type: 'datetime';
41
+ type: "datetime";
32
42
  } ? z.ZodDate : F extends {
33
- type: 'checkbox';
43
+ type: "checkbox";
34
44
  } ? z.ZodBoolean : F extends {
35
- type: 'switch';
45
+ type: "switch";
36
46
  } ? z.ZodBoolean : F extends {
37
- type: 'select';
47
+ type: "select";
38
48
  hasMany: true;
39
49
  } ? z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>> : F extends {
40
- type: 'select';
50
+ type: "select";
41
51
  } ? z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]> : F extends {
42
- type: 'radio';
52
+ type: "radio";
43
53
  } ? z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]> : F extends {
44
- type: 'tags';
54
+ type: "tags";
45
55
  } ? z.ZodArray<z.ZodString> : F extends {
46
- type: 'upload';
56
+ type: "upload";
47
57
  hasMany: true;
48
58
  } ? z.ZodArray<z.ZodUnion<[z.ZodType<File>, z.ZodString]>> : F extends {
49
- type: 'upload';
50
- } ? z.ZodUnion<[z.ZodType<File>, z.ZodString]> : z.ZodTypeAny;
51
- /**
52
- * Transforms an array of field definitions into the shape of a Zod object.
53
- * Only includes fields with a `name` property (data fields).
54
- *
55
- * Uses the `const T` generic to preserve literal field names.
56
- *
57
- * @example
58
- * const fields = [
59
- * { type: 'text', name: 'email' },
60
- * { type: 'number', name: 'age' },
61
- * ] as const;
62
- *
63
- * type Shape = FieldsToShape<typeof fields>;
64
- * // { email: z.ZodString; age: z.ZodNumber }
65
- */
66
- type FieldsToShape<T extends readonly Field[]> = {
67
- [K in T[number] as K extends {
68
- name: infer N extends string;
69
- } ? N : never]: K extends {
70
- name: string;
71
- } ? FieldToZod<K> : never;
72
- };
73
- /**
74
- * Function signature for field schema builders.
75
- * Each field type has a builder that converts the field config to a Zod schema.
76
- */
59
+ type: "upload";
60
+ } ? z.ZodUnion<[z.ZodType<File>, z.ZodString]> : F extends {
61
+ type: "group";
62
+ fields: infer Nested extends readonly Field[];
63
+ } ? z.ZodObject<InnerFieldsShape<Nested>> : F extends {
64
+ type: "array";
65
+ fields: infer Nested extends readonly Field[];
66
+ } ? z.ZodArray<z.ZodObject<InnerFieldsShape<Nested>>> : z.ZodTypeAny;
67
+ type FieldToZod<F extends Field> = MakeOptional<InnerBaseFieldType<F>, F>;
68
+ type FieldsToShape<T extends readonly Field[]> = InnerFieldsShape<T>;
77
69
  type SchemaBuilder<TField extends Field = Field> = (field: TField) => z.ZodTypeAny;
78
- /**
79
- * Map of field types to their schema builders.
80
- */
81
70
  type SchemaBuilderMap = {
82
- [K in Field['type']]?: SchemaBuilder<Extract<Field, {
71
+ [K in Field["type"]]?: SchemaBuilder<Extract<Field, {
83
72
  type: K;
84
73
  }>>;
85
74
  };
86
75
  /**
87
76
  * Infer the TypeScript type from a BuzzForm schema.
88
- *
89
- * Use this instead of `z.infer<typeof schema>` to avoid needing to import
90
- * `z` from `@buildnbuzz/buzzform/zod`.
91
- *
92
- * @example
93
- * import { createSchema, type InferSchema } from '@buildnbuzz/buzzform';
94
- *
95
- * const loginSchema = createSchema([
96
- * { type: 'email', name: 'email', required: true },
97
- * { type: 'password', name: 'password', required: true },
98
- * ]);
99
- *
100
- * type LoginFormData = InferSchema<typeof loginSchema>;
101
- * // { email: string; password: string }
102
- *
103
- * @see {@link https://form.buildnbuzz.com/docs/type-inference Type Inference Guide}
104
77
  */
105
- type InferSchema<T extends z.ZodTypeAny> = z.infer<T>;
78
+ type InferType<T extends z.ZodTypeAny> = z.infer<T>;
79
+ /**
80
+ * @deprecated Use `InferType` instead. This will be removed in a future version.
81
+ */
82
+ type InferSchema<T extends z.ZodTypeAny> = InferType<T>;
106
83
 
107
84
  /**
108
85
  * Strict field typing utilities for compile-time validation.
@@ -243,4 +220,4 @@ declare function setNestedValue<T extends Record<string, unknown>>(obj: T, path:
243
220
  */
244
221
  declare function formatBytes(bytes: number, decimals?: number): string;
245
222
 
246
- export { type FieldToZod as F, type InferSchema as I, type SchemaBuilder as S, type FieldsToShape as a, type SchemaBuilderMap as b, createSchema as c, coerceToNumber as d, extractValidationConfig as e, fieldsToZodSchema as f, coerceToDate as g, getPatternErrorMessage as h, isFileLike as i, isFileTypeAccepted as j, createArrayHelpers as k, generateFieldId as l, makeOptional as m, getNestedValue as n, formatBytes as o, collectFieldValidators as p, getSiblingData as q, getValueByPath as r, setNestedValue as s, type FieldValidator as t };
223
+ export { type FieldToZod as F, type InferType as I, type SchemaBuilder as S, type FieldsToShape as a, type SchemaBuilderMap as b, type InferSchema as c, createSchema as d, extractValidationConfig as e, fieldsToZodSchema as f, coerceToNumber as g, coerceToDate as h, getPatternErrorMessage as i, isFileLike as j, isFileTypeAccepted as k, createArrayHelpers as l, makeOptional as m, generateFieldId as n, getNestedValue as o, formatBytes as p, collectFieldValidators as q, getSiblingData as r, setNestedValue as s, getValueByPath as t, type FieldValidator as u };
@@ -1,108 +1,85 @@
1
1
  import { z } from 'zod';
2
2
  import { F as Field, T as TextField, E as EmailField, P as PasswordField, o as TextareaField, N as NumberField, D as DateField, p as DatetimeField, r as SelectField, s as CheckboxField, t as SwitchField, u as RadioField, w as TagsField, x as UploadField, G as GroupField, y as ArrayField, z as RowField, I as TabsField, J as CollapsibleField, V as ValidationContext, K as FieldType, i as ValidationFn, A as ArrayHelpers } from './adapter-nQW28cyO.js';
3
3
 
4
- /**
5
- * Maps a BuzzForm field definition to its corresponding Zod type.
6
- * Used for type inference in createSchema.
7
- *
8
- * Order matters for conditional types - more specific matches first.
9
- */
10
- type FieldToZod<F extends Field> = F extends {
4
+ type ExtractL1<F> = F extends {
5
+ type: "row" | "collapsible";
6
+ fields: infer Nested extends readonly Field[];
7
+ } ? Nested[number] : F extends {
8
+ type: "tabs";
9
+ tabs: readonly (infer T)[];
10
+ } ? T extends {
11
+ fields: infer TabFields extends readonly Field[];
12
+ } ? TabFields[number] : never : F;
13
+ type ExtractL2<F> = ExtractL1<ExtractL1<F>>;
14
+ type ExtractL3<F> = ExtractL1<ExtractL2<F>>;
15
+ type ExtractL4<F> = ExtractL1<ExtractL3<F>>;
16
+ type FlattenedFields<F> = ExtractL4<F>;
17
+ type MakeOptional<T extends z.ZodTypeAny, F extends Field> = F extends {
18
+ required: true;
19
+ } ? T : z.ZodOptional<T>;
20
+ type InnerFieldsShape<T extends readonly Field[]> = {
21
+ [K in FlattenedFields<T[number]> as K extends {
22
+ name: infer N extends string;
23
+ } ? N : never]: K extends Field ? InnerFieldToZod<K> : never;
24
+ };
25
+ type InnerFieldToZod<F extends Field> = MakeOptional<InnerBaseFieldType<F>, F>;
26
+ type InnerBaseFieldType<F extends Field> = F extends {
11
27
  schema: infer S extends z.ZodTypeAny;
12
28
  } ? S : F extends {
13
- type: 'text';
14
- hasMany: true;
15
- } ? z.ZodArray<z.ZodString> : F extends {
16
- type: 'email';
17
- hasMany: true;
18
- } ? z.ZodArray<z.ZodString> : F extends {
19
- type: 'text';
29
+ type: "text";
20
30
  } ? z.ZodString : F extends {
21
- type: 'email';
31
+ type: "email";
22
32
  } ? z.ZodString : F extends {
23
- type: 'password';
33
+ type: "password";
24
34
  } ? z.ZodString : F extends {
25
- type: 'textarea';
35
+ type: "textarea";
26
36
  } ? z.ZodString : F extends {
27
- type: 'number';
37
+ type: "number";
28
38
  } ? z.ZodNumber : F extends {
29
- type: 'date';
39
+ type: "date";
30
40
  } ? z.ZodDate : F extends {
31
- type: 'datetime';
41
+ type: "datetime";
32
42
  } ? z.ZodDate : F extends {
33
- type: 'checkbox';
43
+ type: "checkbox";
34
44
  } ? z.ZodBoolean : F extends {
35
- type: 'switch';
45
+ type: "switch";
36
46
  } ? z.ZodBoolean : F extends {
37
- type: 'select';
47
+ type: "select";
38
48
  hasMany: true;
39
49
  } ? z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>> : F extends {
40
- type: 'select';
50
+ type: "select";
41
51
  } ? z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]> : F extends {
42
- type: 'radio';
52
+ type: "radio";
43
53
  } ? z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]> : F extends {
44
- type: 'tags';
54
+ type: "tags";
45
55
  } ? z.ZodArray<z.ZodString> : F extends {
46
- type: 'upload';
56
+ type: "upload";
47
57
  hasMany: true;
48
58
  } ? z.ZodArray<z.ZodUnion<[z.ZodType<File>, z.ZodString]>> : F extends {
49
- type: 'upload';
50
- } ? z.ZodUnion<[z.ZodType<File>, z.ZodString]> : z.ZodTypeAny;
51
- /**
52
- * Transforms an array of field definitions into the shape of a Zod object.
53
- * Only includes fields with a `name` property (data fields).
54
- *
55
- * Uses the `const T` generic to preserve literal field names.
56
- *
57
- * @example
58
- * const fields = [
59
- * { type: 'text', name: 'email' },
60
- * { type: 'number', name: 'age' },
61
- * ] as const;
62
- *
63
- * type Shape = FieldsToShape<typeof fields>;
64
- * // { email: z.ZodString; age: z.ZodNumber }
65
- */
66
- type FieldsToShape<T extends readonly Field[]> = {
67
- [K in T[number] as K extends {
68
- name: infer N extends string;
69
- } ? N : never]: K extends {
70
- name: string;
71
- } ? FieldToZod<K> : never;
72
- };
73
- /**
74
- * Function signature for field schema builders.
75
- * Each field type has a builder that converts the field config to a Zod schema.
76
- */
59
+ type: "upload";
60
+ } ? z.ZodUnion<[z.ZodType<File>, z.ZodString]> : F extends {
61
+ type: "group";
62
+ fields: infer Nested extends readonly Field[];
63
+ } ? z.ZodObject<InnerFieldsShape<Nested>> : F extends {
64
+ type: "array";
65
+ fields: infer Nested extends readonly Field[];
66
+ } ? z.ZodArray<z.ZodObject<InnerFieldsShape<Nested>>> : z.ZodTypeAny;
67
+ type FieldToZod<F extends Field> = MakeOptional<InnerBaseFieldType<F>, F>;
68
+ type FieldsToShape<T extends readonly Field[]> = InnerFieldsShape<T>;
77
69
  type SchemaBuilder<TField extends Field = Field> = (field: TField) => z.ZodTypeAny;
78
- /**
79
- * Map of field types to their schema builders.
80
- */
81
70
  type SchemaBuilderMap = {
82
- [K in Field['type']]?: SchemaBuilder<Extract<Field, {
71
+ [K in Field["type"]]?: SchemaBuilder<Extract<Field, {
83
72
  type: K;
84
73
  }>>;
85
74
  };
86
75
  /**
87
76
  * Infer the TypeScript type from a BuzzForm schema.
88
- *
89
- * Use this instead of `z.infer<typeof schema>` to avoid needing to import
90
- * `z` from `@buildnbuzz/buzzform/zod`.
91
- *
92
- * @example
93
- * import { createSchema, type InferSchema } from '@buildnbuzz/buzzform';
94
- *
95
- * const loginSchema = createSchema([
96
- * { type: 'email', name: 'email', required: true },
97
- * { type: 'password', name: 'password', required: true },
98
- * ]);
99
- *
100
- * type LoginFormData = InferSchema<typeof loginSchema>;
101
- * // { email: string; password: string }
102
- *
103
- * @see {@link https://form.buildnbuzz.com/docs/type-inference Type Inference Guide}
104
77
  */
105
- type InferSchema<T extends z.ZodTypeAny> = z.infer<T>;
78
+ type InferType<T extends z.ZodTypeAny> = z.infer<T>;
79
+ /**
80
+ * @deprecated Use `InferType` instead. This will be removed in a future version.
81
+ */
82
+ type InferSchema<T extends z.ZodTypeAny> = InferType<T>;
106
83
 
107
84
  /**
108
85
  * Strict field typing utilities for compile-time validation.
@@ -243,4 +220,4 @@ declare function setNestedValue<T extends Record<string, unknown>>(obj: T, path:
243
220
  */
244
221
  declare function formatBytes(bytes: number, decimals?: number): string;
245
222
 
246
- export { type FieldToZod as F, type InferSchema as I, type SchemaBuilder as S, type FieldsToShape as a, type SchemaBuilderMap as b, createSchema as c, coerceToNumber as d, extractValidationConfig as e, fieldsToZodSchema as f, coerceToDate as g, getPatternErrorMessage as h, isFileLike as i, isFileTypeAccepted as j, createArrayHelpers as k, generateFieldId as l, makeOptional as m, getNestedValue as n, formatBytes as o, collectFieldValidators as p, getSiblingData as q, getValueByPath as r, setNestedValue as s, type FieldValidator as t };
223
+ export { type FieldToZod as F, type InferType as I, type SchemaBuilder as S, type FieldsToShape as a, type SchemaBuilderMap as b, type InferSchema as c, createSchema as d, extractValidationConfig as e, fieldsToZodSchema as f, coerceToNumber as g, coerceToDate as h, getPatternErrorMessage as i, isFileLike as j, isFileTypeAccepted as k, createArrayHelpers as l, makeOptional as m, generateFieldId as n, getNestedValue as o, formatBytes as p, collectFieldValidators as q, getSiblingData as r, setNestedValue as s, getValueByPath as t, type FieldValidator as u };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buildnbuzz/buzzform",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Simple React form library for shadcn/ui. Declare fields, customize rendering, get live validation with minimal boilerplate.",
5
5
  "author": "Parth Lad <parth@buildnbuzz.com>",
6
6
  "license": "MIT",