@apidaze/node-red-contrib-apidaze
Version:
Node-RED module for Apidaze
119 lines (96 loc) • 3.13 kB
JavaScript
module.exports = function (RED) {
'use strict';
const jsonata = require('jsonata');
const callsDb = require('../../helpers/call-store');
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 SetData(config) {
RED.nodes.createNode(this, config);
this.matches = config.matches;
let allConditionsMatch = true;
this.on('input', async (msg, send, done) => {
const { payload } = msg;
const { call } = payload;
if (!(call && call.call_uuid)) {
this.error(`'set-data' 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;
const allCaseConditionsMatch = conditions.every((condition) => {
const {
property,
propertyValueExp,
operation,
value,
} = condition;
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);
return operationResult;
});
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-data', SetData);
};