Skip to content

Commit

Permalink
fix: use spec to find required state closes #4598
Browse files Browse the repository at this point in the history
  • Loading branch information
logaretm committed Dec 14, 2023
1 parent 8f6523a commit 301d487
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 27 deletions.
5 changes: 5 additions & 0 deletions .changeset/angry-steaks-itch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@vee-validate/yup": patch
---

fix: use spec to find required state closes #4598
37 changes: 10 additions & 27 deletions packages/yup/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
import {
AnyObjectSchema,
ArraySchema,
InferType,
Schema,
SchemaFieldDescription,
ValidateOptions,
ValidationError,
} from 'yup';
import { AnyObjectSchema, ArraySchema, InferType, Schema, ValidateOptions, ValidationError } from 'yup';
import {
TypedSchema,
TypedSchemaError,
Expand Down Expand Up @@ -76,49 +68,40 @@ export function toTypedSchema<TSchema extends Schema, TOutput = InferType<TSchem
},
describe(path) {
if (!path) {
return getDescriptionFromYupDescription(yupSchema.describe());
return getDescriptionFromYupSpec(yupSchema.spec);
}

const description = getDescriptionForPath(path, yupSchema);
const description = getSpecForPath(path, yupSchema);
if (!description) {
return {
required: false,
exists: false,
};
}

return getDescriptionFromYupDescription(description);
return getDescriptionFromYupSpec(description);
},
};

return schema;
}

function getDescriptionFromYupDescription(desc: SchemaFieldDescription): TypedSchemaPathDescription {
if ('tests' in desc) {
const required = desc?.tests?.some(t => t.name === 'required') || false;

return {
required,
exists: true,
};
}

function getDescriptionFromYupSpec(spec: AnyObjectSchema['spec']): TypedSchemaPathDescription {
return {
required: false,
exists: false,
required: !spec.optional,
exists: true,
};
}

function getDescriptionForPath(path: string, schema: Schema): SchemaFieldDescription | null {
function getSpecForPath(path: string, schema: Schema): AnyObjectSchema['spec'] | null {
if (!isObjectSchema(schema)) {
return null;
}

if (isNotNestedPath(path)) {
const field = schema.fields[cleanupNonNestedPath(path)];

return field?.describe() || null;
return (field as AnyObjectSchema)?.spec || null;
}

const paths = (path || '').split(/\.|\[(\d+)\]/).filter(Boolean);
Expand All @@ -133,7 +116,7 @@ function getDescriptionForPath(path: string, schema: Schema): SchemaFieldDescrip
}

if (i === paths.length - 1) {
return currentSchema.describe();
return currentSchema.spec;
}
}

Expand Down
4 changes: 4 additions & 0 deletions packages/yup/tests/yup.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ test('reports required state on fields', async () => {
yup.object({
'not.nested.req': yup.string().required(),
name: yup.string(),
num: yup.number().required(),
email: yup.string().required(),
nested: yup.object({
arr: yup.array().of(yup.object({ req: yup.string().required(), nreq: yup.string() })),
Expand All @@ -347,6 +348,7 @@ test('reports required state on fields', async () => {
});

const { meta: name } = useField('name');
const { meta: num } = useField('num');
const { meta: email } = useField('email');
const { meta: req } = useField('nested.obj.req');
const { meta: nreq } = useField('nested.obj.nreq');
Expand All @@ -356,6 +358,7 @@ test('reports required state on fields', async () => {

metaSpy({
name: name.required,
num: num.required,
email: email.required,
objReq: req.required,
objNreq: nreq.required,
Expand All @@ -376,6 +379,7 @@ test('reports required state on fields', async () => {
expect.objectContaining({
name: false,
email: true,
num: true,
objReq: true,
objNreq: false,
arrReq: true,
Expand Down

0 comments on commit 301d487

Please sign in to comment.