do-red
Version:
A do-node and corresponding return-node for creating loops and task-lists.
74 lines (69 loc) • 2.6 kB
JavaScript
const returnHelper = require('./utils/returnHelper')
module.exports = function (RED) {
function DoReturnNode (config) {
RED.nodes.createNode(this, config)
const node = this
// Fallback older version
if (typeof config.saveValue === 'undefined') config.saveValue = false
// set status
if (config.saveValue) {
node.status({ fill: 'green', shape: 'ring', text: 'save into collection' })
} else {
node.status({})
}
node.on('input', function (msg, send, done) {
const throwError = (e) => {
if (done) done(e)
else node.error(e, msg)
}
const _do = msg._do
if (!_do) {
throwError('Missing meta data for returning to do-node. Flow ends here.')
} else {
try {
if (config.mode === 'done' || config.mode === 'continue') {
if (_do.eachType && _do.eachPath && config.saveValue) {
switch (_do.collectionType) {
case 'Array':
msg = returnHelper.handleEachArray(msg)
break
case 'Set':
if (!RED.util.compareObjects(msg.payload, _do.currentSetValue)) {
msg = returnHelper.handleEachSet(msg)
}
break
case 'Object':
msg = returnHelper.handleEachObject(msg, RED)
break
case 'Map':
msg = returnHelper.handleEachMap(msg, RED)
break
default:
throw new Error('No valid collection type set!')
}
// if our original value is (within) payload, we must update our collection within the return payload, which will be set after all tasks.
if (_do.eachPath.startsWith('payload')) {
RED.util.setMessageProperty(_do, _do.eachPath, RED.util.getMessageProperty(msg, 'msg._do.collection'))
} else {
// update the collection in msg property
RED.util.setMessageProperty(msg, _do.eachPath, RED.util.getMessageProperty(msg, 'msg._do.collection'))
}
}
if (config.mode === 'done') {
_do.stack.pop()
}
} else if (config.mode === 'abort') {
_do.stack = []
}
const event = 'do:' + _do.returnTo
msg._event = event
RED.events.emit(event, msg)
} catch (e) {
throwError(e)
}
}
if (done) done()
})
}
RED.nodes.registerType('do-return', DoReturnNode)
}