Source: validator.js

/**
 * @namespace validator
 * @memberof module:kdljs
 */

/**
 * @memberof module:kdljs.validator
 * @param {module:kdljs~Document} doc - KDL document
 * @return {boolean}
 */
function validateDocument (doc) {
  return Array.isArray(doc) && doc.every(node => validateNode(node))
}

/**
 * @access private
 * @memberof module:kdljs.validator
 * @param {module:kdljs~Node} node - KDL node
 * @return {boolean}
 */
function validateNode (node) {
  if (typeof node !== 'object') {
    return false
  }

  if (!Object.prototype.hasOwnProperty.call(node, 'name') ||
      typeof node.name !== 'string') {
    return false
  }

  if (!Object.prototype.hasOwnProperty.call(node, 'values') ||
      !Array.isArray(node.values) ||
      !node.values.every(value => validateValue(value))) {
    return false
  }

  if (!Object.prototype.hasOwnProperty.call(node, 'properties') ||
      typeof node.properties !== 'object' ||
      !Object.values(node.properties).every(value => validateValue(value))) {
    return false
  }

  if (!Object.prototype.hasOwnProperty.call(node, 'children') ||
      !validateDocument(node.children)) {
    return false
  }

  if (!Object.prototype.hasOwnProperty.call(node, 'tags') ||
      !validateTags(node.tags)) {
    return false
  }

  return true
}

/**
 * @access private
 * @memberof module:kdljs.validator
 * @param {module:kdljs~NodeTypeAnnotations} tags - KDL node type annotations
 * @return {boolean}
 */
function validateTags (tags) {
  if (typeof tags !== 'object') {
    return false
  }

  if (!Object.prototype.hasOwnProperty.call(tags, 'values') || !Array.isArray(tags.values)) {
    return false
  }

  if (!Object.prototype.hasOwnProperty.call(tags, 'properties') || typeof tags.properties !== 'object') {
    return false
  }

  return true
}

/**
 * @access private
 * @memberof module:kdljs.validator
 * @param {module:kdljs~Value} value - KDL value
 * @return {boolean}
 */
function validateValue (value) {
  const type = typeof value
  return type === 'string' || type === 'number' || type === 'boolean' || value === null
}

module.exports.validateDocument = validateDocument