File size: 2,164 Bytes
4d70170
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import type { EditStatePayload } from '@vue/devtools-api'

export class StateEditor {
  set(object, path, value, cb = null) {
    const sections = Array.isArray(path) ? path : path.split('.')
    while (sections.length > 1) {
      object = object[sections.shift()]
      if (this.isRef(object)) {
        object = this.getRefValue(object)
      }
    }
    const field = sections[0]
    if (cb) {
      cb(object, field, value)
    }
    else if (this.isRef(object[field])) {
      this.setRefValue(object[field], value)
    }
    else {
      object[field] = value
    }
  }

  get(object, path) {
    const sections = Array.isArray(path) ? path : path.split('.')
    for (let i = 0; i < sections.length; i++) {
      object = object[sections[i]]
      if (this.isRef(object)) {
        object = this.getRefValue(object)
      }
      if (!object) {
        return undefined
      }
    }
    return object
  }

  has(object, path, parent = false) {
    if (typeof object === 'undefined') {
      return false
    }

    const sections = Array.isArray(path) ? path.slice() : path.split('.')
    const size = !parent ? 1 : 2
    while (object && sections.length > size) {
      object = object[sections.shift()]
      if (this.isRef(object)) {
        object = this.getRefValue(object)
      }
    }
    return object != null && Object.prototype.hasOwnProperty.call(object, sections[0])
  }

  createDefaultSetCallback(state: EditStatePayload) {
    return (obj, field, value) => {
      if (state.remove || state.newKey) {
        if (Array.isArray(obj)) {
          obj.splice(field, 1)
        }
        else {
          delete obj[field]
        }
      }
      if (!state.remove) {
        const target = obj[state.newKey || field]
        if (this.isRef(target)) {
          this.setRefValue(target, value)
        }
        else {
          obj[state.newKey || field] = value
        }
      }
    }
  }

  isRef(_ref: any): boolean {
    // To implement in subclass
    return false
  }

  setRefValue(_ref: any, _value: any): void {
    // To implement in subclass
  }

  getRefValue(ref: any): any {
    // To implement in subclass
    return ref
  }
}