function Schema(definition) {
  var _this = this;

  definition || (definition = {}); // TODO: schema validation

  utils.fillIn(this, definition);

  if (this.type === 'object') {
    this.properties = this.properties || {};
    utils.forOwn(this.properties, function (_definition, prop) {
      if (!(_definition instanceof Schema)) {
        _this.properties[prop] = new Schema(_definition);
      }
    });
  } else if (this.type === 'array' && this.items && !(this.items instanceof Schema)) {
    this.items = new Schema(this.items);
  }

  if (this.extends && !(this.extends instanceof Schema)) {
    this.extends = new Schema(this.extends);
  }

  ['allOf', 'anyOf', 'oneOf'].forEach(function (validationKeyword) {
    if (_this[validationKeyword]) {
      _this[validationKeyword].forEach(function (_definition, i) {
        if (!(_definition instanceof Schema)) {
          _this[validationKeyword][i] = new Schema(_definition);
        }
      });
    }
  });
}
js-data's Schema class.

@example <caption>Schema#constructor</caption>
const JSData = require('js-data');
const { Schema } = JSData;
console.log('Using JSData v' + JSData.version.full);

const PostSchema = new Schema({
  type: 'object',
  properties: {
    title: { type: 'string' }
  }
});
PostSchema.validate({ title: 1234 });

@class Schema
@extends Component
@param {object} definition Schema definition according to json-schema.org