Changelog

View Source

All notable changes to this project will be documented in this file.

0.10.7 - 2025-11-16

Added

  • Recipes guide with common use cases and examples of Zoi usage.

0.10.6 - 2025-11-13

Added

  • Zoi.one_of/2 type to accept a value that matches exactly one of the provided literal values.

0.10.5 - 2025-11-13

Changed

  • Zoi.enum/2 typespec for binary now returns binary() instead of literals.

0.10.4 - 2025-11-10

Changed

0.10.3 - 2025-11-10

Added

  • wrap Zoi.Type.t() into Zoi.schema() type
  • Group guides on hexdocs

0.10.2 - 2025-11-10

Added

  • Zoi.Schema.traverse/2 for recursively walking and transforming schema structures. This function applies a transformation to all nested fields while leaving the root schema unchanged, making it easy to apply operations like coercion, nullish, or defaults across an entire schema tree.
  • Zoi.coerce/1 helper function to enable type coercion on schemas that support it.

Changed

  • Zoi.transform/2 and Zoi.refine/2 are now chained in the order they were added, allowing more flexible validation and transformation flows.

0.10.1 - 2025-11-09

Added

0.10.0 - 2025-11-09

Added

  • Zoi.Form module with prepare/1 and parse/2 functions for seamless Phoenix form integration.
  • Phoenix.HTML.FormData protocol implementation for Zoi.Context, enabling Phoenix form rendering without losing the original params.
  • Partial parsing data is now preserved inside %Zoi.Context{} (and surfaced through forms) even when validation fails, allowing Phoenix forms to keep previously valid entries.
  • Keyword schemas defined with another schema as the value now keep the successfully parsed entries even if a sibling entry fails validation.
  • Zoi.Form.prepare/1 now forces coercion on every nested field so Phoenix form strings are cast into their target types automatically.
  • Zoi.Form.parse/2 automatically normalizes LiveView's map-based array format (with numeric string keys) into regular lists in ctx.input, eliminating the need for manual conversion when manipulating array fields dynamically.
  • Architecture diagram in main module documentation (Zoi) showing the parsing flow and validation pipeline with Mermaid visualization.

Changed

  • Achieved 100% test coverage across the entire codebase (previously 99.8%).

0.9.1 - 2025-11-06

Added

0.9.0 - 2025-11-06

Added

Changed

  • Zoi.type_spec/1 for object with string keys now returns generic map() type spec due to how Elixir handles this type internally.

0.9.0-rc.1 - 2025-11-04

Added

  • Zoi.object/2 and Zoi.keyword/2 now accept :empty_values option to define which values are considered empty when parsing objects and keyword lists. By default, this option is set to [], meaning no values are considered empty. You can customize this option to include values like nil, empty strings (""), or any other value you want to treat as empty and it will return a :required error when those values are encountered for required fields.

0.9.0-rc.0 - 2025-11-04

Changed

  • All errors have been reworked to include more context on the error code and issue. Now errors will have the following structure (example):
%Zoi.Error{
  code: :invalid_type,
  issue: {"invalid type: expected string", [expected: :string]},
  message: "invalid type: expected string",
  path: [:user, :name]
}

And it's also possible to have errors with dynamic messages:

%Zoi.Error{
  code: :invalid_literal,
  message: "invalid literal: expected true",
  issue: {"invalid literal: expected %{expected}", [expected: true]},
  path: []
}

This will give more flexibility when handling errors programmatically, and better support with tools such as Gettext for localization.

0.8.4 - 2025-11-01

Changed

0.8.3 - 2025-10-31

Added

  • All types now implements the Inspect protocol. This should improve the ergonomics when working with Zoi types in IEx or when inspecting/debugging it's types.

0.8.2 - 2025-10-30

Added

Changed

  • Zoi.keyword/2 now can accept a schema in the first argument to validate the values of the keyword list
  • Zoi.keyword/2 type_spec now reflects correctly the keyword list definition

0.8.1 - 2025-10-27

Changed

  • Update readme with new metadata examples and reference to main api

0.8.0 - 2025-10-26

Added

  • Zoi.nullish/2 type to accept nil or a value of a specific type
  • @spec for all public functions
  • @typedoc for all public types
  • Zoi.description/1 option to add description metadata to types for documentation purposes
  • Zoi.example/1 option to add example metadata to types for documentation purposes

Changed

  • Zoi.to_json_schema/1 now reads description, example opts from types to include them in the generated JSON Schema

0.7.4 - 2025-10-25

Changed

  • Zoi.regex/3 fix regex compilation, now the regex.opts are properly handled

