bpmnlint 10.1.0 → 10.2.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 +1 -0
- package/config/recommended.js +1 -0
- package/package.json +2 -2
- package/rules/link-event.js +100 -0
- package/rules/no-implicit-start.js +4 -0
package/config/all.js
CHANGED
package/config/recommended.js
CHANGED
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": "10.1
|
|
4
|
+
"version": "10.2.1",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"bpmnlint",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"license": "MIT",
|
|
29
29
|
"scripts": {
|
|
30
30
|
"all": "run-s lint test-coverage",
|
|
31
|
-
"lint": "eslint .",
|
|
31
|
+
"lint": "eslint . --ext js,mjs",
|
|
32
32
|
"dev": "npm test -- --watch",
|
|
33
33
|
"test": "mocha --exclude 'test/integration/*/**' 'test/**/*.*js'",
|
|
34
34
|
"test-coverage": "nyc --reporter=lcov --reporter=html npm test",
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
const {
|
|
2
|
+
groupBy
|
|
3
|
+
} = require('min-dash');
|
|
4
|
+
|
|
5
|
+
const {
|
|
6
|
+
is
|
|
7
|
+
} = require('bpmnlint-utils');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A rule that verifies that link events are properly used.
|
|
12
|
+
*
|
|
13
|
+
* This implies:
|
|
14
|
+
*
|
|
15
|
+
* * for every link throw there exists a link catch within
|
|
16
|
+
* the same scope, and vice versa
|
|
17
|
+
* * there exists only a single pair of [ throw, catch ] links
|
|
18
|
+
* with a given name, per scope
|
|
19
|
+
* * link events have a name
|
|
20
|
+
*
|
|
21
|
+
*/
|
|
22
|
+
module.exports = function() {
|
|
23
|
+
|
|
24
|
+
function check(node, reporter) {
|
|
25
|
+
|
|
26
|
+
if (!is(node, 'bpmn:FlowElementsContainer')) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const links = (node.flowElements || []).filter(isLinkEvent);
|
|
31
|
+
|
|
32
|
+
for (const link of links) {
|
|
33
|
+
if (!link.name) {
|
|
34
|
+
reporter.report(link.id, 'Link event is missing name');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const names = groupBy(links, (link) => link.name);
|
|
39
|
+
|
|
40
|
+
for (const [ name, events ] of Object.entries(names)) {
|
|
41
|
+
|
|
42
|
+
// ignore unnamed (validated earlier)
|
|
43
|
+
if (!name) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// missing catch or throw event
|
|
48
|
+
if (events.length === 1) {
|
|
49
|
+
const event = events[0];
|
|
50
|
+
|
|
51
|
+
reporter.report(event.id, `Link ${isThrowEvent(event) ? 'catch' : 'throw' } event with name <${ name }> missing in scope`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const throwEvents = events.filter(isThrowEvent);
|
|
55
|
+
|
|
56
|
+
if (throwEvents.length > 1) {
|
|
57
|
+
for (const event of throwEvents) {
|
|
58
|
+
reporter.report(event.id, `Duplicate link throw event with name <${name}> in scope`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const catchEvents = events.filter(isCatchEvent);
|
|
63
|
+
|
|
64
|
+
if (catchEvents.length > 1) {
|
|
65
|
+
for (const event of catchEvents) {
|
|
66
|
+
reporter.report(event.id, `Duplicate link catch event with name <${name}> in scope`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
check
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
// helpers /////////////////
|
|
80
|
+
|
|
81
|
+
function isLinkEvent(node) {
|
|
82
|
+
|
|
83
|
+
var eventDefinitions = node.eventDefinitions || [];
|
|
84
|
+
|
|
85
|
+
if (!is(node, 'bpmn:Event')) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return eventDefinitions.some(
|
|
90
|
+
definition => is(definition, 'bpmn:LinkEventDefinition')
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function isThrowEvent(node) {
|
|
95
|
+
return is(node, 'bpmn:ThrowEvent');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function isCatchEvent(node) {
|
|
99
|
+
return is(node, 'bpmn:CatchEvent');
|
|
100
|
+
}
|
|
@@ -20,6 +20,10 @@ module.exports = function() {
|
|
|
20
20
|
function isImplicitStart(node) {
|
|
21
21
|
const incoming = node.incoming || [];
|
|
22
22
|
|
|
23
|
+
if (is(node, 'bpmn:Activity') && node.isForCompensation) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
|
|
23
27
|
if (is(node, 'bpmn:SubProcess') && node.triggeredByEvent) {
|
|
24
28
|
return false;
|
|
25
29
|
}
|