GithubHelp home page GithubHelp logo

json-schema-yup-transform's People

Contributors

armand1m avatar dependabot[bot] avatar ericwooley avatar jdpnielsen avatar lorenzodejong avatar matpen avatar nas5w avatar ritchieanesco avatar zobzn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

json-schema-yup-transform's Issues

nullable: true (OAS3 Support?)

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/

allOf property

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!

Issue with enums

"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

[DataTypes.STRING]: isString,

cannot parse type: ["string", "null"] and type:["object", "null"]

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"
        }
      }
    }

Retrieve the Yup schema

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(), }

Errors extending schemas with yup >= 0.30

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.

Message of array objects

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

String type with enum keyword is not allowed to have value undefined

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!

required?.join is not a function

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:

  • node_modules/json-schema-yup-transformer/dist/yup/schemas/number.d.ts contains this line
    export declare const createBaseNumberSchema: (yupSchema: Yup.NumberSchema, [key, value]: SchemaItem, required: JSONSchema["required"]) => Yup.NumberSchema;
    Since I never used typescript before, I am not sure about this, but the code looks like 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());
  • however, the generated code (in node_modules/json-schema-yup-transformer/dist/yup/schemas/number.js line 35) looks like const createNumberSchema = ([key, value], required) => { ... }: therefore required ends up to be the original JSON schema, which is an object, not an array;
  • modifying that to 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?

How to set multiple conditional rules

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"]
  }
]

Conditional in object.

It is posible ?

if: {
properties: { consent: { properties : { value : { const: true } } }}
},

Thank ?

JSON to Build a Schema & Config with Nested Arrays of Objects?

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',
            },
          },
        },
      },
    },
  },
};

Conditionally requiring fields using `oneOf`

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.

Import statement in examples is not correct

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.

How to have a conditional validate on multiple values

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']
  }
      
}

Bug: Incorrectly transformed schema with "if" and "contains"

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
    });
  });
});

Invalid date-time format regex

Current behavior:

Validator regex for date-time matches only 2018-11-13T20:20:39+00:00.

Expected behaviour:

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"'

if/then validation help

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" }

IF else then test

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();

});
});

Not required enum throws validation error on "" and undefined.

Steps to reproduce:

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,
      })
    );

Current behavior:

Validation error.

Expected behavior:

No error because things is not required.

Required object type not working

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

Support of internalization

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...

Error on import of json-schema-yup-transform

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:

  • I am experiencing this both in Node.js (v16.14.2) and in Chrome with webpack 5;
  • version 1.6.4 works correctly;
  • quick investigation reveals that cyclic dependencies may be the reason for the bug, see #59.

array.of() support?

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()

Second properties in else conditional

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();

});
});

stringify-object package should be a dependency

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

Custom error message not working for strings

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.

Set label to field title if it exists

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?

Yup 0.32.x support

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.