Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSON schema does not explicitly add "additionProperties: false" #41

Open
crobinson42 opened this issue Nov 8, 2023 · 1 comment
Open

Comments

@crobinson42
Copy link

This validator:

v
  .object({
    id: v.string().required(),
    username: v.string(),
    nested: v.object({
      email: v.string(),
    }),
  })

Will produce this json-schema:

{
  type: 'object',
  properties: {
    id: { type: 'string' },
    username: { type: 'string' },
    nested: { type: 'object', properties: [Object] }
  },
  required: [ 'id' ]
}

The problem here is that JSON-schema validators like ajv infer if there is no additionalProperties: false then additional properties are allowed. This conflicts with the implementation of the ObjectValidator because if you want to allow additional properties you are required to chain .additional({ ... }) which should imply to the developer that when .additional({...}) is not used then to expect _additionalProperties: false_ in the json-schema output.

@crobinson42
Copy link
Author

In case anyone comes here looking for a solution, I patch the JSON-schema programmatically using this function:

/**
 * This function will recursively search for JSON-schema { type: 'object' } and add { additionalProperties: false } to them.
 * @param data
 */
export function addAdditionalPropertiesFalse(data: any) {
  // If the current data is an object and not an array, proceed
  if (typeof data === 'object' && !Array.isArray(data)) {
    // Check if the object has the type property 'object'
    if (data.type === 'object') {
      // Add the additionalProperties property set to false
      data.additionalProperties = false;
    }

    // Iterate over each property of the object
    for (let key in data) {
      // If the property is an object or an array, recurse into it
      if (typeof data[key] === 'object') {
        addAdditionalPropertiesFalse(data[key]);
      }
    }
  } else if (Array.isArray(data)) {
    // Iterate over each item of the array
    for (let i = 0; i < data.length; i++) {
      // If the item is an object or an array, recurse into it
      if (typeof data[i] === 'object') {
        addAdditionalPropertiesFalse(data[i]);
      }
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant