API Reference
This page is a curated quick reference for the core Ack classes, methods, and annotations. Use the generated API documentation for every public declaration and exact signatures; use the linked guides here for explanations and examples.
Core Ack Class
Entry point for creating schemas. See Schema Types.
Ack.string(): Creates aStringSchemafor validatingStringvalues.Ack.integer(): Creates anIntegerSchemafor validatingintvalues. Rejectsdouble(e.g.42.0).Ack.double(): Creates aDoubleSchemafor validatingdoublevalues. Rejectsint(e.g.42).Ack.number(): Creates aNumberSchemafor validating anynumvalue (accepts bothintanddouble).Ack.boolean(): Creates aBooleanSchemafor validatingboolvalues.Ack.list(AckSchema itemSchema): Creates aListSchemafor validating arrays. Nullable item schemas are not supported; make the list itself nullable instead.Ack.object(Map<String, AckSchema> properties): Creates anObjectSchemafor validating objects.Ack.enumValues(List<T> values): Creates anEnumSchema<T>for Dart enum types. Parses enum.namestrings into typed enum values. Pass typed enum values toencodeorsafeEncodefor the reverse direction. Preferred overenumStringwhen a Dart enum exists.Ack.enumCodec(List<T> values): LikeenumValues, but returns aCodecSchema<String, T>instead of anEnumSchema<T>. Use this when downstream code expects every value-shape to be aCodecSchema(e.g. a registry of codecs). The decode and encode functions are identity — the underlyingEnumSchemastill maps betweenTand the enum’s.name.Ack.enumString(List<String> values): Creates aStringSchemaconstrained to the given values. For ad-hoc string lists without a backing Dart enum.Ack.anyOf(List<AckSchema> schemas): Creates anAnyOfSchemafor union types.Ack.any(): Creates anAnySchemathat accepts any non-null JSON-safe value. Chain.nullable()to allownull.Ack.instance<T extends Object>(): Creates a schema that checks a value is a Dart instance ofT(runtime type check; handy as a codecoutputschema).Ack.codec(...)/Ack.date()/Ack.datetime()/Ack.uri()/Ack.duration()/Ack.enumCodec(...): Create codecs. See Codecs.Ack.lazy(String name, AckSchema Function() builder, {int maxDepth = 100}): Creates a memoized deferred schema reference for recursive schema graphs.maxDepthmust be at least1and limits parsing, runtime validation, and encoding. JSON Schema export renders Draft-7definitions/$refentries usingnamebut warns that the runtime-only depth limit was omitted.Ack.discriminated<T extends Object>(...): Creates a discriminated union schema. Branches may be plainObjectSchemaor transformed schemas whose base is anObjectSchema. The union owns the discriminator: branches normally omit it, boundary payloads must include it, compatible branch discriminator fields are allowed, and conflicts are rejected. Exported/generated branches expose the exact branch literal.
AckSchema<Boundary, Runtime> (Base Class)
Base class for all schema types.
Primary Validation Methods
SchemaResult<Runtime> safeParse(Object? data, {String? debugName}): Validatesdataand returns aSchemaResult. Invalid input and recoverableExceptionvalues thrown by constraint/refinement callbacks become failures.Errorvalues from those callbacks are rethrown with their original stack trace. Codec/transform decoder failures, includingErrorvalues, becomeSchemaTransformErrorfailures.Runtime? parse(Object? data, {String? debugName}): Validatesdataand returns the value; throwsAckExceptionon failure.SchemaResult<TOut> safeParseAs<TOut extends Object>(Object? data, TOut Function(Runtime?) map, {String? debugName}): Parses and maps the validated value toTOut. Mapper failures, includingErrorvalues, becomeSchemaTransformErrorfailures.TOut parseAs<TOut extends Object>(Object? data, TOut Function(Runtime?) map, {String? debugName}): Throwing variant ofsafeParseAs.SchemaResult<Boundary> safeEncode(Runtime? value, {String? debugName}): Encodes a runtime value to the boundary representation.Boundary? encode(Runtime? value, {String? debugName}): Throwing variant ofsafeEncode.
Schema Modification Methods
AckSchema<Boundary, Runtime> nullable({bool value = true}): Returns a new schema that also acceptsnull.AckSchema<Boundary, Runtime> optional({bool value = true}): Returns a new schema marked as optional (for object fields).AckSchema<Boundary, Runtime> describe(String description): Attaches a description for documentation and JSON Schema generation.DefaultSchema<Boundary, Runtime> withDefault(Runtime value): Wraps the schema in aDefaultSchemathat suppliesvaluewhen the parse input isnull.
Primitive schemas (StringSchema, IntegerSchema, DoubleSchema, NumberSchema, BooleanSchema) are strict — they reject values whose Dart runtime type doesn’t match. IntegerSchema and DoubleSchema do not overlap (42.0 fails Ack.integer(), 42 fails Ack.double()); use Ack.number() when either is acceptable. For non-num boundary types (e.g. numeric strings), use transform or codec to convert before validation.
Custom Validation Methods
AckSchema<Boundary, Runtime> constrain(Constraint<Runtime> constraint, {String? message}): Adds a constraint and optionally overrides its message. The constraint must mix inValidator<Runtime>, or anArgumentErroris thrown.AckSchema<Boundary, Runtime> withConstraint(Constraint<Runtime> constraint): Adds a constraint directly (no message override;constraindelegates here).AckSchema<Boundary, Runtime> refine(bool Function(Runtime) validate, {String message = 'The value did not pass the custom validation.'}): Adds a custom validation predicate with an optional error message.CodecSchema<Boundary, R> transform<R>(R Function(Runtime) transformer): Transforms validated runtime values toR(parse-only; encode fails).
Utility Methods
Map<String, Object?> toJsonSchema(): Returns a Draft-7 JSON Schema map via the canonicalAckSchemaModelboundary.AckSchemaModel toSchemaModel(): Returns the canonical, target-independent boundary model for schema adapters, including export warnings.Map<String, Object?> toMap(): Serializes the schema for debugging.
See also Schema Types for detailed usage examples.
StringSchema
Schema for validating strings. See String Validation.
Length Constraints
minLength(int min): Minimum string lengthmaxLength(int max): Maximum string lengthlength(int exact): Exact string lengthnotEmpty(): String must not be empty (equivalent tominLength(1))
Pattern Matching
matches(String pattern, {String? example, String? message}): Must match a regex pattern. Patterns are not automatically anchored — use^...$for full-string matching. See String validation for details.contains(String pattern, {String? example, String? message}): Must contain the pattern anywhere in the string.startsWith(String value): Must start withvalue.endsWith(String value): Must end withvalue.
Format Validation
email(): Must be valid email formaturl(): Must be valid URL format (alias foruri())uri(): Must be a valid absolute URI with a scheme and hostuuid(): Must be valid UUID formatip({int? version}): Must be valid IP address (version 4 or 6)ipv4(): Must be valid IPv4 addressipv6(): Must be valid IPv6 address
Date and Time
date(): Must be valid ISO 8601 date (YYYY-MM-DD)datetime(): Must be a valid ISO 8601 datetime; announced RFC leap seconds are accepted and preserved as stringstime(): Must be valid time format (HH:MM:SS)
Transformations
trim(): Removes leading and trailing whitespacetoLowerCase(): Converts to lowercasetoUpperCase(): Converts to uppercase
IntegerSchema / DoubleSchema / NumberSchema (Number Schemas)
Schemas for validating numeric values. IntegerSchema only accepts int,
DoubleSchema only accepts double, and NumberSchema accepts any num
(either int or double). DoubleSchema and NumberSchema reject non-finite
values by default. See Number Validation.
Each method’s parameter type matches the schema’s runtime type: int for IntegerSchema, double for DoubleSchema, and num for NumberSchema.
min(N limit): Minimum value (inclusive)max(N limit): Maximum value (inclusive)greaterThan(N limit): Must be greater than limit (exclusive)lessThan(N limit): Must be less than limit (exclusive)positive(): Must be greater than 0negative(): Must be less than 0multipleOf(N factor): Must be a multiple of the factorfinite(): Must be finite (DoubleSchemaandNumberSchema; already the default)safe(): Must be within safe integer range (IntegerSchemaonly)
BooleanSchema
Schema for validating booleans. Validates true and false values strictly — non-boolean inputs are rejected. For boundary types that arrive as strings (e.g. "true"/"false"), use a transform or codec to convert before validation.
ListSchema<T>
Schema for validating arrays. See List Validation.
minItems(int min): Minimum number of items (alias:minLength)maxItems(int max): Maximum number of items (alias:maxLength)exactLength(int exact): Exact number of items (alias:length)nonEmpty(): List must have at least one item (alias:notEmpty)unique(): All items must be unique
ObjectSchema
Schema for validating objects (maps). See Object Validation.
- Constructed using
Ack.object(Map<String, AckSchema> properties, {bool additionalProperties = false}). - Use
.pick(List<String> keys)to create schema with only specified properties. - Use
.omit(List<String> keys)to create schema excluding specified properties. - Use
.extend(Map<String, AckSchema> newProperties)to add more properties. - Use
.partial()to make all properties optional. - Use
.strict()to disallow additional properties. - Use
.passthrough()to allow additional properties not defined in the schema. - Use
.merge(ObjectSchema other)to combine with another object schema.
SchemaResult<T>
Object returned by safeParse(). See Error Handling.
bool isOk:trueif validation succeeded.bool isFail:trueif validation failed.T? getOrThrow(): Returns the validated value (which can benullfor a nullable schema), or throwsAckExceptionon failure.T? getOrNull(): Returns the validated value, ornullon failure.SchemaError getError(): Returns the validation error; only valid whenisFailistrue.T? getOrElse(T? Function() orElse): Returns the validated value, or callsorElseon failure.SchemaResult<R> map<R>(R Function(T?) transform): Maps the successful value to a new result type; propagates failures unchanged.R match<R>({required R Function(T?) onOk, required R Function(SchemaError) onFail}): Pattern-matches on success or failure.void ifOk(void Function(T?) action): Executesactiononly when the result is successful.void ifFail(void Function(SchemaError) action): Executesactiononly when the result is a failure.
SchemaError (and subclasses)
Represents a validation failure. See Error handling.
String message: Human-readable error message.SchemaContext context: Context about where the error occurred.
Subclasses:
TypeMismatchError: The input has the wrong Dart runtime type.SchemaConstraintsError: One or more constraint violations.SchemaNestedError: Validation failures in nested objects or arrays.SchemaValidationError: Custom refinement failures.SchemaTransformError: Decode/transform callback failures.SchemaEncodeError: Encode-path failures (non-nullable null, one-way transform, encoder threw, etc.).
Constraint<T>
Base class for custom validation rules. See Custom validation.
String constraintKey: Unique identifier for the constraint.String description: Human-readable description.Map<String, Object?> toMap(): Serializes the constraint for debugging.
Validator<T> (mixin)
Validation behavior mixin used with Constraint<T>.
bool isValid(T value): Returnstruewhen the value passes validation.String buildMessage(T value): Builds the validation failure message.ConstraintError? validate(T value): Validates a value and returns an error if invalid.
Additional schema types
Ack ships with a broad set of schema factories beyond what is listed here.
See Schema types for the full catalogue,
including Ack.date(), Ack.literal(), and list/object combinators.
Ack.discriminated(...)
Schema for polymorphic validation based on a string discriminator property.
- Branch schemas normally omit the discriminator field.
- The boundary payload must still contain the discriminator key.
- If a branch schema includes the discriminator field, it must be
Ack.literal(...)matching the branch key orAck.enumString(...)containing it. Broad, transformed, refined, or otherwise restrictive discriminator fields are rejected. - Exported and generated schemas expose each branch discriminator as an exact literal.
- Generated subtype
parse()andsafeParse()methods validate through the union’s effective branch.
Ack.lazy(...)
Schema reference for recursive object graphs.
- Created using
Ack.lazy<Boundary, Runtime>(name, builder).maxDepthdefaults to100and must be at least1; pass it explicitly only to override the default. - The builder is resolved once and memoized.
- Exceeding
maxDepthreturns a validation failure during parsing, runtime validation, or encoding. toJsonSchema()andtoSchemaModel()export Draft-7definitions/$refentries using the lazyname. The runtime-only depth limit cannot be represented by$ref, so exported schema models warn that it was omitted.- Bare or wrapped lazy schemas cannot be used as discriminated-union branches because the branch discriminator must be analyzable at construction time.
Code generation annotations
Use the ack_generator builders in
either direction: @AckInfer() generates a model from a schema, and
@AckModel() generates a schema from a class. AckSchema is the runtime
schema type; there is no @AckSchema() annotation. After adding matching
.ack.dart and .ack.g.dart part directives, run:
dart run build_runner build@AckInfer()
Target: Schema variables and getters
Generates: An immutable model class backed by the existing schema
Annotate a top-level schema variable or getter. The schema stays in your source file and remains responsible for validation and codecs.
Supported schema types:
Ack.object({...})→ immutable object models- Primitives:
Ack.string(),Ack.integer(),Ack.double(),Ack.boolean() - Collections:
Ack.list(...), typed sets and maps - Enums:
Ack.literal(),Ack.enumString(),Ack.enumValues() - Discriminated unions:
Ack.discriminated(...)
Unsupported: nullable roots, one-way transforms, Ack.any(), Ack.anyOf(), bare Ack.instance<T>(), and anonymous inline objects
For Ack.discriminated(...) constraints with @AckInfer, see
Model Code Generation.
Example:
import 'package:ack/ack.dart';
import 'package:ack_annotations/ack_annotations.dart';
part 'user.ack.dart';
part 'user.ack.g.dart';
@AckInfer()
final userSchema = Ack.object({
'name': Ack.string(),
'email': Ack.string().email(),
});
// Generated:
// - final class User { ... }
// - The schema variable remains unchanged
// Usage:
final user = User.parse({'name': 'Alice', 'email': 'alice@example.com'});
print(user.name); // Type-safe String access
print(user.email); // Type-safe String access
print(user.toJson());@AckModel()
Target: Public, constructable classes
Generates: A public <ClassName>Schema facade backed by a private raw
wireSchema and typed codec, plus the _$ClassAck mixin for toJson,
safeToJson, copyWith, and deep collection-aware == / hashCode /
toString
Ack infers schema fields from constructor-backed fields. Required parameters,
nullable types, optional parameters, and constructor defaults determine field
presence. Use caseStyle for model-wide JSON naming and @JsonKey(name: ...)
for a field override. Instantiable models and implicit union branches must
apply the generated mixin. copyWith treats null as “keep the current
value.”
Inferred field types: strings, booleans, numeric types, DateTime, Uri,
Duration, enums, nested lists, and sets
Constraint annotations:
- numeric:
@Min,@Max,@MultipleOf,@Positive,@Negative - strings:
@MinLength,@MaxLength,@Pattern,@Email,@NotEmpty - collections:
@MinItems,@MaxItems,@UniqueItems
Use @AckField to override schema and/or AckFieldPresence. A no-op
@AckField() is rejected. A sealed base annotated with
@AckModel(discriminatorKey: ...) generates a discriminated union from its
same-library concrete branches. Unknown properties use
AckAdditionalPropertiesMode (reject by default; discard or capture).
@AckModel(caseStyle: AckCaseStyle.snake)
final class Account with _$AccountAck {
const Account({required this.displayName, this.role = 'member'});
@MinLength(2)
final String displayName;
final String role;
static final fromJson = AccountSchema.fromJson;
}
final account = AccountSchema.parse({'display_name': 'Ada'});
print(account.toJson());
print(AccountSchema.toJsonSchema());The facade exposes schema, wireSchema, parse, safeParse, fromJson,
encode, safeEncode, toJsonSchema, and toSchemaModel. The backing
_accountSchema is library-private and no public lower-camel alias is
generated. Set schemaName: 'WireAccountSchema' to choose the exact facade
class name.
Nested class-first fields compose through AddressSchema.schema. Imports with
combinators must expose both names (show Address, AddressSchema). A
schema-first @AckInfer() declaration may also compose the facade explicitly,
and class-first models can use schema-first generated model types on a clean
build.
@AckModel() cannot share a class with @JsonSerializable(). Class-first
value roots, automatic recursive graphs, and undiscriminated anyOf shapes are
unsupported; use schema-first @AckInfer() and named Ack.lazy for those
cases. See
Model Code Generation for the complete
tutorial and comparison.
EnumSchema<T>
Schema for mapping enum .name strings at the boundary to typed enum values at
runtime. Created using Ack.enumValues(List<T> values) where T extends Enum;
encode and safeEncode map typed enum values back to their names.
AnyOfSchema
Schema for union types; the value must match one of several schemas. Created using Ack.anyOf(List<AckSchema> schemas).
DiscriminatedObjectSchema
Schema for polymorphic validation based on a discriminator field.
- Created using
Ack.discriminated<T extends Object>(...)withdiscriminatorKeyandschemas. effectiveBranch(String discriminatorValue): Returns the branch schema with the discriminator injected as the exact branch literal. Generated subtypes use this to validate a specific branch.
AckSchemaModel
Canonical export model for Ack schemas.
- Created by
schema.toSchemaModel(). - Represents the boundary/export shape, JSON-compatible defaults, discriminator metadata, target-independent constraints, and export warnings.
schema.toSchemaModel().toJsonSchema()returns the same Draft-7 map asschema.toJsonSchema().- Adapters that need a JSON map should call
schema.toJsonSchema(); adapters for non-JSON targets should convert fromAckSchemaModelrather than traversingAckSchemasubclasses directly.
AnySchema
Accepts any non-null JSON-safe value without further validation.
- Created by
Ack.any(). - Useful for dynamic payloads or pass-through metadata.
CodecSchema<Boundary, Runtime>
Schema that decodes boundary values into runtime values and encodes runtime
values back to the boundary representation. Use encode / safeEncode for the
reverse direction. See Codecs.
schema.transform<R>(R Function(Runtime) transformer): one-way transform (parse only;encodefails with a one-way error).schema.codec<R>({required R Function(Runtime) decode, required Runtime Function(R) encode, AckSchema<dynamic, R>? output}): bidirectional codec; the optionaloutputschema validates the runtime value.Ack.codec<Boundary, InputRuntime, Runtime>({required input, required decode, required encode, output}): builds a codec from aninputschema.
Built-in codecs:
Ack.date()→CodecSchema<String, DateTime>(ISOYYYY-MM-DD↔ local-midnightDateTime)Ack.datetime()→CodecSchema<String, DateTime>(ISO 8601 ↔ UTCDateTime; leap-second strings are rejected because Dart cannot represent them)Ack.uri()→CodecSchema<String, Uri>(absolute URI string ↔Uri)Ack.duration()→CodecSchema<int, Duration>(milliseconds ↔Duration)Ack.enumCodec(List<T> values)→CodecSchema<String, T>(enum.name↔ enum value)
Optional schemas
Every schema can be marked optional via the optional({bool value = true}) fluent API.
schema.optional()setsisOptionaltotruewithout wrapping the schema.schema.optional(value: false)clears the optional flag.- Optional affects object-field presence only; combine with
.nullable()to also allow explicitnull.
See the Schema types guide for detailed usage and examples.