Skip to content

Commit

Permalink
restructure
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcisbee committed Nov 13, 2020
1 parent 75ef078 commit 9e200a3
Show file tree
Hide file tree
Showing 12 changed files with 336 additions and 100 deletions.
File renamed without changes.
18 changes: 18 additions & 0 deletions src/validate/ref.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const jsonPointer = require("../json-pointer");

/**
* @this {import('src').Context}
* @param {*} value
* @param {*} currentSchema
* @param {(string | number)[]} position
*/
function validateRef(value, currentSchema, position) {
const match = currentSchema.$ref.match(/^#\/(.*)$/);
if (match && match[1]) {
const schema = jsonPointer(this.schema, match[1].split("/"));
this.validateSchema(value, position, schema);
return;
}
}

module.exports = validateRef;
117 changes: 17 additions & 100 deletions src/validate/schema.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
const GenericError = require("../diagnostics/generic-error");
const jsonPointer = require("../json-pointer");

const validateProperties = require("./properties");
const validateItems = require("./items");
const validateRequired = require("./required");
const validateEnum = require("./enum");
const validateAnyOf = require("./anyOf");
const validateAnyOf = require("./any-of");
const validateString = require("./type/string");
const validateObject = require("./type/object");
const validateNumber = require("./type/number");
const validateBoolean = require("./type/boolean");
const validateNull = require("./type/null");
const validateMultiple = require("./type/multiple");
const validateArray = require("./type/array");
const validateRef = require("./ref");

/**
* @this {import('src').Context}
Expand All @@ -24,118 +28,37 @@ function validateSchema(json, position, currentSchema = this.schema) {
}

if (currentSchema.type === "array") {
if (!Array.isArray(json)) {
this.error('Incorrect type. Expected "array".', "type", position);
return;
}

if (!this.shallow && currentSchema.items) {
validateItems.call(this, json, currentSchema.items, position);
}

validateArray.call(this, json, currentSchema, position);
return;
}

if (currentSchema.type === "object") {
if (!json || typeof json !== "object" || Array.isArray(json)) {
this.error('Incorrect type. Expected "object".', "type", position);
return;
}

if (!this.shallow && currentSchema.required) {
validateRequired.call(this, json, currentSchema.required, position);
}

if (currentSchema.properties) {
validateProperties.call(this, json, currentSchema, position);
}

validateObject.call(this, json, currentSchema, position);
return;
}

if (currentSchema.type === "string") {
if (typeof json !== "string") {
this.error(`"${json}" should be string`, "type", position);
return;
}

if (currentSchema.enum) {
validateEnum.call(this, json, currentSchema.enum, position);
}

validateString.call(this, json, currentSchema, position);
return;
}

if (currentSchema.type === "number" || currentSchema.type === "integer") {
if (typeof json !== "number") {
this.error(`"${json}" should be number`, "type", position);
return;
}

if (currentSchema.enum) {
validateEnum.call(this, json, currentSchema.enum, position);
}

validateNumber.call(this, json, currentSchema, position);
return;
}

if (currentSchema.type === "boolean") {
if (typeof json !== "boolean") {
this.error(`"${json}" should be boolean`, "type", position);
return;
}

if (currentSchema.enum) {
validateEnum.call(this, json, currentSchema.enum, position);
}

validateBoolean.call(this, json, currentSchema, position);
return;
}

if (currentSchema.type === "null") {
if (json !== null) {
this.error(`"${json}" should be null`, "type", position);
return;
}

if (currentSchema.enum) {
validateEnum.call(this, json, currentSchema.enum, position);
}

validateNull.call(this, json, currentSchema, position);
return;
}

if (Array.isArray(currentSchema.type)) {
let errorCount = 0;
for (const type of currentSchema.type) {
try {
validateSchema.call(
{...this, shallow: true},
json,
position,
{
type,
},
);
return;
} catch (e) {
errorCount++;
}
}

if (errorCount >= currentSchema.type.length) {
this.error(
`"${json}" should be ${currentSchema.type.join(" or ")}`,
"type",
position,
);
return;
}

if (currentSchema.enum) {
validateEnum.call(this, json, currentSchema.enum, position);
}

validateMultiple.call(this, json, currentSchema, position);
return;
}

Expand All @@ -152,13 +75,7 @@ function validateSchema(json, position, currentSchema = this.schema) {
}

if (currentSchema.$ref) {
const match = currentSchema.$ref.match(/^#\/(.*)$/);
if (match && match[1]) {
const schema = jsonPointer(this.schema, match[1].split("/"));
validateSchema.call(this, json, position, schema);
return;
}

validateRef.call(this, json, currentSchema, position);
return;
}

Expand Down
20 changes: 20 additions & 0 deletions src/validate/type/array.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const validateItems = require("../items");

/**
* @this {import('src').Context}
* @param {*} value
* @param {*} currentSchema
* @param {(string | number)[]} position
*/
function validateArray(value, currentSchema, position) {
if (!Array.isArray(value)) {
this.error('Incorrect type. Expected "array".', "type", position);
return;
}

if (!this.shallow && currentSchema.items) {
validateItems.call(this, value, currentSchema.items, position);
}
}

module.exports = validateArray;
20 changes: 20 additions & 0 deletions src/validate/type/boolean.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const validateEnum = require("../enum");

/**
* @this {import('src').Context}
* @param {*} value
* @param {*} currentSchema
* @param {(string | number)[]} position
*/
function validateBoolean(value, currentSchema, position) {
if (typeof value !== "boolean") {
this.error(`"${value}" should be boolean`, "type", position);
return;
}

if (currentSchema.enum) {
validateEnum.call(this, value, currentSchema.enum, position);
}
}

module.exports = validateBoolean;
43 changes: 43 additions & 0 deletions src/validate/type/multiple.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const validateEnum = require("../enum");

/**
* @this {import('src').Context}
* @param {*} value
* @param {*} currentSchema
* @param {(string | number)[]} position
*/
function validateMultiple(value, currentSchema, position) {
let errorCount = 0;
let skip = false;

for (const type of currentSchema.type) {
try {
this.validateSchema.call(
{...this, shallow: true},
value,
position,
{
type,
},
);
skip = true;
break;
} catch (e) {
errorCount++;
}
}

if (!skip && errorCount >= currentSchema.type.length) {
this.error(
`"${value}" should be ${currentSchema.type.join(" or ")}`,
"type",
position,
);
}

if (currentSchema.enum) {
validateEnum.call(this, value, currentSchema.enum, position);
}
}

module.exports = validateMultiple;
20 changes: 20 additions & 0 deletions src/validate/type/null.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const validateEnum = require("../enum");

/**
* @this {import('src').Context}
* @param {*} value
* @param {*} currentSchema
* @param {(string | number)[]} position
*/
function validateNull(value, currentSchema, position) {
if (value !== null) {
this.error(`"${value}" should be null`, "type", position);
return;
}

if (currentSchema.enum) {
validateEnum.call(this, value, currentSchema.enum, position);
}
}

module.exports = validateNull;
20 changes: 20 additions & 0 deletions src/validate/type/number.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const validateEnum = require("../enum");

/**
* @this {import('src').Context}
* @param {*} value
* @param {*} currentSchema
* @param {(string | number)[]} position
*/
function validateNumber(value, currentSchema, position) {
if (typeof value !== "number") {
this.error(`"${value}" should be number`, "type", position);
return;
}

if (currentSchema.enum) {
validateEnum.call(this, value, currentSchema.enum, position);
}
}

module.exports = validateNumber;
25 changes: 25 additions & 0 deletions src/validate/type/object.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const validateRequired = require("../required");
const validateProperties = require("../properties");

/**
* @this {import('src').Context}
* @param {*} value
* @param {*} currentSchema
* @param {(string | number)[]} position
*/
function validateObject(value, currentSchema, position) {
if (!value || typeof value !== "object" || Array.isArray(value)) {
this.error('Incorrect type. Expected "object".', "type", position);
return;
}

if (!this.shallow && currentSchema.required) {
validateRequired.call(this, value, currentSchema.required, position);
}

if (currentSchema.properties) {
validateProperties.call(this, value, currentSchema, position);
}
}

module.exports = validateObject;
20 changes: 20 additions & 0 deletions src/validate/type/string.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const validateEnum = require("../enum");

/**
* @this {import('src').Context}
* @param {*} value
* @param {*} currentSchema
* @param {(string | number)[]} position
*/
function validateString(value, currentSchema, position) {
if (typeof value !== "string") {
this.error(`"${value}" should be string`, "type", position);
return;
}

if (currentSchema.enum) {
validateEnum.call(this, value, currentSchema.enum, position);
}
}

module.exports = validateString;
Loading

0 comments on commit 9e200a3

Please sign in to comment.