Generate validator function off of the given schema object
@param schema
@returns {Function}
176761
function generateValidationFn(schema) {
        return function (req) {

            // if already an error, return without doing any additional validation
            if (req.error) { return req; }

            var keys = Object.keys(schema);
            var len = (req.value && req.value.trim().length) || 0;
            var i, key, originalKey;

            for (i = 0; i < keys.length; i++) {
                key = originalKey = keys[i];
                if (key.indexOf('ui-') === 0) {
                    key = key.substring(3);
                }

                // if validation function exists but it returns false then we have error
                if (check[key] && !check[key](schema, req.value)) {
                    var errMsg = schema[key + 'Desc'] || errorMessage[key] || 'Invalid input';
                    req.error = errMsg
                        .replace('{' + key + '}', schema[originalKey])
                        .replace('{value}', req.value)
                        .replace('{length}', len);
                    break;
                }
            }

            return req;
        };
    }
562622
function generate(schema) {
  const ret = [];
  if (!validate(schema)) {
    return ret;
  }

  const fullSample = jsf(schema);
  if (!fullSample) {
    return ret;
  }

  ret.push({
    valid: true,
    data: fullSample,
    message: 'should work with all required properties'
  });

  ret.push(...generateFromRequired(schema));
  ret.push(...generateFromRequired(schema, false));
  ret.push(...generateForTypes(schema));

  return ret;
}
819904
function dynamic(createSchema, defaults, options) {
  if (kindOf(createSchema) !== 'function') {
    if (process.env.NODE_ENV !== 'production') {
      throw new Error(
        `Dynamic structs must be defined as a function, but you passed: ${createSchema}`
      )
    } else {
      throw new Error(`Invalid schema: ${createSchema}`)
    }
  }

  const name = 'dynamic'
  const type = 'dynamic...'
  const validate = (value = resolveDefaults(defaults), data) => {
    const schema = createSchema(value, data)

    if (kindOf(schema) !== 'function') {
      if (process.env.NODE_ENV !== 'production') {
        throw new Error(
          `Dynamic structs must return a schema, but you passed: ${schema}`
        )
      } else {
        throw new Error(`Invalid schema: ${schema}`)
      }
    }

    const [error, result] = schema.validate(value)

    if (error) {
      return [error]
    }

    return [undefined, result]
  }

  return new Kind(name, type, validate)
}
375042
def validate(raw_schema, target=None, **kwargs):
    
    schema = schema_validator(raw_schema, **kwargs)
    if target is not None:
        validate_object(target, schema=schema, **kwargs)
1339828
def _validate(self, schema):
        
        if isinstance(schema, _str_type):
            schema = self.validator.schema_registry.get(schema, schema)

        if schema is None:
            raise SchemaError(errors.SCHEMA_ERROR_MISSING)

        schema = copy(schema)
        for field in schema:
            if isinstance(schema[field], _str_type):
                schema[field] = rules_set_registry.get(schema[field],
                                                       schema[field])

        if not self.schema_validator(schema, normalize=False):
            raise SchemaError(self.schema_validator.errors)
1041201
def _process_schema(self, schema_dict, validators):
        
        schema_flat = util.flatten(schema_dict)

        for key, expression in schema_flat.items():
            try:
                schema_flat[key] = syntax.parse(expression, validators)
            except SyntaxError as e:
                # Tack on some more context and rethrow.
                error = str(e) + ' at node \'%s\'' % key
                raise SyntaxError(error)
        return schema_flat
1181610
def _validate_keyschema(self, schema, field, value):
        
        if isinstance(value, Mapping):
            validator = self._get_child_validator(
                document_crumb=field,
                schema_crumb=(field, 'keyschema'),
                schema=dict(((k, schema) for k in value.keys())))
            if not validator(dict(((k, k) for k in value.keys())),
                             normalize=False):
                self._drop_nodes_from_errorpaths(validator._errors,
                                                 [], [2, 4])
                self._error(field, errors.KEYSCHEMA, validator._errors)
1336787
function trimSchema(schema) {
    var schemaObject = {};

    _.each(schema, function (value, key) {
        if (value !== null && typeof value !== 'undefined') {
            schemaObject[key] = value;
        }
    });

    return schemaObject;
}
557358
def validate_input(function):
    """"""
    @wraps(function)
    def wrapper(*args, **kwargs):
        try:
            name = function.__name__ + '_validator'  # find validator name
            globals()[name](kwargs)  # call validation function
            return function(*args, **kwargs)
        except KeyError:
            raise Exception("Could not find validation schema for the"
                            " function " + function.__name__)
    return wrapper
