{"size": 1569, "ext": "js", "max_stars_repo_path": "src/schema.js", "max_stars_repo_name": "foo-dogsquared/json-database", "max_stars_repo_stars_event_min_datetime": null, "max_stars_repo_stars_event_max_datetime": null, "max_issues_repo_path": "src/schema.js", "max_issues_repo_name": "foo-dogsquared/json-database", "max_issues_repo_issues_event_min_datetime": "2019-03-17T11:58:42.000Z", "max_issues_repo_issues_event_max_datetime": "2019-03-17T11:58:42.000Z", "max_forks_repo_path": "src/schema.js", "max_forks_repo_name": "foo-dogsquared/jayson-db", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": null, "max_issues_count": 1, "max_forks_count": null, "avg_line_length": 30.7647058824, "max_line_length": 102, "alphanum_fraction": 0.7151051625}
const Ajv = require('ajv');

class SchemaError extends Error {
  constructor(statusCode, description = statusCode) {
    const errorMessage = `Schema error: ${statusCode} ${description}`;
    super(errorMessage);
    this.statusCode = statusCode;
    this.description = errorMessage;
  }
}

const SchemaErrorList = {
  invalidType: new TypeError('Invalid schema type (it should be a valid JSON)'),
  schemaMatchFailed: new SchemaError(201, 'Data is invalid according to the schema'),
  filterFunctionType: new SchemaError(202, 'Filter callback is not a function'),
  duplicateKey: new SchemaError(203, 'Duplicate key'),
  keyNotFound: new SchemaError(204, 'Key not found'),
}

class Schema {
  constructor(...schemaObjects) {
    if (typeof schemaObjects !== 'object') throw SchemaErrorList.invalidType
    if (!(schemaObjects instanceof Object)) throw SchemaErrorList.invalidType
    
    // setting up read-only properties
    Object.defineProperty(this, "ajv", {value: new Ajv({ schemas: schemaObjects}), enumerable: true});
    Object.defineProperty(this, "validator", {value: this.ajv.compile()})
    Object.defineProperty(this, "structure", {value: schemaObjects, enumerable: true});
  }

  /**
  * Simply validates the data to be passed with the schema
  * @param data {Object}
  * @return {Boolean}
  **/
  validate(data) {
    return this.validator.validate(this.structure, data);
  }
}

function isSchema(schemaObject) {
  return schemaObject && schemaObject instanceof Schema;
}

module.exports = {
  Schema,
  SchemaError,
  SchemaErrorList,
  isSchema,
};
