bpmnlint 11.13.0 → 11.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/config/all.js CHANGED
@@ -25,6 +25,7 @@ const allRules = [
25
25
  'start-event-required',
26
26
  'sub-process-blank-start-event',
27
27
  'superfluous-gateway',
28
+ 'superfluous-label',
28
29
  'superfluous-termination'
29
30
  ];
30
31
 
@@ -24,6 +24,7 @@ module.exports = {
24
24
  'start-event-required': 'error',
25
25
  'sub-process-blank-start-event': 'error',
26
26
  'superfluous-gateway': 'warn',
27
+ 'superfluous-label': 'warn',
27
28
  'superfluous-termination': 'warn'
28
29
  }
29
30
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bpmnlint",
3
3
  "description": "Validate your BPMN diagrams based on configurable lint rules",
4
- "version": "11.13.0",
4
+ "version": "11.14.1",
5
5
  "main": "lib/index.js",
6
6
  "keywords": [
7
7
  "bpmnlint",
@@ -35,12 +35,12 @@ module.exports = function() {
35
35
  // (2) Filter BPMN elements without visual representation
36
36
  const visualBpmnElements = bpmnElements.filter(hasVisualRepresentation);
37
37
 
38
- // (3) Construct array of BPMNDI references
39
- const diBpmnReferences = getAllDiBpmnReferences(node);
38
+ // (3) Construct set of BPMNDI references
39
+ const referencedBpmnElementIds = getReferencedBpmnElementIds(node);
40
40
 
41
41
  // (4) Report elements without BPMNDI
42
42
  visualBpmnElements.forEach((element) => {
43
- if (diBpmnReferences.indexOf(element.id) === -1) {
43
+ if (!referencedBpmnElementIds.has(element.id)) {
44
44
  reporter.report(element.id, 'Element is missing bpmndi');
45
45
  }
46
46
  });
@@ -105,16 +105,17 @@ function getAllBpmnElements(rootElements) {
105
105
  }
106
106
 
107
107
  /**
108
- * Get all BPMN elements within a bpmn:Definitions node
108
+ * Get the ids of all BPMN elements referenced by BPMNDI elements
109
+ * within a bpmn:Definitions node
109
110
  *
110
111
  * @param {ModdleElement} definitionsNode - A moddleElement representing the
111
112
  * bpmn:Definitions element
112
113
  *
113
- * @return {string[]} ids of all BPMNDI element part of
114
- * this bpmn:Definitions node
114
+ * @return {Set<string>} ids of all BPMN elements referenced by BPMNDI
115
+ * elements part of this bpmn:Definitions node
115
116
  */
116
- function getAllDiBpmnReferences(definitionsNode) {
117
- return flatten(
117
+ function getReferencedBpmnElementIds(definitionsNode) {
118
+ return new Set(flatten(
118
119
  definitionsNode.get('diagrams').map((diagram) => {
119
120
 
120
121
  const diElements = diagram.plane.planeElement || [];
@@ -124,7 +125,7 @@ function getAllDiBpmnReferences(definitionsNode) {
124
125
  return element.bpmnElement?.id;
125
126
  });
126
127
  })
127
- );
128
+ ));
128
129
  }
129
130
 
130
131
  /**
@@ -0,0 +1,74 @@
1
+ const {
2
+ is
3
+ } = require('bpmnlint-utils');
4
+
5
+ const {
6
+ annotateRule
7
+ } = require('./helper');
8
+
9
+
10
+ /**
11
+ * A rule that checks that unconditional sequence flows do not
12
+ * have a label.
13
+ *
14
+ * Labels are only meaningful on sequence flows forking out of
15
+ * XOR/OR gateways, on conditional flows, and on default flows.
16
+ * Anywhere else they duplicate information already conveyed by
17
+ * the diagram.
18
+ *
19
+ * @type { import('../lib/types.js').RuleFactory }
20
+ */
21
+ module.exports = function() {
22
+
23
+ function check(node, reporter) {
24
+
25
+ if (!is(node, 'bpmn:SequenceFlow')) {
26
+ return;
27
+ }
28
+
29
+ const name = (node.name || '').trim();
30
+
31
+ if (!name) {
32
+ return;
33
+ }
34
+
35
+ if (hasCondition(node) || isDefaultFlow(node) || isGatewayFork(node)) {
36
+ return;
37
+ }
38
+
39
+ reporter.report(node.id, 'Sequence flow has superfluous label', [ 'name' ]);
40
+ }
41
+
42
+ return annotateRule('superfluous-label', {
43
+ check
44
+ });
45
+
46
+ };
47
+
48
+
49
+ // helpers /////////////////////////////
50
+
51
+ function hasCondition(flow) {
52
+ return !!flow.conditionExpression;
53
+ }
54
+
55
+ function isDefaultFlow(flow) {
56
+ const source = flow.sourceRef;
57
+
58
+ return source && source['default'] === flow;
59
+ }
60
+
61
+ function isGatewayFork(flow) {
62
+ const source = flow.sourceRef;
63
+
64
+ if (!source) {
65
+ return false;
66
+ }
67
+
68
+ const isDecisionGateway = (
69
+ is(source, 'bpmn:ExclusiveGateway') ||
70
+ is(source, 'bpmn:InclusiveGateway')
71
+ );
72
+
73
+ return isDecisionGateway && (source.outgoing || []).length > 1;
74
+ }