| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 | 'use strict';var IDENTIFIER = /^[a-z_$][a-z0-9_$-]*$/i;var customRuleCode = require('./dotjs/custom');var definitionSchema = require('./definition_schema');module.exports = {  add: addKeyword,  get: getKeyword,  remove: removeKeyword,  validate: validateKeyword};/** * Define custom keyword * @this  Ajv * @param {String} keyword custom keyword, should be unique (including different from all standard, custom and macro keywords). * @param {Object} definition keyword definition object with properties `type` (type(s) which the keyword applies to), `validate` or `compile`. * @return {Ajv} this for method chaining */function addKeyword(keyword, definition) {  /* jshint validthis: true */  /* eslint no-shadow: 0 */  var RULES = this.RULES;  if (RULES.keywords[keyword])    throw new Error('Keyword ' + keyword + ' is already defined');  if (!IDENTIFIER.test(keyword))    throw new Error('Keyword ' + keyword + ' is not a valid identifier');  if (definition) {    this.validateKeyword(definition, true);    var dataType = definition.type;    if (Array.isArray(dataType)) {      for (var i=0; i<dataType.length; i++)        _addRule(keyword, dataType[i], definition);    } else {      _addRule(keyword, dataType, definition);    }    var metaSchema = definition.metaSchema;    if (metaSchema) {      if (definition.$data && this._opts.$data) {        metaSchema = {          anyOf: [            metaSchema,            { '$ref': 'https://raw.githubusercontent.com/ajv-validator/ajv/master/lib/refs/data.json#' }          ]        };      }      definition.validateSchema = this.compile(metaSchema, true);    }  }  RULES.keywords[keyword] = RULES.all[keyword] = true;  function _addRule(keyword, dataType, definition) {    var ruleGroup;    for (var i=0; i<RULES.length; i++) {      var rg = RULES[i];      if (rg.type == dataType) {        ruleGroup = rg;        break;      }    }    if (!ruleGroup) {      ruleGroup = { type: dataType, rules: [] };      RULES.push(ruleGroup);    }    var rule = {      keyword: keyword,      definition: definition,      custom: true,      code: customRuleCode,      implements: definition.implements    };    ruleGroup.rules.push(rule);    RULES.custom[keyword] = rule;  }  return this;}/** * Get keyword * @this  Ajv * @param {String} keyword pre-defined or custom keyword. * @return {Object|Boolean} custom keyword definition, `true` if it is a predefined keyword, `false` otherwise. */function getKeyword(keyword) {  /* jshint validthis: true */  var rule = this.RULES.custom[keyword];  return rule ? rule.definition : this.RULES.keywords[keyword] || false;}/** * Remove keyword * @this  Ajv * @param {String} keyword pre-defined or custom keyword. * @return {Ajv} this for method chaining */function removeKeyword(keyword) {  /* jshint validthis: true */  var RULES = this.RULES;  delete RULES.keywords[keyword];  delete RULES.all[keyword];  delete RULES.custom[keyword];  for (var i=0; i<RULES.length; i++) {    var rules = RULES[i].rules;    for (var j=0; j<rules.length; j++) {      if (rules[j].keyword == keyword) {        rules.splice(j, 1);        break;      }    }  }  return this;}/** * Validate keyword definition * @this  Ajv * @param {Object} definition keyword definition object. * @param {Boolean} throwError true to throw exception if definition is invalid * @return {boolean} validation result */function validateKeyword(definition, throwError) {  validateKeyword.errors = null;  var v = this._validateKeyword = this._validateKeyword                                  || this.compile(definitionSchema, true);  if (v(definition)) return true;  validateKeyword.errors = v.errors;  if (throwError)    throw new Error('custom keyword definition is invalid: '  + this.errorsText(v.errors));  else    return false;}
 |