MCPcopy Index your code
hub / github.com/nodejs/node / setKeys

Function setKeys

deps/npm/lib/utils/queryable.js:126–212  ·  view source on GitHub ↗
(_data, _key)

Source from the content-addressed store, hash-verified

124 // e.g: ['foo', 'bar', 'baz'] -> { foo: { bar: { baz: {} } }
125 const keys = parseKeys(key)
126 const setKeys = (_data, _key) => {
127 if (FORBIDDEN_KEYS.has(String(_key))) {
128 throw Object.assign(new Error(`Forbidden key: "${_key}"`), { code: 'EFORBIDDENKEY' })
129 }
130 // handles array indexes, converting valid integers to numbers
131 // note that occurrences of Symbol(append) will throw so we just ignore these for now
132 let maybeIndex = Number.NaN
133 try {
134 maybeIndex = Number(_key)
135 } catch {
136 // leave it NaN
137 }
138 if (!Number.isNaN(maybeIndex)) {
139 _key = maybeIndex
140 }
141
142 // creates new array in case key is an index and the array obj is not yet defined
143 const keyIsAnArrayIndex = _key === maybeIndex || _key === _append
144 const dataHasNoItems = !Object.keys(_data).length
145 if (keyIsAnArrayIndex && dataHasNoItems && !Array.isArray(_data)) {
146 _data = []
147 }
148
149 // converting from array to an object is also possible, in case the user is using force mode
150 // we should also convert existing arrays to an empty object if the current _data is an array
151 if (force && Array.isArray(_data) && !keyIsAnArrayIndex) {
152 _data = { ..._data }
153 }
154
155 // the _append key is a special key that is used to represent the empty-bracket notation
156 // e.g: arr[] -> arr[arr.length]
157 if (_key === _append) {
158 if (!Array.isArray(_data)) {
159 throw Object.assign(new Error(`Can't use append syntax in non-Array element`), {
160 code: 'ENOAPPEND',
161 })
162 }
163 _key = _data.length
164 }
165
166 // retrieves the next data object to recursively iterate on
167 // throws if trying to override a literal value or add props to an array
168 const next = () => {
169 const haveContents = !force && _data[_key] != null && value !== _delete
170 const shouldNotOverrideLiteralValue = !(typeof _data[_key] === 'object')
171 // if the next obj to recurse is an array and the next key to be appended to the resulting obj is not an array index, then it should throw since we can't append arbitrary props to arrays
172 const shouldNotAddPropsToArrays =
173 typeof keys[0] !== 'symbol' && Array.isArray(_data[_key]) && Number.isNaN(Number(keys[0]))
174
175 const overrideError = haveContents && shouldNotOverrideLiteralValue
176 if (overrideError) {
177 throw Object.assign(
178 new Error(`Property ${_key} already exists and is not an Array or Object.`),
179 { code: 'EOVERRIDEVALUE' }
180 )
181 }
182
183 const addPropsToArrayError = haveContents && shouldNotAddPropsToArrays

Callers 1

setterFunction · 0.85

Calls 6

StringClass · 0.85
assignMethod · 0.80
nextFunction · 0.70
hasMethod · 0.65
keysMethod · 0.65
shiftMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…