ritchieanesco / json-schema-yup-transform Goto Github PK
View Code? Open in Web Editor NEWTransform a JSON Schema to Yup Schema
License: MIT License
Transform a JSON Schema to Yup Schema
License: MIT License
I have a schema that is something like:
const schema = {
$schema: "http://json-schema.org/draft-07/schema#",
$id: "http://example.com/person.schema.json",
title: "Person",
description: "A person",
type: "object",
properties: {
firstName: {
description: "Name of the person",
title: "First Name",
type: "string"
},
},
required: ["firstName"]
};
The default error message is Firstname is a required field
. I'd prefer to use the title instead of the key. Yup supports setting a label, so with the schema above I'd expect to get something like:
Yup.object({
firstName: Yup.string()
.label("First Name")
.required()
});
resulting in the error message First Name is a required field
. Is this possible?
It is posible ?
if: {
properties: { consent: { properties : { value : { const: true } } }}
},
Thank ?
I had an issue where there was an anyOf block in which no type was given for a property because it was nullable: true. Is this a bug or is this library meant for older json-schema support?
Uncaught Error: Type key is missing
at Object.createValidationSchema [as default] (index.ts:112:1)
at index.ts:26:1
at Array.map (<anonymous>)
at Object.push../node_modules/json-schema-yup-transformer/dist/yup/schemas/composition/index.js.exports.createAnyOfSchema (index.ts:25:1)
at getValidationSchema (index.ts:43:1)
at Object.createValidationSchema [as default] (index.ts:110:1)
at Object.push../node_modules/json-schema-yup-transformer/dist/yup/builder/index.js.exports.buildProperties (index.ts:75:1)
at Object.push../node_modules/json-schema-yup-transformer/dist/yup/builder/index.js.exports.build [as default] (index.ts:285:1)
at convertToYup (index.ts:15:1)
at ContainerForm.js:21:1
at invokePassiveEffectCreate (react-dom.development.js:23487:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:3945:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:3994:1)
at invokeGuardedCallback (react-dom.development.js:4056:1)
at flushPassiveEffectsImpl (react-dom.development.js:23574:1)
at unstable_runWithPriority (scheduler.development.js:468:1)
at runWithPriority$1 (react-dom.development.js:11276:1)
at flushPassiveEffects (react-dom.development.js:23447:1)
at react-dom.development.js:23324:1
at workLoop (scheduler.development.js:417:1)
at flushWork (scheduler.development.js:390:1)
at MessagePort.performWorkUntilDeadline (scheduler.development.js:157:1)
See this for reference:
Note that there is no null type; instead, the [nullable](https://swagger.io/docs/specification/data-models/data-types/#null) attribute is used as a modifier of the base type.
https://swagger.io/docs/specification/data-models/data-types/
Given schema is an object type and is required, when object is empty then convertToYup should return an invalid response.
const schema: JSONSchema7 = {
type: "object",
$schema: "http://json-schema.org/draft-07/schema#",
$id: "test",
title: "Test",
properties: {
items: {
type: "object"
}
},
required: ["items"]
};
const yupschema = convertToYup(schema) as Yup.ObjectSchema;
let isValid = yupschema.isValidSync({});
expect(isValid).toBeFalsy();
// => True
Is the a way to have conditional validation based on multiple fields?
For example, having an if statement that needs two values to be true in order to execute?
This is a rough example below that doesn't seem to work.
{
$schema: 'http://json-schema.org/draft-07/schema#',
$id: 'http://example.com/example.json',
type: 'object',
title: 'Test',
properties: {
age: {
type: 'string',
},
height: {
type: 'string',
minLength: 1,
},
weight: {
type: 'string',
format: 'date',
},
},
if: {
properties: {
height: {
type: 'string',
const: '6',
},
weight: {
type: 'string',
const: '100',
}
then: {
properties: {
age: { type: 'string' }
},
required: ['age']
}
}
Hi.
As detailed in the yup documentation, it's possible to invoke an override of the message.
Is there a way to implement the internalization on your library ?
import { es } from 'yup-locales';
import { setLocale } from 'yup';
import convertToYup from "json-schema-yup-transformer";
setLocale(es)
/** some code */
const schemaToYup = convertToYup(mySchema);
But the error message are still in english, not in spain...
When the JSON schema has an if condition for a field which is type of array, the contains check does not transform properly to Yup schema
if: {
properties: {
key1: {
contains: { const: "other" },
},
},
},
Jest unit test proving the failure.
import Ajv from "ajv"; // @6.12.6
import convertToYup from "json-schema-yup-transformer"; // @1.6.12
const validateSchema = async (schema: string, data: any): Promise<boolean> => {
const jsonSchema = JSON.parse(schema);
const validate = new Ajv().compile(jsonSchema);
return validate(data);
}
const getIsJsonSchemaValid = (validation: string, data: Record<string, any>) => {
const jsonSchema = JSON.parse(validation);
const yupSchema = convertToYup(jsonSchema);
return yupSchema.isValidSync(data);
};
describe("validate schema transformation", () => {
describe("conditional schema - array", () => {
const schema = JSON.stringify({
type: "object",
required: ["key1"],
properties: {
["key1"]: {
type: "array",
items: { type: "string" },
},
["key2"]: { type: "string" },
},
if: {
properties: {
["key1"]: {
contains: { const: "other" },
},
},
},
then: {
properties: {
["key2"]: { type: "string", minLength: 2 },
},
required: ["key2"],
},
additionalProperties: true,
}
);
it("should pass with correct data", async () => {
const data = {
key1: ["qwe", "sss"],
key2: "s"
};
const jsonValid = await validateSchema(schema, data);
const yupValid = getIsJsonSchemaValid(schema, data);
expect(jsonValid).toBeTruthy();
expect(yupValid).toBeTruthy();
});
it("should pass with correct data 2", async () => {
const data = {
key1: ["ss", "other", "sss"],
key2: "sq"
};
const jsonValid = await validateSchema(schema, data);
const yupValid = getIsJsonSchemaValid(schema, data);
expect(jsonValid).toBeTruthy();
expect(yupValid).toBeTruthy();
});
it("should fail with bad data", async () => {
const data = {
key1: ["ss", "other", "sss"],
key2: "s"
};
const jsonValid = await validateSchema(schema, data);
const yupValid = getIsJsonSchemaValid(schema, data);
expect(jsonValid).toBeFalsy();
expect(yupValid).toBeFalsy(); // Fails here
});
});
});
Hi,
I need some help how to retrieve the Yup schema. Doesn't seems to exist in the returned object, I dynamically generate a form from JSON to be used in Formik.
{ "_deps": [], "_conditions": [], "_options": { "abortEarly": true, "recursive": true }, "_exclusive": {}, "_whitelist": { "list": {}, "refs": {} }, "_blacklist": { "list": {}, "refs": {} }, "tests": [], "transforms": [ null ], "type": "object", "_type": "object", "fields": { "name": { "_deps": [], "_conditions": [], "_options": { "abortEarly": true, "recursive": true }, "_exclusive": { "required": true }, "_whitelist": { "list": {}, "refs": {} }, "_blacklist": { "list": {}, "refs": {} }, "tests": [ null ], "transforms": [ null, null ], "type": "string", "_type": "string" }, "company_name": { "_deps": [], "_conditions": [], "_options": { "abortEarly": true, "recursive": true }, "_exclusive": { "required": true }, "_whitelist": { "list": {}, "refs": {} }, "_blacklist": { "list": {}, "refs": {} }, "tests": [ null ], "transforms": [ null, null ], "type": "string", "_type": "string" }, "email": { "_deps": [], "_conditions": [], "_options": { "abortEarly": true, "recursive": true }, "_exclusive": { "required": true, "email": false }, "_whitelist": { "list": {}, "refs": {} }, "_blacklist": { "list": {}, "refs": {} }, "tests": [ null, null ], "transforms": [ null, null, null, null ], "type": "string", "_type": "string" }, "mobile": { "_deps": [], "_conditions": [], "_options": { "abortEarly": true, "recursive": true }, "_exclusive": { "required": true }, "_whitelist": { "list": {}, "refs": {} }, "_blacklist": { "list": {}, "refs": {} }, "tests": [ null ], "transforms": [ null, null ], "type": "number", "_type": "number" }, "message": { "_deps": [], "_conditions": [], "_options": { "abortEarly": true, "recursive": true }, "_exclusive": { "required": true }, "_whitelist": { "list": {}, "refs": {} }, "_blacklist": { "list": {}, "refs": {} }, "tests": [ null ], "transforms": [ null, null ], "type": "string", "_type": "string" }, "test": { "_deps": [], "_conditions": [], "_options": { "abortEarly": true, "recursive": true }, "_exclusive": { "required": true }, "_whitelist": { "list": {}, "refs": {} }, "_blacklist": { "list": {}, "refs": {} }, "tests": [ null ], "transforms": [ null, null ], "type": "string", "_type": "string" }, "date": { "_deps": [], "_conditions": [], "_options": { "abortEarly": true, "recursive": true }, "_exclusive": { "required": true, "matches": false }, "_whitelist": { "list": {}, "refs": {} }, "_blacklist": { "list": {}, "refs": {} }, "tests": [ null, null ], "transforms": [ null, null, null, null ], "type": "string", "_type": "string" }, "number": { "_deps": [], "_conditions": [], "_options": { "abortEarly": true, "recursive": true }, "_exclusive": { "required": true }, "_whitelist": { "list": {}, "refs": {} }, "_blacklist": { "list": {}, "refs": {} }, "tests": [ null ], "transforms": [ null, null ], "type": "number", "_type": "number" } }, "_nodes": [ "message", "mobile", "email", "company_name", "name" ], "_excludedEdges": [] }
Would like the Yup schema like this:
{ name: yup.string().required(), age: yup.number().required().positive().integer(), email: yup.string().email(), website: yup.string().url(), }
After upgrading from 1.6.8
to 1.6.11
the following error happens in my project:
number.js:123 Uncaught (in promise) TypeError: required?.join is not a function
at createBaseNumberSchema (number.js:123:1)
at Object.createNumberSchema [as number] (number.js:41:1)
at getValidationSchema (index.js:56:1)
at Object.createValidationSchema [as default] (index.js:86:1)
at push.50253.exports.buildProperties (index.js:60:1)
at push.50253.exports.build (index.js:195:1)
at push.50253.exports.buildProperties (index.js:29:1)
at push.50253.exports.build [as default] (index.js:195:1)
at convertToYup (index.js:31:1)
I tried to map the bug to the source, with the following results:
export declare const createBaseNumberSchema: (yupSchema: Yup.NumberSchema, [key, value]: SchemaItem, required: JSONSchema["required"]) => Yup.NumberSchema;
JSONSchema["required"]
is supposed to extract the required
property from the given schema: this also conforms to the variable naming, and the fact that the required
variable is probably supposed to contain an array (because we are calling join()
);const createNumberSchema = ([key, value], required) => { ... }
: therefore required
ends up to be the original JSON schema, which is an object
, not an array
;const createNumberSchema = ([key, value], { required }) => { ... }
seem to fix the problem, but many similar errors appear (for example in createStringSchema()
);Can it be that something went wrong with the transpilation during the release process?
The first code block below is a sample of the kind of object I'm dealing with - there can be many objects nested at any of the 3 array "levels" reflected in this object (outerAnds, middleOrs, and innerAnds).
Notice that there are 2 objects nested in the array of innerAnds
, "Subscription" and "Video", and 2 innerAnds
are nested in the single middleOr
.
The contents of the arrays are arbitrary based on user interaction in the UI.
This example from @ritchieanesco got me close - I'm having success nesting with only one object in each of the arrays.
But I'm failing to figure out the proper shapes for schema
and config
for arbitrary nesting.
I'm hoping that I can build these objects dynamically as users interact with the UI - which would be easy enough if knew the shapes needed.
The second code block... well, scroll down below the first and I'll show you what is working - but it doesn't reflect multiple array elements at any level.
const sampleObject = {
outerAnds: [
{
middleOrs: [
{
innerAnds: [
{
slug: 'Subscription',
label: 'Subscription',
fields: {
isIsNot: 'Is',
subscription: '401978',
},
},
{
slug: 'Video',
label: 'Video',
fields: {
didDidNot: 'Did',
videoEvent: 'WATCH_25',
video: 'About Net-Results',
},
},
],
},
{
innerAnds: [
{
slug: 'VisitDuration',
label: 'Website Visit Duration',
fields: {
isIsNot: 'Is',
numberOptions: 'GreaterThan',
valNumber: '30',
timeUnits: 'Seconds',
},
},
],
},
],
},
],
};
Below are a schema
and config
that work (the correct validation errors show up in my form as desired) - but there is only one "element" at each of the 3 array "levels" in which this object can nest.
So it seems I'm almost there but need some syntax help :)
Thanks for trying!
type: 'object',
$schema: 'http://json-schema.org/draft-07/schema#',
$id: 'example',
title: 'Example',
properties: {
outerAnds: {
type: 'array',
items: {
type: 'object',
properties: {
middleOrs: {
type: 'array',
items: {
type: 'object',
properties: {
innerAnds: {
type: 'array',
items: {
type: 'object',
properties: {
fields: {
type: 'object',
properties: {
isIsNot: {
type: 'string',
},
subscription: {
type: 'string',
},
},
required: ['isIsNot', 'subscription'],
},
},
},
},
},
},
},
},
},
},
},
};
const config = {
errors: {
outerAnds: {
middleOrs: {
innerAnds: {
fields: {
isIsNot: {
required: 'Please make a selection',
},
subscription: {
required: 'Please choose a Subscription List',
string: 'Please choose a Subscription List',
},
},
},
},
},
},
};
Validator regex for date-time matches only 2018-11-13T20:20:39+00:00
.
It should validate (also/only) for ISO format as it is a standard format JSON uses for dates. You can test it in console:
JSON.stringify(new Date(Date.now()))
result
'"2021-12-12T18:34:11.227Z"'
Hi, First of all thank you for creating this library,
I have a question, I would like to know if the library have support for array.of() and if it has how would the json scheme be to have this output?
people: yup
.array()
.of(
yup.object().shape({
name: yup.string().required(),
phoneNumber: yup.string().required()
})
)
.required()
When importing json-schema-yup-transformer
as of version 1.6.8
:
import convertToYup from 'json-schema-yup-transformer';
// or with CJS: const convertToYup = require('json-schema-yup-transformer');
the following error happens:
/tmp/test/node_modules/json-schema-yup-transformer/dist/schema/utils.js:29
[_1.DataTypes.STRING]: isString_1.default,
^
TypeError: Cannot read properties of undefined (reading 'STRING')
at Object.<anonymous> (/tmp/test/node_modules/json-schema-yup-transformer/dist/schema/utils.js:29:19)
at Module._compile (node:internal/modules/cjs/loader:1103:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1157:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.<anonymous> (/tmp/test/node_modules/json-schema-yup-transformer/dist/schema/index.js:14:14)
at Module._compile (node:internal/modules/cjs/loader:1103:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1157:10)
Additional info:
1.6.4
works correctly;When adding this library to a nextjs application, compilation fails:
ModuleNotFoundError: Module not found: Error: Can't resolve 'stringify-object' in '.../webapp/node_modules/json-schema-yup-transformer/dist/yup/addMethods'
If this is a dependency it should be added as such
Great library and excellent docs!
I have a validation passes validation when using a plain json schema validator: https://www.jsonschemavalidator.net/s/XQqK0y9U
But I've set up a codesandbox with essentially the same schema but I get false when running isValid on my yupschema: https://codesandbox.io/s/reverent-sun-ckfc9
Perhaps theres something very simple I'm missing here. Would love any and all pointers.
Including my schema here for reference but we can also see it in either link above:
Schema
{
"$id": "http://example.com/example.json",
"$schema": "http://json-schema.org/draft-07/schema",
"default": {},
"title": "STEP EDITOR",
"description": "The Overview is used to name and describe a Step when viewed as part of a Path.",
"type": "object",
"examples": [
{
"title": "Step Title",
"summary": "Step Summary",
"description": "Step Description",
"objectives": [
"home",
"green"
],
"tags": [
{
"slug": "music-production",
"name": "Music Production",
"customOption": true
},
{
"slug": "games-production",
"name": "Games Production"
}
]
}
],
"required": [
"language"
],
"properties": {
"language": {
"$id": "#/properties/language",
"type": "string",
"title": "Choose Default Language",
"description": "Choose Default Language",
"default": "en-us",
"anyOf": [
{
"type": "string",
"title": "English",
"enum": [
"en-us"
]
},
{
"type": "string",
"title": "Japanese",
"enum": [
"ja"
]
}
],
"examples": [
"en-us"
]
},
"title": {
"$id": "#/properties/title",
"type": "string",
"title": "Step Title",
"description": "Enter Step Title",
"default": "",
"tooltip": "Step title has a 100 character limit. It displays in various locations as part of a Path it is added to.",
"examples": [
"Step Title"
],
"maxLength": 100
},
"summary": {
"$id": "#/properties/summary",
"type": "string",
"title": "Step Summary",
"description": "Enter Step Summary",
"default": "",
"tooltip": "Step Summary has a 300 character limit. It displays in various locations as part of a Path it is added to and provides a short and concise summary.",
"examples": [
"Step Summary"
],
"maxLength": 300
},
"description": {
"$id": "#/properties/description",
"type": "string",
"title": "Description",
"description": "Enter Step Description for Logged in Students (Optional)",
"default": "",
"tooltip": "Step description can be seen by instructors and curriculum creators. It is used to provide a more detailed description than the short summary.",
"examples": [
"Step Description"
],
"maxLength": 300
},
"objectives": {
"$id": "#/properties/objectives",
"default": [
""
],
"type": "array",
"title": "Objectives",
"description": "Enter Step Objectives for Logged in Students (Optional)",
"tooltip": "Step objectives can be seen by instructors and curriculum creators and is used to outline the goals.",
"additionalItems": true,
"minItems": 0,
"items": {
"$id": "#/properties/objectives/items",
"title": "Enter Step Objectives for Logged in Students (Optional)",
"type": "string"
}
},
"tags": {
"$id": "#/properties/tags",
"default": [],
"description": "Choose Tags",
"examples": [
[
{
"slug": "music-production",
"name": "Music Production",
"customOption": true
},
{
"slug": "games-production",
"name": "Games Production"
}
]
],
"title": "Choose Tags",
"minItems": 1,
"type": "array",
"additionalItems": true,
"items": {
"$id": "#/properties/tags/items",
"type": "object",
"examples": [
{
"slug": "music-production",
"name": "Music Production",
"customOption": true
}
],
"required": [
"slug",
"name"
],
"properties": {
"slug": {
"$id": "#/properties/tags/items/slug",
"type": "string",
"title": "Slug",
"examples": [
"music-production"
]
},
"name": {
"$id": "#/properties/tags/items/name",
"type": "string",
"title": "Name",
"examples": [
"Music Production"
]
},
"customOption": {
"$id": "#/properties/tags/items/customOption",
"type": "boolean",
"title": "customOption",
"examples": [
true
]
}
},
"additionalProperties": true
}
}
},
"additionalProperties": false,
"if": {
"properties": {
"language": {
"const": "en-us"
}
}
},
"then": {
"properties": {
"title": {
"$id": "#/properties/title",
"type": "string",
"title": "Step Title",
"description": "Enter Step Title",
"default": "",
"tooltip": "Step title has a 100 character limit. It displays in various locations as part of a Path it is added to.",
"examples": [
"Step Title"
],
"maxLength": 100
},
"summary": {
"$id": "#/properties/summary",
"type": "string",
"title": "Step Summary",
"description": "Enter Step Summary",
"default": "",
"tooltip": "Step Summary has a 300 character limit. It displays in various locations as part of a Path it is added to and provides a short and concise summary.",
"examples": [
"Step Summary"
],
"maxLength": 300
},
"tags": {
"$id": "#/properties/tags",
"default": [],
"description": "Choose Tags",
"examples": [
[
{
"slug": "music-production",
"name": "Music Production",
"customOption": true
},
{
"slug": "games-production",
"name": "Games Production"
}
]
],
"title": "Choose Tags",
"minItems": 1,
"type": "array",
"additionalItems": true,
"items": {
"$id": "#/properties/tags/items",
"type": "object",
"examples": [
{
"slug": "music-production",
"name": "Music Production",
"customOption": true
}
],
"required": [
"slug",
"name"
],
"properties": {
"slug": {
"$id": "#/properties/tags/items/slug",
"type": "string",
"title": "Slug",
"examples": [
"music-production"
]
},
"name": {
"$id": "#/properties/tags/items/name",
"type": "string",
"title": "Name",
"examples": [
"Music Production"
]
},
"customOption": {
"$id": "#/properties/tags/items/customOption",
"type": "boolean",
"title": "customOption",
"examples": [
true
]
}
},
"additionalProperties": true
}
}
},
"required": [
"title",
"summary",
"tags"
]
}
}
payload to validate:
{ "language": "ja" }
"json-schema-yup-transformer": "1.6.8"
When I updated from version 1.6.4 to version 1.6.8, I get this sort of error
Uncaught TypeError: Cannot read properties of undefined (reading 'STRING')
at Object../node_modules/json-schema-yup-transformer/dist/schema/utils.js (utils.ts:28:1)
at __webpack_require__ (bootstrap:856:1)
at fn (bootstrap:150:1)
at Object../node_modules/json-schema-yup-transformer/dist/schema/index.js (index.ts:2:1)
at __webpack_require__ (bootstrap:856:1)
at fn (bootstrap:150:1)
at Object../node_modules/json-schema-yup-transformer/dist/yup/addMethods/array.js (array.ts:9:1)
at __webpack_require__ (bootstrap:856:1)
at fn (bootstrap:150:1)
at Object../node_modules/json-schema-yup-transformer/dist/yup/addMethods/index.js (index.ts:2:1)
at __webpack_require__ (bootstrap:856:1)
at fn (bootstrap:150:1)
at Object../node_modules/json-schema-yup-transformer/dist/yup/builder/index.js (index.ts:6:1)
at __webpack_require__ (bootstrap:856:1)
at fn (bootstrap:150:1)
at Object../node_modules/json-schema-yup-transformer/dist/yup/index.js (index.ts:1:1)
at __webpack_require__ (bootstrap:856:1)
at fn (bootstrap:150:1)
at Object../node_modules/json-schema-yup-transformer/dist/index.js (index.ts:3:1)
at __webpack_require__ (bootstrap:856:1)
at fn (bootstrap:150:1)
at Module.<anonymous> (utils.ts:44:1)
.....(local code)
which roughly says that DataTypes is undefined
Hey, thanks for writing this library. I'm trying to integrate it into my project using Formik, and noticed that the import seems incorrect.
import { convertToYup } from 'json-schema-yup-transformer';
gives me the compilation error: Object(...) is not a function
.
Adjusting the import to: import convertToYup from 'json-schema-yup-transformer';
and then using this works:
import convertToYup from 'json-schema-yup-transformer;
const yupValidation = convertToYup(jsonSchema);
// Then use with Formik
Thanks for this library, keep up the good work.
Native Typescript support was added to Yup in v0.32.0. I think there might need to be some adjustments made to support this, as I ran into some errors when trying to extend a schema. This causes Yup to throw a validation error when typing in an input:
const yupSchema = convertToYup(passwordSchema).concat(
yup.object().shape({
confirmNewPassword: yup
.string()
.equals(
[yup.ref("newPassword")],
"Both passwords must match."
)
.required(),
})
);
I think this has to do with the different Yup version json-schema-yup-transform uses.
Hello, in me json schema, array of objects.
"items": {
"description": "oooo",
"type": "array",
"items" : {
"type" : "object",
"properties" : {
"importe": {
"description": "oooo",
"type": "number",
"nullable": false
},
"descripcion": {
"description": "oooo",
"type": "string",
"nullable": false
},
....
Don't take the messages errors ,
"items": [{
"importe": {
"required": "El campo ${path} es requerido"
},
"descripcion": {
"required": "El campo ${path} es requerido"
}
}]
It's a bug , you cant help me.
Thk
With the recent merge of https://github.com/ritchieanesco/json-schema-yup-transform/pull/42/files, yup transformer cannot parse type: ["string", "null"]
type:["object", "null"]
It currently throwing below exception
TypeError: sourceVal.concat is not a function
at prependDeep (/Users/wuh2/project/json-schema-yup-transform-master/node_modules/yup/lib/util/prependDeep.js:27:72)
at prependDeep (/Users/wuh2/project/json-schema-yup-transform-master/node_modules/yup/lib/util/prependDeep.js:29:48)
at ObjectSchema.concat (/Users/wuh2/project/json-schema-yup-transform-master/node_modules/yup/lib/mixed.js:202:41)
at ObjectSchema.concat (/Users/wuh2/project/json-schema-yup-transform-master/node_modules/yup/lib/object.js:254:48)
at Object.exports.buildProperties (/Users/wuh2/project/json-schema-yup-transform-master/src/yup/builder/index.ts:34:51)
at Object.exports.build [as default] (/Users/wuh2/project/json-schema-yup-transform-master/src/yup/builder/index.ts:244:16)
at Object.convertToYup [as default] (/Users/wuh2/project/json-schema-yup-transform-master/src/index.ts:15:32)
at Object.<anonymous> (/Users/wuh2/project/json-schema-yup-transform-master/test/yup/object.test.ts:186:33)
at Object.asyncJestTest (/Users/wuh2/project/json-schema-yup-transform-master/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:100:37)
at /Users/wuh2/project/json-schema-yup-transform-master/node_modules/jest-jasmine2/build/queueRunner.js:45:12
This is the JSON schema input I am trying to transform
{
type: "object",
$schema: "http://json-schema.org/draft-07/schema#",
$id: "test",
title: "Test",
definitions: {
address: {
type: "object",
properties: {
street_address: { type: ["string", "null"] }
},
}
},
properties: {
mailingAddress: {
$ref: "#/definitions/address"
}
}
}
Hi! @ritchieanesco or @nas5w, can someone explain me how to use this allOf property? I'm trying to implement multiple conditionals and I don't know how to use it. Thanks!
const testSchema = {
type: "object",
$schema: "http://json-schema.org/draft-07/schema#",
$id: "test",
title: "Test",
properties: {
things: {
type: "string",
enum: ["a", "b"],
},
},
};
const yupschema = convertToYup(testSchema);
console.log(
yupschema!.isValidSync({
things: "",
})
);
console.log(
yupschema!.isValidSync({
things: null,
})
);
console.log(
yupschema!.isValidSync({
things: undefined,
})
);
Validation error.
No error because things
is not required.
There are an example with single conditional rule. Is there a way to set more than one condition?
"Is" and "then" keys must be unique. So the only option I see is pass conditions as an array. But when I do so, rules not applied.
if: [
{
properties: {
country: {
const: "Australia"
}
}
}
],
then: [
{
properties: {
residencyYears: {
type: "number",
minimum: 12
}
},
required: ["residencyYears"]
}
]
Thank you so much for this library. It is absolutely amazing.
I have a schema where at least one field is required. The JSON schema looks like this as an example.
type: "object",
$schema: "http://json-schema.org/draft-07/schema#",
$id: "testform",
properties: {
favouriteColour: {
default: "",
type: "string",
},
favouriteFruit: {
default: "",
type: "string",
},
},
required: ["name", "age"],
oneOf: [
{
required: ["favouriteColour"],
},
{
required: ["favouriteFruit"],
},
],
};
The rules are not getting applied in Yup. I know the examples show oneOf
being used to conditionally type a property, but I was wondering if there was a way to use it like this.
Another question I have is - when I define a schema like below:
const testSchema = {
type: "object",
$schema: "http://json-schema.org/draft-07/schema#",
$id: "testform",
properties: {
likes: {
type: "array",
default: [],
minItems: 2
maxItems: 4,
},
},
When I don't include the likes field in the validation data, a validation error is raised that the array field has to have the minimum elements. I have not included the property name in the array of required elements, so I would expect that the validation should only fail if the element is not an empty list? Can you please explain what I am doing wrong in this case? Thanks.
Sorry I don't understand why it requires the second property of the else
import * as Yup from "yup";
import { JSONSchema7 } from "json-schema";
import convertToYup from "../../src";
describe("convertToYup() number conditions", () => {
it("should validate other conditional", () => {
const schema: JSONSchema7 = {
type: "object",
$schema: "http://json-schema.org/draft-07/schema#",
$id: "test",
title: "Test",
properties: {
mode: {
type: "string",
enum: ["C", "E"]
}
},
required: ["type"],
if: {
properties: { counmodetry: { type: "string", const: "E" } }
},
then: {
properties: {
namecorp: { type: "string"},
weburl: { type: "string" }
},
required: [
"namecorp" , "weburl"
]
},
else: {
properties: {
firstname: { type: "string"},
lastname : { type: "string"}
},
required: [
"firstname" , "lastname"
]
}
};
const yupschema = convertToYup(schema) as Yup.ObjectSchema;
const dataC = {
mode: "E",
namecorp: "Micro",
weburl: "wwww.google.com",
firstname: undefined,
lastname : undefined
}
const dataE = {
mode: "C",
namecorp: undefined,
weburl: undefined,
firstname: "Albert",
lastname : "Einstein"
}
try{
yupschema.validateSync(dataC)
}catch(error) {
console.log('---->', error)
};
let isValid = yupschema.isValidSync(dataC);
expect(isValid).toBeTruthy();
let isValid2 = yupschema.isValidSync(dataE);
expect(isValid2).toBeTruthy();
});
});
example
const validator = convertToYup({
type: 'object',
properties: {
arr: {
type: 'array',
uniqueItems: true, // this is ignored
items: {
type: 'string'
}
}
}
});
validator.isValidSync({ arr: ["a", "a"] }); // gives true instead of false
When you define a string
property with format: email
or format: uri
the validations work, but the custom error messages aren't.
const schema = {
properties: {
name: {
type: "string",
format: "email"
}
}
};
const config = {
errors: {
name: {
string: "Custom Email Error!",
format: "Testing other way",
email: "Testing other way 2",
}
}
};
When you run the validation with that, the result will always be: Name is an invalid email format
and you won't be able to change the message.
Here is a working example in code sandbox
You can see there that the required message is working, but not the other ones.
Hello, I do not understand why this test does not fail, thank you very much.
import * as Yup from "yup";
import { JSONSchema7 } from "json-schema";
import convertToYup from "../../src";
describe("convertToYup() number conditions", () => {
it("should validate other conditional", () => {
const schema: JSONSchema7 = {
type: "object",
$schema: "http://json-schema.org/draft-07/schema#",
$id: "test",
title: "Test",
properties: {
postcode: {
type: "number",
enum: [3000, 4000]
}
},
required: ["postcode"],
if: {
properties: { postcode: { type: "number", const: 3000 } }
},
then: {
properties: {
product: { type: "string", maxLength: 2 }
}
},
else: {
properties: {
product: { type: "string", maxLength: 1 }
}
}
};
const yupschema = convertToYup(schema) as Yup.ObjectSchema;
const data = {
postcode: 3000,
product: "ABC"
};
let isValid = yupschema.isValidSync(data);
expect(isValid).toBeTruthy();
});
});
Having this schema:
const schema= { title: 'Form', type: 'object', properties: { id: { type: 'string', title: 'id', enum: ['1', '2', '3'], }, }, };
After submit I'm getting the error:
"Id does not match any of the enumerables"
Forcing me to select a value from my select component.
Only works if I add the default keyword on it.
It that happened to anyone?
Thanks!
It seems I cannot nest a yup scheme generated by this library inside a raw yup scheme.
Example: Let's start with
const SCHEMA_AB = {
$schema: 'http://json-schema.org/draft-07/schema#',
$id: 'http://example.com/person.schema.json',
type: 'object',
properties: {
a: { type: 'string', maxLength: 3, },
b: { type: 'string', maxLength: 3, },
},
required: ['a', 'b'],
};
const yupSchemaAb = convertToYup(SCHEMA_AB);
const yupSchemaAbRaw = yup.object().shape({
a: yup.string().required().max(3),
b: yup.string().required().max(3),
});
In this case, the two schemas are semantically equivalent, and indeed they work as expected:
// this works
let res = null;
res = await yupSchemaAbRaw.validate({ a: 'x', b: 'z' });
expect(res).toEqual({ a: 'x', b: 'z' });
res = await yupSchemaAb.validate({ a: 'x', b: 'z' });
expect(res).toEqual({ a: 'x', b: 'z' });
res = await expect(yupSchemaAbRaw.validate({ a: 'x', b: 'too long' })).rejects.toThrow(Error);
res = await expect(yupSchemaAb.validate({ a: 'x', b: 'too long' })).rejects.toThrow(Error);
However, if I put those equivalent schemas inside another, the generated one does not work
const yupSchemaFull = yup.object().shape({
text: yup.string().required().max(5),
ab: yupSchemaAb,
});
const yupSchemaFullRaw = yup.object().shape({
text: yup.string().required().max(5),
ab: yupSchemaAbRaw,
});
res = await yupSchemaFullRaw.validate({ text: 's', ab: { a: 'x', b: 'z' } });
expect(res).toEqual({ text: 's', ab: { a: 'x', b: 'z' } });
res = await expect(yupSchemaFullRaw.validate({ text: 's', ab: { a: 'x', b: 'too long' } })).rejects.toThrow(Error);
// ANY OF THE FOLLOWING TWO FAIL
res = await yupSchemaFull.validate({ text: 's', ab: { a: 'x', b: 'z' } });
res = await expect(yupSchemaFull.validate({ text: 's', ab: { a: 'x', b: 'too long' } })).rejects.toThrow(Error)
Both tests using yupSchemaFull
fail with thrown: "Exceeded timeout of 15000 ms for a test.
Internally, they seem to do the correct validation (in the "too long" case, a ValidationError is thrown to the console) but it seems there are something wrong with the sync/async logic...
Issue #21, seems to be related
#21 (comment)
but, contrarily yo the comments there I don't see a difference with yup versions (the above results are with yup 0.31.1 - which I tried after having problems with the current 0.32.11)
I'm using json-schema-yup-transform 1.6.3 with Node 14, webpack 5.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.