bpmnlint-plugin-camunda-compat 0.5.0 → 0.6.2

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/CHANGELOG.md CHANGED
@@ -6,6 +6,20 @@ All notable changes to [bpmnlint-plugin-camunda-compat](https://github.com/camun
6
6
 
7
7
  ___Note:__ Yet to be released changes appear here._
8
8
 
9
+ ## 0.6.2
10
+
11
+ * `FIX`: fix error message formatting ([#27](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/27))
12
+
13
+ ## 0.6.1
14
+
15
+ * `FIX`: lanes supported ([#26](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/26))
16
+
17
+ ## 0.6.0
18
+
19
+ * `FEAT`: adjust error messages to be more friendly ([#22](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/22))
20
+ * `FEAT`: lint error code and message name ([#21](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/21))
21
+ * `FIX`: task definition retries not required ([#20](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/20))
22
+
9
23
  ## 0.5.0
10
24
 
11
25
  * `FEAT`: update Camunda Cloud rules to lint extension elements and their properties ([#18](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/18))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bpmnlint-plugin-camunda-compat",
3
- "version": "0.5.0",
3
+ "version": "0.6.2",
4
4
  "description": "A bpmnlint plug-in for Camunda Cloud and Platform compatibility",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -5,7 +5,7 @@ const {
5
5
  hasErrorReference,
6
6
  hasEventDefinitionOfType,
7
7
  hasEventDefinitionOfTypeOrNone,
8
- hasNoLanes,
8
+ hasMessageReference,
9
9
  isNotBpmn,
10
10
  withTranslations
11
11
  } = require('./utils/element');
@@ -35,65 +35,127 @@ module.exports = [
35
35
  'bpmn:MessageFlow',
36
36
  'bpmn:ParallelGateway',
37
37
  'bpmn:Participant',
38
+ 'bpmn:Process',
38
39
  'bpmn:SequenceFlow',
39
40
  'bpmn:TextAnnotation',
40
41
  {
41
42
  type: 'bpmn:BoundaryEvent',
42
- check: checkEvery(
43
- hasEventDefinitionOfType([
44
- 'bpmn:ErrorEventDefinition',
45
- 'bpmn:MessageEventDefinition',
46
- 'bpmn:TimerEventDefinition'
47
- ]),
48
- checkIf(
49
- checkEventDefinition(hasErrorReference),
50
- hasEventDefinitionOfType('bpmn:ErrorEventDefinition')
43
+ check: withTranslations(
44
+ checkEvery(
45
+ hasEventDefinitionOfType([
46
+ 'bpmn:ErrorEventDefinition',
47
+ 'bpmn:MessageEventDefinition',
48
+ 'bpmn:TimerEventDefinition'
49
+ ]),
50
+ checkIf(
51
+ checkEventDefinition(hasErrorReference),
52
+ hasEventDefinitionOfType('bpmn:ErrorEventDefinition')
53
+ ),
54
+ checkIf(
55
+ checkEvery(
56
+ checkEventDefinition(hasMessageReference),
57
+ checkIf(
58
+ checkEventDefinition(hasZeebeSubscription),
59
+ checkEventDefinition(hasMessageReference)
60
+ )
61
+ ),
62
+ hasEventDefinitionOfType('bpmn:MessageEventDefinition')
63
+ )
51
64
  ),
52
- checkIf(
53
- checkEventDefinition(hasZeebeSubscription),
54
- hasEventDefinitionOfType('bpmn:MessageEventDefinition')
55
- )
65
+ {
66
+ 'Element of type <bpmn:BoundaryEvent> not supported by {{ executionPlatform }}': 'An <Undefined Boundary Event> is not supported by {{ executionPlatform }}',
67
+ 'Element of type <bpmn:ErrorEventDefinition> must have property <errorRef>': 'An <Error Boundary Event> must have a defined <Error Reference>',
68
+ 'Element of type <bpmn:Error> must have property <errorCode>': 'An <Error Boundary Event> with <Error Reference> must have a defined <Error code>',
69
+ 'Element of type <bpmn:MessageEventDefinition> must have property <messageRef>': 'A <Message Boundary Event> must have a defined <Message Reference>',
70
+ 'Element of type <bpmn:Message> must have property <name>': 'A <Message Boundary Event> with <Message Reference> must have a defined <Name>',
71
+ 'Element of type <bpmn:Message> must have extension element of type <zeebe:Subscription>': 'A <Message Boundary Event> with <Message Reference> must have a defined <Subscription correlation key>',
72
+ 'Element of type <zeebe:Subscription> must have property <correlationKey>': 'A <Message Boundary Event> with <Message Reference> must have a defined <Subscription correlation key>'
73
+ }
56
74
  )
57
75
  },
58
76
  {
59
77
  type: 'bpmn:CallActivity',
60
- check: checkEvery(
61
- hasZeebeCalledElement,
62
- hasZeebeLoopCharacteristics
78
+ check: withTranslations(
79
+ checkEvery(
80
+ hasZeebeCalledElement,
81
+ hasZeebeLoopCharacteristics
82
+ ),
83
+ {
84
+ 'Element of type <bpmn:CallActivity> must have extension element of type <zeebe:CalledElement>': 'A <Call Activity> must have a defined <Called element>',
85
+ 'Element of type <zeebe:CalledElement> must have property <processId>': 'A <Call Activity> must have a defined <Called element>',
86
+ 'Element of type <bpmn:MultiInstanceLoopCharacteristics> must have extension element of type <zeebe:LoopCharacteristics>': 'A <Call Activity> with <Multi-instance marker> must have a defined <Input collection>',
87
+ 'Element of type <zeebe:LoopCharacteristics> must have property <inputCollection>': 'A <Call Activity> with <Multi-instance marker> must have a defined <Input collection>',
88
+ 'Element of type <zeebe:LoopCharacteristics> must have property <outputElement> if it has property <outputCollection>': 'A <Call Activity> with <Multi-instance marker> and defined <Output collection> must have a defined <Output element>',
89
+ 'Element of type <zeebe:LoopCharacteristics> must have property <outputCollection> if it has property <outputElement>': 'A <Call Activity> with <Multi-instance marker> and defined <Output element> must have a defined <Output collection>'
90
+ }
63
91
  )
64
92
  },
65
93
  {
66
94
  type: 'bpmn:EndEvent',
67
- check: checkEvery(
68
- hasEventDefinitionOfTypeOrNone('bpmn:ErrorEventDefinition'),
69
- checkIf(
70
- checkEventDefinition(hasErrorReference),
71
- hasEventDefinitionOfType('bpmn:ErrorEventDefinition')
72
- )
95
+ check: withTranslations(
96
+ checkEvery(
97
+ hasEventDefinitionOfTypeOrNone('bpmn:ErrorEventDefinition'),
98
+ checkIf(
99
+ checkEventDefinition(hasErrorReference),
100
+ hasEventDefinitionOfType('bpmn:ErrorEventDefinition')
101
+ )
102
+ ),
103
+ {
104
+ 'Element of type <bpmn:EndEvent> (<bpmn:MessageEventDefinition>) not supported by {{ executionPlatform }}': 'A <Message End Event> is not supported by {{ executionPlatform }}',
105
+ 'Element of type <bpmn:ErrorEventDefinition> must have property <errorRef>': 'An <Error End Event> must have a defined <Error Reference>',
106
+ 'Element of type <bpmn:Error> must have property <errorCode>': 'An <Error End Event> with <Error Reference> must have a defined <Error code>'
107
+ }
73
108
  )
74
109
  },
75
110
  {
76
111
  type: 'bpmn:IntermediateCatchEvent',
77
- check: checkEvery(
78
- hasEventDefinitionOfType([
79
- 'bpmn:TimerEventDefinition',
80
- 'bpmn:MessageEventDefinition'
81
- ]),
82
- checkIf(
83
- checkEventDefinition(hasZeebeSubscription),
84
- hasEventDefinitionOfType('bpmn:MessageEventDefinition')
85
- )
112
+ check: withTranslations(
113
+ checkEvery(
114
+ hasEventDefinitionOfType([
115
+ 'bpmn:TimerEventDefinition',
116
+ 'bpmn:MessageEventDefinition'
117
+ ]),
118
+ checkIf(
119
+ checkEvery(
120
+ checkEventDefinition(hasMessageReference),
121
+ checkIf(
122
+ checkEventDefinition(hasZeebeSubscription),
123
+ checkEventDefinition(hasMessageReference)
124
+ )
125
+ ),
126
+ hasEventDefinitionOfType('bpmn:MessageEventDefinition')
127
+ )
128
+ ),
129
+ {
130
+ 'Element of type <bpmn:IntermediateCatchEvent> not supported by {{ executionPlatform }}': 'A <Undefined Intermediate Catch Event> is not supported by {{ executionPlatform }}',
131
+ 'Element of type <bpmn:MessageEventDefinition> must have property <messageRef>': 'A <Message Intermediate Catch Event> must have a defined <Message Reference>',
132
+ 'Element of type <bpmn:Message> must have property <name>': 'A <Message Intermediate Catch Event> with <Message Reference> must have a defined <Name>',
133
+ 'Element of type <bpmn:Message> must have extension element of type <zeebe:Subscription>': 'A <Message Intermediate Catch Event> with <Message Reference> must have a defined <Subscription correlation key>',
134
+ 'Element of type <zeebe:Subscription> must have property <correlationKey>': 'A <Message Intermediate Catch Event> with <Message Reference> must have a defined <Subscription correlation key>'
135
+ }
86
136
  )
87
137
  },
88
- {
89
- type: 'bpmn:Process',
90
- check: hasNoLanes
91
- },
92
138
  {
93
139
  type: 'bpmn:ReceiveTask',
94
- check: checkEvery(
95
- checkFlowNode(hasZeebeSubscription),
96
- hasZeebeLoopCharacteristics
140
+ check: withTranslations(
141
+ checkEvery(
142
+ checkFlowNode(hasMessageReference),
143
+ checkIf(
144
+ checkFlowNode(hasZeebeSubscription),
145
+ checkFlowNode(hasMessageReference)
146
+ ),
147
+ hasZeebeLoopCharacteristics
148
+ ),
149
+ {
150
+ 'Element of type <bpmn:MultiInstanceLoopCharacteristics> must have extension element of type <zeebe:LoopCharacteristics>': 'A <Receive Task> with <Multi-instance marker> must have a defined <Input collection>',
151
+ 'Element of type <zeebe:LoopCharacteristics> must have property <inputCollection>': 'A <Receive Task> with <Multi-instance marker> must have a defined <Input collection>',
152
+ 'Element of type <zeebe:LoopCharacteristics> must have property <outputElement> if it has property <outputCollection>': 'A <Receive Task> with <Multi-instance marker> and defined <Output collection> must have a defined <Output element>',
153
+ 'Element of type <zeebe:LoopCharacteristics> must have property <outputCollection> if it has property <outputElement>': 'A <Receive Task> with <Multi-instance marker> and defined <Output element> must have a defined <Output collection>',
154
+ 'Element of type <bpmn:ReceiveTask> must have property <messageRef>': 'A <Receive Task> must have a defined <Message Reference>',
155
+ 'Element of type <bpmn:Message> must have property <name>': 'A <Receive Task> with <Message Reference> must have a defined <Name>',
156
+ 'Element of type <bpmn:Message> must have extension element of type <zeebe:Subscription>': 'A <Receive Task> with <Message Reference> must have a defined <Subscription correlation key>',
157
+ 'Element of type <zeebe:Subscription> must have property <correlationKey>': 'A <Receive Task> with <Message Reference> must have a defined <Subscription correlation key>'
158
+ }
97
159
  )
98
160
  },
99
161
  {
@@ -104,34 +166,71 @@ module.exports = [
104
166
  hasZeebeTaskDefinition
105
167
  ),
106
168
  {
107
- 'foo': 'bar'
169
+ 'Element of type <bpmn:ServiceTask> must have extension element of type <zeebe:TaskDefinition>': 'A <Service Task> must have a <Task definition type>',
170
+ 'Element of type <zeebe:TaskDefinition> must have property <type>': 'A <Service Task> must have a <Task definition type>',
171
+ 'Element of type <bpmn:MultiInstanceLoopCharacteristics> must have extension element of type <zeebe:LoopCharacteristics>': 'A <Service Task> with <Multi-instance marker> must have a defined <Input collection>',
172
+ 'Element of type <zeebe:LoopCharacteristics> must have property <inputCollection>': 'A <Service Task> with <Multi-instance marker> must have a defined <Input collection>',
173
+ 'Element of type <zeebe:LoopCharacteristics> must have property <outputElement> if it has property <outputCollection>': 'A <Service Task> with <Multi-instance marker> and defined <Output collection> must have a defined <Output element>',
174
+ 'Element of type <zeebe:LoopCharacteristics> must have property <outputCollection> if it has property <outputElement>': 'A <Service Task> with <Multi-instance marker> and defined <Output element> must have a defined <Output collection>'
108
175
  }
109
176
  )
110
177
  },
111
178
  {
112
179
  type: 'bpmn:StartEvent',
113
- check: checkEvery(
114
- hasEventDefinitionOfTypeOrNone([
115
- 'bpmn:ErrorEventDefinition',
116
- 'bpmn:MessageEventDefinition',
117
- 'bpmn:TimerEventDefinition'
118
- ]),
119
- checkIf(
120
- checkEventDefinition(hasErrorReference),
121
- hasEventDefinitionOfType('bpmn:ErrorEventDefinition')
180
+ check: withTranslations(
181
+ checkEvery(
182
+ hasEventDefinitionOfTypeOrNone([
183
+ 'bpmn:ErrorEventDefinition',
184
+ 'bpmn:MessageEventDefinition',
185
+ 'bpmn:TimerEventDefinition'
186
+ ]),
187
+ checkIf(
188
+ checkEventDefinition(hasErrorReference),
189
+ hasEventDefinitionOfType('bpmn:ErrorEventDefinition')
190
+ ),
191
+ checkIf(
192
+ checkEvery(
193
+ checkEventDefinition(hasMessageReference),
194
+ checkIf(
195
+ checkEventDefinition(hasZeebeSubscription),
196
+ checkEventDefinition(hasMessageReference)
197
+ )
198
+ ),
199
+ hasEventDefinitionOfType('bpmn:MessageEventDefinition')
200
+ )
122
201
  ),
123
- checkIf(
124
- checkEventDefinition(hasZeebeSubscription),
125
- hasEventDefinitionOfType('bpmn:MessageEventDefinition')
126
- )
202
+ {
203
+ 'Element of type <bpmn:ErrorEventDefinition> must have property <errorRef>': 'An <Error Start Event> must have a defined <Error Reference>',
204
+ 'Element of type <bpmn:Error> must have property <errorCode>': 'An <Error Start Event> with <Error Reference> must have a defined <Error code>',
205
+ 'Element of type <bpmn:MessageEventDefinition> must have property <messageRef>': 'A <Message Start Event> must have a defined <Message Reference>',
206
+ 'Element of type <bpmn:Message> must have property <name>': 'A <Message Start Event> with <Message Reference> must have a defined <Name>',
207
+ 'Element of type <bpmn:Message> must have extension element of type <zeebe:Subscription>': 'A <Message Start Event> with <Message Reference> must have a defined <Subscription correlation key>',
208
+ 'Element of type <zeebe:Subscription> must have property <correlationKey>': 'A <Message Start Event> with <Message Reference> must have a defined <Subscription correlation key>'
209
+ }
127
210
  )
128
211
  },
129
212
  {
130
213
  type: 'bpmn:SubProcess',
131
- check: hasZeebeLoopCharacteristics
214
+ check: withTranslations(
215
+ hasZeebeLoopCharacteristics,
216
+ {
217
+ 'Element of type <bpmn:MultiInstanceLoopCharacteristics> must have extension element of type <zeebe:LoopCharacteristics>': 'A <Sub Process> with <Multi-instance marker> must have a defined <Input collection>',
218
+ 'Element of type <zeebe:LoopCharacteristics> must have property <inputCollection>': 'A <Sub Process> with <Multi-instance marker> must have a defined <Input collection>',
219
+ 'Element of type <zeebe:LoopCharacteristics> must have property <outputElement> if it has property <outputCollection>': 'A <Sub Process> with <Multi-instance marker> and defined <Output collection> must have a defined <Output element>',
220
+ 'Element of type <zeebe:LoopCharacteristics> must have property <outputCollection> if it has property <outputElement>': 'A <Sub Process> with <Multi-instance marker> and defined <Output element> must have a defined <Output collection>'
221
+ }
222
+ )
132
223
  },
133
224
  {
134
225
  type: 'bpmn:UserTask',
135
- check: hasZeebeLoopCharacteristics
226
+ check: withTranslations(
227
+ hasZeebeLoopCharacteristics,
228
+ {
229
+ 'Element of type <bpmn:MultiInstanceLoopCharacteristics> must have extension element of type <zeebe:LoopCharacteristics>': 'A <User Task> with <Multi-instance marker> must have a defined <Input collection>',
230
+ 'Element of type <zeebe:LoopCharacteristics> must have property <inputCollection>': 'A <User Task> with <Multi-instance marker> must have a defined <Input collection>',
231
+ 'Element of type <zeebe:LoopCharacteristics> must have property <outputElement> if it has property <outputCollection>': 'A <User Task> with <Multi-instance marker> and defined <Output collection> must have a defined <Output element>',
232
+ 'Element of type <zeebe:LoopCharacteristics> must have property <outputCollection> if it has property <outputElement>': 'A <User Task> with <Multi-instance marker> and defined <Output element> must have a defined <Output collection>'
233
+ }
234
+ )
136
235
  }
137
236
  ];
@@ -2,4 +2,4 @@ const { createRule } = require('./utils/rule');
2
2
 
3
3
  const checks = require('./camunda-cloud-1-0-checks');
4
4
 
5
- module.exports = createRule('Camunda Cloud', '1.0', checks, 'Zeebe');
5
+ module.exports = createRule('Camunda Cloud', '1.0', checks, 'Camunda Platform 8 (Zeebe 1.0)');
@@ -2,7 +2,10 @@ const camundaCloud10Checks = require('./camunda-cloud-1-0-checks');
2
2
 
3
3
  const { checkEvery } = require('./utils/rule');
4
4
 
5
- const { hasNoEventDefinition } = require('./utils/element');
5
+ const {
6
+ hasNoEventDefinition,
7
+ withTranslations
8
+ } = require('./utils/element');
6
9
 
7
10
  const {
8
11
  hasZeebeTaskDefinition,
@@ -13,31 +16,74 @@ module.exports = [
13
16
  ...camundaCloud10Checks,
14
17
  {
15
18
  type: 'bpmn:BusinessRuleTask',
16
- check: checkEvery(
17
- hasZeebeLoopCharacteristics,
18
- hasZeebeTaskDefinition
19
+ check: withTranslations(
20
+ checkEvery(
21
+ hasZeebeLoopCharacteristics,
22
+ hasZeebeTaskDefinition
23
+ ),
24
+ {
25
+ 'Element of type <bpmn:BusinessRuleTask> must have extension element of type <zeebe:TaskDefinition>': 'A <Business Rule Task> must have a <Task definition type>',
26
+ 'Element of type <zeebe:TaskDefinition> must have property <type>': 'A <Business Rule Task> must have a <Task definition type>',
27
+ 'Element of type <bpmn:MultiInstanceLoopCharacteristics> must have extension element of type <zeebe:LoopCharacteristics>': 'A <Business Rule Task> with <Multi-instance marker> must have a defined <Input collection>',
28
+ 'Element of type <zeebe:LoopCharacteristics> must have property <inputCollection>': 'A <Business Rule Task> with <Multi-instance marker> must have a defined <Input collection>',
29
+ 'Element of type <zeebe:LoopCharacteristics> must have property <outputElement> if it has property <outputCollection>': 'A <Business Rule Task> with <Multi-instance marker> and defined <Output collection> must have a defined <Output element>',
30
+ 'Element of type <zeebe:LoopCharacteristics> must have property <outputCollection> if it has property <outputElement>': 'A <Business Rule Task> with <Multi-instance marker> and defined <Output element> must have a defined <Output collection>'
31
+ }
19
32
  )
20
33
  },
21
34
  {
22
35
  type: 'bpmn:IntermediateThrowEvent',
23
- check: hasNoEventDefinition
36
+ check: withTranslations(
37
+ hasNoEventDefinition,
38
+ {
39
+ 'Element of type <bpmn:IntermediateThrowEvent> (<bpmn:MessageEventDefinition>) not supported by {{ executionPlatform }}': 'A <Message Intermediate Throw Event> is not supported by {{ executionPlatform }}'
40
+ }
41
+ )
24
42
  },
25
43
  {
26
44
  type: 'bpmn:ManualTask',
27
- check: hasZeebeLoopCharacteristics
45
+ check: withTranslations(
46
+ hasZeebeLoopCharacteristics,
47
+ {
48
+ 'Element of type <bpmn:MultiInstanceLoopCharacteristics> must have extension element of type <zeebe:LoopCharacteristics>': 'A <Manual Task> with <Multi-instance marker> must have a defined <Input collection>',
49
+ 'Element of type <zeebe:LoopCharacteristics> must have property <inputCollection>': 'A <Manual Task> with <Multi-instance marker> must have a defined <Input collection>',
50
+ 'Element of type <zeebe:LoopCharacteristics> must have property <outputElement> if it has property <outputCollection>': 'A <Manual Task> with <Multi-instance marker> and defined <Output collection> must have a defined <Output element>',
51
+ 'Element of type <zeebe:LoopCharacteristics> must have property <outputCollection> if it has property <outputElement>': 'A <Manual Task> with <Multi-instance marker> and defined <Output element> must have a defined <Output collection>'
52
+ }
53
+ )
28
54
  },
29
55
  {
30
56
  type: 'bpmn:ScriptTask',
31
- check: checkEvery(
32
- hasZeebeLoopCharacteristics,
33
- hasZeebeTaskDefinition
57
+ check: withTranslations(
58
+ checkEvery(
59
+ hasZeebeLoopCharacteristics,
60
+ hasZeebeTaskDefinition
61
+ ),
62
+ {
63
+ 'Element of type <bpmn:ScriptTask> must have extension element of type <zeebe:TaskDefinition>': 'A <Script Task> must have a <Task definition type>',
64
+ 'Element of type <zeebe:TaskDefinition> must have property <type>': 'A <Script Task> must have a <Task definition type>',
65
+ 'Element of type <bpmn:MultiInstanceLoopCharacteristics> must have extension element of type <zeebe:LoopCharacteristics>': 'A <Script Task> with <Multi-instance marker> must have a defined <Input collection>',
66
+ 'Element of type <zeebe:LoopCharacteristics> must have property <inputCollection>': 'A <Script Task> with <Multi-instance marker> must have a defined <Input collection>',
67
+ 'Element of type <zeebe:LoopCharacteristics> must have property <outputElement> if it has property <outputCollection>': 'A <Script Task> with <Multi-instance marker> and defined <Output collection> must have a defined <Output element>',
68
+ 'Element of type <zeebe:LoopCharacteristics> must have property <outputCollection> if it has property <outputElement>': 'A <Script Task> with <Multi-instance marker> and defined <Output element> must have a defined <Output collection>'
69
+ }
34
70
  )
35
71
  },
36
72
  {
37
73
  type: 'bpmn:SendTask',
38
- check: checkEvery(
39
- hasZeebeLoopCharacteristics,
40
- hasZeebeTaskDefinition
74
+ check: withTranslations(
75
+ checkEvery(
76
+ hasZeebeLoopCharacteristics,
77
+ hasZeebeTaskDefinition
78
+ ),
79
+ {
80
+ 'Element of type <bpmn:SendTask> must have extension element of type <zeebe:TaskDefinition>': 'A <Send Task> must have a <Task definition type>',
81
+ 'Element of type <zeebe:TaskDefinition> must have property <type>': 'A <Send Task> must have a <Task definition type>',
82
+ 'Element of type <bpmn:MultiInstanceLoopCharacteristics> must have extension element of type <zeebe:LoopCharacteristics>': 'A <Send Task> with <Multi-instance marker> must have a defined <Input collection>',
83
+ 'Element of type <zeebe:LoopCharacteristics> must have property <inputCollection>': 'A <Send Task> with <Multi-instance marker> must have a defined <Input collection>',
84
+ 'Element of type <zeebe:LoopCharacteristics> must have property <outputElement> if it has property <outputCollection>': 'A <Send Task> with <Multi-instance marker> and defined <Output collection> must have a defined <Output element>',
85
+ 'Element of type <zeebe:LoopCharacteristics> must have property <outputCollection> if it has property <outputElement>': 'A <Send Task> with <Multi-instance marker> and defined <Output element> must have a defined <Output collection>'
86
+ }
41
87
  )
42
88
  }
43
89
  ];
@@ -2,4 +2,4 @@ const { createRule } = require('./utils/rule');
2
2
 
3
3
  const checks = require('./camunda-cloud-1-1-checks');
4
4
 
5
- module.exports = createRule('Camunda Cloud', '1.1', checks, 'Zeebe');
5
+ module.exports = createRule('Camunda Cloud', '1.1', checks, 'Camunda Platform 8 (Zeebe 1.1)');
@@ -11,6 +11,7 @@ const {
11
11
  hasErrorReference,
12
12
  hasEventDefinitionOfType,
13
13
  hasEventDefinitionOfTypeOrNone,
14
+ withTranslations
14
15
  } = require('./utils/element');
15
16
 
16
17
  const { hasZeebeTaskDefinition } = require('./utils/cloud/element');
@@ -21,25 +22,37 @@ module.exports = [
21
22
  [
22
23
  {
23
24
  type: 'bpmn:IntermediateThrowEvent',
24
- check: checkEvery(
25
- hasEventDefinitionOfTypeOrNone('bpmn:MessageEventDefinition'),
26
- checkIf(
27
- hasZeebeTaskDefinition,
28
- hasEventDefinitionOfType('bpmn:MessageEventDefinition')
29
- )
25
+ check: withTranslations(
26
+ checkEvery(
27
+ hasEventDefinitionOfTypeOrNone('bpmn:MessageEventDefinition'),
28
+ checkIf(
29
+ hasZeebeTaskDefinition,
30
+ hasEventDefinitionOfType('bpmn:MessageEventDefinition')
31
+ )
32
+ ),
33
+ {
34
+ 'Element of type <bpmn:IntermediateThrowEvent> must have extension element of type <zeebe:TaskDefinition>': 'An <Intermediate Throw Event> must have a <Task definition type>',
35
+ 'Element of type <zeebe:TaskDefinition> must have property <type>': 'An <Intermediate Throw Event> must have a <Task definition type>'
36
+ }
30
37
  )
31
38
  },
32
39
  {
33
40
  type: 'bpmn:EndEvent',
34
- check: checkEvery(
35
- hasEventDefinitionOfTypeOrNone([
36
- 'bpmn:ErrorEventDefinition',
37
- 'bpmn:MessageEventDefinition'
38
- ]),
39
- checkIf(
40
- checkEventDefinition(hasErrorReference),
41
- hasEventDefinitionOfType('bpmn:ErrorEventDefinition')
42
- )
41
+ check: withTranslations(
42
+ checkEvery(
43
+ hasEventDefinitionOfTypeOrNone([
44
+ 'bpmn:ErrorEventDefinition',
45
+ 'bpmn:MessageEventDefinition'
46
+ ]),
47
+ checkIf(
48
+ checkEventDefinition(hasErrorReference),
49
+ hasEventDefinitionOfType('bpmn:ErrorEventDefinition')
50
+ )
51
+ ),
52
+ {
53
+ 'Element of type <bpmn:ErrorEventDefinition> must have property <errorRef>': 'An <Error End Event> must have a defined <Error Reference>',
54
+ 'Element of type <bpmn:Error> must have property <errorCode>': 'An <Error End Event> with <Error Reference> must have a defined <Error code>'
55
+ }
43
56
  )
44
57
  }
45
58
  ]
@@ -2,4 +2,4 @@ const { createRule } = require('./utils/rule');
2
2
 
3
3
  const checks = require('./camunda-cloud-1-2-checks');
4
4
 
5
- module.exports = createRule('Camunda Cloud', '1.2', checks, 'Zeebe');
5
+ module.exports = createRule('Camunda Cloud', '1.2', checks, 'Camunda Platform 8 (Zeebe 1.2)');
@@ -5,6 +5,8 @@ const {
5
5
  replaceCheck
6
6
  } = require('./utils/rule');
7
7
 
8
+ const { withTranslations } = require('./utils/element');
9
+
8
10
  const {
9
11
  hasZeebeCalledDecisionOrTaskDefinition,
10
12
  hasZeebeLoopCharacteristics
@@ -14,9 +16,22 @@ module.exports = [
14
16
  ...replaceCheck(
15
17
  camundaCloud12Checks,
16
18
  'bpmn:BusinessRuleTask',
17
- checkEvery(
18
- hasZeebeCalledDecisionOrTaskDefinition,
19
- hasZeebeLoopCharacteristics
19
+ withTranslations(
20
+ checkEvery(
21
+ hasZeebeCalledDecisionOrTaskDefinition,
22
+ hasZeebeLoopCharacteristics
23
+ ),
24
+ {
25
+ 'Element of type <bpmn:BusinessRuleTask> must have one extension element of type <zeebe:CalledDecision> or <zeebe:TaskDefinition>': 'A <Business Rule Task> must have a defined <Implementation>',
26
+ 'Element of type <bpmn:BusinessRuleTask> must have one or many extension elements of type <zeebe:CalledDecision> or <zeebe:TaskDefinition>': 'A <Business Rule Task> must have a defined <Implementation>',
27
+ 'Element of type <zeebe:TaskDefinition> must have property <type>': 'A <Business Rule Task> with <Implementation: Job worker> must have a defined <Task definition type>',
28
+ 'Element of type <zeebe:CalledDecision> must have property <decisionId>': 'A <Business Rule Task> with <Implementation: DMN decision> must have a defined <Called decision ID>',
29
+ 'Element of type <zeebe:CalledDecision> must have property <resultVariable>': 'A <Business Rule Task> with <Implementation: DMN decision> must have a defined <Result variable>',
30
+ 'Element of type <bpmn:MultiInstanceLoopCharacteristics> must have extension element of type <zeebe:LoopCharacteristics>': 'A <Business Rule Task> with <Multi-instance marker> must have a defined <Input collection>',
31
+ 'Element of type <zeebe:LoopCharacteristics> must have property <inputCollection>': 'A <Business Rule Task> with <Multi-instance marker> must have a defined <Input collection>',
32
+ 'Element of type <zeebe:LoopCharacteristics> must have property <outputElement> if it has property <outputCollection>': 'A <Business Rule Task> with <Multi-instance marker> and defined <Output collection> must have a defined <Output element>',
33
+ 'Element of type <zeebe:LoopCharacteristics> must have property <outputCollection> if it has property <outputElement>': 'A <Business Rule Task> with <Multi-instance marker> and defined <Output element> must have a defined <Output collection>'
34
+ }
20
35
  )
21
36
  )
22
37
  ];
@@ -2,4 +2,4 @@ const { createRule } = require('./utils/rule');
2
2
 
3
3
  const checks = require('./camunda-cloud-1-3-checks');
4
4
 
5
- module.exports = createRule('Camunda Cloud', '1.3', checks, 'Zeebe');
5
+ module.exports = createRule('Camunda Cloud', '1.3', checks, 'Camunda Platform 8 (Zeebe 1.3)');
@@ -2,4 +2,4 @@ const { createRule } = require('./utils/rule');
2
2
 
3
3
  const checks = require('./camunda-cloud-8-0-checks');
4
4
 
5
- module.exports = createRule('Camunda Cloud', '8.0', checks, 'Camunda Platform');
5
+ module.exports = createRule('Camunda Cloud', '8.0', checks, 'Camunda Platform 8');
@@ -29,9 +29,6 @@ module.exports.hasZeebeCalledDecisionOrTaskDefinition = checkFlowNode(
29
29
  properties: {
30
30
  type: {
31
31
  required: true
32
- },
33
- retries: {
34
- required: true
35
32
  }
36
33
  }
37
34
  }
@@ -102,9 +99,6 @@ module.exports.hasZeebeTaskDefinition = checkFlowNode(
102
99
  properties: {
103
100
  type: {
104
101
  required: true
105
- },
106
- retries: {
107
- required: true
108
102
  }
109
103
  }
110
104
  })
@@ -131,14 +131,6 @@ module.exports.hasMultiInstanceLoopCharacteristics = function(node) {
131
131
  return true;
132
132
  };
133
133
 
134
- module.exports.hasNoLanes = function(node) {
135
- const laneSets = node.get('laneSets');
136
-
137
- return !laneSets
138
- || !laneSets.length
139
- || getElementNotSupportedError(node.$type, 'bpmn:LaneSet', [ 'laneSets' ]);
140
- };
141
-
142
134
  module.exports.isNotBpmn = function(node) {
143
135
  return !is(node, 'bpmn:BaseElement');
144
136
  };
@@ -176,7 +168,7 @@ module.exports.findExtensionElement = findExtensionElement;
176
168
  function getElementNotSupportedError(type, propertyType, path = null) {
177
169
  if (propertyType) {
178
170
  return {
179
- message: `Element of type <${ type }> (<${ propertyType }>) not supported by {{ executionPlatform }} {{ executionPlatformVersion }}`,
171
+ message: `Element of type <${ type }> (<${ propertyType }>) not supported by {{ executionPlatform }}`,
180
172
  path,
181
173
  error: {
182
174
  type: ERROR_TYPES.ELEMENT_TYPE,
@@ -187,7 +179,7 @@ function getElementNotSupportedError(type, propertyType, path = null) {
187
179
  }
188
180
 
189
181
  return {
190
- message: `Element of type <${ type }> not supported by {{ executionPlatform }} {{ executionPlatformVersion }}`,
182
+ message: `Element of type <${ type }> not supported by {{ executionPlatform }}`,
191
183
  path,
192
184
  error: {
193
185
  type: ERROR_TYPES.ELEMENT_TYPE,
@@ -288,7 +280,7 @@ function checkProperties(node, properties, parentNode) {
288
280
  return [
289
281
  ...results,
290
282
  {
291
- message: `Element of type <${ node.$type }> must have property <${ propertyName }> if property <${ propertyChecks.dependendRequired }> is set`,
283
+ message: `Element of type <${ node.$type }> must have property <${ propertyName }> if it has property <${ propertyChecks.dependendRequired }>`,
292
284
  path: path
293
285
  ? [ ...path, propertyName ]
294
286
  : [ propertyName ],
@@ -343,8 +335,7 @@ module.exports.checkProperties = checkProperties;
343
335
  * {
344
336
  * type: 'zeebe:TaskDefinition',
345
337
  * properties: {
346
- * type: { required: true },
347
- * retries: { required: true }
338
+ * type: { required: true }
348
339
  * }
349
340
  * }
350
341
  * ]);
@@ -361,7 +352,7 @@ module.exports.hasExtensionElementsOfTypes = function(types, exclusive = false)
361
352
 
362
353
  if (!extensionElements || !extensionElements.length) {
363
354
  return {
364
- message: `Element of type <${ node.$type }> must have have at least one ${ formatTypes(types, true) } extension element`,
355
+ message: `Element of type <${ node.$type }> must have one or many extension elements of type ${ formatTypes(types, true) }`,
365
356
  path: getPath(node, parentNode),
366
357
  error: {
367
358
  type: ERROR_TYPES.EXTENSION_ELEMENT_REQUIRED,
@@ -372,7 +363,7 @@ module.exports.hasExtensionElementsOfTypes = function(types, exclusive = false)
372
363
 
373
364
  if (exclusive && extensionElements.length > 1) {
374
365
  return {
375
- message: `Element of type <${ node.$type }> must have have either one ${ formatTypes(types, true) } extension element`,
366
+ message: `Element of type <${ node.$type }> must have one extension element of type ${ formatTypes(types, true) }`,
376
367
  path: getPath(node, parentNode)
377
368
  };
378
369
  }
@@ -415,8 +406,7 @@ module.exports.hasExtensionElementsOfTypes = function(types, exclusive = false)
415
406
  * {
416
407
  * type: 'zeebe:TaskDefinition',
417
408
  * properties: {
418
- * type: { required: true },
419
- * retries: { required: true }
409
+ * type: { required: true }
420
410
  * }
421
411
  * }
422
412
  * );
@@ -433,9 +423,7 @@ module.exports.hasExtensionElementOfType = function(type) {
433
423
 
434
424
  if (!extensionElement) {
435
425
  return {
436
- message: `Element of type <${ node.$type }> must have <${getType(
437
- type
438
- )}> extension element`,
426
+ message: `Element of type <${ node.$type }> must have extension element of type <${ getType(type) }>`,
439
427
  path: getPath(node, parentNode),
440
428
  error: {
441
429
  type: ERROR_TYPES.EXTENSION_ELEMENT_REQUIRED,
@@ -552,7 +540,7 @@ module.exports.checkFlowNode = function(check) {
552
540
  *
553
541
  * @returns {Function}
554
542
  */
555
- module.exports.checkMessage = function(check) {
543
+ function checkMessage(check) {
556
544
  return function(node, parentNode) {
557
545
  const results = checkProperties(node, {
558
546
  messageRef: {
@@ -570,7 +558,9 @@ module.exports.checkMessage = function(check) {
570
558
 
571
559
  return check(message);
572
560
  };
573
- };
561
+ }
562
+
563
+ module.exports.checkMessage = checkMessage;
574
564
 
575
565
  /**
576
566
  * @example
@@ -603,7 +593,41 @@ module.exports.checkLoopCharacteristics = function(check) {
603
593
  };
604
594
  };
605
595
 
606
- module.exports.hasErrorReference = checkError(() => true);
596
+ module.exports.hasErrorReference = checkError(
597
+ (node) => {
598
+ const results = checkProperties(node, {
599
+ errorCode: {
600
+ required: true
601
+ }
602
+ });
603
+
604
+ if (results.length === 1) {
605
+ return results[ 0 ];
606
+ } else if (results.length > 1) {
607
+ return results;
608
+ }
609
+
610
+ return true;
611
+ }
612
+ );
613
+
614
+ module.exports.hasMessageReference = checkMessage(
615
+ (node) => {
616
+ const results = checkProperties(node, {
617
+ name: {
618
+ required: true
619
+ }
620
+ });
621
+
622
+ if (results.length === 1) {
623
+ return results[ 0 ];
624
+ } else if (results.length > 1) {
625
+ return results;
626
+ }
627
+
628
+ return true;
629
+ }
630
+ );
607
631
 
608
632
  function translate(result, translations) {
609
633
  if (isString(result)) {
@@ -13,6 +13,10 @@ const {
13
13
 
14
14
  const { toSemverMinor } = require('./engine-profile');
15
15
 
16
+ const { ERROR_TYPES } = require('./element');
17
+
18
+ const { getTypeString } = require('./type');
19
+
16
20
  /**
17
21
  * Factory function for rules. Returns a rule for a given execution platform,
18
22
  * execution platform version and an array of checks. Must be run on
@@ -23,6 +27,7 @@ const { toSemverMinor } = require('./engine-profile');
23
27
  * @param {string} ruleExecutionPlatform
24
28
  * @param {string} ruleExecutionPlatformVersion
25
29
  * @param {(Object|string)[]} checks
30
+ * @param {string} executionPlatformLabel
26
31
  *
27
32
  * @returns {Function}
28
33
  */
@@ -52,8 +57,26 @@ module.exports.createRule = function(ruleExecutionPlatform, ruleExecutionPlatfor
52
57
 
53
58
  const id = node.get('id') || '';
54
59
 
60
+ const label = getLabel(node);
61
+
55
62
  if (results === false) {
56
- reporter.report(id, `Element of type <${ node.$type }> not supported by ${ executionPlatformLabel || ruleExecutionPlatform } ${ toSemverMinor(ruleExecutionPlatformVersion) }`);
63
+ const message = getMessage(node, ruleExecutionPlatform, ruleExecutionPlatformVersion, executionPlatformLabel);
64
+
65
+ let options = {
66
+ error: {
67
+ type: ERROR_TYPES.ELEMENT_TYPE,
68
+ element: node.$type
69
+ }
70
+ };
71
+
72
+ if (label) {
73
+ options = {
74
+ ...options,
75
+ label
76
+ };
77
+ }
78
+
79
+ reporter.report(id, message, options);
57
80
  } else {
58
81
  if (!isArray(results)) {
59
82
  results = [ results ];
@@ -69,9 +92,20 @@ module.exports.createRule = function(ruleExecutionPlatform, ruleExecutionPlatfor
69
92
  ...rest
70
93
  } = result;
71
94
 
72
- message = addExecutionPlatform(message, executionPlatformLabel || ruleExecutionPlatform, toSemverMinor(ruleExecutionPlatformVersion));
95
+ message = addExecutionPlatform(message, executionPlatformLabel || `${ ruleExecutionPlatform } ${ toSemverMinor(ruleExecutionPlatformVersion) }`);
96
+
97
+ let options = {
98
+ ...rest
99
+ };
73
100
 
74
- reporter.report(id, message, rest);
101
+ if (label) {
102
+ options = {
103
+ ...options,
104
+ label
105
+ };
106
+ }
107
+
108
+ reporter.report(id, message, options);
75
109
  });
76
110
  }
77
111
  }
@@ -106,7 +140,7 @@ function checkNode(node, checks) {
106
140
 
107
141
  // (1) check using type only
108
142
  if (isString(check)) {
109
- return is(node, check);
143
+ return isExactly(node, check);
110
144
  }
111
145
 
112
146
  const { type } = check;
@@ -117,7 +151,7 @@ function checkNode(node, checks) {
117
151
  }
118
152
 
119
153
  // (3) check using type and function
120
- if (!is(node, type)) {
154
+ if (!isExactly(node, type)) {
121
155
  return false;
122
156
  }
123
157
 
@@ -209,10 +243,9 @@ function replaceChecks(checks, replacements) {
209
243
 
210
244
  module.exports.replaceChecks = replaceChecks;
211
245
 
212
- function addExecutionPlatform(string, executionPlatform, executionPlatformVersion) {
246
+ function addExecutionPlatform(string, executionPlatform) {
213
247
  return string
214
- .replace('{{ executionPlatform }}', executionPlatform)
215
- .replace('{{ executionPlatformVersion }}', executionPlatformVersion);
248
+ .replace('{{ executionPlatform }}', executionPlatform);
216
249
  }
217
250
 
218
251
  /**
@@ -248,4 +281,44 @@ function getErrors(results) {
248
281
  }
249
282
 
250
283
  return false;
284
+ }
285
+
286
+ function isExactly(node, type) {
287
+ const { $model } = node;
288
+
289
+ return $model.getType(node.$type) === $model.getType(type);
290
+ }
291
+
292
+ function getIndefiniteArticle(type) {
293
+ if ([
294
+ 'Error',
295
+ 'Escalation',
296
+ 'Event',
297
+ 'Intermediate',
298
+ 'Undefined'
299
+ ].includes(type.split(' ')[ 0 ])) {
300
+ return 'An';
301
+ }
302
+
303
+ return 'A';
304
+ }
305
+
306
+ function getMessage(node, executionPlatform, executionPlatformVersion, label) {
307
+ const type = getTypeString(node);
308
+
309
+ const indefiniteArticle = getIndefiniteArticle(type);
310
+
311
+ return addExecutionPlatform(`${ indefiniteArticle } <${ type }> is not supported by {{ executionPlatform }}`, label || `${ executionPlatform } ${ toSemverMinor(executionPlatformVersion) }`);
312
+ }
313
+
314
+ function getLabel(node) {
315
+ if (is(node, 'bpmn:Group')) {
316
+ const categoryValueRef = node.get('categoryValueRef');
317
+
318
+ return categoryValueRef && categoryValueRef.get('value');
319
+ } else if (is(node, 'bpmn:TextAnnotation')) {
320
+ return node.get('text');
321
+ }
322
+
323
+ return node.get('name');
251
324
  }
@@ -0,0 +1,47 @@
1
+ function getEventDefinition(node) {
2
+ const eventDefinitions = node.get('eventDefinitions');
3
+
4
+ return eventDefinitions && eventDefinitions[0];
5
+ }
6
+
7
+ function getEventDefinitionPrefix(eventDefinition) {
8
+ const localType = getLocalType(eventDefinition);
9
+
10
+ return localType.replace('EventDefinition', '');
11
+ }
12
+
13
+ function getLocalType(node) {
14
+ const { $descriptor } = node;
15
+
16
+ const { localName } = $descriptor.ns;
17
+
18
+ return localName;
19
+ }
20
+
21
+ function formatTypeString(string) {
22
+ return string.replace(/([a-z])([A-Z])/g, '$1 $2').trim();
23
+ }
24
+
25
+ module.exports.getTypeString = function(node) {
26
+ let type = getLocalType(node);
27
+
28
+ const eventDefinition = getEventDefinition(node);
29
+
30
+ if (eventDefinition) {
31
+ type = `${ getEventDefinitionPrefix(eventDefinition) }${ type }`;
32
+ } else if ([
33
+ 'BoundaryEvent',
34
+ 'EndEvent',
35
+ 'IntermediateCatchEvent',
36
+ 'IntermediateThrowEvent',
37
+ 'StartEvent'
38
+ ].includes(type)) {
39
+ type = `Undefined ${ type }`;
40
+ }
41
+
42
+ if (type === 'Task') {
43
+ type = 'Undefined Task';
44
+ }
45
+
46
+ return formatTypeString(type);
47
+ };