Skip to content

Commit

Permalink
Fix error for nested object properties with multiiple types
Browse files Browse the repository at this point in the history
  • Loading branch information
ritchieanesco committed Feb 25, 2022
1 parent 38641e2 commit b000fbf
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 12 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "json-schema-yup-transformer",
"author": "Ritchie Anesco <info@ritchieanesco.com>",
"version": "1.6.3",
"version": "1.6.4",
"description": "Transforms a draft 7 specification JSON Schema to a Yup Schema",
"license": "MIT",
"main": "dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion src/yup/builder/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export const buildProperties = (
}
return { ...all, ...buildCondition(schema) };
}, [])
: [];
: [];
const newSchema = createValidationSchema([key, value], jsonSchema);
schema = {
...schema,
Expand Down
28 changes: 18 additions & 10 deletions src/yup/schemas/object/object.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,24 @@ const createObjectSchema = (
const defaultMessage = getErrorMessage(description, DataTypes.OBJECT)
|| capitalize(`${label} is not of type object`);

let shape = value.properties
&& buildProperties(value.properties, jsonSchema);

(value.required ?? []).forEach(requiredField => {
if (shape !== undefined) {
shape[requiredField] = createRequiredSchema(shape[requiredField], value, [requiredField, value])
}
});

let Schema = Yup.object(shape).typeError(defaultMessage);
// Seperate compositional schemas from standard schemas.
// Standard schemas return Object schemas, compositional schemas return mixed or lazy schemas.
// Lazy schemas can not be concatenated which will throw an error when traversing a nested object.
const schm = JSON.stringify(jsonSchema.properties)
const isComposition = schm.indexOf("anyOf") > -1 || schm.indexOf("oneOf") > -1

let Schema: Yup.ObjectSchema
if (isComposition) {
let shape = value.properties && buildProperties(value.properties, jsonSchema);
(value.required ?? []).forEach(requiredField => {
if (shape !== undefined) {
shape[requiredField] = createRequiredSchema(shape[requiredField], value, [requiredField, value])
}
});
Schema = Yup.object(shape).typeError(defaultMessage);
} else {
Schema = Yup.object().typeError(defaultMessage);
}

/** Set required if ID is in required schema */
Schema = createRequiredSchema(Schema, jsonSchema, [key, value]);
Expand Down
39 changes: 39 additions & 0 deletions test/yup/string.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -408,4 +408,43 @@ describe("convertToYup() string", () => {
}
expect(errorMessage).toBe(`${fieldTitle} is required`);
});


it("should validate multiple types in a nested object", () => {
const schema: JSONSchema7Extended = {
type: "object",
$schema: "http://json-schema.org/draft-07/schema#",
$id: "test",
title: "Test",
properties: {
address: {
type: "object",
properties: {
name: {
type: ["string", "null"]
}
}
}
}
};
const yupschema = convertToYup(schema) as Yup.ObjectSchema;

expect(() => {
yupschema.isValidSync({
address: {
name: ""
}
});
}).toBeTruthy();

expect(() => {
yupschema.isValidSync({
address: {
name: null
}
});
}).toBeTruthy();

});

});

0 comments on commit b000fbf

Please sign in to comment.