* Set the provided value in the source data set at the provided coordinates. * * @param {number|string} row Physical row index. * @param {number|string} column Property name / physical column index. * @param {*} value The value to be set at the provided coordinates.
(row: number | string, column: string | number, value: unknown)
| 221 | * @param {*} value The value to be set at the provided coordinates. |
| 222 | */ |
| 223 | setAtCell(row: number | string, column: string | number, value: unknown) { |
| 224 | // Normalize row: accept string numeric indices (e.g. '0', '1') passed by setSourceDataAtCell, |
| 225 | // but reject prototype-pollution keys like '__proto__', 'constructor', 'prototype'. |
| 226 | let normalizedRow: number; |
| 227 | |
| 228 | if (typeof row === 'string') { |
| 229 | const parsed = Number(row); |
| 230 | |
| 231 | if (Number.isNaN(parsed) || !Number.isInteger(parsed) || parsed < 0) { |
| 232 | return; |
| 233 | } |
| 234 | normalizedRow = parsed; |
| 235 | } else if (typeof row !== 'number' || !Number.isInteger(row) || row < 0) { |
| 236 | return; |
| 237 | } else { |
| 238 | normalizedRow = row; |
| 239 | } |
| 240 | |
| 241 | if (normalizedRow >= this.countRows() || (typeof column === 'number' && column >= this.countFirstRowKeys())) { |
| 242 | // Not enough rows and/or columns. |
| 243 | return; |
| 244 | } |
| 245 | |
| 246 | if (this.hot!.hasHook('modifySourceData')) { |
| 247 | const valueHolder = createObjectPropListener(value); |
| 248 | |
| 249 | this.hot!.runHooks('modifySourceData', normalizedRow, column, valueHolder, 'set'); |
| 250 | |
| 251 | if (valueHolder.isTouched()) { |
| 252 | value = valueHolder.value; |
| 253 | } |
| 254 | } |
| 255 | |
| 256 | const dataRow = this.modifyRowData(normalizedRow); |
| 257 | |
| 258 | if (!Number.isInteger(column)) { |
| 259 | // column argument is the prop name |
| 260 | if (Array.isArray(dataRow)) { |
| 261 | // String numeric column with array data — convert to number and write directly, same as |
| 262 | // the integer path below. setProperty rejects arrays, so this must be handled here. |
| 263 | const numericIndex = Number(column); |
| 264 | |
| 265 | if (!Number.isNaN(numericIndex) && Number.isInteger(numericIndex) && |
| 266 | numericIndex >= 0 && numericIndex < this.countFirstRowKeys()) { |
| 267 | dataRow[numericIndex] = value; |
| 268 | } |
| 269 | } else if (isObject(dataRow)) { |
| 270 | setProperty(dataRow as Record<string, unknown>, String(column), value); |
| 271 | } |
| 272 | } else if (Array.isArray(dataRow)) { |
| 273 | dataRow[column as number] = value; |
| 274 | } else if (isObject(dataRow)) { |
| 275 | setProperty(dataRow as Record<string, unknown>, String(column), value); |
| 276 | } |
| 277 | } |
| 278 | |
| 279 | /** |
| 280 | * Get data from the source data set using the physical indexes. |
no test coverage detected