0.7.3 - 2025-10-20

Added

  • Zoi.email/1 now accepts pattern option to customize the email regex

Changed

  • Zoi.enum/2 now accepts coerce option to coerce values to the key or to the value

0.7.2 - 2025-10-13

Added

  • Fixed example in guides/using_zoi_to_generate_openapi_specs.md

0.7.1 - 2025-10-12

Added

  • Zoi.to_json_schema/1 support for metadata (e.g., example, description)
  • guides/quickstart_guide.md added to the documentation

0.7.0 - 2025-10-10

Added

Changed

  • Zoi.array/2 fixed path in errors when parsing arrays
  • Zoi.regex/2 fixed regex compile errors when used in module attributes

0.6.6 - 2025-10-08

Added

  • Zoi.metadata/1 - option to add metadata to types for documentation purposes

Changed

0.6.5 - 2025-10-07

Added

  • Zoi.example/1 option to add example values to types for documentation and testing purposes

0.6.4 - 2025-09-30

Added

  • Zoi.downcase/1 refinement to validate if a string is in lowercase
  • Zoi.upcase/1 refinement to validate if a string is in uppercase
  • Zoi.hex/1 refinement to validate if a string is a valid hexadecimal

0.6.3 - 2025-09-27

Added

  • keys in Zoi.object/2 data structure
  • Zoi.struct/2 type to parse structs and maps into structs
  • Zoi.Struct module with helper functions to work with structs. This module offers two main functions:
    • Zoi.Struct.enforce_keys/1: List of keys that must be present in the struct
    • Zoi.Struct.struct_keys/1: List of keys and their default values to be used with defstruct

0.6.2 - 2025-09-26

Added

Changed

  • Refactor all errors to be generated on type creation instead of parsing time

0.6.1 - 2025-09-08

Added

0.6.0 - 2025-09-07

Added

  • Zoi.required/2 type to enforce presence of a value in keyword and object types

Changed

  • Zoi.object/2 now uses mfa to call inner transform function
  • Zoi.keyword/2 have all fields set as optional by default, use Zoi.required/2 to enforce presence of a value

0.5.7 - 2025-09-06

Changed

0.5.6 - 2025-09-05

Added

  • Zoi.parse!/3 function that raises an error if parsing fails
  • Zoi.type_spec/2 function that returns the Elixir type spec for a given Zoi schema, implemented for all types

0.5.5 - 2025-09-03

Added

Changed

0.5.4 - 2025-08-29

Added

  • Guide for converting keys from maps
  • Guide for generating schema from JSON structure

0.5.3 - 2025-08-29

Changed

  • Fix transform and refinement types

0.5.2 - 2025-08-28

Added

Changed

  • Zoi.map/3 now parses key and value types correctly
  • Fix encapsulated types ignoring refinements and transforms when parsing

0.5.1 - 2025-08-17

Changed

0.5.0 - 2025-08-17

Added

Changed

0.4.0 - 2025-08-14

Added

  • Zoi.Context module to provide context when parsing data

Changed

  • Zoi.object/2 will not automatically parse objects with inputs that differ from the string/atom keys map format. For example:
schema = Zoi.object(%{
  name: Zoi.string(),
  age: Zoi.integer()
})
Zoi.object(schema, %{"name" => "John", "age" => 30})
{:error, _errors}

To make this API work, you can pass coerce: true option to Zoi.object/2. This will make the object parser to check from the Map input if the keys are strings or atoms and fetch it's values automatically.

schema = Zoi.object(%{
  name: Zoi.string(),
  age: Zoi.integer()
})
Zoi.object(schema, %{"name" => "John", "age" => 30}, coerce: true)
{:ok, %{name: "John", age: 30}}

0.3.4 - 2025-08-09

Added

0.3.3 - 2025-08-09

Added

0.3.2 - 2025-08-09

Added

0.3.1 - 2025-08-08

Added

0.3.0 - 2025-08-07

Added

Changed

0.2.3 - 2025-08-06

Added

0.2.2 - 2025-08-06

Added

Changed

  • Improved error messages for all validations and types
  • Zoi.treefy_errors/1 now returns a more human-readable structure
  • Zoi.optional/2 cannot accept nil as a value anymore. Use Zoi.nullable/2 instead.
  • Zoi.optional/2 inside Zoi.object/2 now handles optional fields correctly

0.2.1 - 2025-08-06

Added

  • Custom error messages for primitive types

Changed

  • Zoi.number/2 now returns proper error message

0.2.0 - 2025-08-05

Added

Changed

  • errors are now returned as a list of %Zoi.Error{} structs