import { Array, Option, Schema as S } from 'effect';
import { type Rule, type RuleMessage } from './rule.js';
/** The `NotValidated` state: user hasn't interacted yet. */
export type NotValidated = Readonly<{
_tag: 'NotValidated';
value: A;
}>;
/** The `Validating` state: async validation is in flight. */
export type Validating = Readonly<{
_tag: 'Validating';
value: A;
}>;
/** The `Valid` state: every rule passed. */
export type Valid = Readonly<{
_tag: 'Valid';
value: A;
}>;
/** The `Invalid` state: one or more rules failed. Carries a non-empty `errors` array. */
export type Invalid = Readonly<{
_tag: 'Invalid';
value: A;
errors: Array.NonEmptyReadonlyArray;
}>;
/** The four-state union that represents a field's value in the Model. */
export type Field = NotValidated | Validating | Valid | Invalid;
/** Constructs a `NotValidated` state. */
export declare const NotValidated: (field: Readonly<{
value: A;
}>) => NotValidated;
/** Constructs a `Validating` state. */
export declare const Validating: (field: Readonly<{
value: A;
}>) => Validating;
/** Constructs a `Valid` state. */
export declare const Valid: (field: Readonly<{
value: A;
}>) => Valid;
/** Constructs an `Invalid` state. */
export declare const Invalid: (field: Readonly<{
value: A;
errors: Array.NonEmptyReadonlyArray;
}>) => Invalid;
/** Builds the four-state `Field` Schema for a value of the given Schema. Put the
* result in your Model. The value Schema should match what the control
* actually holds as the user edits, not the type you parse it into:
* `Field(S.String)` for text inputs, `Field(S.Array(S.String))` for a
* multi-select. A scalar like a checkbox's boolean usually stays plain
* `S.Boolean` in the Model; wrap it in `Field` only when it needs the
* validation lifecycle. Validation rules stay separate, in a `makeRules`
* bundle. */
export declare const Field: (valueSchema: S.Codec) => S.Union;
}>, S.TaggedStruct<"Validating", {
readonly value: S.Codec;
}>, S.TaggedStruct<"Valid", {
readonly value: S.Codec;
}>, S.TaggedStruct<"Invalid", {
readonly value: S.Codec;
readonly errors: S.NonEmptyArray;
}>]>;
/** A field's validation rules: the required message (if any), the list of rules,
* and an empty predicate. Produced by `makeRules`; consumed by the module's
* operations (`validate`, `validateAll`, `isValid`, `isRequired`). The fields
* are accessible but treating them as stable is discouraged. Prefer the
* operations so internal shape changes don't break callers. */
export type Rules = Readonly<{
requiredMessage: Option.Option>;
rules: ReadonlyArray>;
isEmpty: (value: A) => boolean;
}>;
/** Options accepted by `makeRules`. */
export type MakeRulesOptions = Readonly<{
/** When present, the field is required: empty values become `Invalid`
* with the given message, and `isValid` requires `Valid`. Absent
* means the field is optional: empty values stay `NotValidated`, and
* `isValid` accepts `Valid` or `NotValidated`. */
required?: RuleMessage;
rules?: ReadonlyArray>;
/** Predicate for what counts as "empty" for this field. Defaults to empty
* string and empty array; every other value is treated as present. Pass
* `(value) => value.trim() === ''` to treat whitespace-only input as empty. */
isEmpty?: (value: A) => boolean;
}>;
/** Creates a `Rules` bundle from options. The value type defaults to `string`;
* for other field values, annotate it: `makeRules>({ ... })`. */
export declare const makeRules: (options?: MakeRulesOptions) => Rules;
/** Validates a new value and returns the next field state.
*
* For required fields, an empty value produces `Invalid` with the
* required message. For optional fields, an empty value produces
* `NotValidated`. Non-empty values run through the field's rules;
* the first failure becomes `Invalid`, otherwise the result is `Valid`. */
export declare const validate: (rules: Rules) => (value: A) => Field;
/** Like `validate` but collects every failing rule into the
* `Invalid` state's errors array instead of stopping at the first. */
export declare const validateAll: (rules: Rules) => (value: A) => Field;
/** Returns true when the field's current state is acceptable given its
* rules. For required fields, only `Valid` returns `true`. For optional
* fields, `Valid` or `NotValidated` both return `true`. `Invalid` and
* `Validating` always return `false`.
*
* The name is distinct from the `Valid` tag on purpose: `isValid`
* answers "is this state an acceptable result?", which for an optional
* field is broader than `_tag === 'Valid'`. For pattern-matching on the
* state itself, check the `_tag` directly. */
export declare const isValid: (rules: Rules) => (state: Field) => boolean;
/** Returns true when the rules mark the field as required. Useful for
* rendering affordances like a `*` next to required field labels. */
export declare const isRequired: (rules: Rules) => boolean;
/** Returns true when the state's tag is `Invalid`. Tag-only predicate;
* unlike `!isValid(rules)(state)`, this does not treat `NotValidated`
* or `Validating` as errors. Use for "has the user seen a rule failure
* on this field?" affordances like red borders or per-step error
* indicators. */
export declare const isInvalid: (state: Field) => boolean;
/** Returns true when every field is acceptable per its rules, by `isValid`.
* Each pair is a field's `[state, rules]`. The pairs in one call share a
* value type, so a call gates fields of a single type; for a form that mixes
* types, call `allValid` once per type and combine the results with `&&`.
* Use for form-level submit gates. */
export declare const allValid: (pairs: ReadonlyArray, Rules]>) => boolean;
/** Returns true when any state in the input has tag `Invalid`. Use for
* "this step/section has errors" affordances, independent of rules. */
export declare const anyInvalid: (states: ReadonlyArray>) => boolean;
//# sourceMappingURL=fieldValidation.d.ts.map