bpmnlint-plugin-camunda-compat 0.9.2 → 0.12.0
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/index.js +49 -54
- package/package.json +9 -9
- package/rules/called-decision-or-task-definition/index.js +6 -7
- package/rules/called-element.js +2 -2
- package/rules/duplicate-task-headers.js +57 -0
- package/rules/element-type/config.js +107 -172
- package/rules/inclusive-gateway.js +52 -0
- package/rules/loop-characteristics.js +2 -2
- package/rules/no-zeebe-properties.js +23 -0
- package/rules/subscription.js +2 -2
- package/rules/user-task-form.js +2 -0
- package/rules/utils/element.js +73 -33
- package/rules/utils/error-types.js +2 -1
- package/CHANGELOG.md +0 -87
package/index.js
CHANGED
@@ -1,71 +1,66 @@
|
|
1
|
+
const { omit } = require('min-dash');
|
2
|
+
|
1
3
|
const calledDecisionOrTaskDefinitionConfig = require('./rules/called-decision-or-task-definition/config'),
|
2
4
|
elementTypeConfig = require('./rules/element-type/config');
|
3
5
|
|
6
|
+
const camundaCloud10Rules = {
|
7
|
+
'called-decision-or-task-definition': [ 'error', calledDecisionOrTaskDefinitionConfig.camundaCloud10 ],
|
8
|
+
'called-element': 'error',
|
9
|
+
'duplicate-task-headers': 'error',
|
10
|
+
'element-type': [ 'error', elementTypeConfig.camundaCloud10 ],
|
11
|
+
'error-reference': 'error',
|
12
|
+
'loop-characteristics': 'error',
|
13
|
+
'message-reference': 'error',
|
14
|
+
'no-template': 'error',
|
15
|
+
'no-zeebe-properties': 'error',
|
16
|
+
'subscription': 'error',
|
17
|
+
'user-task-form': 'error'
|
18
|
+
};
|
19
|
+
|
20
|
+
const camundaCloud11Rules = {
|
21
|
+
...camundaCloud10Rules,
|
22
|
+
'called-decision-or-task-definition': [ 'error', calledDecisionOrTaskDefinitionConfig.camundaCloud11 ],
|
23
|
+
'element-type': [ 'error', elementTypeConfig.camundaCloud11 ]
|
24
|
+
};
|
25
|
+
|
26
|
+
const camundaCloud12Rules = {
|
27
|
+
...camundaCloud11Rules,
|
28
|
+
'called-decision-or-task-definition': [ 'error', calledDecisionOrTaskDefinitionConfig.camundaCloud12 ],
|
29
|
+
'element-type': [ 'error', elementTypeConfig.camundaCloud12 ]
|
30
|
+
};
|
31
|
+
|
32
|
+
const camundaCloud13Rules = {
|
33
|
+
...camundaCloud12Rules,
|
34
|
+
'called-decision-or-task-definition': [ 'error', calledDecisionOrTaskDefinitionConfig.camundaCloud13 ]
|
35
|
+
};
|
36
|
+
|
37
|
+
const camundaCloud80Rules = omit(camundaCloud13Rules, 'no-template');
|
38
|
+
|
39
|
+
const camundaCloud81Rules = {
|
40
|
+
...omit(camundaCloud80Rules, 'no-zeebe-properties'),
|
41
|
+
'element-type': [ 'error', elementTypeConfig.camundaCloud81 ],
|
42
|
+
'inclusive-gateway': 'error'
|
43
|
+
};
|
44
|
+
|
4
45
|
module.exports = {
|
5
46
|
configs: {
|
6
47
|
'camunda-cloud-1-0': {
|
7
|
-
rules:
|
8
|
-
'called-decision-or-task-definition': [ 'error', calledDecisionOrTaskDefinitionConfig.camundaCloud10 ],
|
9
|
-
'called-element': 'error',
|
10
|
-
'element-type': [ 'error', elementTypeConfig.camundaCloud10 ],
|
11
|
-
'error-reference': 'error',
|
12
|
-
'loop-characteristics': 'error',
|
13
|
-
'message-reference': 'error',
|
14
|
-
'no-template': 'error',
|
15
|
-
'subscription': 'error',
|
16
|
-
'user-task-form': 'error'
|
17
|
-
}
|
48
|
+
rules: camundaCloud10Rules
|
18
49
|
},
|
19
50
|
'camunda-cloud-1-1': {
|
20
|
-
rules:
|
21
|
-
'called-decision-or-task-definition': [ 'error', calledDecisionOrTaskDefinitionConfig.camundaCloud11 ],
|
22
|
-
'called-element': 'error',
|
23
|
-
'element-type': [ 'error', elementTypeConfig.camundaCloud11 ],
|
24
|
-
'error-reference': 'error',
|
25
|
-
'loop-characteristics': 'error',
|
26
|
-
'message-reference': 'error',
|
27
|
-
'no-template': 'error',
|
28
|
-
'subscription': 'error',
|
29
|
-
'user-task-form': 'error'
|
30
|
-
}
|
51
|
+
rules: camundaCloud11Rules
|
31
52
|
},
|
32
53
|
'camunda-cloud-1-2': {
|
33
|
-
rules:
|
34
|
-
'called-decision-or-task-definition': [ 'error', calledDecisionOrTaskDefinitionConfig.camundaCloud12 ],
|
35
|
-
'called-element': 'error',
|
36
|
-
'element-type': [ 'error', elementTypeConfig.camundaCloud12 ],
|
37
|
-
'error-reference': 'error',
|
38
|
-
'loop-characteristics': 'error',
|
39
|
-
'message-reference': 'error',
|
40
|
-
'no-template': 'error',
|
41
|
-
'subscription': 'error',
|
42
|
-
'user-task-form': 'error'
|
43
|
-
}
|
54
|
+
rules: camundaCloud12Rules
|
44
55
|
},
|
45
56
|
'camunda-cloud-1-3': {
|
46
|
-
rules:
|
47
|
-
'called-decision-or-task-definition': [ 'error', calledDecisionOrTaskDefinitionConfig.camundaCloud13 ],
|
48
|
-
'called-element': 'error',
|
49
|
-
'element-type': [ 'error', elementTypeConfig.camundaCloud12 ],
|
50
|
-
'error-reference': 'error',
|
51
|
-
'loop-characteristics': 'error',
|
52
|
-
'message-reference': 'error',
|
53
|
-
'no-template': 'error',
|
54
|
-
'subscription': 'error',
|
55
|
-
'user-task-form': 'error'
|
56
|
-
}
|
57
|
+
rules: camundaCloud13Rules
|
57
58
|
},
|
58
59
|
'camunda-cloud-8-0': {
|
59
|
-
rules:
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
'error-reference': 'error',
|
64
|
-
'loop-characteristics': 'error',
|
65
|
-
'message-reference': 'error',
|
66
|
-
'subscription': 'error',
|
67
|
-
'user-task-form': 'error'
|
68
|
-
}
|
60
|
+
rules: camundaCloud80Rules
|
61
|
+
},
|
62
|
+
'camunda-cloud-8-1': {
|
63
|
+
rules: camundaCloud81Rules
|
69
64
|
}
|
70
65
|
}
|
71
66
|
};
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "bpmnlint-plugin-camunda-compat",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.12.0",
|
4
4
|
"description": "A bpmnlint plug-in for Camunda Platform compatibility",
|
5
5
|
"main": "index.js",
|
6
6
|
"scripts": {
|
@@ -23,21 +23,21 @@
|
|
23
23
|
},
|
24
24
|
"license": "MIT",
|
25
25
|
"devDependencies": {
|
26
|
-
"bpmn-moddle": "^7.1.
|
26
|
+
"bpmn-moddle": "^7.1.3",
|
27
27
|
"bpmnlint": "^7.8.0",
|
28
|
-
"chai": "^4.3.
|
29
|
-
"eslint": "^
|
30
|
-
"eslint-plugin-bpmn-io": "^0.
|
31
|
-
"mocha": "^
|
28
|
+
"chai": "^4.3.6",
|
29
|
+
"eslint": "^8.23.0",
|
30
|
+
"eslint-plugin-bpmn-io": "^0.14.1",
|
31
|
+
"mocha": "^10.0.0",
|
32
32
|
"modeler-moddle": "^0.1.0",
|
33
|
-
"sinon": "^
|
33
|
+
"sinon": "^14.0.0",
|
34
34
|
"sinon-chai": "^3.7.0",
|
35
|
-
"zeebe-bpmn-moddle": "^0.
|
35
|
+
"zeebe-bpmn-moddle": "^0.14.0"
|
36
36
|
},
|
37
37
|
"dependencies": {
|
38
38
|
"@bpmn-io/moddle-utils": "^0.1.0",
|
39
39
|
"bpmnlint-utils": "^1.0.2",
|
40
|
-
"min-dash": "^3.8.
|
40
|
+
"min-dash": "^3.8.1"
|
41
41
|
},
|
42
42
|
"files": [
|
43
43
|
"rules",
|
@@ -8,9 +8,8 @@ const { getPath } = require('@bpmn-io/moddle-utils');
|
|
8
8
|
const {
|
9
9
|
findExtensionElement,
|
10
10
|
getEventDefinition,
|
11
|
-
|
12
|
-
|
13
|
-
hasExtensionElementsOfTypes
|
11
|
+
hasExtensionElement,
|
12
|
+
hasProperties
|
14
13
|
} = require('../utils/element');
|
15
14
|
|
16
15
|
const { reportErrors } = require('../utils/reporter');
|
@@ -99,14 +98,14 @@ module.exports = function(config) {
|
|
99
98
|
}
|
100
99
|
|
101
100
|
if (isAny(node, elementsCalledDecision) && isAny(node, elementsTaskDefinition)) {
|
102
|
-
errors =
|
101
|
+
errors = hasExtensionElement(node, [
|
103
102
|
'zeebe:CalledDecision',
|
104
103
|
'zeebe:TaskDefinition'
|
105
|
-
], node
|
104
|
+
], node);
|
106
105
|
} else if (isAny(node, elementsCalledDecision)) {
|
107
|
-
errors =
|
106
|
+
errors = hasExtensionElement(node, 'zeebe:CalledDecision', node);
|
108
107
|
} else {
|
109
|
-
errors =
|
108
|
+
errors = hasExtensionElement(node, 'zeebe:TaskDefinition', node);
|
110
109
|
}
|
111
110
|
|
112
111
|
if (errors && errors.length) {
|
package/rules/called-element.js
CHANGED
@@ -2,7 +2,7 @@ const { is } = require('bpmnlint-utils');
|
|
2
2
|
|
3
3
|
const {
|
4
4
|
findExtensionElement,
|
5
|
-
|
5
|
+
hasExtensionElement,
|
6
6
|
hasProperties
|
7
7
|
} = require('./utils/element');
|
8
8
|
|
@@ -14,7 +14,7 @@ module.exports = function() {
|
|
14
14
|
return;
|
15
15
|
}
|
16
16
|
|
17
|
-
let errors =
|
17
|
+
let errors = hasExtensionElement(node, 'zeebe:CalledElement', node);
|
18
18
|
|
19
19
|
if (errors && errors.length) {
|
20
20
|
reportErrors(node, reporter, errors);
|
@@ -0,0 +1,57 @@
|
|
1
|
+
const {
|
2
|
+
is,
|
3
|
+
isAny
|
4
|
+
} = require('bpmnlint-utils');
|
5
|
+
|
6
|
+
const {
|
7
|
+
findExtensionElement,
|
8
|
+
getMessageEventDefinition,
|
9
|
+
hasDuplicatedPropertyValues
|
10
|
+
} = require('./utils/element');
|
11
|
+
|
12
|
+
const { reportErrors } = require('./utils/reporter');
|
13
|
+
|
14
|
+
module.exports = function() {
|
15
|
+
function check(node, reporter) {
|
16
|
+
if (!is(node, 'bpmn:UserTask') && !isZeebeServiceTask(node)) {
|
17
|
+
return;
|
18
|
+
}
|
19
|
+
|
20
|
+
const taskHeaders = findExtensionElement(node, 'zeebe:TaskHeaders');
|
21
|
+
|
22
|
+
if (!taskHeaders) {
|
23
|
+
return;
|
24
|
+
}
|
25
|
+
|
26
|
+
const errors = hasDuplicatedPropertyValues(taskHeaders, 'values', 'key', node);
|
27
|
+
|
28
|
+
if (errors && errors.length) {
|
29
|
+
reportErrors(node, reporter, errors);
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
return {
|
34
|
+
check
|
35
|
+
};
|
36
|
+
};
|
37
|
+
|
38
|
+
// helpers //////////
|
39
|
+
|
40
|
+
function isZeebeServiceTask(element) {
|
41
|
+
if (is(element, 'zeebe:ZeebeServiceTask')) {
|
42
|
+
return true;
|
43
|
+
}
|
44
|
+
|
45
|
+
if (isAny(element, [
|
46
|
+
'bpmn:EndEvent',
|
47
|
+
'bpmn:IntermediateThrowEvent'
|
48
|
+
])) {
|
49
|
+
return getMessageEventDefinition(element);
|
50
|
+
}
|
51
|
+
|
52
|
+
if (is(element, 'bpmn:BusinessRuleTask')) {
|
53
|
+
return findExtensionElement(element, 'zeebe:TaskDefinition');
|
54
|
+
}
|
55
|
+
|
56
|
+
return false;
|
57
|
+
}
|
@@ -1,186 +1,121 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
'bpmn:UserTask'
|
25
|
-
],
|
26
|
-
elementsNoEventDefinitionRequired: [
|
27
|
-
'bpmn:EndEvent',
|
28
|
-
'bpmn:StartEvent'
|
29
|
-
],
|
30
|
-
eventDefinitions: {
|
31
|
-
'bpmn:BoundaryEvent': [
|
32
|
-
'bpmn:ErrorEventDefinition',
|
33
|
-
'bpmn:MessageEventDefinition',
|
34
|
-
'bpmn:TimerEventDefinition'
|
35
|
-
],
|
36
|
-
'bpmn:EndEvent': [
|
37
|
-
'bpmn:ErrorEventDefinition'
|
38
|
-
],
|
39
|
-
'bpmn:IntermediateCatchEvent': [
|
40
|
-
'bpmn:MessageEventDefinition',
|
41
|
-
'bpmn:TimerEventDefinition'
|
42
|
-
],
|
43
|
-
'bpmn:StartEvent': [
|
44
|
-
'bpmn:ErrorEventDefinition',
|
45
|
-
'bpmn:MessageEventDefinition',
|
46
|
-
'bpmn:TimerEventDefinition'
|
47
|
-
]
|
48
|
-
}
|
49
|
-
},
|
50
|
-
camundaCloud11: {
|
51
|
-
elements: [
|
1
|
+
const camundaCloud10Elements = [
|
2
|
+
'bpmn:Association',
|
3
|
+
'bpmn:BoundaryEvent',
|
4
|
+
'bpmn:CallActivity',
|
5
|
+
'bpmn:Collaboration',
|
6
|
+
'bpmn:Definitions',
|
7
|
+
'bpmn:EndEvent',
|
8
|
+
'bpmn:EventBasedGateway',
|
9
|
+
'bpmn:ExclusiveGateway',
|
10
|
+
'bpmn:Group',
|
11
|
+
'bpmn:IntermediateCatchEvent',
|
12
|
+
'bpmn:MessageFlow',
|
13
|
+
'bpmn:ParallelGateway',
|
14
|
+
'bpmn:Participant',
|
15
|
+
'bpmn:Process',
|
16
|
+
'bpmn:ReceiveTask',
|
17
|
+
'bpmn:SequenceFlow',
|
18
|
+
'bpmn:ServiceTask',
|
19
|
+
'bpmn:StartEvent',
|
20
|
+
'bpmn:SubProcess',
|
21
|
+
'bpmn:TextAnnotation',
|
22
|
+
'bpmn:UserTask'
|
23
|
+
];
|
52
24
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
'bpmn:ExclusiveGateway',
|
62
|
-
'bpmn:Group',
|
63
|
-
'bpmn:IntermediateCatchEvent',
|
64
|
-
'bpmn:MessageFlow',
|
65
|
-
'bpmn:ParallelGateway',
|
66
|
-
'bpmn:Participant',
|
67
|
-
'bpmn:Process',
|
68
|
-
'bpmn:ReceiveTask',
|
69
|
-
'bpmn:SequenceFlow',
|
70
|
-
'bpmn:ServiceTask',
|
71
|
-
'bpmn:StartEvent',
|
72
|
-
'bpmn:SubProcess',
|
73
|
-
'bpmn:TextAnnotation',
|
74
|
-
'bpmn:UserTask',
|
25
|
+
const camundaCloud11Elements = [
|
26
|
+
...camundaCloud10Elements,
|
27
|
+
'bpmn:BusinessRuleTask',
|
28
|
+
'bpmn:IntermediateThrowEvent',
|
29
|
+
'bpmn:ManualTask',
|
30
|
+
'bpmn:ScriptTask',
|
31
|
+
'bpmn:SendTask'
|
32
|
+
];
|
75
33
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
'bpmn:ManualTask',
|
80
|
-
'bpmn:ScriptTask',
|
81
|
-
'bpmn:SendTask'
|
82
|
-
],
|
83
|
-
elementsNoEventDefinitionRequired: [
|
34
|
+
const camundaCloud12Elements = [
|
35
|
+
...camundaCloud11Elements
|
36
|
+
];
|
84
37
|
|
85
|
-
|
86
|
-
|
87
|
-
|
38
|
+
const camundaCloud81Elements = [
|
39
|
+
...camundaCloud12Elements,
|
40
|
+
'bpmn:InclusiveGateway'
|
41
|
+
];
|
88
42
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
'bpmn:BoundaryEvent': [
|
94
|
-
'bpmn:ErrorEventDefinition',
|
95
|
-
'bpmn:MessageEventDefinition',
|
96
|
-
'bpmn:TimerEventDefinition'
|
97
|
-
],
|
98
|
-
'bpmn:EndEvent': [
|
99
|
-
'bpmn:ErrorEventDefinition'
|
100
|
-
],
|
101
|
-
'bpmn:IntermediateCatchEvent': [
|
102
|
-
'bpmn:MessageEventDefinition',
|
103
|
-
'bpmn:TimerEventDefinition'
|
104
|
-
],
|
105
|
-
'bpmn:StartEvent': [
|
106
|
-
'bpmn:ErrorEventDefinition',
|
107
|
-
'bpmn:MessageEventDefinition',
|
108
|
-
'bpmn:TimerEventDefinition'
|
109
|
-
]
|
110
|
-
}
|
111
|
-
},
|
112
|
-
camundaCloud12: {
|
113
|
-
elements: [
|
43
|
+
const camundaCloud10ElementsNoEventDefinitionRequired = [
|
44
|
+
'bpmn:EndEvent',
|
45
|
+
'bpmn:StartEvent'
|
46
|
+
];
|
114
47
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
'bpmn:Collaboration',
|
120
|
-
'bpmn:Definitions',
|
121
|
-
'bpmn:EndEvent',
|
122
|
-
'bpmn:EventBasedGateway',
|
123
|
-
'bpmn:ExclusiveGateway',
|
124
|
-
'bpmn:Group',
|
125
|
-
'bpmn:IntermediateCatchEvent',
|
126
|
-
'bpmn:MessageFlow',
|
127
|
-
'bpmn:ParallelGateway',
|
128
|
-
'bpmn:Participant',
|
129
|
-
'bpmn:Process',
|
130
|
-
'bpmn:ReceiveTask',
|
131
|
-
'bpmn:SequenceFlow',
|
132
|
-
'bpmn:ServiceTask',
|
133
|
-
'bpmn:StartEvent',
|
134
|
-
'bpmn:SubProcess',
|
135
|
-
'bpmn:TextAnnotation',
|
136
|
-
'bpmn:UserTask',
|
48
|
+
const camundaCloud11ElementsNoEventDefinitionRequired = [
|
49
|
+
...camundaCloud10ElementsNoEventDefinitionRequired,
|
50
|
+
'bpmn:IntermediateThrowEvent'
|
51
|
+
];
|
137
52
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
'bpmn:ManualTask',
|
142
|
-
'bpmn:ScriptTask',
|
143
|
-
'bpmn:SendTask'
|
144
|
-
],
|
145
|
-
elementsNoEventDefinitionRequired: [
|
53
|
+
const camundaCloud12ElementsNoEventDefinitionRequired = [
|
54
|
+
...camundaCloud11ElementsNoEventDefinitionRequired
|
55
|
+
];
|
146
56
|
|
147
|
-
|
148
|
-
|
149
|
-
|
57
|
+
const camundaCloud81ElementsNoEventDefinitionRequired = [
|
58
|
+
...camundaCloud12ElementsNoEventDefinitionRequired
|
59
|
+
];
|
150
60
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
61
|
+
const camundaCloud10EventDefinitions = {
|
62
|
+
'bpmn:BoundaryEvent': [
|
63
|
+
'bpmn:ErrorEventDefinition',
|
64
|
+
'bpmn:MessageEventDefinition',
|
65
|
+
'bpmn:TimerEventDefinition'
|
66
|
+
],
|
67
|
+
'bpmn:EndEvent': [
|
68
|
+
'bpmn:ErrorEventDefinition'
|
69
|
+
],
|
70
|
+
'bpmn:IntermediateCatchEvent': [
|
71
|
+
'bpmn:MessageEventDefinition',
|
72
|
+
'bpmn:TimerEventDefinition'
|
73
|
+
],
|
74
|
+
'bpmn:StartEvent': [
|
75
|
+
'bpmn:ErrorEventDefinition',
|
76
|
+
'bpmn:MessageEventDefinition',
|
77
|
+
'bpmn:TimerEventDefinition'
|
78
|
+
]
|
79
|
+
};
|
155
80
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
'bpmn:MessageEventDefinition',
|
160
|
-
'bpmn:TimerEventDefinition'
|
161
|
-
],
|
162
|
-
'bpmn:EndEvent': [
|
81
|
+
const camundaCloud11EventDefinitions = {
|
82
|
+
...camundaCloud10EventDefinitions
|
83
|
+
};
|
163
84
|
|
164
|
-
|
165
|
-
|
85
|
+
const camundaCloud12EventDefinitions = {
|
86
|
+
...camundaCloud11EventDefinitions,
|
87
|
+
'bpmn:EndEvent': [
|
88
|
+
...camundaCloud11EventDefinitions['bpmn:EndEvent'],
|
89
|
+
'bpmn:MessageEventDefinition'
|
90
|
+
],
|
91
|
+
'bpmn:IntermediateThrowEvent': [
|
92
|
+
'bpmn:MessageEventDefinition'
|
93
|
+
]
|
94
|
+
};
|
166
95
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
'bpmn:IntermediateCatchEvent': [
|
171
|
-
'bpmn:MessageEventDefinition',
|
172
|
-
'bpmn:TimerEventDefinition'
|
173
|
-
],
|
174
|
-
'bpmn:StartEvent': [
|
175
|
-
'bpmn:ErrorEventDefinition',
|
176
|
-
'bpmn:MessageEventDefinition',
|
177
|
-
'bpmn:TimerEventDefinition'
|
178
|
-
],
|
96
|
+
const camundaCloud81EventDefinitions = {
|
97
|
+
...camundaCloud12EventDefinitions
|
98
|
+
};
|
179
99
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
100
|
+
module.exports = {
|
101
|
+
camundaCloud10: {
|
102
|
+
elements: camundaCloud10Elements,
|
103
|
+
elementsNoEventDefinitionRequired: camundaCloud10ElementsNoEventDefinitionRequired,
|
104
|
+
eventDefinitions: camundaCloud10EventDefinitions
|
105
|
+
},
|
106
|
+
camundaCloud11: {
|
107
|
+
elements: camundaCloud11Elements,
|
108
|
+
elementsNoEventDefinitionRequired: camundaCloud11ElementsNoEventDefinitionRequired,
|
109
|
+
eventDefinitions: camundaCloud11EventDefinitions
|
110
|
+
},
|
111
|
+
camundaCloud12: {
|
112
|
+
elements: camundaCloud12Elements,
|
113
|
+
elementsNoEventDefinitionRequired: camundaCloud12ElementsNoEventDefinitionRequired,
|
114
|
+
eventDefinitions: camundaCloud12EventDefinitions
|
115
|
+
},
|
116
|
+
camundaCloud81: {
|
117
|
+
elements: camundaCloud81Elements,
|
118
|
+
elementsNoEventDefinitionRequired: camundaCloud81ElementsNoEventDefinitionRequired,
|
119
|
+
eventDefinitions: camundaCloud81EventDefinitions
|
185
120
|
}
|
186
121
|
};
|
@@ -0,0 +1,52 @@
|
|
1
|
+
const { is } = require('bpmnlint-utils');
|
2
|
+
|
3
|
+
const { hasProperties, ERROR_TYPES } = require('./utils/element');
|
4
|
+
|
5
|
+
const { reportErrors } = require('./utils/reporter');
|
6
|
+
|
7
|
+
module.exports = function() {
|
8
|
+
function check(node, reporter) {
|
9
|
+
if (!is(node, 'bpmn:InclusiveGateway')) {
|
10
|
+
return;
|
11
|
+
}
|
12
|
+
|
13
|
+
const incoming = node.get('incoming');
|
14
|
+
|
15
|
+
if (incoming && incoming.length > 1) {
|
16
|
+
const error = {
|
17
|
+
message: `Element of type <${ node.$type }> must have one property <incoming> of type <bpmn:SequenceFlow>`,
|
18
|
+
path: [ 'incoming' ],
|
19
|
+
error: {
|
20
|
+
type: ERROR_TYPES.PROPERTY_NOT_ALLOWED,
|
21
|
+
node,
|
22
|
+
parentNode: null,
|
23
|
+
property: 'incoming'
|
24
|
+
}
|
25
|
+
};
|
26
|
+
|
27
|
+
reportErrors(node, reporter, error);
|
28
|
+
}
|
29
|
+
|
30
|
+
const outgoing = node.get('outgoing');
|
31
|
+
|
32
|
+
if (outgoing && outgoing.length > 1) {
|
33
|
+
for (let sequenceFlow of outgoing) {
|
34
|
+
if (node.get('default') !== sequenceFlow) {
|
35
|
+
const errors = hasProperties(sequenceFlow, {
|
36
|
+
conditionExpression: {
|
37
|
+
required: true
|
38
|
+
}
|
39
|
+
}, sequenceFlow);
|
40
|
+
|
41
|
+
if (errors.length) {
|
42
|
+
reportErrors(sequenceFlow, reporter, errors);
|
43
|
+
}
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
return {
|
50
|
+
check
|
51
|
+
};
|
52
|
+
};
|
@@ -3,7 +3,7 @@ const { is } = require('bpmnlint-utils');
|
|
3
3
|
const {
|
4
4
|
findExtensionElement,
|
5
5
|
hasProperties,
|
6
|
-
|
6
|
+
hasExtensionElement
|
7
7
|
} = require('./utils/element');
|
8
8
|
|
9
9
|
const { reportErrors } = require('./utils/reporter');
|
@@ -32,7 +32,7 @@ module.exports = function() {
|
|
32
32
|
return;
|
33
33
|
}
|
34
34
|
|
35
|
-
errors =
|
35
|
+
errors = hasExtensionElement(loopCharacteristics, 'zeebe:LoopCharacteristics', node);
|
36
36
|
|
37
37
|
if (errors && errors.length) {
|
38
38
|
reportErrors(node, reporter, errors);
|
@@ -0,0 +1,23 @@
|
|
1
|
+
const { is } = require('bpmnlint-utils');
|
2
|
+
|
3
|
+
const { hasNoExtensionElement } = require('./utils/element');
|
4
|
+
|
5
|
+
const { reportErrors } = require('./utils/reporter');
|
6
|
+
|
7
|
+
module.exports = function() {
|
8
|
+
function check(node, reporter) {
|
9
|
+
if (!is(node, 'zeebe:PropertiesHolder')) {
|
10
|
+
return;
|
11
|
+
}
|
12
|
+
|
13
|
+
const errors = hasNoExtensionElement(node, 'zeebe:Properties', node);
|
14
|
+
|
15
|
+
if (errors && errors.length) {
|
16
|
+
reportErrors(node, reporter, errors);
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
return {
|
21
|
+
check
|
22
|
+
};
|
23
|
+
};
|
package/rules/subscription.js
CHANGED
@@ -6,7 +6,7 @@ const {
|
|
6
6
|
const {
|
7
7
|
findExtensionElement,
|
8
8
|
getEventDefinition,
|
9
|
-
|
9
|
+
hasExtensionElement,
|
10
10
|
hasProperties
|
11
11
|
} = require('./utils/element');
|
12
12
|
|
@@ -37,7 +37,7 @@ module.exports = function() {
|
|
37
37
|
return;
|
38
38
|
}
|
39
39
|
|
40
|
-
let errors =
|
40
|
+
let errors = hasExtensionElement(messageRef, 'zeebe:Subscription', node);
|
41
41
|
|
42
42
|
if (errors && errors.length) {
|
43
43
|
reportErrors(node, reporter, errors);
|
package/rules/user-task-form.js
CHANGED
package/rules/utils/element.js
CHANGED
@@ -5,7 +5,10 @@ const {
|
|
5
5
|
some
|
6
6
|
} = require('min-dash');
|
7
7
|
|
8
|
-
const {
|
8
|
+
const {
|
9
|
+
is,
|
10
|
+
isAny
|
11
|
+
} = require('bpmnlint-utils');
|
9
12
|
|
10
13
|
const { getPath } = require('@bpmn-io/moddle-utils');
|
11
14
|
|
@@ -13,12 +16,22 @@ const { ERROR_TYPES } = require('./error-types');
|
|
13
16
|
|
14
17
|
module.exports.ERROR_TYPES = ERROR_TYPES;
|
15
18
|
|
16
|
-
|
19
|
+
function getEventDefinition(node) {
|
17
20
|
const eventDefinitions = node.get('eventDefinitions');
|
18
21
|
|
19
22
|
if (eventDefinitions) {
|
20
23
|
return eventDefinitions[ 0 ];
|
21
24
|
}
|
25
|
+
}
|
26
|
+
|
27
|
+
module.exports.getEventDefinition = getEventDefinition;
|
28
|
+
|
29
|
+
module.exports.getMessageEventDefinition = function(node) {
|
30
|
+
if (is(node, 'bpmn:ReceiveTask')) {
|
31
|
+
return node;
|
32
|
+
}
|
33
|
+
|
34
|
+
return getEventDefinition(node);
|
22
35
|
};
|
23
36
|
|
24
37
|
function findExtensionElements(node, types) {
|
@@ -72,6 +85,50 @@ function formatTypes(types, exclusive = false) {
|
|
72
85
|
|
73
86
|
module.exports.formatTypes = formatTypes;
|
74
87
|
|
88
|
+
module.exports.hasDuplicatedPropertyValues = function(node, propertiesName, propertyName, parentNode = null) {
|
89
|
+
const properties = node.get(propertiesName);
|
90
|
+
|
91
|
+
const propertyValues = properties.map(property => property.get(propertyName));
|
92
|
+
|
93
|
+
// (1) find duplicates
|
94
|
+
const duplicates = propertyValues.reduce((duplicates, propertyValue, index) => {
|
95
|
+
if (propertyValues.indexOf(propertyValue) !== index && !duplicates.includes(propertyValue)) {
|
96
|
+
return [
|
97
|
+
...duplicates,
|
98
|
+
propertyValue
|
99
|
+
];
|
100
|
+
}
|
101
|
+
|
102
|
+
return duplicates;
|
103
|
+
}, []);
|
104
|
+
|
105
|
+
// (2) report error for each duplicate
|
106
|
+
if (duplicates.length) {
|
107
|
+
return duplicates.map(duplicate => {
|
108
|
+
|
109
|
+
// (3) find properties with duplicate
|
110
|
+
const duplicateProperties = properties.filter(property => property.get(propertyName) === duplicate);
|
111
|
+
|
112
|
+
// (4) report error
|
113
|
+
return {
|
114
|
+
message: `Properties of type <${ duplicateProperties[ 0 ].$type }> have property <${ propertyName }> with duplicate value of <${ duplicate }>`,
|
115
|
+
path: null,
|
116
|
+
error: {
|
117
|
+
type: ERROR_TYPES.PROPERTY_VALUE_DUPLICATED,
|
118
|
+
node,
|
119
|
+
parentNode: parentNode == node ? null : parentNode,
|
120
|
+
duplicatedProperty: propertyName,
|
121
|
+
duplicatedPropertyValue: duplicate,
|
122
|
+
properties: duplicateProperties,
|
123
|
+
propertiesName
|
124
|
+
}
|
125
|
+
};
|
126
|
+
});
|
127
|
+
}
|
128
|
+
|
129
|
+
return [];
|
130
|
+
};
|
131
|
+
|
75
132
|
module.exports.hasProperties = function(node, properties, parentNode = null) {
|
76
133
|
return Object.entries(properties).reduce((results, property) => {
|
77
134
|
const [ propertyName, propertyChecks ] = property;
|
@@ -133,7 +190,7 @@ module.exports.hasProperties = function(node, properties, parentNode = null) {
|
|
133
190
|
return [
|
134
191
|
...results,
|
135
192
|
{
|
136
|
-
message: `
|
193
|
+
message: `Element of type <${ node.$type }> must not have property <${ propertyName }> of type <${ propertyValue.$type }>`,
|
137
194
|
path: path
|
138
195
|
? [ ...path, propertyName ]
|
139
196
|
: [ propertyName ],
|
@@ -152,7 +209,7 @@ module.exports.hasProperties = function(node, properties, parentNode = null) {
|
|
152
209
|
return [
|
153
210
|
...results,
|
154
211
|
{
|
155
|
-
message: `
|
212
|
+
message: `Element of type <${ node.$type }> must not have property <${ propertyName }>`,
|
156
213
|
path: path
|
157
214
|
? [ ...path, propertyName ]
|
158
215
|
: [ propertyName ],
|
@@ -170,38 +227,21 @@ module.exports.hasProperties = function(node, properties, parentNode = null) {
|
|
170
227
|
}, []);
|
171
228
|
};
|
172
229
|
|
173
|
-
module.exports.
|
174
|
-
const
|
230
|
+
module.exports.hasExtensionElement = function(node, types, parentNode = null) {
|
231
|
+
const typesArray = isArray(types) ? types : [ types ];
|
175
232
|
|
176
|
-
|
177
|
-
return [
|
178
|
-
{
|
179
|
-
message: exclusive
|
180
|
-
? `Element of type <${ node.$type }> must have one extension element of type ${ formatTypes(types, true) }`
|
181
|
-
: `Element of type <${ node.$type }> must have one or many extension elements of type ${ formatTypes(types, true) }`,
|
182
|
-
path: getPath(node, parentNode),
|
183
|
-
error: {
|
184
|
-
type: ERROR_TYPES.EXTENSION_ELEMENT_REQUIRED,
|
185
|
-
node,
|
186
|
-
parentNode: parentNode == node ? null : parentNode,
|
187
|
-
requiredExtensionElement: types,
|
188
|
-
exclusive
|
189
|
-
}
|
190
|
-
}
|
191
|
-
];
|
192
|
-
}
|
233
|
+
const extensionElements = findExtensionElements(node, typesArray);
|
193
234
|
|
194
|
-
if (
|
235
|
+
if (!extensionElements || extensionElements.length !== 1) {
|
195
236
|
return [
|
196
237
|
{
|
197
|
-
message: `Element of type <${ node.$type }> must have one extension element of type ${ formatTypes(
|
238
|
+
message: `Element of type <${ node.$type }> must have one extension element of type ${ formatTypes(typesArray, true) }`,
|
198
239
|
path: getPath(node, parentNode),
|
199
240
|
error: {
|
200
241
|
type: ERROR_TYPES.EXTENSION_ELEMENT_REQUIRED,
|
201
242
|
node,
|
202
243
|
parentNode: parentNode == node ? null : parentNode,
|
203
|
-
requiredExtensionElement: types
|
204
|
-
exclusive
|
244
|
+
requiredExtensionElement: types
|
205
245
|
}
|
206
246
|
}
|
207
247
|
];
|
@@ -210,19 +250,19 @@ module.exports.hasExtensionElementsOfTypes = function(node, types, parentNode =
|
|
210
250
|
return [];
|
211
251
|
};
|
212
252
|
|
213
|
-
module.exports.
|
253
|
+
module.exports.hasNoExtensionElement = function(node, type, parentNode = null) {
|
214
254
|
const extensionElement = findExtensionElement(node, type);
|
215
255
|
|
216
|
-
if (
|
256
|
+
if (extensionElement) {
|
217
257
|
return [
|
218
258
|
{
|
219
|
-
message: `Element of type <${ node.$type }> must have extension element of type <${ type }>`,
|
220
|
-
path: getPath(
|
259
|
+
message: `Element of type <${ node.$type }> must not have extension element of type <${ type }>`,
|
260
|
+
path: getPath(extensionElement, parentNode),
|
221
261
|
error: {
|
222
|
-
type: ERROR_TYPES.
|
262
|
+
type: ERROR_TYPES.EXTENSION_ELEMENT_NOT_ALLOWED,
|
223
263
|
node,
|
224
264
|
parentNode: parentNode == node ? null : parentNode,
|
225
|
-
|
265
|
+
extensionElement
|
226
266
|
}
|
227
267
|
}
|
228
268
|
];
|
@@ -5,5 +5,6 @@ module.exports.ERROR_TYPES = Object.freeze({
|
|
5
5
|
PROPERTY_DEPENDEND_REQUIRED: 'propertyDependendRequired',
|
6
6
|
PROPERTY_NOT_ALLOWED: 'propertyNotAllowed',
|
7
7
|
PROPERTY_REQUIRED: 'propertyRequired',
|
8
|
-
PROPERTY_TYPE_NOT_ALLOWED: 'propertyTypeNotAllowed'
|
8
|
+
PROPERTY_TYPE_NOT_ALLOWED: 'propertyTypeNotAllowed',
|
9
|
+
PROPERTY_VALUE_DUPLICATED: 'propertyValueDuplicated'
|
9
10
|
});
|
package/CHANGELOG.md
DELETED
@@ -1,87 +0,0 @@
|
|
1
|
-
# Changelog
|
2
|
-
|
3
|
-
All notable changes to [bpmnlint-plugin-camunda-compat](https://github.com/camunda/bpmnlint-plugin-camunda-compat) are documented here. We use [semantic versioning](http://semver.org/) for releases.
|
4
|
-
|
5
|
-
## Unreleased
|
6
|
-
|
7
|
-
___Note:__ Yet to be released changes appear here._
|
8
|
-
|
9
|
-
## 0.9.2
|
10
|
-
|
11
|
-
* `FIX`: ignore null properties ([#39](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/39))
|
12
|
-
|
13
|
-
## 0.9.1
|
14
|
-
|
15
|
-
* `FIX`: add name to reports ([#38](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/38))
|
16
|
-
|
17
|
-
## 0.9.0
|
18
|
-
|
19
|
-
* `FEAT`: add user task forms rule ([#32](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/32))
|
20
|
-
|
21
|
-
## 0.8.0
|
22
|
-
|
23
|
-
* `FEAT`: add templates rule ([#31](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/31))
|
24
|
-
|
25
|
-
## 0.7.1
|
26
|
-
|
27
|
-
* `FIX`: lint subscription only if start event child of sub process ([#34](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/34))
|
28
|
-
|
29
|
-
## 0.7.0
|
30
|
-
|
31
|
-
* `FEAT`: refactor plugin structure ([#29](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/29))
|
32
|
-
* `DEPS`: update to `bpmnlint@7.8.0` ([#29](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/29))
|
33
|
-
|
34
|
-
### Breaking Changes
|
35
|
-
|
36
|
-
* configuration not selected based on execution platform and version anymore, either configure manually or use [`@camunda/linting`](https://github.com/camunda/linting)
|
37
|
-
* error message not adjusted to be shown in Camunda Modeler anymore
|
38
|
-
* error type ELEMENT_TYPE changed to ELEMENT_TYPE_NOT_ALLOWED
|
39
|
-
* error type PROPERTY_TYPE changed to PROPERTY_TYPE_NOT_ALLOWED
|
40
|
-
* error data changed (cf. docs/ERRORS.md)
|
41
|
-
|
42
|
-
## 0.6.2
|
43
|
-
|
44
|
-
* `FIX`: fix error message formatting ([#27](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/27))
|
45
|
-
|
46
|
-
## 0.6.1
|
47
|
-
|
48
|
-
* `FIX`: lanes supported ([#26](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/26))
|
49
|
-
|
50
|
-
## 0.6.0
|
51
|
-
|
52
|
-
* `FEAT`: adjust error messages to be more friendly ([#22](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/22))
|
53
|
-
* `FEAT`: lint error code and message name ([#21](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/21))
|
54
|
-
* `FIX`: task definition retries not required ([#20](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/20))
|
55
|
-
|
56
|
-
## 0.5.0
|
57
|
-
|
58
|
-
* `FEAT`: update Camunda Cloud rules to lint extension elements and their properties ([#18](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/18))
|
59
|
-
|
60
|
-
## 0.4.0
|
61
|
-
|
62
|
-
* `CHORE`: rename `Cloud` `1.4` to `8.0` ([#14](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/14))
|
63
|
-
* `CHORE`: rename `Cloud` to `Platform`/`Zeebe` ([#15](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/15))
|
64
|
-
|
65
|
-
## 0.3.0
|
66
|
-
|
67
|
-
* `FEAT`: support multiInstance for subprocesses with cloud 1.0 ([#6](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/6))
|
68
|
-
* `FEAT`: add Camunda Platform rules ([#5](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/5))
|
69
|
-
* `FEAT`: add Camunda Cloud 1.4 rule ([#5](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/5))
|
70
|
-
* `TEST`: add Cloud 1.1, 1.2, 1.3 integration tests ([#4](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/4))
|
71
|
-
* `TEST`: verify exported configs ([#5](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/5))
|
72
|
-
* `DEPS`: fix security audit warnings ([#6](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/6))
|
73
|
-
* `DOCS`: update link to documentation
|
74
|
-
* `DOCS`: link Camunda Cloud and Platform BPMN coverage
|
75
|
-
|
76
|
-
## 0.2.0
|
77
|
-
|
78
|
-
* `FEAT`: early return if execution platform does not match
|
79
|
-
* `FIX`: correct check for `bpmn:BaseElement`
|
80
|
-
|
81
|
-
## 0.1.1
|
82
|
-
|
83
|
-
* `FEAT`: initial support for Camunda Cloud 1.0, 1.1, 1.2, and 1.3
|
84
|
-
|
85
|
-
## ...
|
86
|
-
|
87
|
-
Check `git log` for earlier history.
|