lib/keyword.js
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/epoberezkin/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;
}
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/epoberezkin/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;
}
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/epoberezkin/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 ; }
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
Define custom keyword