UNPKG

do-red

Version:

A do-node and corresponding return-node for creating loops and task-lists.

141 lines (131 loc) 4.93 kB
const isObject = (obj) => (!!obj && typeof obj === 'object' && Array.isArray(obj) === false) const handleEachArray = (msg) => { const _do = msg._do if (_do.yieldType === 'indexValue') { let newIndex = _do.index if (!isObject(msg.payload)) { throw new Error(`Error: Payload is not an object, but should replace index and value for { ${_do.index}: ${_do.collection[_do.index]} }`) } newIndex = Object.keys(msg.payload)[0] if (newIndex !== 'undefined' && isNaN(Number(newIndex))) { throw new Error(`Error: Payload key is not a number, but should replace { ${_do.index}: ${_do.collection[_do.index]} }`) } // check if deleted and and has no delete flag -> then we delete the value from the collection (else) if (newIndex === 'undefined' && !_do.valueDeleted) { // const oldValue = _do.collection[_do.index] _do.collection.splice(_do.index, 1) // _do.collection = _do.collection.filter(el => el !== oldValue) // check if works with object?! _do.index = _do.index - 1 _do.valueDeleted = true _do.collectionLength = _do.collectionLength - 1 // if value was removed in one task and another task wants to add it at the old position again } else if (_do.valueDeleted && Number(newIndex) === _do.index + 1) { _do.index = _do.index + 1 _do.collectionLength = _do.collectionLength + 1 _do.collection.splice(_do.index, 0, msg.payload[newIndex]) delete _do.valueDeleted // set new index/value } else if (newIndex !== 'undefined') { _do.collection[newIndex] = msg.payload[newIndex] // if index was moved, old index will be undefined and not be removed if (Number(newIndex) !== _do.index) { _do.collection[_do.index] = undefined } } } else { _do.collection[_do.index] = msg.payload } return msg } const handleEachSet = (msg) => { const _do = msg._do // if value in Set is an object, we must have the reference of it, which seems to go lost during Node-Red (currentSetValue = set1.values().next() ) // can't delete it with an equal looking object. if (typeof _do.currentSetValue === 'object') { const colIterator = _do.collection.values() for (const el of colIterator) { if (JSON.stringify(el) === JSON.stringify(_do.currentSetValue)) { _do.currentSetValue = el break } } } _do.collection.delete(_do.currentSetValue) _do.collection.add(msg.payload) _do.currentSetValue = msg.payload return msg } const handleEachObject = (msg, RED) => { const _do = msg._do const obj = RED.util.getMessageProperty(msg, 'msg._do.collection') let currentKey = _do.keys[_do.index] const deleteObject = () => { delete obj[currentKey] _do.keys[_do.index] = undefined } const changeObject = (newKey, newValue, onlyKey = false) => { if (currentKey !== newKey) { obj[newKey] = obj[currentKey] delete obj[currentKey] _do.keys[_do.index] = newKey currentKey = newKey } if (!onlyKey) obj[currentKey] = newValue } if (_do.yieldType === 'value') { changeObject(currentKey, msg.payload) } else if (_do.yieldType === 'key') { if (msg.payload === undefined) { deleteObject() } else { changeObject(msg.payload, null, true) } } else if (_do.yieldType === 'keyValue') { if (!isObject(msg.payload) && msg.payload !== undefined) { throw new Error(`Error: Payload is not an object. But should replace { ${currentKey}: ${RED.util.getObjectProperty(obj, currentKey)} }`) } if (msg.payload === undefined) { deleteObject() } else { const newKey = Object.keys(msg.payload)[0] const newValue = msg.payload[newKey] changeObject(newKey, newValue) } } return msg } const handleEachMap = (msg, RED) => { const _do = msg._do const thisMap = RED.util.getMessageProperty(msg, 'msg._do.collection') const currentKey = _do.keys[_do.index] if (_do.yieldType === 'value') { thisMap.set(currentKey, msg.payload) } else if (_do.yieldType === 'key') { if (msg.payload !== currentKey) { if (msg.payload !== undefined) thisMap.set(msg.payload, thisMap.get(currentKey)) thisMap.delete(currentKey) _do.keys[_do.index] = msg.payload } } else if (_do.yieldType === 'keyValue') { if (msg.payload === undefined) { thisMap.delete(currentKey) } else { if (!isObject(msg.payload)) { throw new Error(`Error: Payload is not an object. But should replace { ${currentKey}: ${RED.util.getObjectProperty(thisMap, currentKey)} }`) } const newKey = Object.keys(msg.payload)[0] if (newKey !== currentKey) { thisMap.delete(currentKey) _do.keys[_do.index] = newKey thisMap.set(newKey, msg.payload[newKey]) } } } return msg } module.exports = { handleEachArray, handleEachSet, handleEachObject, handleEachMap }