| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 | 'use strict';var IDENTIFIER = /^[a-z_$][a-z0-9_$\-]*$/i;var customRuleCode = require('./dotjs/custom');module.exports = {  add: addKeyword,  get: getKeyword,  remove: removeKeyword};/** * 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`. */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) {    if (definition.macro && definition.valid !== undefined)      throw new Error('"valid" option cannot be used with macro keywords');    var dataType = definition.type;    if (Array.isArray(dataType)) {      var i, len = dataType.length;      for (i=0; i<len; i++) checkDataType(dataType[i]);      for (i=0; i<len; i++) _addRule(keyword, dataType[i], definition);    } else {      if (dataType) checkDataType(dataType);      _addRule(keyword, dataType, definition);    }    var $data = definition.$data === true && this._opts.v5;    if ($data && !definition.validate)      throw new Error('$data support: "validate" function is not defined');    var metaSchema = definition.metaSchema;    if (metaSchema) {      if ($data) {        metaSchema = {          anyOf: [            metaSchema,            { '$ref': 'https://raw.githubusercontent.com/epoberezkin/ajv/master/lib/refs/json-schema-v5.json#/definitions/$data' }          ]        };      }      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    };    ruleGroup.rules.push(rule);    RULES.custom[keyword] = rule;  }  function checkDataType(dataType) {    if (!RULES.types[dataType]) throw new Error('Unknown type ' + dataType);  }}/** * 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. */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;      }    }  }}
 |