diff --git a/lib/cli/index.js b/lib/cli/index.js index cb7747a..5ede809 100644 --- a/lib/cli/index.js +++ b/lib/cli/index.js @@ -73,7 +73,11 @@ async function initialise() { config.rules[r] = true; } } else { - config.rules[r] = true; + if (rule.meta && rule.meta.hasOwnProperty('default')) { + config.rules[r] = rule.meta.default; + } else { + config.rules[r] = true; + } } } console.log("module.exports = "+JSON.stringify(config,null,4)) diff --git a/lib/rules/index.js b/lib/rules/index.js index bc4af7e..4c6b3bf 100644 --- a/lib/rules/index.js +++ b/lib/rules/index.js @@ -6,5 +6,6 @@ module.exports = { "no-overlapping-nodes": require("./no-overlapping-nodes"), "no-unconnected-http-nodes": require("./no-unconnected-http-nodes"), "no-unnamed-functions": require("./no-unnamed-functions"), - "no-unnamed-links": require("./no-unnamed-links") + "no-unnamed-links": require("./no-unnamed-links"), + "no-cross-links": require("./no-cross-links") } diff --git a/lib/rules/no-cross-links.js b/lib/rules/no-cross-links.js new file mode 100644 index 0000000..c126ca2 --- /dev/null +++ b/lib/rules/no-cross-links.js @@ -0,0 +1,64 @@ +function findCrossTabLinks(flowSet) { + const linkIns = new Map(); + const linkOuts = []; + const tabLabel = new Map(); + + flowSet.flows.forEach((tab) => { + tabLabel.set(tab.id, (tab.config && tab.config.label) || ""); + }); + + flowSet.nodes.forEach((n) => { + if (n.type === "link in") linkIns.set(n.id, n); + if (n.type === "link out") linkOuts.push(n); + }); + + const results = []; + + for (const out of linkOuts) { + const targets = (out.outboundWires || []).flat(); + + for (const wire of targets) { + const destNode = wire.destinationNode; + if (!destNode) continue; + const inn = linkIns.get(destNode.id); + if (inn) { + if (out.z !== inn.z) { + results.push({ + from: out.id, + fromName: out.config.name || "", + fromTab: out.z, + fromTabLabel: tabLabel.get(out.z) || "", + to: inn.id, + toName: inn.config.name || "", + toTab: inn.z, + toTabLabel: tabLabel.get(inn.z) || "", + }); + } + } + } + } + return results; +} + +module.exports = { + meta: { + type: "problem", + severity: "warn", + docs: { description: "Detect link nodes that cross tabs" }, + default: false, + }, + + create(context) { + return { + start(flowSet) { + const crossTab = findCrossTabLinks(flowSet); + crossTab.forEach((link) => { + context.report({ + location: [link.to, link.from], + message: `Cross tab link node found, between flow "${link.toTabLabel}" and flow "${link.fromTabLabel}"`, + }); + }); + }, + }; + }, +};