- Elixir is bumped to 1.15
- OTP is bumped to 26.0
do_authorize
's typespec was fixedex_doc
version was bumped
- not properly functioning check (since elixir 1.11.0) for struct parameters has been removed
- a bug in
coerce_with/2
was fixed: a parameter got coerced (asnil
) even if it is not required run!
raises anExop.Operation.ErrorResult
error when an operation returns an error tuple
Code.ensure_compiled/1
instead of deprecatedCode.ensure_compiled?/1
:struct
check's bug fixed (when a value to be checked is not a struct itself)
breaking changes in this version!
- a validation
type: :struct
that had been deprecated since ver. 1.2.2 was finally removed - the
func
check's callback arguments now aligned withcoerce_with
callback, they are: a parameter's name/value tuple (the first), all parameters map given to an operation (the second), the output of the validation callback fuction has been updated as well (check README for details) Exop.Chain
'soperation
(step
) now can be conditional withif: _your_condition_func/1
option provided (see README for the details)Exop.Chain
'soperation
now can coerce incoming parameters withcoerce_with: your_coerce_func/1
option before any further checks/invocations
- basic validation message extension with "got:" (credits to https://github.com/sgilson) makes error-tuple messages more descriptive
- new
:subset_of
check allows you to check whether a given list is a subset of defined check-list
- a bug in
coerce_with/2
refactored behavior was fixed
- the issue with
coerce_with/2
within aninner
check has been fixed (coercion simply didn't work in inner) - parameters
:default
option now accepts 1-arity function as well as a certain value (see README)
- got rid some dialyzer warnings
- specs for macros were added
- Exop.Policy module has been removed because simplified policy check is here since v1.1.1
- if Exop.Policy action returns something different from either
true
orfalse
, this output is treated as authorization error message (reason) - behaviour of unknown struct checks has been changed. Now it generates ArgumentError exception on compile time if struct parameter is not existing struct.
allow_nil
check behavior bug has been fixed (default value and validations skipping)
breaking changes in this version!
- Exop supports elixir >= 1.6.0
- behaviour of unknown type checks has been changed. Now it generates ArgumentError exception on compile time if type check is not supported.
YourOperation.run/1
now accepts structs as well as keywords and maps- implicit inner: now you can omit
type
andinner
checks keywords in order to check inner of your parameter - ex_doc 0.20 (better docs)
:from
parameter option to be able pass one name of a parameter and work with it within an operation under another name- new checks for
:length
:gte
,gt
,lte
,lt
:length
doesnt work with numbers anymore:length
and:numericality
checks return an error for unsupported types (previously unsupported type passed the check):coerce_with
now accepts only a 2-arity function with a coerced param tuple and a map of all received params (see README for more info)defined_params/1
function has been removed, nowprocess/1
function takes only parameters defined in a operation's contract. You still can pass any parameters inrun/1
orrun!/1
but Exop will proceed only with parameters declared in the contract
- allow to pass function of arity one to
func
validation
use Exop.Chain
now accepts:name_in_error
option: when it is set totrue
a failed operation in a chain returns the operation's module name as the first elements of output tuple{YourOperation, {:error, _}}
- new
type: :uuid
check which supports both UUID1 and UUID4 - new aliases for
:numericality
check (to make your code slim)::eq, :gt, :gte, :lt, :lte
:inner
check now accepts opts as both map and keyword (earlier only map has been allowed)- a few macros (like
parameter
,operation
etc.)locals_without_parens
formatter rule has been exported. Placeimport_deps: [:exop]
into your project's.formatter.exs
file in order to use it. step/2
has been added as an alias forExop.Chain
'soperation/2
macro
Exop.Chain
bug was fixed (the last operation in a chain returned a result not wrapped into ok-tuple)Exop.Chain
allows now to pass additional parameters to any operation in a chain
list_item
check allows you to omittype
check definition, in this caselist_item
checks for the list type under the hoodstruct
type check is deprecatedrequired: false
+allow_nil: false
behavior has been fixedtype: :struct
check has been revised
- you get a warning if there is no any
parameter
definition inner
check allows you to omittype
check definition, in this caseinner
checks for an appropriate type (either Map or Keyword) under the hoodinner
returns an item's error as"a[:c]" => ["is required"]
:keyword
option fortype
check has been added- it is allowed now to pass just a module (atom like
MyStruct
) tostruct
check, not only%MyStruct{}
- breaking:
required
hastrue
value by default, so paramter is required by default if only you haven't specifyrequired: false
(a bit more info in the README) list_item
now accept both: Map and Keyword as items checkslist_item
returns an item's error as"list_param[index]" => [error_messages]
:module
option fortype
check (if you want to be more explicit)- Checks list as links in the README
- new
allow_nil
attribute for a parameter which allows you to passnil
as a parameter's value (and omit all validation checks invokation) - a few (
min
,max
,is
) aliases were added tonumericality
check coerce_with
now respects error tuple which might be returned from coerce function (that error tuple is returned as an operation's result immediately)
- a bug with
type
check was fixed: previously this check passed if a parameter's value isnil
, nownil
passes the check only if:atom
type is specified
- now it is possible to return an :error-tuple of any length from an operation. Previously only a tuple of two elements was treated as error result, any other results treated as success and were wrapped into :ok-tuple
- now it is possible to provide 3-arity function to the
func
check: in previous verisons this check expected only a function with arity == 2 to invoke for checking (1. params passed to an operation, 2. param to check value), starting from this version you can provide a function with arity == 3 (in this case Exop will invoke your function with: 1. params passed to an operation, 2. param to check name, 3. param to check value) coerce_with
can take a function of arity == 2 (not only with arity == 1), coercion function/2 will be invoked with args: 1. parameter name 2. parameter value (coercion function with arity == 1 still takes just a parameter value)- some checks aliases were added
- some dialyzer warnings were fixed
in
¬_in
checks error message fix (for example, atoms list displays as atoms list :) )- you can now name your parameters with strings, not only atoms and even combine string- and atom-named parameters
- a policy action argument now can be a value of any type (previously only map was allowed)
- there is no need to use
Exop.Policy
in a policy module anymore (you still can use it and there is no need to rewrite exsisting policies): simply define a module with policy checks (actions) functions which are expected to take a single argument (any type) and return eithertrue
orfalse
-
required
check was revised. Nownil
is treated as a value. It means that before this versionrequired
check returned an error if a parameter had anil
value. From this version this check fails only if parameter wasn't provided to an operation.To simulate previous behaviour (if you need to keep backward compatibility with parameters passed into an operation) you can do:
parameter :a, required: true, func: &__MODULE__.old_required/2 def old_required(_params, nil), do: {:error, "is required"} def old_required(_params, param), do: true
-
ValidationError
now has an operation name in its message (better for debugging and logging)
A bunch of changes were made in this release with some brand new functionality, so I decided to bump version to 1.0.0, finally. Exop has been working since 2016 on various projects, in production. I think it means something and I can say it is production-ready :)
Exop.Chain
helps you to organize a number of operations into an invocation chainExop.Fallback
handles your operations fails (error-tuple results)Exop.Policy
was simplified- minor codebase updates
- docs were reviewed
- An operation's
process/1
now takes a map of parameters (contract) instead of a keywords list (This will help you to pattern-match them) - Credo was wiped out (with annoying warning on
@lint
) - Code was formatted with elixir formatter
- New
list_item
parameter check.
- Fixed
required
check when a struct was checked withinner
.
- Fixed
required
check whenfalse
was treated as the absence of a parameter.
-
Does not validate nil parameters if they are not required. For example:
defmodule Operation do use Exop.Operation parameter :value, type: %MyStruct{} # ... end # Old versions Operation.run([]) # {:error, {:validation, %{value: ["is not expected struct"]}} # This version Operation.run([]) # {:ok, ...}
In previous versions such code returns validation error, because
nil
is not aMyStruct
struct (even if it is not required by default).In current version such behaviour is fixed and Exop will not run validations for nil parameters if they are not required.
-
equals
check: Checks whether a parameter's value exactly equals given value (with type equality).parameter :some_param, equals: 100.5
-
run/1
output: If yourprocess/1
function returns a tuple{:ok, _your_result_}
Exop will not wrap this output into former{:ok, _output_}
tuple.So, if
process/1
returns{:ok, :its_ok}
you'll get exactly that tuple, not{:ok, {:ok, :its_ok}}
.(
run!/1
acts in the same manner with respect of it's bang nature)
- Log improvements:
Logger provides operation's module name if a contract validation failed. Like:
14:21:05.944 [warn] Elixir.ExopOperationTest.Operation errors: param1: has wrong type param2: has wrong type
- Docs ExDocs (hex docs) were mostly provided. Will be useful for some IDEs/editors plugins usage (with docs helpers) and Dash users (like me).
func/2
check: Custom validation function now receives two arguments: the first is a contract of an operation (parameters with their values), the second - the actual parameter value to check. So, now you can validate a parameter depending on other parameters values.
-
func/1
check: You can provide your error message if custom validation function returns{:error, "Your validation message"}
. In other casesfalse
is treaded as validation fail with default message"isn't valid"
, everything else - validation success. -
run/1
output: If yourprocess/1
function returns a tuple{:error, _error_reason_}
Exop will not wrap this output into former{:ok, _output_}
tuple.So, if
process/1
returns{:error, :ugly_error}
you'll get exactly that tuple, not{:ok, {:error, :ugly_error}}
.(
run!/1
acts in the same manner with respect of it's bang nature (will return unwrapped value, an exception or your error tuple))