UNPKG

@apidaze/node-red-contrib-apidaze

Version:
147 lines (121 loc) 3.97 kB
module.exports = function (RED) { 'use strict'; const jsonata = require('jsonata'); const { Parser } = require('xml2js'); const callsDb = require('../../helpers/call-store'); const parser = new Parser({ attrkey: '_', charkey: 'z', mergeAttrs: false, explicitArray: false, explicitRoot: false, }); const operations = { contains: (value1, value2) => value1.toString().includes(value2.toString()), notContains: (value1, value2) => !value1.toString().includes(value2.toString()), equal: (value1, value2) => value1 === value2, notEqual: (value1, value2) => value1 !== value2, regex: (value1, value2) => { const regexMatch = value2 .toString() .match(new RegExp('^/(.*?)/([gimy]*)$')); let regex; if (!regexMatch) { regex = new RegExp(value2.toString()); } else if (regexMatch.length === 1) { regex = new RegExp(regexMatch[1]); } else { regex = new RegExp(regexMatch[1], regexMatch[2]); } return !!value1.toString().match(regex); }, }; function SetXML(config) { RED.nodes.createNode(this, config); this.matches = config.matches; const node = this; let allConditionsMatch = true; this.on('input', async (msg, send, done) => { const { payload } = msg; const { call } = payload; if (!(call && call.call_uuid)) { this.error(`'set-xml' called on non-existent call.`); return; } try { const calls = await callsDb.fetch(call.call_uuid); if (calls && calls[0]) { msg.payload.call = calls[0]; } } catch (err) { console.error('An error has occured.', payload, err); } for (const match of this.matches) { const conditions = match.conditions; const properties = match.properties; let allCaseConditionsMatch = true; for (const condition of conditions) { const { property, propertyValueExp, operation, value, xml, xmlValueType } = condition; if (property === 'always_match') { // already updating the script as it always matches try { const xmlOutput = RED.util.evaluateNodeProperty(xml, xmlValueType, node, msg); const scriptItem = await parser.parseStringPromise(`<root>${xmlOutput}</root>`); msg.payload.script.push(scriptItem); } catch (err) { this.error('Error dealing with the XML preparation.'); } continue; } const operationFunc = operations[operation]; const isPropertyCustomString = property === 'custom_string'; const data = (() => { if (isPropertyCustomString) { try { return jsonata(propertyValueExp).evaluate(msg); } catch (err) { console.error( 'An error has occured with jsonata.', payload, err ); return ''; } } return msg.payload.call[property]; })(); const operationResult = operationFunc(data, value); if (operationResult === false) { allCaseConditionsMatch = false; } } if (allCaseConditionsMatch) { properties.forEach((property) => { const { key, value } = property; msg.payload.call.custom[key] = value; }); if (properties.length) { await callsDb.update(call.call_uuid, msg.payload.call); } } else { allConditionsMatch = false; } } if (allConditionsMatch) { send(msg); } else { send(null); } done(); }); } RED.nodes.registerType('set-xml', SetXML); };