changed rule adding logic

This commit is contained in:
Niko Vujić
2025-12-31 10:41:14 +01:00
parent 7c9c1ddf3a
commit 84797d50c4
4 changed files with 135 additions and 179 deletions

View File

@@ -1,57 +1,80 @@
const net = require("net");
module.exports = function (RED) {
function buildControlNamesFromRules(rules) {
function buildNamesFromList(targets) {
return targets
.split(/\r?\n/)
.map((l) => l.trim())
.filter((l) => l.length > 0);
}
function buildNamesStartsWith(targets, startIndex, endIndex) {
const prefixes = buildNamesFromList(targets);
const names = [];
if (!Array.isArray(rules)) {
return names;
if (startIndex > endIndex) {
const tmp = startIndex;
startIndex = endIndex;
endIndex = tmp;
}
rules.forEach((rule) => {
if (!rule) {
return;
}
const type = (rule.t || rule.type || "eq").toString();
if (type === "idx") {
const base = (rule.v || rule.base || "").trim();
if (!base) {
return;
}
let from = parseInt(rule.from, 10);
let to = parseInt(rule.to, 10);
if (Number.isNaN(from) && Number.isNaN(to)) {
return;
}
if (Number.isNaN(from)) {
from = to;
}
if (Number.isNaN(to)) {
to = from;
}
if (from > to) {
const tmp = from;
from = to;
to = tmp;
}
for (let i = from; i <= to; i += 1) {
names.push(base + i);
}
} else {
const name = (rule.v || rule.value || "").trim();
if (name) {
names.push(name);
}
prefixes.forEach((prefix) => {
for (let i = startIndex; i <= endIndex; i += 1) {
names.push(prefix + i);
}
});
return names;
}
function buildNamesEndsWith(targets, startIndex, endIndex) {
const suffixes = buildNamesFromList(targets);
const names = [];
if (startIndex > endIndex) {
const tmp = startIndex;
startIndex = endIndex;
endIndex = tmp;
}
suffixes.forEach((suffix) => {
for (let i = startIndex; i <= endIndex; i += 1) {
names.push(String(i) + suffix);
}
});
return names;
}
function buildNamesStartsAndEnds(targets, startIndex, endIndex) {
const patterns = buildNamesFromList(targets);
const names = [];
if (startIndex > endIndex) {
const tmp = startIndex;
startIndex = endIndex;
endIndex = tmp;
}
patterns.forEach((pattern) => {
const parts = pattern.split("|");
const prefix = (parts[0] || "").trim();
const suffix = (parts[1] || "").trim();
if (!prefix && !suffix) {
return;
}
for (let i = startIndex; i <= endIndex; i += 1) {
names.push(prefix + i + suffix);
}
});
return names;
}
function buildControlNames(mode, targets, startIndex, endIndex) {
if (mode === "startsWith") {
return buildNamesStartsWith(targets, startIndex, endIndex);
}
if (mode === "endsWith") {
return buildNamesEndsWith(targets, startIndex, endIndex);
}
if (mode === "startsAndEnds") {
return buildNamesStartsAndEnds(targets, startIndex, endIndex);
}
return buildNamesFromList(targets);
}
function normaliseAction(action) {
const a = (action || "").toString().toLowerCase();
if (a === "unsubscribe" || a === "unsub") {
@@ -65,17 +88,12 @@ module.exports = function (RED) {
const node = this;
node.action = config.action || "subscribe";
let storedRules = config.rules;
if (typeof storedRules === "string") {
try {
storedRules = JSON.parse(storedRules);
} catch (e) {
storedRules = [];
}
}
node.rules = Array.isArray(storedRules) ? storedRules : [];
node.transport = config.transport || "TCP";
node.connectionConfig = RED.nodes.getNode(config.connection);
node.mode = config.mode || "list";
node.targets = config.targets || "";
node.startIndex = parseInt(config.startIndex, 10) || 1;
node.endIndex = parseInt(config.endIndex, 10) || node.startIndex;
node.transport = config.transport || "TCP";
node.on("input", (msg, send, done) => {
send =
@@ -86,16 +104,26 @@ module.exports = function (RED) {
done = done || function () {};
const action = normaliseAction(msg.action || node.action);
let rules = msg.rules || node.rules;
if (typeof rules === "string") {
try {
rules = JSON.parse(rules);
} catch (e) {
rules = [];
const mode = (msg.mode || node.mode || "list").toString();
const targets =
typeof msg.targets === "string" && msg.targets.trim().length
? msg.targets
: node.targets;
let startIndex = node.startIndex;
let endIndex = node.endIndex;
if (Object.prototype.hasOwnProperty.call(msg, "startIndex")) {
const v = parseInt(msg.startIndex, 10);
if (!Number.isNaN(v)) {
startIndex = v;
}
}
if (!Array.isArray(rules)) {
rules = [];
if (Object.prototype.hasOwnProperty.call(msg, "endIndex")) {
const v = parseInt(msg.endIndex, 10);
if (!Number.isNaN(v)) {
endIndex = v;
}
}
const transport =
@@ -103,7 +131,7 @@ module.exports = function (RED) {
? msg.transport.trim()
: node.transport;
const names = buildControlNamesFromRules(rules);
const names = buildControlNames(mode, targets || "", startIndex, endIndex);
if (!names.length) {
node.warn("xilica-subscribe: no rules defined");