Access element registry from rules

Is there a ‘best practice’ way to access the element registry (or, in general, other elements than the current node) from a bpmnlint rule? I’ve found this question, but it seems to be more complicated than necessary for what I’m after.

As an example, let’s say I want to write a rule that a collapsed pool must be connected by a message flow:

const {
    is,
    isAny
} = require('bpmnlint-utils');

/**
 * A rule that checks if collapsed pools have at least one attached message flow
 */
module.exports = function() {

    function check(node, reporter) {
        
        if(!is(node, 'bpmn:Participant')){
            return;
        }
        if(!node.processRef){
            const messageFlows = []; //Get list of message flows
            var poolFlows = messageFlows.filter(flow => flow.sourceRef== node.id || flow.targetRef == node.id);
            if(poolFlows.length == 0){
                reporter.report(node.id, 'Collapsed pool must have at least one message flow');
            }
        }
    }

    return { check };
};


How do I get the values for messageFlows?
(I know that this particular example is possible if I check from the Process node instead, but I have some other rules where that’s not really feasible.)

The example you mention is from a different context. In diagram-js there is a rules feature. This is not to be confused with lint rules which are a feature used in bpmnlint. There is no element registry (or any flat list of all the elements) in bpmnlint. A lint rule’s check function is called for every node of the model when the linter traverses it. The node (and its potential parent and child nodes) is all the context you have. An implementation for the example you’ve given might look like this:

check(node, reporter) {
  if (!is(node, "bpmn:Collaboration")) {
    return;
  }

  const participants = node.get("participants"),
    messageFlows = node.get("messageFlows");

  participants.forEach((participant) => {
    if (
      !participant.get("processRef") &&
      !messageFlows.find((messageFlow) => {
        return (
          messageFlow.get("sourceRef") === participant ||
          messageFlow.get("targetRef") === participant
        );
      })
    ) {
      reporter.report(
        participant.get("id"),
        "Empty participants must be connected by message flow"
      );
    }
  });
}

CodeSandbox: Lint Rule Example - CodeSandbox

That’s a shame, I was really hoping there was a better solution. Thanks anyway!

Why is this a problem? What rules can you not implement?

I can’t remember all of them, but the one I’m working on now is checking that comments are always associated with elements. (It’s not an especially important rule, and I’m not even sure if the element registry would have solved this, but it’s the reason why I asked.)

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.