- Add
checkAsync
,conformAsync
,isValidAsync
andvalidateAsync
main API functions. Always return a promise, instead of a hybrid for sync and async spec validation.
- Attach failed path to result in async collection validation;
- Fix npm audit errors;
- Properly log runtime predicate failure to console to facilitate debugging;
- Consider only known collections (array, object, map) when checking if a value is a collection. This ensures that other complex values such as dates are note treated as collections, but as values;
- Consider both
null
andundefined
when checking for required keys; - Remove unused and unexported
setPred
function;
- Consider non collection/pred specs (ie
1, null, "foo"
) as always true predicates. This facilitates combination of spec and required keys as a selection object, since requirements are only true/false values;
- Keep optionality attribute when combining collection specs;
- Fix selection with spread;
- Exclude
undefined
props in selection;
- Consider spread in requirements;
- Use external documentation site instead of only the README;
- Compare type with strict equality
===
inisColl
;
- Subvalues that are
undefined
are not validated. Therequired
option should be used to ensure values are present. Otherwise, each spec had to be defined takingundefined
into account.
- Set arity on combined pred function based on argument pred functions. Allows checking arity before creating/passing
getFrom
function. - Expose
validatePred
andgetPath
utility function.
- Pass
options
tokey
pred. - Pass
getFrom
instead ofgoTo
to_validate
inor
. - Always return promise on valid result.
- Ensure value is always attached to
validate
result. - Properly reify arguments to
or
to avoid unpredictable bugs.
Still some breaking changes in this release, but it is stabilizing. The context
that was provided to predicate spec functions was very brittle. It was nearly impossible to define a deeply nested context and most predicate functions had to know way more than they should in order to perform validation. Now, a getFrom
helper function is passed as the second argument to predicate spec functions. It accepts a relative string path (similar to those used with cd
command in CLIs) that points to another location in the value being validated.
This should favor a particuliar way of defining specs, where the parent that should know about a particular constraint should be the one defining the spec for a nested value. Here's an example :
Let's say we have a list of choices. Taken individually, each choice could be any primitive value (string, number, boolean, etc.). However, the choices list itself is aware that there should be no duplicate choices; each choice doesn't know about this constraint. Although it would be possible to add this validation as a predicate function on the choices list itself, it might be better to define it on each individual choice for better error handling in forms, etc. This validation would be defined at the choices level however.
Moreover, the list of choices itself could be used in a parent value that provides context for what kind of choices are allowed. This restriction on type would then be defined at the parent level.
/* Not concerned with unicity or specific type. Highly reusable. */
const primitive = s.or(number, string, boolean);
/* Not concerned about specific type, but ensures values are unique. Highly reusable. */
const noDuplicatesList = s.spread(
s.and(primitive, function uniqueValue(x, getFrom) {
const list = getFrom("..");
return list.filter((item) => item === x).length <= 1 || "must be unique";
})
);
/* Don't have to specify again that choices must be unique.
* Add a constraint on list values based on another prop. */
const spec = {
type: oneOf(["string", "number"]),
choices: s.and(
noDuplicatesList,
s.spread(function choiceByType(choice, getFrom) {
const type = getFrom("../../type");
return typeof choice === type || `must be of type '${type}'`;
})
),
};
/* Each choice will be a unique string value. */
const value = {
type: "string",
choices: ["foo", "bar"],
};
- Replace
context
with more flexiblegetFrom
helper in predicate spec functions. - Remove
pair
in favor ofkey
to spec spread objects. - Split
validate
and_validate
to prevent former from being called with internal only params.
- Add
key
spec creator on main API to replacepair
. - Allow customizing "is invalid" message
or
didn't validate as expected
- Allow customization of built-in reason messages.
- Append validation result to
conform
error.details
.
createSelection
fails withCannot create property 'arrayMerge' of '1'
- Ensure a promise is always returned in the validation result
- Treat all types of functions (regular, generator, async, ...) as predicate specs
check
should always return stringified reason, even when no key
- Do not compress output so that code is readable and can act as its own source map.
- Export only UMD and "modern" (
<script type="module">
) bundles, instead of UMD + CJS + Modules + Modern. Should still be importable from any project, but entry points may have changed and bundle size is considerably reduced.
- Remove source maps; they didn't point to any useful code and removing them makes for a much lighter package.
This is a complete refactor of the internals. While the API did not change much from prior version, it did change a little. But since the library is most probably not used by anyone yet, and since I'm just getting used to open source development, I did not keep track of the API changes. For the next releases, changes will be better documented.
- Complete refactor from gathered knowledge
- Standardize specs as Map objects internally
- Reduce usage of Symbol constants
- Use "..." key as spread even on arrays
- Better use
Promise.all
to resolve validation races
- Use Microbundle instead of Rollup
- Remove Ramda dependency
- Expose helper and utility functions for outsude consumption (
getPred
,getSpread
,isOpt
,typeOf
,get
, ...)