All files destructor.ts

96.25% Statements 77/80
92.31% Branches 24/26
87.5% Functions 14/16
97.26% Lines 71/73

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 1553x                 3x                 3x   13x   3x 254x     3x 20x     3x 99x 99x 18x 18x 31x     31x 31x 31x 13x   31x 31x 31x 31x 20x 8x 8x   12x         20x   31x 8x   23x     18x 81x 17x 17x 28x     28x 28x 28x 21x   28x 28x 28x 28x 13x 7x 7x   6x         13x   28x 7x   21x     17x   64x 20x   44x     3x           28x 28x       3x         13x 13x 13x 5x     13x 30x 30x   13x     3x                   3x           6x 6x      
import {
  Segments,
  Node,
  DestrcutorRules,
  isArrayPattern,
  isObjectPattern,
  isIdentifier,
  isDestructorExpression
} from './types'
import { isNum } from './utils'
 
type Mutatators = {
  getIn: (segments: Segments, source: any) => any
  setIn: (segments: Segments, source: any, value: any) => void
  deleteIn?: (segments: Segments, source: any) => any
  existIn?: (segments: Segments, source: any, start: number) => boolean
}
 
const DestrcutorCache = new Map()
 
const isValid = (val: any) => val !== undefined && val !== null
 
export const getDestructor = (source: string) => {
  return DestrcutorCache.get(source)
}
 
export const setDestructor = (source: string, rules: DestrcutorRules) => {
  DestrcutorCache.set(source, rules)
}
 
export const parseDestructorRules = (node: Node): DestrcutorRules => {
  let rules = []
  if (isObjectPattern(node)) {
    let index = 0
    node.properties.forEach(child => {
      rules[index] = {
        path: []
      }
      rules[index].key = child.key.value
      rules[index].path.push(child.key.value)
      if (isIdentifier(child.value)) {
        rules[index].key = child.value.value
      }
      const basePath = rules[index].path
      const childRules = parseDestructorRules(child.value as Node)
      let k = index
      childRules.forEach(rule => {
        if (rules[k]) {
          rules[k].key = rule.key
          rules[k].path = basePath.concat(rule.path)
        } else {
          rules[k] = {
            key: rule.key,
            path: basePath.concat(rule.path)
          }
        }
        k++
      })
      if (k > index) {
        index = k
      } else {
        index++
      }
    })
    return rules
  } else if (isArrayPattern(node)) {
    let index = 0
    node.elements.forEach((child, key) => {
      rules[index] = {
        path: []
      }
      rules[index].key = key
      rules[index].path.push(key)
      if (isIdentifier(child)) {
        rules[index].key = child.value
      }
      const basePath = rules[index].path
      const childRules = parseDestructorRules(child as Node)
      let k = index
      childRules.forEach(rule => {
        if (rules[k]) {
          rules[k].key = rule.key
          rules[k].path = basePath.concat(rule.path)
        } else {
          rules[k] = {
            key: rule.key,
            path: basePath.concat(rule.path)
          }
        }
        k++
      })
      if (k > index) {
        index = k
      } else {
        index++
      }
    })
    return rules
  }
  if (isDestructorExpression(node)) {
    return parseDestructorRules(node.value)
  }
  return rules
}
 
export const setInByDestructor = (
  source: any,
  rules: DestrcutorRules,
  value: any,
  mutators: Mutatators
) => {
  rules.forEach(({ key, path }) => {
    mutators.setIn([key], source, mutators.getIn(path, value))
  })
}
 
export const getInByDestructor = (
  source: any,
  rules: DestrcutorRules,
  mutators: Mutatators
) => {
  let response = {}
  Eif (rules.length) {
    if (isNum(rules[0].path[0])) {
      response = []
    }
  }
  source = isValid(source) ? source : {}
  rules.forEach(({ key, path }) => {
    mutators.setIn(path, response, source[key])
  })
  return response
}
 
export const deleteInByDestructor = (
  source: any,
  rules: DestrcutorRules,
  mutators: Mutatators
) => {
  rules.forEach(({ key }) => {
    mutators.deleteIn([key], source)
  })
}
 
export const existInByDestructor = (
  source: any,
  rules: DestrcutorRules,
  start: number,
  mutators: Mutatators
) => {
  return rules.every(({ key }) => {
    return mutators.existIn([key], source, start)
  })
}