From edc4e42ec3cf09a5855ed5bcfc89dc24dd274417 Mon Sep 17 00:00:00 2001 From: Vlad Barosan Date: Fri, 18 May 2018 11:39:20 -0700 Subject: [PATCH] Add custom type validator to support x-ms-mutability --- lib/helpers.js | 1 + lib/validation/custom-zschema-validators.js | 52 ++++++++++++++++++++- package.json | 2 +- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/lib/helpers.js b/lib/helpers.js index b4647161..1f3578e1 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -111,6 +111,7 @@ function createJSONValidator () { // overwrite validators through rewire until z-schema supports overriding the validators. ZSchemaValidator.__set__('JsonValidators.enum', customValidators.enumValidator); + ZSchemaValidator.__set__('JsonValidators.type', customValidators.typeValidator); ZSchemaValidator.__set__('JsonValidators.required', customValidators.requiredPropertyValidator); ZSchema.__set__('JsonValidation', ZSchemaValidator); diff --git a/lib/validation/custom-zschema-validators.js b/lib/validation/custom-zschema-validators.js index 7021b53f..21163f91 100644 --- a/lib/validation/custom-zschema-validators.js +++ b/lib/validation/custom-zschema-validators.js @@ -48,7 +48,7 @@ function requiredPropertyValidator (report, schema, json) { requiredPropertyName = schema.required[idx]; xMsMutability = (schema.properties && schema.properties[`${requiredPropertyName}`]) && schema.properties[`${requiredPropertyName}`]['x-ms-mutability']; - // If a response has x-ms-mutability property and its missing the read we can skip this step + // If a response has x-ms-mutability property and its missing the read we can skip this step if (this.validateOptions && this.validateOptions.isResponse && xMsMutability && xMsMutability.indexOf('read') === -1) { continue; } @@ -63,5 +63,55 @@ function requiredPropertyValidator (report, schema, json) { } } +function typeValidator (report, schema, json) { + // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.2.2 + var jsonType = whatIs(json); + var xMsMutabilityAllowsNullType = schema['x-ms-mutability'] && schema['x-ms-mutability'].indexOf('read') === -1; + var isResponse = this.validateOptions && this.validateOptions.isResponse; + + if (isResponse && xMsMutabilityAllowsNullType) { + return; + } + if (typeof schema.type === 'string') { + if (jsonType !== schema.type && (jsonType !== 'integer' || schema.type !== 'number')) { + report.addError('INVALID_TYPE', [schema.type, jsonType], null, schema.description); + } + } else { + if (schema.type.indexOf(jsonType) === -1 && (jsonType !== 'integer' || schema.type.indexOf('number') === -1)) { + report.addError('INVALID_TYPE', [schema.type, jsonType], null, schema.description); + } + } +} + +function whatIs (what) { + var to = typeof what; + + if (to === 'object') { + if (what === null) { + return 'null'; + } + if (Array.isArray(what)) { + return 'array'; + } + return 'object'; // typeof what === 'object' && what === Object(what) && !Array.isArray(what); + } + + if (to === 'number') { + if (Number.isFinite(what)) { + if (what % 1 === 0) { + return 'integer'; + } else { + return 'number'; + } + } + if (Number.isNaN(what)) { + return 'not-a-number'; + } + return 'unknown-number'; + } + return to; // undefined, boolean, string, function +} + module.exports.enumValidator = enumValidator; module.exports.requiredPropertyValidator = requiredPropertyValidator; +module.exports.typeValidator = typeValidator; diff --git a/package.json b/package.json index 3cca2ac0..47cf8d23 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,6 @@ "rewire": "^4.0.0", "swagger-methods": "^1.0.0", "swagger-schema-official": "2.0.0-bab6bed", - "z-schema": "^3.21.0" + "z-schema": "^3.22.0" } }