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 requiredThis 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'}) // => nullWe 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.requiredno longer adds a test named 'required', this state can be determined via the schemaspecordescribe()metadata- String schema now override
requireddirectly to add their length check (this test is calledrequiredfor 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,
ArraySchemainitial 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
nullfor 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
whentypes and API (#1542) (da74254)
BREAKING CHANGES
mixedschema 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.thisis 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.