Releases: jquense/yup
v1 Because I finally got around to it
v1.0.0-beta.7
Fixes published artifacts for the main
field
v1.0.0-beta.5 - partial fixes and cast migration path
Beta 5 fixes partial
and deepPartial
making it work correctly with lazy
schema. Specifically the optionality is added after lazy is evaluated but before any other when
conditions are added. This makes it consistent with other conditional schema, where runtime conditions always supersede previous schema configuration. This allows for optional overrides if necessary.
const person = object({
name: string().required(),
age: number().required(),
legalGuardian: string().when('age', {
is: (age) => age != null && age < 18,
then: (schema) => schema.required(),
}),
});
const optionalPerson = person.partial()
person.cast({name: 'James', age: 6 }) // => TypeError legalGuardian required
// age is still required b/c it's applied after the `partial`
optionalPerson.cast({name: 'James', age: 6 }) // => TypeError legalGuardian required
This works slightly differently for lazy
which have no schema to "start" with:
const config = object({
nameOrIdNumber: lazy((value) => {
if (typeof value === 'number') return number().required()
return string().required()
}),
});
const opti = config.partial()
config.cast({}) // => TypeError nameOrIdNumber is required
config.partial().cast({}) // => {}
Cast optionality migration path
A larger breaking change in v1 is the assertion of optionality during cast
, making previous patterns like string().nullable().required()
no longer possible. Generally this pattern is used when deserialized data is not valid to start, but will become valid through user input such as with an HTML form. v1 no longer allows this, but in order to make migration easier we've added an option to cast
that mimics the previous behavior (not exactly but closely).
const name = string().required()
name.cast(null, { assert: 'ignore-optionality'}) // => null
We recommend updating your schema to new patterns where possible but this allows for incremental upgrades
What's Changed
- chore(deps): update all non-major dependencies by @renovate in #1630
- chore(deps): update all non-major dependencies by @renovate in #1652
- fix(docs): correct typo "coarce" to "coerce" by @eunicode in #1654
- chore(deps): update all non-major dependencies by @renovate in #1656
- chore(deps): update all non-major dependencies by @renovate in #1665
- Capitalize two words in README by @Glitchy-Tozier in #1676
- Fix typo by @karlhorky in #1672
- Show example of function message by @karlhorky in #1674
- chore(deps): update all non-major dependencies by @renovate in #1678
- Fix typo: coarce -> coerce by @karlhorky in #1677
- chore(deps): update all non-major dependencies by @renovate in #1685
- chore(deps): update all non-major dependencies by @renovate in #1692
- chore(deps): update all non-major dependencies by @renovate in #1697
- chore(deps): update all non-major dependencies by @renovate in #1699
- chore(deps): update all non-major dependencies by @renovate in #1709
- chore(deps): update all non-major dependencies by @renovate in #1714
- Fix Typo : delete duplicate word "passed" by @ANTARES-KOR in #1696
- chore(deps): update all non-major dependencies by @renovate in #1722
- chore(deps): update all non-major dependencies by @renovate in #1727
- chore(deps): update all non-major dependencies by @renovate in #1731
- chore(deps): update all non-major dependencies by @renovate in #1737
- chore(deps): update all non-major dependencies by @renovate in #1744
- small typo fix by @somodis in #1745
- feat: better Lazy types and deepPartial fixes by @jquense in #1748
- feat: add cast nullability migration path. by @jquense in #1749
New Contributors
- @eunicode made their first contribution in #1654
- @Glitchy-Tozier made their first contribution in #1676
- @karlhorky made their first contribution in #1672
- @ANTARES-KOR made their first contribution in #1696
- @somodis made their first contribution in #1745
Full Changelog: v1.0.0-beta.4...v1.0.0-beta.5
v1.0.0-beta.4
What's Changed
- chore(deps): update all non-major dependencies by @renovate in #1611
- chore(deps): update all non-major dependencies by @renovate in #1614
- chore(deps): update all non-major dependencies by @renovate in #1618
- chore(deps): update all non-major dependencies by @renovate in #1622
Full Changelog: v1.0.0-beta.3...v1.0.0-beta.4
Fix object.partial(), `required` changes
This release fixes a bug with object().partial
where required()
schema we're still failing validation. Now they will no longer do that. To enable this fix we made a breaking change to the way that required
is implemented.
schema.required
no longer adds a test named 'required', this state can be determined via the schemaspec
ordescribe()
metadata- String schema now override
required
directly to add their length check (this test is calledrequired
for some ease of back compat)
Tuple types
Beta.2 adds core tuple
type support, see the docs for more: https://github.com/jquense/yup#tuple
v1.0.0-beta.1 Flat bundles
1.0.0-beta.1 (2022-01-03)
Features
- flat bundles and size reductions (753abdf)
- Refactors a number of internal APIs for Schema type implementers, making it easier to consistently create subclasses of
Schema
.
BREAKING CHANGES
- Yup now compiles to a flat bundle using rollup, this gives us faster to parse and smaller code, as well as clearer size insights (10.26kb gzipped!). The possible breaking change is around cherry picking imports, if you are cherry picking imports from yup
import string from 'yup/lib/string'
this will no longer work. This pattern has not been supported for a long time and could cause larger than necessary bundles.
v1.0.0-beta.0
1.0.0-beta.0 (2021-12-29)
- feat!: add json() method and remove default object/array coercion (94b73c4)
Features
- Make Array generic consistent with others (a82353f)
BREAKING CHANGES
- types only,
ArraySchema
initial generic is the array type not the type of the array element.array<T>()
is still the inner type. - object and array schema no longer parse JSON strings by default, nor do they return
null
for invalid casts.
object().json().cast('{}')
array().json().cast('[]')
to mimic the previous behavior
API pruning
Bug Fixes
- add originalValue to TestContext type (#1527) (fcc5ae7), closes /github.com/abnersajr/DefinitelyTyped/blob/a186d99d0c3a92424691a82130374a1b9145c7cd/types/yup/index.d.ts#L446
Features
- allow mixed schema to specify type check (3923039)
- concat() is shallow and does not merge (#1541) (a2f99d9)
- simplify base class hierarchy (#1543) (c184dcf)
- stricter
when
types and API (#1542) (da74254)
BREAKING CHANGES
mixed
schema are no longer treated as the base class for other schema types. It hasn't been for a while, but we've done some nasty prototype slinging to make it behave like it was. Now typescript types should be 1 to 1 with the actual classes yup exposes.
In general this should not affect anything unless you are extending (via addMethod
or otherwise) mixed
prototype.
import {
- mixed,
+ Schema,
} from 'yup';
- addMethod(mixed, 'method', impl)
+ addMethod(Schema, 'method', impl)
- concat works shallowly now. Previously concat functioned like a deep merge for object, which produced confusing behavior with incompatible concat'ed schema. Now concat for objects works similar to how it works for other types, the provided schema is applied on top of the existing schema, producing a new schema that is the same as calling each builder method in order
- The function version of
when()
has been changed to make it easier to type. values are always passed as an array and schema, and options always the second and third argument.this
is no longer set to the schema instance. and all functions must return a schema to be type safe
string()
- .when('other', function (other) => {
- if (other) return this.required()
+ .when('other', ([other], schema) => {
+ return other ? schema.required() : schema
})
Better, Faster, Stronger...generics
Changes the object generics to store the derived type instead of the object shape. This imposes a few limitations on type accuracy at the edges, but dramatically speeds up the type processing by tsc
on the command line and in editor. It also removes the need for the SchemaOf
helper which worked...poorly.
Instead the ObjectSchema
class accepts a plain type as its first generic:
interface Folder {
id: ObjectId,
label: string,
files?: File[]
}
- const folder: SchemaOf<Folder, ObjectId | File> = object({
- id: mixed<ObjectId>().defined(),
- label: string().defined(),
- files: array(mixed<File>().defined())
- })
+ const folder: ObjectSchema<Folder> = object({
+ id: mixed<ObjectId>().defined(),
+ label: string().defined(),
+ files: array(mixed<File>().defined())
+ })
It's a small diff, but big improvement in type accuracy and usability, especially with custom schema for class instances.
Note that the generics on the
object()
factory method are still the "object shape, meaningobject<Folder>()
won't work as expected. This is a compromise between the two strategies for handling generics and allows for an accurate type onobject().getDefault()
A number of the improvements here are made possible by simplifications to yup's API and logic, this introduces a few breaking changes though most are small and easily migrated from.
Nullability and presence
This is the largest, and likely most disruptive change. Prior yup allowed for patterns like:
const nullableRequiredString = string().nullable().required()
nullableRequiredString.cast(null) // -> null
nullableRequiredString.validate(null) // ValidationError("this is required and cannot be null")
This may seem unintuitive behavior (and it is) but allowed for a common client side validation case, where we want to use a single schema to parse server data, as well as validate user input. In other words, a server might return invalid "default" values that should still fail when trying to submit.
Now, nullable()
, defined
and required
are all mutually dependent methods. Meaning string().nullable().defined().required()
produces a schema where the value must be a string, and not null
or undefined
. The effect of this is that the type of a cast()
is now accurate and the same as the type returned from validate
.