function componentValidator()

in plugins/lib/decl-validator.js [153:220]


  function componentValidator({expects, components, values, replacements}) {
    const matchesCompoundValue = anymatch(values)
    return decl => {
      const {prop, value: compoundValue} = decl
      const parsed = valueParser(compoundValue)
      if (parsed.nodes.length === 1 && matchesCompoundValue(compoundValue)) {
        return {valid: true, errors: []}
      }

      const errors = []

      let fixable = false
      let componentIndex = 0
      for (const [index, node] of Object.entries(parsed.nodes)) {
        if (SKIP_VALUE_NODE_TYPES.has(node.type)) {
          continue
        }

        const value = valueParser.stringify(node)

        let componentProp = components[componentIndex++]
        let validator = getPropValidator(componentProp)
        if (validatorsByReplacementValue.has(value)) {
          validator = validatorsByReplacementValue.get(value)
          componentProp = validator.rule.name
        }

        const nestedProp = `${componentProp} (in ${prop})`
        if (validator) {
          const result = validator.validate({prop: nestedProp, value}, true)
          if (result.replacement) {
            parsed.nodes[index] = {
              type: 'word',
              value: result.replacement
            }
            fixable = true
          }
          for (const error of result.errors) {
            errors.push(error)
          }
        } else {
          errors.push({expects, prop: nestedProp, value})
        }
      }

      let replacement = fixable ? valueParser.stringify(parsed) : undefined

      // if a compound replacement exists, suggest *that* instead
      if (replacement && replacements[replacement]) {
        do {
          replacement = replacements[replacement]
        } while (replacements[replacement])
        return {
          valid: false,
          errors: [{expects, prop, value: compoundValue, replacement}],
          fixable: true,
          replacement
        }
      }

      return {
        valid: errors.length === 0,
        errors,
        fixable,
        replacement
      }
    }
  }