| 76 | } |
| 77 | |
| 78 | const getter = ({ data, key }, { unwrapSingleItemArrays = true } = {}) => { |
| 79 | // keys are a list in which each entry represents the name of a property that should be walked through the object in order to return the final found value |
| 80 | const keys = parseKeys(key) |
| 81 | let _data = data |
| 82 | let label = '' |
| 83 | |
| 84 | for (const k of keys) { |
| 85 | // empty-bracket-shortcut-syntax is not supported on getter |
| 86 | if (k === _append) { |
| 87 | throw Object.assign(new Error('Empty brackets are not valid syntax for retrieving values.'), { |
| 88 | code: 'EINVALIDSYNTAX', |
| 89 | }) |
| 90 | } |
| 91 | |
| 92 | // extra logic to take into account printing array, along with its special syntax in which using a dot-sep property name after an array will expand it's results |
| 93 | // e.g: arr.name -> arr[0].name=value, arr[1].name=value, ... |
| 94 | const maybeIndex = Number(k) |
| 95 | if (Array.isArray(_data) && !Number.isInteger(maybeIndex)) { |
| 96 | _data = _data.reduce((acc, i, index) => { |
| 97 | acc[`${label}[${index}].${k}`] = i[k] |
| 98 | return acc |
| 99 | }, {}) |
| 100 | return _data |
| 101 | } else { |
| 102 | if (!Object.hasOwn(_data, k)) { |
| 103 | return undefined |
| 104 | } |
| 105 | _data = _data[k] |
| 106 | } |
| 107 | |
| 108 | label += k |
| 109 | } |
| 110 | |
| 111 | // these are some legacy expectations from the old API consumed by lib/view.js |
| 112 | if (unwrapSingleItemArrays && Array.isArray(_data) && _data.length <= 1) { |
| 113 | _data = _data[0] |
| 114 | } |
| 115 | |
| 116 | return { |
| 117 | [key]: _data, |
| 118 | } |
| 119 | } |
| 120 | |
| 121 | const setter = ({ data, key, value, force }) => { |
| 122 | // setter goes to recursively transform the provided data obj |