ritchieanesco/json-schema-yup-transform

nullable: true (OAS3 Support?)

Closed this issue · 3 comments

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/

Can you pls provide the schema and some test data that replicates this issue?

Sure, here is a schema I am using that has been generated from a different library. The offending properties are domainName and usageContext.

For example, I think specifically the problem is from the property "title": "Schema$Container.domainName", as it does not have a type key. I'm not an expert on schemas but I think domainName should be any of string[] or null. But null in OAS3 isn't explicitly a type which is where the transformer gets tripped up.

{
    "properties": {
        "accountId": {
            "title": "Schema$Container.accountId",
            "nullable": true,
            "type": "string"
        },
        "containerId": {
            "title": "Schema$Container.containerId",
            "nullable": true,
            "type": "string"
        },
        "domainName": {
            "anyOf": [
                {
                    "items": {
                        "title": "Schema$Container.domainName.[]",
                        "type": "string"
                    },
                    "title": "Schema$Container.domainName.[]",
                    "type": "array"
                },
                {
                    "title": "Schema$Container.domainName",
                    "nullable": true
                }
            ],
            "title": "Schema$Container.domainName"
        },
        "fingerprint": {
            "title": "Schema$Container.fingerprint",
            "nullable": true,
            "type": "string"
        },
        "name": {
            "title": "Schema$Container.name",
            "nullable": true,
            "type": "string"
        },
        "notes": {
            "title": "Schema$Container.notes",
            "nullable": true,
            "type": "string"
        },
        "path": {
            "title": "Schema$Container.path",
            "nullable": true,
            "type": "string"
        },
        "publicId": {
            "title": "Schema$Container.publicId",
            "nullable": true,
            "type": "string"
        },
        "tagManagerUrl": {
            "title": "Schema$Container.tagManagerUrl",
            "nullable": true,
            "type": "string"
        },
        "usageContext": {
            "anyOf": [
                {
                    "items": {
                        "title": "Schema$Container.usageContext.[]",
                        "type": "string"
                    },
                    "title": "Schema$Container.usageContext.[]",
                    "type": "array"
                },
                {
                    "title": "Schema$Container.usageContext",
                    "nullable": true
                }
            ],
            "title": "Schema$Container.usageContext"
        }
    },
    "additionalProperties": false,
    "title": "Schema$Container",
    "type": "object"
}

Ok, so this library adheres to the json schema darft 7 spec. I was unable to find nullable in draft 7 or the latest spec, but i'm assuming nullable allows the field to accept null and the defined type. If this assumption is correct, you could apply this the following way:

    const schema: JSONSchema7Extended = {
      type: "object",
      $schema: "http://json-schema.org/draft-07/schema#",
      $id: "test",
      title: "Test",
      properties: {
        name: {
          type: ["string", "null"]
        }
      }
    };
    const yupschema = convertToYup(schema) as Yup.ObjectSchema;

    let isValid = yupschema.isValidSync({
      name: "test"
    });
    // => returns true

    isValid = yupschema.isValidSync({
      name: null
    });
    // => returns true

    isValid = yupschema.isValidSync({
      name: []
    });
    // => returns false