codekie/openapi-examples-validator

View on GitHub
src/impl/service/no-additional-properties.js

Summary

Maintainability
A
0 mins
Test Coverage
const { applyCallbackToAllObjectModels } = require('./common');

module.exports = {
    setNoAdditionalProperties
};

const JSON_SCHEMA_COMBINERS = [
    'oneOf',
    'allOf',
    'anyOf',
    'not'
];

/**
 * Sets the flag to indicate that it doesn't allow properties that are not described in the schema
 * @param {Object}                  openApiSpec         The to-be-modified schema
 * @param {Array.<String>}          [examplePaths=[]]   The paths to the examples, which's content must not be modified
 */
function setNoAdditionalProperties(openApiSpec, examplePaths = []) {
    // Match all combiner keywords that are not preceded by a 'properties' keyword.
    // This allow to have objects that have as property name one of the combiner keywords.
    const hasJsonCombinerParentRegex
        = new RegExp('(?<!\\[\'properties\'\\])\\[\'(?:' + JSON_SCHEMA_COMBINERS.join('|') + ')\'\\]');

    applyCallbackToAllObjectModels(openApiSpec, examplePaths,
        (path) => {
            return (schema) => {
                // Exclude schema that have a JSON combiner as parent
                if (hasJsonCombinerParentRegex.test(path)) {
                    console.warn('"additionalProperties" flag not set '
                        + `for ${path} because it has a parent with a JSON-schema combiner keyword.`);
                    return;
                }
                // Exclude schema that contains a JSON combiner
                if (JSON_SCHEMA_COMBINERS.some((combiner) => schema.hasOwnProperty(combiner))) {
                    console.warn('"additionalProperties" flag not set '
                        + `for ${path} because it contains JSON-schema combiner keyword.`);
                    return;
                }
                // Exclude schema that already contains additionalProperties
                if (schema.hasOwnProperty('additionalProperties')) {
                    return;
                }
                schema.additionalProperties = false;
            };
        });
}