import { type Formatter as FormatterI } from "./Formatter.ts"; import type * as Schema from "./Schema.ts"; import type * as SchemaAST from "./SchemaAST.ts"; import type { StandardSchemaV1 } from "./StandardSchema.ts"; declare const TypeId = "~effect/SchemaIssue/Issue"; /** * Returns `true` if the given value is an {@link Issue}. * * **When to use** * * Use when you need to narrow an `unknown` value to `Issue` in error-handling * code, such as distinguishing an `Issue` from other error types in a catch-all * handler. * * **Details** * * - Checks for the internal `TypeId` brand on the value. * * **Example** (Type-guarding an unknown error) * * ```ts import.meta.vitest * import { SchemaIssue } from "effect" * * const issue = new SchemaIssue.MissingKey(undefined) * SchemaIssue.isIssue(issue) // => true * SchemaIssue.isIssue("not an issue") // => false * ``` * * @see {@link Issue} * * @stability stable * @category guards * @since 4.0.0 */ export declare function isIssue(u: unknown): u is Issue; /** * Returns `true` when an issue contains an input reported by the schema parser. * * **When to use** * * Use when reading `Issue.input`, especially when `undefined` is a valid input * value. * * **Details** * * Reported input is stored as an own property. This guard checks for that * property and narrows `input` from optional to required. * * **Example** (Reading a reported input) * * ```ts import.meta.vitest * import { Result, Schema, SchemaIssue } from "effect" * * const result = Schema.decodeUnknownResult(Schema.String)(1, { reportInput: true }) * if (Result.isFailure(result) && SchemaIssue.hasInput(result.failure.issue)) { * result.failure.issue.input // => 1 * } * ``` * * @see {@link Issue} for the complete issue model * * @stability stable * @category guards * @since 4.0.0 */ export declare function hasInput(issue: Issue): issue is Issue & { readonly input: unknown; }; /** * Union of all terminal (leaf) issue types that have no inner `Issue` children. * * **When to use** * * Use when constraining formatter hooks to only handle terminal nodes or when * pattern matching on the `_tag` of an issue and only leaf nodes matter. * * **Details** * * Members: {@link InvalidType}, {@link InvalidValue}, {@link MissingKey}, * {@link UnexpectedKey}, {@link Forbidden}, {@link OneOf}. * * @see {@link Issue} — the full union including composite nodes * @see {@link LeafHook} — formatter hook that operates on `Leaf` values * * @stability stable * @category models * @since 4.0.0 */ export type Leaf = InvalidType | InvalidValue | MissingKey | UnexpectedKey | Forbidden | OneOf; /** * The root discriminated union of all validation error nodes. * * **When to use** * * Use when typing the error channel in `Effect` results from * schema parsing, or when writing custom formatters or issue-tree walkers. * * **Details** * * Every node has a `_tag` field for pattern-matching. The union includes both * terminal {@link Leaf} types and composite types that wrap inner issues: * {@link Filter}, {@link Encoding}, {@link Pointer}, {@link Composite}, * {@link AnyOf}. Use {@link makeFormatterDefault} when a human-readable * representation is needed. When parsing with `reportInput: true`, * value-bearing issues expose the rejected value through an enumerable `input` * field. Built-in formatters may include reported input in default messages. This * is not a general sanitization boundary: paths, ASTs, union successes, and * custom annotations or messages are preserved as supplied and remain the * caller's responsibility. * * @see {@link Leaf} — the terminal subset * @see {@link isIssue} — type guard * @see {@link hasInput} — checks whether an issue reports an input * @stability stable * @category models * @since 4.0.0 */ export type Issue = Leaf | Filter | Encoding | Pointer | Composite | AnyOf; interface IssueNode { readonly [TypeId]: typeof TypeId; /** * The input reported by the schema parser, when input reporting is enabled * and the issue is associated with a present value. */ readonly input?: unknown; } /** * Represents a schema issue produced when a schema filter (refinement check) fails. * * **When to use** * * Use when you need to inspect a schema issue that records which refinement * check rejected the value. * * **Details** * * - `filter` is the AST filter node that produced this issue. * - `issue` is the inner issue describing the failure reason. * * **Example** (Matching a Filter issue) * * ```ts import.meta.vitest * import { SchemaAST, SchemaIssue } from "effect" * * const formatIssue = SchemaIssue.makeFormatterDefault() * * function describe(issue: SchemaIssue.Issue): string { * if (issue._tag === "Filter") { * return `Filter failed: ${formatIssue(issue.issue)}` * } * return formatIssue(issue) * } * * const issue = new SchemaIssue.Filter( * SchemaAST.isPattern(/^valid$/), * new SchemaIssue.InvalidValue() * ) * describe(issue) // => `Filter failed: Expected a valid value` * ``` * * @see {@link Leaf} — terminal issue types that commonly appear as the inner `issue` * @see {@link CheckHook} — formatter hook for `Filter` issues * * @stability stable * @category models * @since 4.0.0 */ export interface Filter extends IssueNode { readonly _tag: "Filter"; /** * The filter that failed. */ readonly filter: SchemaAST.Filter; /** * The issue that occurred. */ readonly issue: Issue; } /** * Constructs a schema issue for a failed refinement check. * * @stability stable * @category constructors * @since 4.0.0 */ export declare const Filter: new ( /** * The filter that failed. */ filter: SchemaAST.Filter, /** * The issue that occurred. */ issue: Issue, /** * The present input associated with the issue. It is retained only when * `options.reportInput` is `true`. */ input?: unknown, /** * The effective parse options controlling input retention. */ options?: SchemaAST.ParseOptions) => Filter; /** * Represents a schema issue produced when a schema transformation (encode/decode step) fails. * * **When to use** * * Use when you need to inspect failures from `Schema.decodeTo` / `Schema.encodeTo` * transformations. * * **Details** * * - `ast` is the AST node for the transformation that failed. * - `issue` is the inner issue describing the failure. * * @see {@link Filter} — failure from a refinement check (not a transformation) * @see {@link Composite} — multiple issues from a single schema node * * @stability stable * @category models * @since 4.0.0 */ export interface Encoding extends IssueNode { readonly _tag: "Encoding"; /** * The schema that caused the issue. */ readonly ast: SchemaAST.AST; /** * The issue that occurred. */ readonly issue: Issue; } /** * Constructs a schema issue for a failed transformation. * * @stability stable * @category constructors * @since 4.0.0 */ export declare const Encoding: new (ast: SchemaAST.AST, issue: Issue, input?: unknown, options?: SchemaAST.ParseOptions) => Encoding; /** * Wraps an inner {@link Issue} with a property-key path, indicating *where* in * a nested structure the error occurred. * * **When to use** * * Use when you need to walk the issue tree to accumulate path segments for error * reporting. * * **Details** * * - `path` is an array of property keys (strings, numbers, or symbols). * - Formatters concatenate nested `Pointer` paths into a single path like * `["a"]["b"][0]`. * * @see {@link Composite} — groups multiple issues under one schema node * * @stability stable * @category models * @since 4.0.0 */ export interface Pointer extends IssueNode { readonly _tag: "Pointer"; /** * The path to the location in the input that caused the issue. */ readonly path: ReadonlyArray; /** * The issue that occurred. */ readonly issue: Issue; } /** * Constructs a schema issue that points to a nested location. * * @stability stable * @category constructors * @since 4.0.0 */ export declare const Pointer: new (path: ReadonlyArray, issue: Issue) => Pointer; /** * Represents a schema issue produced when a required key or tuple index is missing from the input. * * **When to use** * * Use when you need to detect absent fields in struct/tuple validation. * * **Details** * * - `annotations` may contain a custom `messageMissingKey` for formatting. * * @see {@link Pointer} — wraps this issue with the missing key's path * @see {@link UnexpectedKey} — the opposite case (extra key present) * * @stability stable * @category models * @since 4.0.0 */ export interface MissingKey extends IssueNode { readonly _tag: "MissingKey"; /** * The metadata for the issue. */ readonly annotations: Schema.Annotations.Key | undefined; } /** * Constructs a schema issue for a missing key or tuple index. * * @stability stable * @category constructors * @since 4.0.0 */ export declare const MissingKey: new (annotations: Schema.Annotations.Key | undefined) => MissingKey; /** * Represents a schema issue produced when an input object or tuple contains a key/index not * declared by the schema. * * **When to use** * * Use when you need to detect excess properties during strict struct/tuple * validation. * * **Details** * * - `ast` is the schema that was being validated against. * - `annotations` on `ast` may contain a custom `messageUnexpectedKey`. * - The default formatter renders this as `"Expected no excess property"`, or * `"Unexpected key with value "` when the issue reports an input. * * @see {@link MissingKey} — the opposite case (required key absent) * @see {@link Pointer} — wraps this issue with the unexpected key's path * * @stability stable * @category models * @since 4.0.0 */ export interface UnexpectedKey extends IssueNode { readonly _tag: "UnexpectedKey"; /** * The schema that caused the issue. */ readonly ast: SchemaAST.AST; } /** * Constructs a schema issue for an unexpected key or tuple index. * * @stability stable * @category constructors * @since 4.0.0 */ export declare const UnexpectedKey: new (ast: SchemaAST.AST, input?: unknown, options?: SchemaAST.ParseOptions) => UnexpectedKey; /** * Represents a schema issue that groups multiple child issues under a single schema node. * * **When to use** * * Use when you need to walk the issue tree for struct/tuple schemas that collect * all field errors rather than failing on the first. * * **Details** * * - `issues` is a non-empty readonly array (at least one child). * - Formatters flatten `Composite` by recursing into each child. * * @see {@link AnyOf} — used for union no-match errors (similar but different semantics) * @see {@link Pointer} — adds path context to individual issues * * @stability stable * @category models * @since 4.0.0 */ export interface Composite extends IssueNode { readonly _tag: "Composite"; /** * The schema that caused the issue. */ readonly ast: SchemaAST.AST; /** * The issues that occurred. */ readonly issues: readonly [Issue, ...Array]; } /** * Constructs a schema issue that groups multiple child issues. * * @stability stable * @category constructors * @since 4.0.0 */ export declare const Composite: new (ast: SchemaAST.AST, issues: readonly [Issue, ...Array], input?: unknown, options?: SchemaAST.ParseOptions) => Composite; /** * Represents a schema issue produced when the runtime type of the input does not match the type * expected by the schema. * * **When to use** * * Use when you need to detect basic type mismatches, such as a wrong primitive * or `null` where an object was expected. * * **Details** * * - `ast` is the schema node that expected a different type. * - The default formatter renders this as `"Expected "`, adding * `", got "` when the issue reports an input. * * **Example** (Formatting a type mismatch) * * ```ts import.meta.vitest * import { Schema, SchemaIssue } from "effect" * * const formatIssue = SchemaIssue.makeFormatterDefault() * const issue = new SchemaIssue.InvalidType(Schema.String.ast) * formatIssue(issue) // => "Expected string" * ``` * * @see {@link InvalidValue} — the input has the right type but fails a value constraint * * @stability stable * @category models * @since 4.0.0 */ export interface InvalidType extends IssueNode { readonly _tag: "InvalidType"; /** * The schema that caused the issue. */ readonly ast: SchemaAST.AST; } /** * Constructs a schema issue for an input with an invalid runtime type. * * @stability stable * @category constructors * @since 4.0.0 */ export declare const InvalidType: new (ast: SchemaAST.AST, input?: unknown, options?: SchemaAST.ParseOptions) => InvalidType; /** * Represents a schema issue produced when the input has the correct type but its value violates a * constraint (e.g. a string that is too short, a number out of range). * * **When to use** * * Use when you need to detect constraint violations from `Schema.check` with * `Schema.isMinLength`, `Schema.isGreaterThan`, or similar checks. * * **Details** * * - A `message` annotation is returned unchanged and takes precedence over all * other default formatting. * - Without `message`, an `expected` annotation is formatted as * `"Expected "`, adding `", got "` when input is reported. * - Without either annotation, the default formatter renders * `"Expected a valid value"`, or `"Invalid data "` when input is * reported. * * **Example** (Returning InvalidValue from a custom filter) * * ```ts import.meta.vitest * import { SchemaIssue } from "effect" * * const formatIssue = SchemaIssue.makeFormatterDefault() * const issue = new SchemaIssue.InvalidValue({ message: "must not be empty" }) * formatIssue(issue) // => "must not be empty" * ``` * * @see {@link InvalidType} — the input has the wrong type entirely * @see {@link Filter} — composite wrapper when a schema filter produces this issue * * @stability stable * @category models * @since 4.0.0 */ export interface InvalidValue extends IssueNode { readonly _tag: "InvalidValue"; /** * The metadata for the issue. */ readonly annotations: Schema.Annotations.Issue | undefined; } /** * Constructs a schema issue for a value that violates a constraint. * * @stability stable * @category constructors * @since 4.0.0 */ export declare const InvalidValue: new (annotations?: Schema.Annotations.Issue | undefined, input?: unknown, options?: SchemaAST.ParseOptions) => InvalidValue; /** * Represents a schema issue produced when a forbidden operation is encountered during parsing, * such as an asynchronous Effect running inside `Schema.decodeUnknownSync`. * * **When to use** * * Use when you need to detect that a schema requires async execution but was run * synchronously. * * **Details** * * - `annotations` optionally carries a `message` string. * - The default formatter renders this as `"Forbidden operation"`. * * **Example** (Creating a Forbidden issue) * * ```ts import.meta.vitest * import { SchemaIssue } from "effect" * * const formatIssue = SchemaIssue.makeFormatterDefault() * const issue = new SchemaIssue.Forbidden( * { message: "async operation not allowed in sync context" } * ) * formatIssue(issue) // => "async operation not allowed in sync context" * ``` * * @see {@link InvalidValue} — for value-constraint failures (not operation failures) * * @stability stable * @category models * @since 4.0.0 */ export interface Forbidden extends IssueNode { readonly _tag: "Forbidden"; /** * The metadata for the issue. */ readonly annotations: Schema.Annotations.Issue | undefined; } /** * Constructs a schema issue for a forbidden parsing operation. * * @stability stable * @category constructors * @since 4.0.0 */ export declare const Forbidden: new (annotations: Schema.Annotations.Issue | undefined, input?: unknown, options?: SchemaAST.ParseOptions) => Forbidden; /** * Represents a schema issue produced when a value does not match *any* member of a union schema. * * **When to use** * * Use when you need to inspect which union members were attempted and why each * failed. * * **Details** * * - `ast` is the `Union` AST node. * - `issues` contains the per-member failures. * * **Gotchas** * * `issues` is empty when no union member was applicable. In that case, the * default formatter reports the expected type for the union and appends * `", got "` when input is reported. * * @see {@link OneOf} — the opposite: *too many* members matched * @see {@link Composite} — groups multiple issues under a non-union schema * * @stability stable * @category models * @since 4.0.0 */ export interface AnyOf extends IssueNode { readonly _tag: "AnyOf"; /** * The schema that caused the issue. */ readonly ast: SchemaAST.Union; /** * The issues that occurred. */ readonly issues: ReadonlyArray; } /** * Constructs a schema issue for a value that matches no union member. * * @stability stable * @category constructors * @since 4.0.0 */ export declare const AnyOf: new (ast: SchemaAST.Union, issues: ReadonlyArray, input?: unknown, options?: SchemaAST.ParseOptions) => AnyOf; /** * Represents a schema issue produced when a value matches *multiple* members of a union that is * configured to allow exactly one match (oneOf mode). * * **When to use** * * Use when you need to detect ambiguous union matches when `oneOf` validation is * enabled. * * **Details** * * - `ast` is the `Union` AST node. * - `successes` lists the AST nodes of each member that accepted the input. * - The default formatter renders this as * `"Expected exactly one member to match"`, or * `"Expected exactly one member to match the input "` when input is * reported. * * @see {@link AnyOf} — the opposite: *no* members matched * * @stability stable * @category models * @since 4.0.0 */ export interface OneOf extends IssueNode { readonly _tag: "OneOf"; /** * The schema that caused the issue. */ readonly ast: SchemaAST.Union; /** * The schemas that were successful. */ readonly successes: ReadonlyArray; } /** * Constructs a schema issue for a value that matches multiple union members. * * @stability stable * @category constructors * @since 4.0.0 */ export declare const OneOf: new (ast: SchemaAST.Union, successes: ReadonlyArray, input?: unknown, options?: SchemaAST.ParseOptions) => OneOf; /** * A function type that converts an {@link Issue} into a formatted * representation. Specialisation of the generic `Formatter` from * `Formatter.ts` with `Value` fixed to `Issue`. * * @see {@link makeFormatterDefault} — creates a `Formatter` * @see {@link makeFormatterStandardSchemaV1} — creates a `Formatter` * * @stability stable * @category formatting * @since 4.0.0 */ export interface Formatter extends FormatterI { } /** * Callback type used to format {@link Leaf} issues into strings. * * **When to use** * * Use when customizing how {@link makeFormatterStandardSchemaV1} renders * terminal issues. * * @see {@link defaultLeafHook} — the built-in implementation * @see {@link Leaf} — the union of terminal issue types * * @stability stable * @category formatting * @since 4.0.0 */ export type LeafHook = (issue: Leaf) => string; /** * Returns the built-in {@link LeafHook} used by default formatters. * * **When to use** * * Use as the default leaf renderer when customizing only the {@link CheckHook}. * * **Details** * * - Checks for a `message` annotation first; returns it if present. * - For `InvalidValue`, an `expected` annotation uses the standard expected * value message and includes reported input when available. * - Otherwise generates a default message per `_tag`. When the issue reports * input, the message includes its formatted value where applicable: * - `InvalidType` → `"Expected "` or `"Expected , got "` * - `InvalidValue` → `"Expected a valid value"` or `"Invalid data "` * - `MissingKey` → `"Missing key"` * - `UnexpectedKey` → `"Expected no excess property"` or * `"Unexpected key with value "` * - `Forbidden` → `"Forbidden operation"` * - `OneOf` → `"Expected exactly one member to match"` or * `"Expected exactly one member to match the input "` * * **Example** (Formatting Standard Schema issues with defaultLeafHook) * * ```ts import.meta.vitest * import { SchemaIssue } from "effect" * * const formatter = SchemaIssue.makeFormatterStandardSchemaV1({ * leafHook: SchemaIssue.defaultLeafHook * }) * formatter(new SchemaIssue.MissingKey(undefined)) // => { issues: [{ path: [], message: "Missing key" }] } * ``` * * @see {@link LeafHook} * @see {@link makeFormatterStandardSchemaV1} * * @stability stable * @category formatting * @since 4.0.0 */ export declare const defaultLeafHook: LeafHook; /** * Callback type used to format {@link Filter} issues into strings. * * **When to use** * * Use when customizing how {@link makeFormatterStandardSchemaV1} renders * filter failures. * * **Details** * * - Returns `string` to override the message, or `undefined` to fall back to * the default formatting. * * @see {@link defaultCheckHook} — the built-in implementation * @see {@link Filter} — the issue type this hook formats * * @stability stable * @category formatting * @since 4.0.0 */ export type CheckHook = (issue: Filter) => string | undefined; /** * Returns the built-in {@link CheckHook} used by default formatters. * * **When to use** * * Use as the default filter renderer when customizing only the {@link LeafHook}. * * **Details** * * - Looks for a `message` annotation on the filter first, then on the inner * issue. * - Returns `undefined` when no annotation is found, causing the formatter to * fall back to `"Expected "` or, when the filter reports input, * `"Expected , got "`. * * @see {@link CheckHook} * @see {@link makeFormatterStandardSchemaV1} * * @stability stable * @category formatting * @since 4.0.0 */ export declare const defaultCheckHook: CheckHook; /** * Creates a {@link Formatter} that produces a `StandardSchemaV1.FailureResult`. * * **When to use** * * Use when you need schema parse errors in * [Standard Schema V1](https://github.com/standard-schema/standard-schema) * format, optionally customizing leaf or check issue rendering. * * **Details** * * - Returns a `Formatter`. * - Each leaf issue is flattened into `{ message, path }` entries. * - `Pointer` paths are accumulated to produce full property paths. * - Falls back to {@link defaultLeafHook} / {@link defaultCheckHook} when no * hooks are provided. * - Default messages include reported input when the issue that produces the * message has an `input` field. The returned Standard Schema issues do not * receive an `input` field. * * **Gotchas** * * Reported input can appear inside the Standard Schema `message` string even * though it is not exposed as a separate property. Custom hooks control their * complete message and are not modified. * * **Example** (Creating a Standard Schema V1 formatter) * * ```ts import.meta.vitest * import { SchemaIssue } from "effect" * * const formatter = SchemaIssue.makeFormatterStandardSchemaV1() * formatter(new SchemaIssue.MissingKey(undefined)).issues[0].message // => "Missing key" * ``` * * @see {@link makeFormatterDefault} — produces a plain string instead * @see {@link LeafHook} * @see {@link CheckHook} * * @stability stable * @category formatting * @since 4.0.0 */ export declare function makeFormatterStandardSchemaV1(options?: { readonly leafHook?: LeafHook | undefined; readonly checkHook?: CheckHook | undefined; }): Formatter; /** * Creates a {@link Formatter} that converts an {@link Issue} into a * human-readable multi-line string. * * **When to use** * * Use when you need to format a `SchemaIssue.Issue` as error messages for * logging, CLI output, or developer-facing diagnostics. * * **Details** * * - Flattens the issue tree into `{ message, path }` entries using * {@link defaultLeafHook} and {@link defaultCheckHook}. * - Includes reported input in default messages when the node producing the * message has an `input` field. * - Each entry is rendered as `""` or `"\n at "`. * - Multiple entries are joined with newlines. * * **Gotchas** * * Formatting an issue can disclose input retained with `reportInput: true`. * Wrapper inputs are not inherited by child messages, and custom messages are * returned unchanged. * * **Example** (Formatting an issue as a string) * * ```ts import.meta.vitest * import { SchemaIssue } from "effect" * * const formatter = SchemaIssue.makeFormatterDefault() * formatter(new SchemaIssue.MissingKey(undefined)) // => "Missing key" * ``` * * @see {@link makeFormatterStandardSchemaV1} — produces Standard Schema V1 format instead * @see {@link Formatter} * * @stability stable * @category formatting * @since 4.0.0 */ export declare function makeFormatterDefault(): Formatter; export {}; //# sourceMappingURL=SchemaIssue.d.ts.map