192322
function (version) {
  var that = this;
  var createValidators = function (spec, validatorsMap) {
    return _.reduce(validatorsMap, function (result, schemas, schemaName) {
      result[schemaName] = helpers.createJsonValidator(schemas);

      return result;
    }, {});
  };
  var fixSchemaId = function (schemaName) {
    // Swagger 1.2 schema files use one id but use a different id when referencing schema files.  We also use the schema
    // file name to reference the schema in ZSchema.  To fix this so that the JSON Schema validator works properly, we
    // need to set the id to be the name of the schema file.
    var fixed = _.cloneDeep(that.schemas[schemaName]);

    fixed.id = schemaName;

    return fixed;
  };
  var primitives = ['string', 'number', 'boolean', 'integer', 'array'];

  switch (version) {
  case '1.2':
    this.docsUrl = 'https://github.com/swagger-api/swagger-spec/blob/master/versions/1.2.md';
    this.primitives = _.union(primitives, ['void', 'File']);
    this.schemasUrl = 'https://github.com/swagger-api/swagger-spec/tree/master/schemas/v1.2';

    // Here explicitly to allow browserify to work
    this.schemas = {
      'apiDeclaration.json': require('../schemas/1.2/apiDeclaration.json'),
      'authorizationObject.json': require('../schemas/1.2/authorizationObject.json'),
      'dataType.json': require('../schemas/1.2/dataType.json'),
      'dataTypeBase.json': require('../schemas/1.2/dataTypeBase.json'),
      'infoObject.json': require('../schemas/1.2/infoObject.json'),
      'modelsObject.json': require('../schemas/1.2/modelsObject.json'),
      'oauth2GrantType.json': require('../schemas/1.2/oauth2GrantType.json'),
      'operationObject.json': require('../schemas/1.2/operationObject.json'),
      'parameterObject.json': require('../schemas/1.2/parameterObject.json'),
      'resourceListing.json': require('../schemas/1.2/resourceListing.json'),
      'resourceObject.json': require('../schemas/1.2/resourceObject.json')
    };

    this.validators = createValidators(this, {
      'apiDeclaration.json': _.map([
        'dataTypeBase.json',
        'modelsObject.json',
        'oauth2GrantType.json',
        'authorizationObject.json',
        'parameterObject.json',
        'operationObject.json',
        'apiDeclaration.json'
      ], fixSchemaId),
      'resourceListing.json': _.map([
        'resourceObject.json',
        'infoObject.json',
        'oauth2GrantType.json',
        'authorizationObject.json',
        'resourceListing.json'
      ], fixSchemaId)
    });

    break;

  case '2.0':
    this.docsUrl = 'https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md';
    this.primitives = _.union(primitives, ['file']);
    this.schemasUrl = 'https://github.com/swagger-api/swagger-spec/tree/master/schemas/v2.0';

    // Here explicitly to allow browserify to work
    this.schemas = {
      'schema.json': require('../schemas/2.0/schema.json')
    };

    this.validators = createValidators(this, {
      'schema.json': [fixSchemaId('schema.json')]
    });

    break;

  default:
    throw new Error(version + ' is an unsupported Swagger specification version');
  }

  this.version = version;
}
1028340
function initJsonSchema (args) {
    // get global validator instance
    var validator = this.global().validator
    // get schema id based on model name - must be globally unique
    this.schemaId = '/model/'+this.name
    // set option to perform schema validation on created/update
    this.validateSchema = args.validate === false ? false : true
    // create schema for model
    var schema = this.schemaMeta = {
        id: this.schemaId,
        properties: {},
        required: [],
        type: 'object',
    }
    // get data column
    var dataColumn = this.columnName('data')
    // create entry in schema for data if model has data
    if (dataColumn) {
        // schema id for data only
        this.schemaDataId = '/model/'+this.name+'/data'
        // create data schema - meta and data schemas are compiled without
        // ref so that the complete schemas can be easily sent to clients
        var schemaData = this.schemaData = schema.properties[dataColumn] = {
            additionalProperties: args.additionalProperties,
            id: this.schemaDataId,
            properties: {},
            type: 'object',
        }
        // merge schema from args over data schema
        _.merge(schemaData.properties, args.properties)
        // if required properties are set then add
        if (args.required) {
            // required must be array
            if (typeof args.required === 'string') {
                args.required = [args.required]
            }
            // throw error if not array
            assert.ok(Array.isArray(args.required), 'required must be array or string')
            // add list of required properties
            schemaData.required = args.required
        }
        // add data schema
        validator.addSchema(schemaData, this.schemaDataId)
    }
    // create schema for each default column
    _.each(this.defaultColumns, (defaultName, columnName) => {
        // skip data column which is already specified
        if (defaultName === 'data') {
            return
        }
        // get column spec
        var column = this.columns[columnName]
        // if there is not schema for type then skip
        if (!defaultSchemas[column.type]) {
            return
        }
        // get column schema
        var columnSchema = _.cloneDeep(defaultSchemas[column.type])
        // set default schema based on type
        schema.properties[columnName] = columnSchema
        // make property required unless nullable
        if (column.null === false) {
            schema.required.push(columnName)
        }
    })
    // add schema
    validator.addSchema(schema, this.schemaId)
}
1277259
function validateReturn (ret, methodMeta) {
    // do not validate if no schema
    if (!defined(methodMeta.schema.return)) {
        return ret
    }
    // do not validate if disabled
    if (!methodMeta.validateReturn) {
        return ret
    }
    // get validator
    var ajv = methodMeta.ajv
    // throw error if validation fails
    if (!ajv.validate(methodMeta.schema.return.id, ret)) {
        // create error
        var error = new Error(`${methodMeta.signature}: invalid return - ${ajv.errorsText()}`)
        // add ajv errors to error data
        error.data = ajv.errors
        // throw error
        throw error
    }
    // return possibly modified result
    return ret
}
1295455
function AposSchemas() {
  var self = this;

  // Populate form elements corresponding to a set of fields as
  // specified in a schema (the schema argument). The inverse of
  // self.convertSomeFields
  self.populateFields = function($el, schema, snippet, callback) {
    schema = self.allowedSubset($el, schema);

    return async.eachSeries(schema, function(field, callback) {

      // Utilized by simple displayers that use a simple HTML
      // element with a name attribute
      var $field = self.findField($el, field.name);

      if (field.contextual) {
        return apos.afterYield(callback);
      }

      var displayer = self.displayers[field.type];

      return displayer(snippet, field.name, $field, $el, field, function() {
        if (field.autocomplete === false) {
          $field.attr('autocomplete', 'off');
        }
        if(field.required === true) {
          self.addError($el, field.name, true, true);
        }
        return apos.afterYield(callback);
      });

    }, afterPopulateFields);

    function afterPopulateFields() {
      callback(null);
    }
  };

  // Gather data from form elements and push it into properties of the data object,
  // as specified by the schema provided. The inverse of self.populateFields
  self.convertFields = function($el, schema, data, callback) {
    schema = self.allowedSubset($el, schema);

    self.findSafe($el, '[data-name]').removeClass('apos-error').removeClass('apos-error-required').removeClass('apos-error-in-advance').find('.apos-error-message').remove();
    var failing;

    // async for loop
    var i = 0;
    function convertField() {
      if (i === schema.length) {
        return apos.afterYield(_.partial(callback, failing));
      }
      var field = schema[i];
      if (field.contextual) {
        i++;
        return apos.afterYield(convertField);
      }
      // This won't be enough for every type of field, so we pass $el too
      var $field = self.findField($el, field.name);
      if (!$field.length) {
        $field = self.findField($el, field.legacy);
      }
      var $fieldset = self.findFieldset($el, field.name);
      if ($fieldset.hasClass('apos-hidden')) {
        // If this field is hidden, it is not reasonable to
        // expect the user to populate it. This allows "required"
        // and "showFields" to interact in a reasonable way. -Tom
        i++;
        return apos.afterYield(convertField);
      }
      return self.converters[field.type](data, field.name, $field, $el, field, function(err) {
        if (err) {
          self.addError($el, field.name, field.required);
          failing = field;
        }
        i++;
        return apos.afterYield(convertField);
      });
    }
    convertField();
  };

  self.allowedSubset = function($el, schema) {
    return _.filter(schema, function(field) {
      if (!field.permission) {
        return true;
      }

      if(apos.data.permissions[field.permission] || apos.data.permissions.admin) {
        return true;
      }

      var $fieldset = self.findFieldset($el, field.name);
      $fieldset.addClass('apos-schemas-restricted');
      return false;
    });
  };

  self.enableSingleton = function($el, name, area, type, optionsArg, callback) {
    if (typeof(optionsArg) === 'function') {
      callback = optionsArg;
      optionsArg = {};
    }
    var items = [];
    if (area && area.items) {
      items = area.items;
    }

    var options = {};
    $.extend(options, optionsArg);
    $.extend(options, {
      type: type
    });

    var $fieldset = self.findFieldset($el, name);
    refreshSingleton(items, callback);

    function refreshSingleton(items, callback) {
      options.content = items;
      $.jsonCall('/apos/edit-virtual-singleton', { dataType: 'html' }, options, function(data) {
        var $editView = self.findSafe($fieldset, '[data-' + name + '-edit-view]');
        $editView.html('');
        $editView.append(data);
        // Make sure slideshows, videos, etc. get their JS
        apos.enablePlayers($editView);

        // getSingleton will pick it up from here
        $editView.data('items', items);

        // If an edit takes place, refresh so we can see the new preview here
        // in the form. This isn't an issue with areas since they are always
        // in the edit state in a form. TODO: consider whether it would be
        // better to create a container that allows widgets to be rendered
        // inline, without a nested dialog box

        var $singleton = self.findSafe($editView, '.apos-singleton:first');
        $singleton.on('aposEdited', function(e, data) {
          refreshSingleton([data], function() {
            // A change event on the singleton's wrapper signifies
            // that getSingleton can now be
            // called to see the new data
            $fieldset.trigger('change');
          });
        });

        if (callback) {
          return callback(null);
        }
      });
    }
  };

  // options argument may be skipped
  self.enableArea = function($el, name, area, options, callback) {
    if (!callback) {
      callback = options;
      options = {};
    }
    var items = [];
    if (area && area.items) {
      items = area.items;
    }
    var $fieldset = self.findFieldset($el, name);
    $.jsonCall('/apos/edit-virtual-area',
      { dataType: 'html' },
      { content: items, options: options }, function(data) {
      var $editView = self.findSafe($fieldset, '[data-' + name + '-edit-view]');
      $editView.append(data);
      // Make sure slideshows, videos, etc. get their JS
      apos.enablePlayers($editView);
      return callback(null);
    });
  };

  // Retrieve a JSON-friendly serialization of the singleton
  self.getSingleton = function($el, name) {
    var $fieldset = self.findFieldset($el, name);
    var items = self.findSafe($fieldset, '[data-' + name + '-edit-view]').data('items');
    items = items || [];
    return items;
  };

  // Retrieve a JSON-friendly serialization of the area
  self.getArea = function($el, name) {
    var $fieldset = self.findFieldset($el, name);
    var $property = self.findSafe($fieldset, '[data-' + name + '-edit-view]');
    return $property.find('.apos-area:first').data('editor').serialize();
  };

  // Methods to convert from a form field of each schema type
  // to a property of the snippet ready to save. The server does
  // all the validation of course, since you can't trust a browser
  // anyway, so this is mostly simple except where the representation
  // in the form differs greatly from the representation the server wants
  self.converters = {
    // Convert the tough cases
    area: function(data, name, $field, $el, field, callback) {
      data[name] = self.getArea($el, name);

      if (field.required && (apos.areaIsEmpty(data[name]))) {
        return apos.afterYield(_.partial(callback, 'required'));
      }
      return apos.afterYield(callback);
    },
    singleton: function(data, name, $field, $el, field, callback) {
      data[name] = self.getSingleton($el, name);
      if (field.required && (apos.singletonIsEmpty(data[name], field.type))) {
        return apos.afterYield(_.partial(callback, 'required'));
      }
      return apos.afterYield(callback);
    },
    array: function(data, name, $field, $el, field, callback) {
      var results = [];
      var $fieldset = self.findFieldset($el, name);
      var $elements = self.findSafe($fieldset, '[data-element]:not(.apos-template)');

      var i = 0;

      var err;

      function convertElement() {
        if (i === $elements.length) {
          data[name] = results;
          return apos.afterYield(_.partial(callback, err));
        }
        var result = {};
        var $element = $($elements[i]);
        result.id = $element.attr('data-id');
        return self.convertFields($element, field.schema, result, function(_err) {
          if (_err) {
            err = _err;
          }
          results.push(result);
          i++;
          return apos.afterYield(convertElement);
        });
      }

      convertElement();
    },
    joinByOne: function(data, name, $field, $el, field, callback) {
      // Fix $field since we can't use the regular name attribute here
      $field = self.findSafe($el, '[data-name="' + name + '"]');
      data[field.idField] = $field.selective('get', { incomplete: true })[0];
      if (field.required && (!data[field.idField])) {
        return apos.afterYield(_.partial(callback, 'required'));
      }
      return apos.afterYield(callback);
    },
    joinByOneReverse: function(data, name, $field, $el, field, callback) {
      // Not edited on this side of the relation
      return apos.afterYield(callback);
    },
    joinByArray: function(data, name, $field, $el, field, callback) {
      // Fix $field since we can't use the regular name attribute here
      $field = self.findSafe($el, '[data-name="' + name + '"]');
      $field.off('afterGetItem');
      // Implement custom relationship field types (tags)
      $field.on('afterGetItem', function(e, item, $item) {
        _.each(field.relationship || [], function(field) {
          if (field.type === 'tags') {
            var $tags = $item.findSafe('[data-name="' + field.name + '"]', '[data-selective]');
            item[field.name] = $tags.selective('get');
          }
        });
      });

      var info = $field.selective('get', { incomplete: true });
      if (field.relationshipsField) {
        data[field.idsField] = _.pluck(info, 'value');
        data[field.relationshipsField] = {};
        var relationship = {};
        _.each(info, function(e) {
          relationship[e.value] = _.omit(e, [ 'value', 'label' ]);
        });
        data[field.relationshipsField] = relationship;
      } else {
        data[field.idsField] = info;
      }
      if (field.required && !data[field.idsField].length) {
        return apos.afterYield(function() {
          return apos.afterYield(_.partial(callback, 'required'));
        });
      }
      return apos.afterYield(callback);
    },
    joinByArrayReverse: function(data, name, $field, $el, field, callback) {
      // Not edited on this side of the relation
      return apos.afterYield(callback);
    },
    group: function(data, name, $field, $el, field, callback) {
      // Just a presentation thing
      return apos.afterYield(callback);
    },
    // The rest are very simple because the server does
    // the serious sanitization work and the representation in the DOM
    // is a simple form element
    string: function(data, name, $field, $el, field, callback) {
      data[name] = $field.val();
      if (field.required && !data[name].length) {
        return apos.afterYield(_.partial(callback, 'required'));
      }
      if (field.max && (data[name].length > field.max)) {
        var $fieldset = self.findFieldset($el, name);
        $fieldset.addClass('apos-error-max');
        return apos.afterYield(_.partial(callback, 'max'));
      }
      return apos.afterYield(callback);
    },
    password: function(data, name, $field, $el, field, callback) {
      data[name] = $field.val();
      if (field.required && !data[name].length) {
        return apos.afterYield(_.partial(callback, 'required'));
      }
      return apos.afterYield(callback);
    },
    slug: function(data, name, $field, $el, field, callback) {
      data[name] = $field.val();
      if (field.required && !data[name].length) {
        return apos.afterYield(_.partial(callback, 'required'));
      }
      return apos.afterYield(callback);
    },
    tags: function(data, name, $field, $el, field, callback) {
      data[name] = self.findSafe($el, '[data-name="' + name + '"]').selective('get', { incomplete: true });
      if (field.required && !data[name].length) {
        return apos.afterYield(_.partial(callback, 'required'));
      }
      return apos.afterYield(callback);
    },
    boolean: function(data, name, $field, $el, field, callback) {
      if (field.checkbox) {
        data[name] = $field.prop('checked');
      } else {
        data[name] = $field.val();
      }
      // Seems odd but sometimes used to mandate an "I agree" box
      if (field.required && !data[name]) {
        return apos.afterYield(_.partial(callback, 'required'));
      }
      return apos.afterYield(callback);
    },
    checkboxes: function(data, name, $field, $el, field, callback) {
      var values = [];
      for (var c in field.choices) {
        var val = field.choices[c].value;
        var checked = $field.filter('[value="'+val+'"]').prop('checked');
        if (checked) {
          values.push(val);
        }
      }
      data[name] = values;
      if (field.required && (!data[name].length)) {
        return apos.afterYield(_.partial(callback, 'required'));
      }
      return apos.afterYield(callback);
    },
    select: function(data, name, $field, $el, field, callback) {
      data[name] = $field.val();
      if (field.required && !data[name].length) {
        return apos.afterYield(_.partial(callback, 'required'));
      }
      return apos.afterYield(callback);
    },
    integer: function(data, name, $field, $el, field, callback) {
      data[name] = $field.val();
      if (field.required && !data[name].length) {
        return apos.afterYield(_.partial(callback, 'required'));
      }
      return apos.afterYield(callback);
    },
    float: function(data, name, $field, $el, field, callback) {
      data[name] = $field.val();
      if (field.required && !data[name].length) {
        return apos.afterYield(_.partial(callback, 'required'));
      }
      return apos.afterYield(callback);
    },
    url: function(data, name, $field, $el, field, callback) {
      data[name] = $field.val();
      if (field.required && !data[name].length) {
        return apos.afterYield(_.partial(callback, 'required'));
      }
      return apos.afterYield(callback);
    },
    date: function(data, name, $field, $el, field, callback) {
      var $fieldset;
      if (field.select) {
        $fieldset = self.findFieldset($el, name);
        var year = $fieldset.find('[data-component="year"]').val();
        var month = $fieldset.find('[data-component="month"]').val();
        var day = $fieldset.find('[data-component="day"]').val();
        if (!(year || month || day)) {
          if (field.required) {
            return apos.afterYield(_.partial(callback, 'required'));
          }
          data[name] = '';
          return apos.afterYield(callback);
        }
        if (!(year && month && day)) {
          // You can't pick only *some* of the fields
          return apos.afterYield(_.partial(callback, 'required'));
        }
        data[name] = year + '-' + month + '-' + day;
        return apos.afterYield(callback);
      } else {
        data[name] = $field.val();
        if (field.required && !data[name].length) {
          return apos.afterYield(_.partial(callback, 'required'));
        }
        return apos.afterYield(callback);
      }
    },
    time: function(data, name, $field, $el, field, callback) {
      data[name] = $field.val();
      if (field.required && !data[name].length) {
        return apos.afterYield(_.partial(callback, 'required'));
      }
      return apos.afterYield(callback);
    },
  };

  // Methods to display all of the field types supported by the schema
  self.displayers = {
    area: function(data, name, $field, $el, field, callback) {
      return self.enableArea($el, name, data[name], field.options || {}, callback);
    },
    singleton: function(data, name, $field, $el, field, callback) {
      return self.enableSingleton($el, name, data[name], field.widgetType, field.options || {}, callback);
    },
    array: function(data, name, $field, $el, field, callback) {
      var $fieldset = self.findFieldset($el, name);
      var $template = self.findSafe($fieldset, '.apos-template[data-element]');

      var $add = self.findSafe($fieldset, '[data-add]');
      var $elements = self.findSafe($fieldset, '[data-elements]');

      // Add the elements via an async for loop without
      // the async module. -Tom

      var i = 0;
      data = data[name] || [];
      function nextElement() {
        if (i === data.length) {
          $elements.sortable({ handle: '[data-move]' });
          return callback(null);
        }
        var $element = $template.clone();
        $element.removeClass('apos-template');
        addRemoveHandler($element);
        addMoveHandler($element);

        // If the minimize option is passed to an array schema field, it
        // will automatically hide all element fields except for the first
        // one. The other fields will be revealed upon toggling the '+'
        // button or focussing the first field.
        if (field.minimize) {
          addOpenHandler($element);
          // Default state for existing elements is closed
          toggleOpen($element, self.findSafe($element, '[data-open-item]'), false);
        } else {
          alwaysOpen($element);
        }

        $element.attr('data-id', data[i].id);

        $elements.append($element);
        return self.populateFields($element, field.schema, data[i], function() {
          i++;
          return nextElement();
        });
      }
      nextElement();

      $add.on('click', function() {
        var $element = $template.clone();
        $element.removeClass('apos-template');
        $elements.prepend($element);
        addRemoveHandler($element);
        addMoveHandler($element);

        if (field.minimize) {
          addOpenHandler($element);
          // Default state for new elements is expanded
          toggleOpen($element, self.findSafe($element, '[data-open-item]'), true);
        } else {
          alwaysOpen($element);
        }

        var element = {};
        _.each(field.schema, function(field) {
          if (field.def !== undefined) {
            element[field.name] = field.def;
          }
        });

        self.populateFields($element, field.schema, element, function() {
          // Make sure lister gets a crack
          apos.emit('enhance', $element);
        });
        return false;
      });

      function addRemoveHandler($element) {
        var $remove = self.findSafe($element, '[data-remove]');
        $remove.on('click', function() {
          $element.remove();
          return false;
        });
      }

      function addMoveHandler($element) {
        var $move = self.findSafe($element, '[data-move-item]');
        $move.on('click', function() {
          if ($(this).attr('data-move-item') === 'up') {
            $element.prev().before($element);
          } else {
            $element.next().after($element);
          }
          return false;
        });
      }

      function addOpenHandler($element) {
        var $open = self.findSafe($element, '[data-open-item]');
        $open.on('click', function() {
          toggleOpen($element, $(this));
          return false;
        });
      }

      function toggleOpen($element, $open, state) {
        var expanded = _.isBoolean(state) ? state : undefined
        $element.toggleClass('apos-array-item--open', expanded);
        self.findSafe($open, 'i').toggleClass('icon-minus', expanded);
        self.findSafe($element, '[data-name]:first-of-type input').focus(function() {
          toggleOpen($element, $open, true);
        });
      }

      function alwaysOpen($element) {
        var $open = self.findSafe($element, '[data-open-item]');
        toggleOpen($element, self.findSafe($element, '[data-open-item]'), true);
        $open.hide();
      }

    },
    string: function(data, name, $field, $el, field, callback) {
      $field.val(data[name]);
      if (field.max) {
        if (field.textarea) {
          if (field.max) {
            var $fieldset = self.findFieldset($el, name);
            $fieldset.removeClass('apos-error-max');
            $field.off('textchange.schema');
            $field.on('textchange.schema', function() {
              var length = $field.val().length;
              if (length > field.max) {
                $fieldset.addClass('apos-error-max');
              } else {
                $fieldset.removeClass('apos-error-max');
              }
            });
          }
        } else {
          $field.attr('maxlength', field.max);
        }
      }
      return apos.afterYield(callback);
    },
    password: function(data, name, $field, $el, field, callback) {
      $field.val(data[name]);
      return apos.afterYield(callback);
    },
    slug: function(data, name, $field, $el, field, callback) {
      $field.val(data[name]);
      return apos.afterYield(callback);
    },
    tags: function(data, name, $field, $el, field, callback) {
      apos.enableTags(self.findSafe($el, '[data-name="' + name + '"]'), data[name], field || {});
      return apos.afterYield(callback);
    },
    url: function(data, name, $field, $el, field, callback) {
      $field.val(data[name]);
      return apos.afterYield(callback);
    },
    checkboxes: function(data, name, $field, $el, field, callback) {
      for(var c in data[name]) {
        $el.find('input[name="'+name+'"][value="'+data[name][c]+'"]').prop('checked', true);
      }
      return apos.afterYield(callback);
    },

    select: function(data, name, $field, $el, field, callback) {

      var $fieldset = self.findFieldset($el, name);
      var $options = $field.find('option');
      // Synthesize options from the choices in the schema, unless
      // the frontend developer has chosen to do it for us
      if (!$options.length) {
        _.each(field.choices, function(choice) {
          var $option = $('<option></option>');
          $option.text(choice.label);
          $option.attr('value', choice.value);
          $field.append($option);
        });
      }

      // Set the default value, taking selectize into account, ugh
      var val = ((data[name] === undefined) && field.choices[0]) ? field.choices[0].value : data[name];
      if ($field[0] && $field[0].selectize) {
       $field[0].selectize.setValue(val);
      } else {
       $field.val(val);
      }

      self.enableShowFields(data, name, $field, $el, field);
      return apos.afterYield(callback);
    },

    integer: function(data, name, $field, $el, field, callback) {
      $field.val(data[name]);
      return apos.afterYield(callback);
    },
    float: function(data, name, $field, $el, field, callback) {
      $field.val(data[name]);
      return apos.afterYield(callback);
    },
    boolean: function(data, name, $field, $el, field, callback) {
      if (field.checkbox) {
        $field.prop('checked', data[name]);
      } else {
        $field.val(data[name] ? '1' : '0');
      }

      self.enableShowFields(data, name, $field, $el, field);
      return apos.afterYield(callback);
    },
    joinByOne: function(data, name, $field, $el, field, callback) {
      // Since we can't use a regular name attribute for a div
      $field = self.findSafe($el, '[data-name="' + name + '"]');
      if (!$field.length) {
        apos.log('Error: your new.html template for the ' + self.name + ' module does not have a snippetSelective call for the ' + name + ' join yet');
      }
      var selectiveData = [];
      var id = data[field.idField];
      if (id) {
        // Let jQuery selective call back for the details
        selectiveData.push(id);
      }
      // For now this is still correct on the browser side, getManager
      // always returns undefined for an index type
      var manager = aposPages.getManager(field.withType);
      var autocomplete = '/apos-pages/autocomplete?type=' + field.withType;
      if (manager) {
        autocomplete = manager._action + '/autocomplete';
      }
      $field.selective({ limit: 1, data: selectiveData, source: autocomplete, nestGuard: '[data-selective]' });

      self.enhanceSelectiveWithSlugs($field);
      return apos.afterYield(callback);
    },
    joinByOneReverse: function(data, name, $field, $el, field, callback) {
      // Not edited on the reverse side
      return apos.afterYield(callback);
    },
    joinByArray: function(data, name, $field, $el, field, callback) {
      // Since we can't use a regular name attribute for a div
      $field = self.findSafe($el, '[data-name="' + name + '"]');
      if (!$field.length) {
        apos.log('Error: your new.html template for the ' + self.name + ' module does not have a snippetSelective call for the ' + name + ' join yet');
      }

      // Implement custom relationship field types (tags)
      $field.off('afterAddItem');
      $field.on('afterAddItem', function(e, item, $item) {
        apos.emit('enhance', $item);
        _.each(field.relationship || [], function(field) {
          if (field.type === 'tags') {
            var $tags = $item.findSafe('[data-name="' + field.name + '"]', '[data-selective]');
            apos.enableTags($tags, item[field.name] || []);
          }
        });
      });

      var selectiveData = [];

      // For now this is still correct on the browser side, getManager
      // always returns undefined for an index type
      var manager = aposPages.getManager(field.withType);
      var autocomplete = '/apos-pages/autocomplete?type=' + field.withType;
      if (manager) {
        autocomplete = manager._action + '/autocomplete';
      }

      // The server knows the title of the joined things, while we know
      // about our relationship properties. Solve the puzzle by
      // passing selective plain old IDs, causing it to call back to its
      // source for the corresponding labels. Provide a custom source
      // that queries the server and then merges in the relationship fields.
      if (field.relationshipsField) {
        var url = autocomplete;
        autocomplete = function(req, callback) {
          $.getJSON(url, req, function(results) {
            // This gives us "label" and "value", add the
            // relationship info and invoke the original callback
            _.each(results, function(result) {
              var relationship = data[field.relationshipsField] && data[field.relationshipsField][result.value];
              if (relationship) {
                _.extend(result, relationship);
                _.each(field.relationship, function(relField) {
                  if (relField.type === 'boolean') {
                    // Fix booleans to work as select elements expect
                    result[relField.name] = result[relField.name] ? '1' : '0';
                  }
                });
              }
            });
            return callback(results);
          });
        };
      }
      var selectiveOptions = {
        preventDuplicates: true,
        sortable: field.sortable,
        extras: !!field.relationship,
        data: data[field.idsField] || [],
        source: autocomplete,
        nestGuard: '[data-selective]'
      };
      if (field.limit !== undefined) {
        selectiveOptions.limit = field.limit;
      }
      $field.selective(selectiveOptions);
      self.enhanceSelectiveWithSlugs($field);
      return apos.afterYield(callback);
    },
    joinByArrayReverse: function(data, name, $field, $el, field, callback) {
      // Not edited on the reverse side
      return apos.afterYield(callback);
    },
    group: function(data, name, $field, $el, field, callback) {
      // Just a presentation thing
      return apos.afterYield(callback);
    },
    date: function(data, name, $field, $el, field, callback) {
      var $fieldset;
      if (field.select) {
        $fieldset = self.findFieldset($el, name);
        var current = data[name];
        var components;
        var year, month, day;
        if (typeof(current) === 'string') {
          components = current.split(/\-/);
          year = components[0];
          month = components[1];
          day = components[2];
          $fieldset.find('[data-component="year"]').val(year);
          $fieldset.find('[data-component="month"]').val(month);
          $fieldset.find('[data-component="day"]').val(day);
        }
      } else {
        $field.val(data[name]);
        apos.enhanceDate($field);
        if (field.legacy) {
          apos.enhanceDate(self.findField($el, field.legacy));
        }
      }
      return apos.afterYield(callback);
    },
    time: function(data, name, $field, $el, field, callback) {
      if (data[name] && data[name].length) {
        // Revert to local time for editing
        $field.val(apos.formatTime(data[name]));
      }
      return apos.afterYield(callback);
    },
  };

  self.addFieldType = function(type) {
    self.displayers[type.name] = type.displayer;
    self.converters[type.name] = type.converter;
  };

  // A convenience method for calling attention to errors in fields in your own
  // independent validation code.

  self.addError = function($el, name, required, inAdvance) {
    var $fieldset = self.findFieldset($el, name);
    $fieldset.addClass('apos-error');
    if (required === true) {
      $fieldset.addClass('apos-error-required');
      self.findSafe($el, '[data-name="' + name + '"]').find('label').append('<span class="apos-error-message"> * required</span>');
    }
    if (inAdvance) {
      $fieldset.addClass('apos-error-in-advance');
    }
  };

  // A convenience allowing you to scroll to the first error present,
  // if any. Not called automatically. You can call this when
  // convertFields passes an error or when your own validation code
  // has invoked addError().

  self.scrollToError = function($el) {
    // Awesome plugin

    var $element = self.findSafe($el, '.apos-error');
    if (!$element.is(':visible')) {
      // Make sure parent tab is active
      var tabId = $element.closest('[data-tab-id]').attr('data-tab-id');
      if (tabId) {
        apos.activateTab($element, tabId);
      }
    }
    $element.scrollintoview();
    $element.find('input,select,textarea').first().focus();
  };

  // Used to search for fieldsets at this level of the schema,
  // without false positives for any schemas nested within it
  self.findFieldset = function($el, name) {
    return self.findSafe($el, '[data-name="' + name + '"]');
  };

  // Used to search for elements without false positives from nested
  // schemas in unrelated fieldsets
  self.findSafe = function($el, sel) {
    return $el.findSafe(sel, '.apos-fieldset');
  };

  // Used to search for simple elements that have a
  // "name" attribute, without false positives from nested
  // schemas in unrelated fieldsets.
  self.findField = function($el, name) {
    var $fieldset = self.findFieldset($el, name);
    return self.findSafe($fieldset, '[name="' + name + '"]');
  };

  self.enhanceSelectiveWithSlugs = function($field) {
    // Change the presentation to include the slug.
    // Based on: http://jqueryui.com/autocomplete/#custom-data
    // I stuck with that markup with a minimum of new markup to
    // allow styling. -Tom
    var $autocomplete = self.findSafe($field, "[data-autocomplete]");
    $autocomplete.data( "ui-autocomplete" )._renderItem = function(ul, item) {
      var inner = '<a><div class="apos-autocomplete-label">' + item.label + '</div>';
      if (item.slug) {
        inner += '<div class="apos-autocomplete-slug">' + item.slug + '</div>';
      }
      inner += '</a>';
      return $('<li class="apos-autocomplete-item">')
        .append(inner)
        .appendTo(ul);
    };
  };

  self.newInstance = function(schema) {
    var def = {};
    _.each(schema, function(field) {
      if (field.def !== undefined) {
        def[field.name] = field.def;
      }
    });
    return def;
  };

  // Enable the showFields option for the choices associated
  // with the given field (boolean or select)

  self.enableShowFields = function(data, name, $field, $el, field) {

    var $fieldset = self.findFieldset($el, name);

    // afterChange shows and hides other fieldsets based on
    // the current value of this field and its visibility.
    // We do this in three situations: at startup, when the
    // user changes the value, and when the visibility of this
    // field has been affected by another field with the
    // showFields option. This allows nested showFields to
    // work properly. -Tom

    afterChange();

    $field.on('change', afterChange);
    $fieldset.on('aposShowFields', afterChange);

    function afterChange() {

      // Implement showFields

      if (!_.find(field.choices || [], function(choice) {
        return choice.showFields;
      })) {
        // showFields is not in use for this select
        return;
      }

      var val;
      if (field.checkbox) {
        val = $field.is(':checked');
      } else {
        val = $field.val();
      }

      var allShowFields = {};

      _.each(field.choices || [], function(choice) {

        // Show the fields for this value if it is the current value
        // *and* the select field itself is currently visible

        var show;

        if ($fieldset.hasClass('apos-hidden')) {
          show = false;
        } else if (field.type === 'boolean') {
          // Comparing boolean values is hard because
          // the string '0' must be considered falsy in
          // order to permit use of select elements. -Tom
          if (val === choice.value) {
            show = true;
          } else if (!choice.value) {
            if ((!val) || (val === '0')) {
              show = true;
            }
          } else {
            if (val && (val !== '0')) {
              show = true;
            }
          }
        } else {
          // type select
          if (val === choice.value) {
            show = true;
          }
        }

        _.each(choice.showFields || [], function(fieldName) {
          if (!_.has(allShowFields, fieldName)) {
            allShowFields[fieldName] = false;
          }
          allShowFields[fieldName] = allShowFields[fieldName] || show;
        });

      });

      _.each(allShowFields, function(val, key) {
        var $fieldset = self.findFieldset($el, key);
        $fieldset.toggleClass('apos-hidden', !val);
        $fieldset.trigger('aposShowFields');
        var $helpText = $fieldset.next('p.apos-help');
        $helpText.toggleClass('apos-hidden', !val);
      });

    }
  };
}
535350
function wrapper(node, schema) {

    // NODES['*'] = xtend(NODES['*'], schema.NODES['*']);
    // delete schema.NODES;

    var ctx = {type: 'root', children: []}
    var replace

    if (!node || typeof node !== 'object' || !node.type) {
        return ctx
    }

    replace = one(xtend(defaults, schema || {}), node, [])

    if (!replace) {
        return ctx
    }

    if ('length' in replace) {
        if (replace.length === 1) {
            return replace[0]
        }

        ctx.children = replace

        return ctx
    }

    return replace
}
1221948
function getValidationFunction (validationOptions) {
        validationOptions = validationOptions || {};

        return function (doc, schema, options) {
            doc = doc || {};
            options = options || {};
            options.isUpdate = options.isUpdate || false;

            // check is update
            if (options.isUpdate) {
                var i,
                    keys = Object.keys(schema.properties),
                    length = keys.length;

                for (i = 0; i < length; i++) {
                    if (!doc.hasOwnProperty(keys[i])) {
                        // set property required to false
                        schema.properties[keys[i]].required = false;

                        // remove property from required array
                        if (Array.isArray(schema.required) && schema.required.indexOf(keys[i]) > -1) {
                            schema.required.splice(schema.required.indexOf(keys[i]), 1);
                        }
                    }
                }
            }

            // add default validation options to options object
            for (var key in validationOptions) {
                // only add options, do not override
                if (validationOptions.hasOwnProperty(key) && !options.hasOwnProperty(key)) {
                    options[key] = validationOptions[key];
                }
            }

            // json schema validate
            return exports.validate(doc, schema, options);
        };
    }
726584
async function validate(descriptor) {
  const {valid, errors} = await Schema.load(descriptor)
  return {valid, errors}
}
1179371
function schemaRequiresTrueValue(schema) {
  // Check if const is a truthy value
  if (schema.const) {
    return true;
  }

  // Check if an enum has a single value of true
  if (schema.enum && schema.enum.length === 1 && schema.enum[0] === true) {
    return true;
  }

  // If anyOf has a single value, evaluate the subschema
  if (schema.anyOf && schema.anyOf.length === 1) {
    return schemaRequiresTrueValue(schema.anyOf[0]);
  }

  // If oneOf has a single value, evaluate the subschema
  if (schema.oneOf && schema.oneOf.length === 1) {
    return schemaRequiresTrueValue(schema.oneOf[0]);
  }

  // Evaluate each subschema in allOf, to see if one of them requires a true
  // value
  if (schema.allOf) {
    return schema.allOf.some(schemaRequiresTrueValue);
  }
}