openapi-enforcer
Advanced tools
Comparing version 1.22.3 to 1.23.0
@@ -7,2 +7,14 @@ # Change Log | ||
## 1.23.0 | ||
### Added | ||
- **You Can Ignore Undefined Property Values** | ||
The default implementation complains of objects where a property is defined but set to `undefined`. | ||
This will cause Schema instances to fail validations, serialization, and deserialization. | ||
Now you have the option to set the global `Enforcer.config.ignoreUndefinedPropertyValues` to `true` or `false` (default) | ||
or when calling a Schema instance's `validate` function you can specify the `ignoreUndefinedPropertyValues` as an option property. | ||
Serialization and deserialization will now ignore undefined values in all cases. | ||
## 1.22.3 | ||
@@ -9,0 +21,0 @@ |
@@ -92,3 +92,4 @@ /** | ||
useCaseSensitivePaths: true, | ||
useNewRefParser: false | ||
useNewRefParser: false, | ||
ignoreUndefinedPropertyValues: false | ||
}; | ||
@@ -95,0 +96,0 @@ |
{ | ||
"name": "openapi-enforcer", | ||
"version": "1.22.3", | ||
"version": "1.23.0", | ||
"description": "Library for validating, parsing, and formatting data against open api schemas.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -98,6 +98,9 @@ /** | ||
Object.keys(value).forEach(key => { | ||
if (properties.hasOwnProperty(key)) { | ||
value[key] = runDeserialize(exception.at(key), map, properties[key], Value.inherit(value[key], { serialize }), options); | ||
} else if (additionalProperties) { | ||
value[key] = runDeserialize(exception.at(key), map, additionalProperties, Value.inherit(value[key], { serialize }), options); | ||
const nestedValue = value[key] | ||
if (nestedValue !== undefined) { | ||
if (properties.hasOwnProperty(key)) { | ||
value[key] = runDeserialize(exception.at(key), map, properties[key], Value.inherit(value[key], {serialize}), options); | ||
} else if (additionalProperties) { | ||
value[key] = runDeserialize(exception.at(key), map, additionalProperties, Value.inherit(value[key], {serialize}), options); | ||
} | ||
} | ||
@@ -104,0 +107,0 @@ }); |
@@ -87,6 +87,9 @@ /** | ||
Object.keys(value).forEach(key => { | ||
if (properties.hasOwnProperty(key)) { | ||
value[key] = runSerialize(exception.at(key), map, properties[key], value[key]); | ||
} else if (additionalProperties) { | ||
value[key] = runSerialize(exception.at(key), map, additionalProperties, value[key]); | ||
const nestedValue = value[key] | ||
if (nestedValue !== undefined) { | ||
if (properties.hasOwnProperty(key)) { | ||
value[key] = runSerialize(exception.at(key), map, properties[key], nestedValue); | ||
} else if (additionalProperties) { | ||
value[key] = runSerialize(exception.at(key), map, additionalProperties, nestedValue); | ||
} | ||
} | ||
@@ -93,0 +96,0 @@ }); |
@@ -37,2 +37,3 @@ /** | ||
* @param {'read', 'write} [options.readWriteMode] Set to 'read' if in read only mode or to 'write' if write only mode. | ||
* @param {boolean} [options.ignoreUndefinedPropertyValues] Whether to ignore undefined property values during validation. | ||
* @returns {*} | ||
@@ -184,2 +185,3 @@ */ | ||
const keys = Object.keys(value); | ||
const ignoreUndefinedProperties = util.ignoreUndefinedProperties(options); | ||
@@ -190,2 +192,3 @@ // validate each property in the value | ||
const index = required.indexOf(key); | ||
if (value[key] === undefined && ignoreUndefinedProperties) return; | ||
if (index !== -1) required.splice(index, 1); | ||
@@ -192,0 +195,0 @@ |
@@ -22,2 +22,3 @@ /** | ||
const Exception = require('./exception'); | ||
const Enforcer = require("../index"); | ||
const rxMediaType = /^([\s\S]+?)\/(?:([\s\S]+?)\+)?([\s\S]+?)$/; | ||
@@ -42,2 +43,3 @@ const punctuation = ',,,,,,,,,,.................................:;!?'; | ||
greatestCommonDenominator, | ||
ignoreUndefinedProperties, | ||
isDate, | ||
@@ -324,2 +326,12 @@ isNumber, | ||
/** | ||
* @param {object} options | ||
* @param {boolean} [options.ignoreUndefinedPropertyValues] Whether to ignore undefined property values during validation. | ||
* @returns boolean | ||
*/ | ||
function ignoreUndefinedProperties (options) { | ||
if (options.ignoreUndefinedPropertyValues !== undefined) return options.ignoreUndefinedPropertyValues | ||
return Enforcer.config.ignoreUndefinedPropertyValues | ||
} | ||
function isDate (value) { | ||
@@ -326,0 +338,0 @@ return value && !isNaN(value) && value instanceof Date; |
@@ -472,2 +472,127 @@ const expect = require('chai').expect; | ||
describe('issue-161 - allow undefined values to be skipped during validation', () => { | ||
let schema | ||
before(() => { | ||
schema = Enforcer.v3_0.Schema({ | ||
type: 'object', | ||
required: ['bool'], | ||
properties: { | ||
str: { type: 'string' }, | ||
obj: { | ||
type: 'object', | ||
properties: { | ||
num: { type: 'string' } | ||
} | ||
}, | ||
bool: { type: 'boolean' } | ||
} | ||
}).value | ||
}) | ||
describe('global config allowUndefinedValuesInObjectValidation set to false', () => { | ||
let previousConfigValue | ||
before(() => { | ||
previousConfigValue = Enforcer.config.ignoreUndefinedPropertyValues | ||
Enforcer.config.ignoreUndefinedPropertyValues = false | ||
}) | ||
after(() => { | ||
Enforcer.config.ignoreUndefinedPropertyValues = previousConfigValue | ||
}) | ||
it('validate will not allow undefined values', () => { | ||
const err = schema.validate({ | ||
str: 'hello', | ||
obj: undefined, | ||
bool: true | ||
}) | ||
expect(err.toString().replace(/(\r)?\n/g, ' ')).to.match(/at: obj[\s\S]+?Received: undefined/) | ||
}) | ||
it('validate will not allow undefined values for required properties', () => { | ||
const err = schema.validate({ | ||
a: 'hello', | ||
bool: undefined | ||
}) | ||
expect(err.toString().replace(/(\r)?\n/g, ' ')).to.match(/at: bool[\s\S]+?Received: undefined/) | ||
}) | ||
it('serialize will allow undefined values', () => { | ||
const { error } = schema.serialize({ | ||
a: 'hello', | ||
obj: undefined, | ||
bool: true | ||
}) | ||
expect(error).to.equal(undefined) | ||
}) | ||
it('validate will ignore undefined values when specified via the option', () => { | ||
const err = schema.validate({ | ||
a: 'hello', | ||
obj: undefined, | ||
bool: true | ||
}, { ignoreUndefinedPropertyValues: true }) | ||
expect(err).to.equal(undefined) | ||
}) | ||
it('validate will not allow undefined values for required properties even when ignored', () => { | ||
const err = schema.validate({ | ||
a: 'hello', | ||
bool: undefined | ||
}, { ignoreUndefinedPropertyValues: true }) | ||
expect(err.toString()).to.contain('One or more required properties missing: bool') | ||
}) | ||
}) | ||
describe('global config allowUndefinedValuesInObjectValidation set to true', () => { | ||
let previousConfigValue | ||
before(() => { | ||
previousConfigValue = Enforcer.config.ignoreUndefinedPropertyValues | ||
Enforcer.config.ignoreUndefinedPropertyValues = true | ||
}) | ||
after(() => { | ||
Enforcer.config.ignoreUndefinedPropertyValues = previousConfigValue | ||
}) | ||
it('validate will allow undefined values', () => { | ||
const err = schema.validate({ | ||
str: 'hello', | ||
obj: undefined, | ||
bool: true | ||
}) | ||
expect(err).to.equal(undefined) | ||
}) | ||
it('validate will not allow undefined values for required properties', () => { | ||
const err = schema.validate({ | ||
a: 'hello', | ||
bool: undefined | ||
}) | ||
expect(err.toString()).to.contain('One or more required properties missing: bool') | ||
}) | ||
it('serialize will allow undefined values', () => { | ||
const { error } = schema.serialize({ | ||
a: 'hello', | ||
obj: undefined, | ||
bool: true | ||
}) | ||
expect(error).to.equal(undefined) | ||
}) | ||
it('validate will not ignore undefined values when specified via the option', () => { | ||
const err = schema.validate({ | ||
a: 'hello', | ||
obj: undefined, | ||
bool: true | ||
}, { ignoreUndefinedPropertyValues: false }) | ||
expect(err.toString().replace(/(\r)?\n/g, ' ')).to.match(/at: obj[\s\S]+?Received: undefined/) | ||
}) | ||
}) | ||
}) | ||
}); |
Sorry, the diff of this file is too big to display
1068416
20971