@camunda/linting 0.8.0 → 0.9.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/lib/Linter.js +5 -6
- package/lib/utils/error-messages.js +122 -109
- package/lib/utils/properties-panel.js +122 -69
- package/lib/utils/version.js +3 -0
- package/package.json +2 -2
package/lib/Linter.js
CHANGED
|
@@ -10,9 +10,11 @@ import { isString } from 'min-dash';
|
|
|
10
10
|
import modelerModdle from 'modeler-moddle/resources/modeler.json';
|
|
11
11
|
import zeebeModdle from 'zeebe-bpmn-moddle/resources/zeebe.json';
|
|
12
12
|
|
|
13
|
-
import { getErrorMessage
|
|
13
|
+
import { getErrorMessage } from './utils/error-messages';
|
|
14
14
|
import { getEntryIds } from './utils/properties-panel';
|
|
15
15
|
|
|
16
|
+
import { toSemverMinor } from './utils/version';
|
|
17
|
+
|
|
16
18
|
const moddle = new BpmnModdle({
|
|
17
19
|
modeler: modelerModdle,
|
|
18
20
|
zeebe: zeebeModdle
|
|
@@ -68,7 +70,8 @@ export class Linter {
|
|
|
68
70
|
...report,
|
|
69
71
|
message: getErrorMessage(
|
|
70
72
|
report,
|
|
71
|
-
|
|
73
|
+
executionPlatform,
|
|
74
|
+
executionPlatformVersion,
|
|
72
75
|
this._modeler
|
|
73
76
|
),
|
|
74
77
|
propertiesPanel: {
|
|
@@ -132,10 +135,6 @@ function toLowerCase(string) {
|
|
|
132
135
|
return string.toLowerCase();
|
|
133
136
|
}
|
|
134
137
|
|
|
135
|
-
function toSemverMinor(executionPlatformVersion) {
|
|
136
|
-
return executionPlatformVersion.split('.').slice(0, 2).join('.');
|
|
137
|
-
}
|
|
138
|
-
|
|
139
138
|
async function createCache(configName) {
|
|
140
139
|
let config = require('bpmnlint-plugin-camunda-compat').configs[ configName ];
|
|
141
140
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ERROR_TYPES } from 'bpmnlint-plugin-camunda-compat/rules/utils/element';
|
|
2
2
|
|
|
3
3
|
import { is } from 'bpmnlint-utils';
|
|
4
|
+
|
|
4
5
|
import {
|
|
5
6
|
every,
|
|
6
7
|
isArray
|
|
@@ -8,30 +9,78 @@ import {
|
|
|
8
9
|
|
|
9
10
|
import { getTypeString } from './types';
|
|
10
11
|
|
|
12
|
+
import { toSemverMinor } from './version';
|
|
13
|
+
|
|
11
14
|
const TIMER_PROPERTIES = [
|
|
15
|
+
'timeCycle',
|
|
12
16
|
'timeDate',
|
|
13
|
-
'timeDuration'
|
|
14
|
-
'timeCycle'
|
|
17
|
+
'timeDuration'
|
|
15
18
|
];
|
|
16
19
|
|
|
17
|
-
|
|
20
|
+
const executionPlatformLabels = {
|
|
21
|
+
'Camunda Cloud': {
|
|
22
|
+
'default': 'Camunda',
|
|
23
|
+
'1.0': 'Camunda 8 (Zeebe 1.0)',
|
|
24
|
+
'1.1': 'Camunda 8 (Zeebe 1.1)',
|
|
25
|
+
'1.2': 'Camunda 8 (Zeebe 1.2)',
|
|
26
|
+
'1.3': 'Camunda 8 (Zeebe 1.3)'
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export function getExecutionPlatformLabel(executionPlatform, executionPlatformVersion) {
|
|
31
|
+
const executionPlatformLabel = executionPlatformLabels[ executionPlatform ]
|
|
32
|
+
&& executionPlatformLabels[ executionPlatform ][ toSemverMinor(executionPlatformVersion) ];
|
|
33
|
+
|
|
34
|
+
if (executionPlatformLabel) {
|
|
35
|
+
return executionPlatformLabel;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (executionPlatformLabels[ executionPlatform ]
|
|
39
|
+
&& executionPlatformLabels[ executionPlatform ][ 'default' ]) {
|
|
40
|
+
executionPlatform = executionPlatformLabels[ executionPlatform ][ 'default' ];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return `${ executionPlatform } ${ toSemverMinor(executionPlatformVersion) }`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function getIndefiniteArticle(type) {
|
|
47
|
+
if ([
|
|
48
|
+
'Ad',
|
|
49
|
+
'Error',
|
|
50
|
+
'Escalation',
|
|
51
|
+
'Event',
|
|
52
|
+
'Inclusive',
|
|
53
|
+
'Intermediate',
|
|
54
|
+
'Undefined'
|
|
55
|
+
].includes(type.split(' ')[ 0 ])) {
|
|
56
|
+
return 'An';
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return 'A';
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function getErrorMessage(report, executionPlatform, executionPlatformVersion, modeler = 'desktop') {
|
|
18
63
|
const {
|
|
19
|
-
|
|
64
|
+
data,
|
|
20
65
|
message
|
|
21
66
|
} = report;
|
|
22
67
|
|
|
23
|
-
if (!
|
|
68
|
+
if (!data) {
|
|
24
69
|
return message;
|
|
25
70
|
}
|
|
26
71
|
|
|
27
|
-
const { type } =
|
|
72
|
+
const { type } = data;
|
|
73
|
+
|
|
74
|
+
if (type === ERROR_TYPES.ELEMENT_COLLAPSED_NOT_ALLOWED) {
|
|
75
|
+
return getElementCollapsedNotAllowedErrorMessage(report);
|
|
76
|
+
}
|
|
28
77
|
|
|
29
78
|
if (type === ERROR_TYPES.ELEMENT_TYPE_NOT_ALLOWED) {
|
|
30
|
-
return getElementTypeNotAllowedErrorMessage(report,
|
|
79
|
+
return getElementTypeNotAllowedErrorMessage(report, executionPlatform, executionPlatformVersion);
|
|
31
80
|
}
|
|
32
81
|
|
|
33
82
|
if (type === ERROR_TYPES.EXTENSION_ELEMENT_NOT_ALLOWED) {
|
|
34
|
-
return getExtensionElementNotAllowedErrorMessage(report,
|
|
83
|
+
return getExtensionElementNotAllowedErrorMessage(report, executionPlatform, executionPlatformVersion);
|
|
35
84
|
}
|
|
36
85
|
|
|
37
86
|
if (type === ERROR_TYPES.EXTENSION_ELEMENT_REQUIRED) {
|
|
@@ -43,80 +92,61 @@ export function getErrorMessage(report, executionPlatformLabel, modeler = 'deskt
|
|
|
43
92
|
}
|
|
44
93
|
|
|
45
94
|
if (type === ERROR_TYPES.PROPERTY_NOT_ALLOWED) {
|
|
46
|
-
return getPropertyNotAllowedErrorMessage(report,
|
|
95
|
+
return getPropertyNotAllowedErrorMessage(report, executionPlatform, executionPlatformVersion, modeler);
|
|
47
96
|
}
|
|
48
97
|
|
|
49
98
|
if (type === ERROR_TYPES.PROPERTY_REQUIRED) {
|
|
50
|
-
return getPropertyRequiredErrorMessage(report
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (type === ERROR_TYPES.PROPERTY_TYPE_NOT_ALLOWED) {
|
|
54
|
-
return getPropertyTypeNotAllowedErrorMessage(report, executionPlatformLabel);
|
|
99
|
+
return getPropertyRequiredErrorMessage(report);
|
|
55
100
|
}
|
|
56
101
|
|
|
57
102
|
if (type === ERROR_TYPES.PROPERTY_VALUE_DUPLICATED) {
|
|
58
103
|
return getPropertyValueDuplicatedErrorMessage(report);
|
|
59
104
|
}
|
|
60
105
|
|
|
61
|
-
if (type === ERROR_TYPES.
|
|
62
|
-
return
|
|
106
|
+
if (type === ERROR_TYPES.EXPRESSION_REQUIRED) {
|
|
107
|
+
return getExpressionRequiredErrorMessage(report);
|
|
63
108
|
}
|
|
64
109
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const executionPlatformLabels = {
|
|
69
|
-
'Camunda Cloud': {
|
|
70
|
-
'defaultPlatformName': 'Camunda',
|
|
71
|
-
'1.0': 'Camunda 8 (Zeebe 1.0)',
|
|
72
|
-
'1.1': 'Camunda 8 (Zeebe 1.1)',
|
|
73
|
-
'1.2': 'Camunda 8 (Zeebe 1.2)',
|
|
74
|
-
'1.3': 'Camunda 8 (Zeebe 1.3)'
|
|
110
|
+
if (type === ERROR_TYPES.EXPRESSION_VALUE_NOT_ALLOWED) {
|
|
111
|
+
return getExpressionValueNotAllowedErrorMessage(report);
|
|
75
112
|
}
|
|
76
|
-
};
|
|
77
113
|
|
|
78
|
-
|
|
79
|
-
|
|
114
|
+
return message;
|
|
115
|
+
}
|
|
80
116
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
117
|
+
function getElementCollapsedNotAllowedErrorMessage(report) {
|
|
118
|
+
const {
|
|
119
|
+
data,
|
|
120
|
+
message
|
|
121
|
+
} = report;
|
|
84
122
|
|
|
85
|
-
|
|
86
|
-
executionPlatform = executionPlatformLabels[executionPlatform]['defaultPlatformName'];
|
|
87
|
-
}
|
|
123
|
+
const { node } = data;
|
|
88
124
|
|
|
89
|
-
|
|
90
|
-
}
|
|
125
|
+
const typeString = getTypeString(node);
|
|
91
126
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
'Error',
|
|
95
|
-
'Escalation',
|
|
96
|
-
'Event',
|
|
97
|
-
'Inclusive',
|
|
98
|
-
'Intermediate',
|
|
99
|
-
'Undefined'
|
|
100
|
-
].includes(type.split(' ')[ 0 ])) {
|
|
101
|
-
return 'An';
|
|
127
|
+
if (is(node, 'bpmn:SubProcess')) {
|
|
128
|
+
return `${ getIndefiniteArticle(typeString) } <${ typeString }> must be expanded`;
|
|
102
129
|
}
|
|
103
130
|
|
|
104
|
-
return
|
|
131
|
+
return message;
|
|
105
132
|
}
|
|
106
133
|
|
|
107
|
-
function getElementTypeNotAllowedErrorMessage(report,
|
|
108
|
-
const {
|
|
134
|
+
function getElementTypeNotAllowedErrorMessage(report, executionPlatform, executionPlatformVersion) {
|
|
135
|
+
const { data } = report;
|
|
109
136
|
|
|
110
|
-
const {
|
|
137
|
+
const {
|
|
138
|
+
allowedVersion,
|
|
139
|
+
node
|
|
140
|
+
} = data;
|
|
111
141
|
|
|
112
142
|
const typeString = getTypeString(node);
|
|
113
143
|
|
|
114
|
-
return `${ getIndefiniteArticle(typeString) } <${ typeString }
|
|
144
|
+
return getSupportedMessage(`${ getIndefiniteArticle(typeString) } <${ typeString }>`, executionPlatform, executionPlatformVersion, allowedVersion);
|
|
115
145
|
}
|
|
116
146
|
|
|
117
147
|
function getPropertyValueDuplicatedErrorMessage(report) {
|
|
118
148
|
const {
|
|
119
|
-
|
|
149
|
+
data,
|
|
120
150
|
message
|
|
121
151
|
} = report;
|
|
122
152
|
|
|
@@ -125,7 +155,7 @@ function getPropertyValueDuplicatedErrorMessage(report) {
|
|
|
125
155
|
parentNode,
|
|
126
156
|
duplicatedPropertyValue,
|
|
127
157
|
properties
|
|
128
|
-
} =
|
|
158
|
+
} = data;
|
|
129
159
|
|
|
130
160
|
const typeString = getTypeString(parentNode || node);
|
|
131
161
|
|
|
@@ -136,26 +166,27 @@ function getPropertyValueDuplicatedErrorMessage(report) {
|
|
|
136
166
|
return message;
|
|
137
167
|
}
|
|
138
168
|
|
|
139
|
-
function getExtensionElementNotAllowedErrorMessage(report,
|
|
169
|
+
function getExtensionElementNotAllowedErrorMessage(report, executionPlatform, executionPlatformVersion) {
|
|
140
170
|
const {
|
|
141
|
-
|
|
171
|
+
data,
|
|
142
172
|
message
|
|
143
173
|
} = report;
|
|
144
174
|
|
|
145
175
|
const {
|
|
176
|
+
allowedVersion,
|
|
146
177
|
node,
|
|
147
178
|
parentNode,
|
|
148
179
|
extensionElement
|
|
149
|
-
} =
|
|
180
|
+
} = data;
|
|
150
181
|
|
|
151
182
|
const typeString = getTypeString(parentNode || node);
|
|
152
183
|
|
|
153
184
|
if (is(node, 'bpmn:BusinessRuleTask') && is(extensionElement, 'zeebe:CalledDecision')) {
|
|
154
|
-
return
|
|
185
|
+
return getSupportedMessage('A <Business Rule Task> with <Implementation: DMN decision>', executionPlatform, executionPlatformVersion, allowedVersion);
|
|
155
186
|
}
|
|
156
187
|
|
|
157
188
|
if (is(extensionElement, 'zeebe:Properties')) {
|
|
158
|
-
return `${ getIndefiniteArticle(typeString) } <${ typeString }> with <Extension properties
|
|
189
|
+
return getSupportedMessage(`${ getIndefiniteArticle(typeString) } <${ typeString }> with <Extension properties>`, executionPlatform, executionPlatformVersion, allowedVersion);
|
|
159
190
|
}
|
|
160
191
|
|
|
161
192
|
return message;
|
|
@@ -163,7 +194,7 @@ function getExtensionElementNotAllowedErrorMessage(report, executionPlatformLabe
|
|
|
163
194
|
|
|
164
195
|
function getExtensionElementRequiredErrorMessage(report) {
|
|
165
196
|
const {
|
|
166
|
-
|
|
197
|
+
data,
|
|
167
198
|
message
|
|
168
199
|
} = report;
|
|
169
200
|
|
|
@@ -171,7 +202,7 @@ function getExtensionElementRequiredErrorMessage(report) {
|
|
|
171
202
|
node,
|
|
172
203
|
parentNode,
|
|
173
204
|
requiredExtensionElement
|
|
174
|
-
} =
|
|
205
|
+
} = data;
|
|
175
206
|
|
|
176
207
|
const typeString = getTypeString(parentNode || node);
|
|
177
208
|
|
|
@@ -200,7 +231,7 @@ function getExtensionElementRequiredErrorMessage(report) {
|
|
|
200
231
|
|
|
201
232
|
function getPropertyDependendRequiredErrorMessage(report) {
|
|
202
233
|
const {
|
|
203
|
-
|
|
234
|
+
data,
|
|
204
235
|
message
|
|
205
236
|
} = report;
|
|
206
237
|
|
|
@@ -209,7 +240,7 @@ function getPropertyDependendRequiredErrorMessage(report) {
|
|
|
209
240
|
parentNode,
|
|
210
241
|
property,
|
|
211
242
|
dependendRequiredProperty
|
|
212
|
-
} =
|
|
243
|
+
} = data;
|
|
213
244
|
|
|
214
245
|
const typeString = getTypeString(parentNode || node);
|
|
215
246
|
|
|
@@ -224,39 +255,40 @@ function getPropertyDependendRequiredErrorMessage(report) {
|
|
|
224
255
|
return message;
|
|
225
256
|
}
|
|
226
257
|
|
|
227
|
-
function getPropertyNotAllowedErrorMessage(report,
|
|
258
|
+
function getPropertyNotAllowedErrorMessage(report, executionPlatform, executionPlatformVersion, modeler = 'desktop') {
|
|
228
259
|
const {
|
|
229
|
-
|
|
260
|
+
data,
|
|
230
261
|
message
|
|
231
262
|
} = report;
|
|
232
263
|
|
|
233
264
|
const {
|
|
265
|
+
allowedVersion,
|
|
234
266
|
node,
|
|
235
267
|
parentNode,
|
|
236
268
|
property
|
|
237
|
-
} =
|
|
269
|
+
} = data;
|
|
238
270
|
|
|
239
271
|
const typeString = getTypeString(parentNode || node);
|
|
240
272
|
|
|
241
273
|
if (property === 'modelerTemplate') {
|
|
242
274
|
if (modeler === 'desktop') {
|
|
243
|
-
return `${ getIndefiniteArticle(typeString) } <Template ${ typeString }
|
|
275
|
+
return getSupportedMessage(`${ getIndefiniteArticle(typeString) } <Template ${ typeString }>`, executionPlatform, executionPlatformVersion, allowedVersion);
|
|
244
276
|
} else if (modeler === 'web') {
|
|
245
|
-
return `${ getIndefiniteArticle(typeString) } <Connector ${ typeString }
|
|
277
|
+
return getSupportedMessage(`${ getIndefiniteArticle(typeString) } <Connector ${ typeString }>`, executionPlatform, executionPlatformVersion, allowedVersion);
|
|
246
278
|
}
|
|
247
279
|
}
|
|
248
280
|
|
|
249
281
|
if (is(node, 'bpmn:InclusiveGateway') && property === 'incoming') {
|
|
250
|
-
return `${ getIndefiniteArticle(typeString) } <${ typeString }> with more than one incoming <Sequence Flow> is not supported by ${
|
|
282
|
+
return `${ getIndefiniteArticle(typeString) } <${ typeString }> with more than one incoming <Sequence Flow> is not supported by ${ getExecutionPlatformLabel(executionPlatform, executionPlatformVersion) }`;
|
|
251
283
|
}
|
|
252
284
|
|
|
253
285
|
return message;
|
|
254
286
|
}
|
|
255
287
|
|
|
256
288
|
|
|
257
|
-
function getPropertyRequiredErrorMessage(report
|
|
289
|
+
function getPropertyRequiredErrorMessage(report) {
|
|
258
290
|
const {
|
|
259
|
-
|
|
291
|
+
data,
|
|
260
292
|
message
|
|
261
293
|
} = report;
|
|
262
294
|
|
|
@@ -264,7 +296,7 @@ function getPropertyRequiredErrorMessage(report, executionPlatformLabel) {
|
|
|
264
296
|
node,
|
|
265
297
|
parentNode,
|
|
266
298
|
requiredProperty
|
|
267
|
-
} =
|
|
299
|
+
} = data;
|
|
268
300
|
|
|
269
301
|
const typeString = getTypeString(parentNode || node);
|
|
270
302
|
|
|
@@ -288,10 +320,6 @@ function getPropertyRequiredErrorMessage(report, executionPlatformLabel) {
|
|
|
288
320
|
return `${ getIndefiniteArticle(typeString) } <${ typeString }> with <Error Reference> must have a defined <Error code>`;
|
|
289
321
|
}
|
|
290
322
|
|
|
291
|
-
if (is(node, 'bpmn:Event') && requiredProperty === 'eventDefinitions') {
|
|
292
|
-
return `${ getIndefiniteArticle(typeString) } <${ typeString }> is not supported by ${ executionPlatformLabel }`;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
323
|
if (is(node, 'zeebe:LoopCharacteristics') && requiredProperty === 'inputCollection') {
|
|
296
324
|
return `${ getIndefiniteArticle(typeString) } <${ typeString }> with <Multi-instance marker> must have a defined <Input collection>`;
|
|
297
325
|
}
|
|
@@ -339,72 +367,57 @@ function getPropertyRequiredErrorMessage(report, executionPlatformLabel) {
|
|
|
339
367
|
return `${ getIndefiniteArticle(typeString) } <${ typeString }> must have a defined <Timer duration>`;
|
|
340
368
|
}
|
|
341
369
|
|
|
342
|
-
if (is(node, 'bpmn:FormalExpression')
|
|
343
|
-
&& requiredProperty === 'body'
|
|
344
|
-
&& TIMER_PROPERTIES.includes(secondLast(report.path))
|
|
345
|
-
) {
|
|
346
|
-
return `${ getIndefiniteArticle(typeString) } <${ typeString }> must have a defined <Timer value>`;
|
|
347
|
-
}
|
|
348
|
-
|
|
349
370
|
return message;
|
|
350
371
|
}
|
|
351
372
|
|
|
352
|
-
function
|
|
373
|
+
function getExpressionRequiredErrorMessage(report) {
|
|
353
374
|
const {
|
|
354
|
-
|
|
355
|
-
message
|
|
375
|
+
data
|
|
356
376
|
} = report;
|
|
357
377
|
|
|
358
378
|
const {
|
|
359
379
|
node,
|
|
360
380
|
parentNode,
|
|
361
381
|
property
|
|
362
|
-
} =
|
|
382
|
+
} = data;
|
|
363
383
|
|
|
364
384
|
const typeString = getTypeString(parentNode || node);
|
|
365
385
|
|
|
366
|
-
if (is(node, 'bpmn:
|
|
367
|
-
return `${ getIndefiniteArticle(typeString) } <${ typeString }>
|
|
386
|
+
if (is(node, 'bpmn:FormalExpression') && TIMER_PROPERTIES.includes(property)) {
|
|
387
|
+
return `${ getIndefiniteArticle(typeString) } <${ typeString }> must have a defined <Timer value>`;
|
|
368
388
|
}
|
|
369
|
-
|
|
370
|
-
return message;
|
|
371
389
|
}
|
|
372
390
|
|
|
373
|
-
function
|
|
391
|
+
function getExpressionValueNotAllowedErrorMessage(report) {
|
|
374
392
|
const {
|
|
375
|
-
|
|
393
|
+
data
|
|
376
394
|
} = report;
|
|
377
395
|
|
|
378
396
|
const {
|
|
379
397
|
node,
|
|
380
398
|
parentNode,
|
|
381
399
|
property
|
|
382
|
-
} =
|
|
400
|
+
} = data;
|
|
383
401
|
|
|
384
402
|
const typeString = getTypeString(parentNode || node);
|
|
385
403
|
|
|
386
|
-
if (is(node, 'bpmn:FormalExpression')
|
|
387
|
-
&& property === 'body'
|
|
388
|
-
&& secondLast(report.path) === 'timeCycle'
|
|
389
|
-
) {
|
|
404
|
+
if (is(node, 'bpmn:FormalExpression') && property === 'timeCycle') {
|
|
390
405
|
return `${ getIndefiniteArticle(typeString) } <${ typeString }> <Time cycle> should be an expression, an ISO 8601 repeating interval, or a cron expression (cron requires Camunda Platform 8.1 or newer)`;
|
|
391
406
|
}
|
|
392
407
|
|
|
393
|
-
if (is(node, 'bpmn:FormalExpression')
|
|
394
|
-
&& property === 'body'
|
|
395
|
-
&& secondLast(report.path) === 'timeDate'
|
|
396
|
-
) {
|
|
408
|
+
if (is(node, 'bpmn:FormalExpression') && property === 'timeDate') {
|
|
397
409
|
return `${ getIndefiniteArticle(typeString) } <${ typeString }> <Time date> should be an expression, or an ISO 8601 date`;
|
|
398
410
|
}
|
|
399
411
|
|
|
400
|
-
if (is(node, 'bpmn:FormalExpression')
|
|
401
|
-
&& property === 'body'
|
|
402
|
-
&& secondLast(report.path) === 'timeDuration'
|
|
403
|
-
) {
|
|
412
|
+
if (is(node, 'bpmn:FormalExpression') && property === 'timeDuration') {
|
|
404
413
|
return `${ getIndefiniteArticle(typeString) } <${ typeString }> <Time duration> should be an expression, or an ISO 8601 interval`;
|
|
405
414
|
}
|
|
406
415
|
}
|
|
407
416
|
|
|
408
|
-
function
|
|
409
|
-
|
|
410
|
-
}
|
|
417
|
+
function getSupportedMessage(prefix, executionPlatform, executionPlatformVersion, allowedVersion) {
|
|
418
|
+
if (allowedVersion) {
|
|
419
|
+
return `${ prefix } is only supported by ${ getExecutionPlatformLabel(executionPlatform, allowedVersion) } or newer`;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
return `${ prefix } is not supported by ${ getExecutionPlatformLabel(executionPlatform, executionPlatformVersion) }`;
|
|
423
|
+
}
|
|
@@ -46,80 +46,85 @@ export function getErrors(reports, element) {
|
|
|
46
46
|
|
|
47
47
|
export function getEntryIds(report) {
|
|
48
48
|
const {
|
|
49
|
-
|
|
50
|
-
id
|
|
49
|
+
data = {},
|
|
50
|
+
id,
|
|
51
|
+
path
|
|
51
52
|
} = report;
|
|
52
53
|
|
|
53
|
-
if (isExtensionElementRequiredError(
|
|
54
|
+
if (isExtensionElementRequiredError(data, 'zeebe:CalledDecision', 'bpmn:BusinessRuleTask')) {
|
|
54
55
|
return [ 'businessRuleImplementation' ];
|
|
55
56
|
}
|
|
56
57
|
|
|
57
|
-
if (
|
|
58
|
+
if (isPropertyError(data, 'errorRef')) {
|
|
58
59
|
return [ 'errorRef' ];
|
|
59
60
|
}
|
|
60
61
|
|
|
61
|
-
if (
|
|
62
|
+
if (isPropertyError(data, 'messageRef')) {
|
|
62
63
|
return [ 'messageRef' ];
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
if (
|
|
66
|
+
if (isPropertyError(data, 'decisionId', 'zeebe:CalledDecision')) {
|
|
66
67
|
return [ 'decisionId' ];
|
|
67
68
|
}
|
|
68
69
|
|
|
69
|
-
if (
|
|
70
|
+
if (isPropertyError(data, 'resultVariable', 'zeebe:CalledDecision')) {
|
|
70
71
|
return [ 'resultVariable' ];
|
|
71
72
|
}
|
|
72
73
|
|
|
73
|
-
if (
|
|
74
|
+
if (isPropertyError(data, 'errorCode', 'bpmn:Error')) {
|
|
74
75
|
return [ 'errorCode' ];
|
|
75
76
|
}
|
|
76
77
|
|
|
77
|
-
if (
|
|
78
|
+
if (isPropertyError(data, 'name', 'bpmn:Message')) {
|
|
78
79
|
return [ 'messageName' ];
|
|
79
80
|
}
|
|
80
81
|
|
|
81
|
-
if (isExtensionElementRequiredError(
|
|
82
|
-
||
|
|
82
|
+
if (isExtensionElementRequiredError(data, 'zeebe:LoopCharacteristics', 'bpmn:MultiInstanceLoopCharacteristics')
|
|
83
|
+
|| isPropertyError(data, 'inputCollection', 'zeebe:LoopCharacteristics')) {
|
|
83
84
|
return [ 'multiInstance-inputCollection' ];
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
if (isPropertyDependendRequiredError(
|
|
87
|
+
if (isPropertyDependendRequiredError(data, 'outputCollection', 'zeebe:LoopCharacteristics')) {
|
|
87
88
|
return [ 'multiInstance-outputCollection' ];
|
|
88
89
|
}
|
|
89
90
|
|
|
90
|
-
if (isPropertyDependendRequiredError(
|
|
91
|
+
if (isPropertyDependendRequiredError(data, 'outputElement', 'zeebe:LoopCharacteristics')) {
|
|
91
92
|
return [ 'multiInstance-outputElement' ];
|
|
92
93
|
}
|
|
93
94
|
|
|
94
|
-
if (isExtensionElementRequiredError(
|
|
95
|
-
||
|
|
95
|
+
if (isExtensionElementRequiredError(data, 'zeebe:CalledElement', 'bpmn:CallActivity')
|
|
96
|
+
|| isPropertyError(data, 'processId', 'zeebe:CalledElement')) {
|
|
96
97
|
return [ 'targetProcessId' ];
|
|
97
98
|
}
|
|
98
99
|
|
|
99
|
-
if (isExtensionElementRequiredError(
|
|
100
|
-
||
|
|
100
|
+
if (isExtensionElementRequiredError(data, 'zeebe:TaskDefinition')
|
|
101
|
+
|| isPropertyError(data, 'type', 'zeebe:TaskDefinition')) {
|
|
101
102
|
return [ 'taskDefinitionType' ];
|
|
102
103
|
}
|
|
103
104
|
|
|
104
|
-
if (
|
|
105
|
-
|
|
105
|
+
if (isPropertyError(data, 'retries', 'zeebe:TaskDefinition')) {
|
|
106
|
+
return [ 'taskDefinitionRetries' ];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (isExtensionElementRequiredError(data, 'zeebe:Subscription')
|
|
110
|
+
|| isPropertyError(data, 'correlationKey', 'zeebe:Subscription')) {
|
|
106
111
|
return [ 'messageSubscriptionCorrelationKey' ];
|
|
107
112
|
}
|
|
108
113
|
|
|
109
|
-
if (
|
|
114
|
+
if (isPropertyError(data, 'formKey', 'zeebe:FormDefinition')) {
|
|
110
115
|
return [ 'customFormKey' ];
|
|
111
116
|
}
|
|
112
117
|
|
|
113
|
-
if (
|
|
118
|
+
if (isPropertyError(data, 'body', 'zeebe:UserTaskForm')) {
|
|
114
119
|
return [ 'formConfiguration' ];
|
|
115
120
|
}
|
|
116
121
|
|
|
117
|
-
if (isPropertyValueDuplicatedError(
|
|
122
|
+
if (isPropertyValueDuplicatedError(data, 'values', 'key', 'zeebe:TaskHeaders')) {
|
|
118
123
|
const {
|
|
119
124
|
node,
|
|
120
125
|
properties,
|
|
121
126
|
propertiesName
|
|
122
|
-
} =
|
|
127
|
+
} = data;
|
|
123
128
|
|
|
124
129
|
return properties.map(property => {
|
|
125
130
|
const index = node.get(propertiesName).indexOf(property);
|
|
@@ -128,40 +133,76 @@ export function getEntryIds(report) {
|
|
|
128
133
|
});
|
|
129
134
|
}
|
|
130
135
|
|
|
131
|
-
if (isExtensionElementNotAllowedError(
|
|
132
|
-
const { extensionElement } =
|
|
136
|
+
if (isExtensionElementNotAllowedError(data, 'zeebe:Properties')) {
|
|
137
|
+
const { extensionElement } = data;
|
|
133
138
|
|
|
134
139
|
return extensionElement.get('zeebe:properties').map((zeebeProperty, index) => {
|
|
135
140
|
return `${ id }-extensionProperty-${ index }-name`;
|
|
136
141
|
});
|
|
137
142
|
}
|
|
138
143
|
|
|
139
|
-
if (
|
|
144
|
+
if (isPropertyError(data, 'conditionExpression', 'bpmn:SequenceFlow')) {
|
|
140
145
|
return [ 'conditionExpression' ];
|
|
141
146
|
}
|
|
142
147
|
|
|
143
|
-
if (
|
|
148
|
+
if (isPropertyError(data, 'timeDuration', 'bpmn:TimerEventDefinition')) {
|
|
144
149
|
return [ 'timerEventDefinitionDurationValue' ];
|
|
145
150
|
}
|
|
146
151
|
|
|
152
|
+
if (isPropertyError(data, 'completionCondition', 'bpmn:MultiInstanceLoopCharacteristics')) {
|
|
153
|
+
return [ 'multiInstance-completionCondition' ];
|
|
154
|
+
}
|
|
155
|
+
|
|
147
156
|
if (TIMER_PROPERTIES.some(property =>
|
|
148
|
-
isOneOfPropertiesRequiredError(
|
|
157
|
+
isOneOfPropertiesRequiredError(data, property, 'bpmn:TimerEventDefinition'))
|
|
149
158
|
) {
|
|
150
159
|
return [ 'timerEventDefinitionType' ];
|
|
151
160
|
}
|
|
152
161
|
|
|
153
|
-
if (
|
|
154
|
-
|
|
162
|
+
if (isExpressionRequiredError(data, 'timeCycle', 'bpmn:FormalExpression')
|
|
163
|
+
|| isExpressionRequiredError(data, 'timeDate', 'bpmn:FormalExpression')
|
|
164
|
+
|| isExpressionRequiredError(data, 'timeDuration', 'bpmn:FormalExpression')) {
|
|
165
|
+
return hasOnlyDurationTimer(data.parentNode) ? [ 'timerEventDefinitionDurationValue' ] : [ 'timerEventDefinitionValue' ];
|
|
155
166
|
}
|
|
156
167
|
|
|
157
|
-
if (
|
|
158
|
-
|
|
168
|
+
if (isExpressionValueNotAllowedError(data, 'timeCycle', 'bpmn:FormalExpression')
|
|
169
|
+
|| isExpressionValueNotAllowedError(data, 'timeDate', 'bpmn:FormalExpression')
|
|
170
|
+
|| isExpressionValueNotAllowedError(data, 'timeDuration', 'bpmn:FormalExpression')) {
|
|
171
|
+
return hasOnlyDurationTimer(data.parentNode) ? [ 'timerEventDefinitionDurationValue' ] : [ 'timerEventDefinitionValue' ];
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const LIST_PROPERTIES = [
|
|
175
|
+
[ 'zeebe:Input', 'input' ],
|
|
176
|
+
[ 'zeebe:Output', 'output' ],
|
|
177
|
+
[ 'zeebe:Property', 'extensionProperty' ],
|
|
178
|
+
[ 'zeebe:Header', 'header' ]
|
|
179
|
+
];
|
|
180
|
+
|
|
181
|
+
for (const [ type, prefix ] of LIST_PROPERTIES) {
|
|
182
|
+
if (hasType(data, type)
|
|
183
|
+
&& getPropertyName(data)) {
|
|
184
|
+
|
|
185
|
+
const index = path[path.length - 2];
|
|
186
|
+
|
|
187
|
+
return [ `${ id }-${prefix}-${index}-${ getPropertyName(data) }` ];
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (hasType(data, 'zeebe:LoopCharacteristics')) {
|
|
192
|
+
return [ `multiInstance-${getPropertyName(data)}` ];
|
|
159
193
|
}
|
|
160
194
|
|
|
161
195
|
return [];
|
|
162
196
|
}
|
|
163
197
|
|
|
164
198
|
export function getErrorMessage(id, report) {
|
|
199
|
+
const { data } = report;
|
|
200
|
+
|
|
201
|
+
// do not override FEEL message
|
|
202
|
+
if (data.type === ERROR_TYPES.FEEL_EXPRESSION_INVALID) {
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
|
|
165
206
|
if (id === 'businessRuleImplementation') {
|
|
166
207
|
return 'Implementation must be defined.';
|
|
167
208
|
}
|
|
@@ -235,16 +276,16 @@ export function getErrorMessage(id, report) {
|
|
|
235
276
|
}
|
|
236
277
|
|
|
237
278
|
if (id === 'timerEventDefinitionDurationValue') {
|
|
238
|
-
return
|
|
279
|
+
return data.type === ERROR_TYPES.EXPRESSION_REQUIRED ?
|
|
239
280
|
'Duration must be defined.' : 'Must be an expression, or an ISO 8601 interval.';
|
|
240
281
|
}
|
|
241
282
|
|
|
242
283
|
if (id === 'timerEventDefinitionValue') {
|
|
243
|
-
if (
|
|
284
|
+
if (data.type === ERROR_TYPES.EXPRESSION_REQUIRED) {
|
|
244
285
|
return 'Value must be defined.';
|
|
245
286
|
}
|
|
246
287
|
|
|
247
|
-
const property =
|
|
288
|
+
const { property } = data;
|
|
248
289
|
|
|
249
290
|
if (property === 'timeCycle') {
|
|
250
291
|
return 'Must be an expression, an ISO 8601 repeating interval, or a cron expression (cron requires Camunda Platform 8.1 or newer).';
|
|
@@ -260,56 +301,68 @@ export function getErrorMessage(id, report) {
|
|
|
260
301
|
}
|
|
261
302
|
}
|
|
262
303
|
|
|
263
|
-
function isExtensionElementNotAllowedError(
|
|
264
|
-
return
|
|
265
|
-
&& is(
|
|
266
|
-
&& (!type || is(
|
|
304
|
+
function isExtensionElementNotAllowedError(data, extensionElement, type) {
|
|
305
|
+
return data.type === ERROR_TYPES.EXTENSION_ELEMENT_NOT_ALLOWED
|
|
306
|
+
&& is(data.extensionElement, extensionElement)
|
|
307
|
+
&& (!type || is(data.node, type));
|
|
267
308
|
}
|
|
268
309
|
|
|
269
|
-
function isExtensionElementRequiredError(
|
|
270
|
-
return
|
|
271
|
-
&& (isArray(
|
|
272
|
-
||
|
|
273
|
-
&& (!type || is(
|
|
310
|
+
function isExtensionElementRequiredError(data, requiredExtensionElement, type) {
|
|
311
|
+
return data.type === ERROR_TYPES.EXTENSION_ELEMENT_REQUIRED
|
|
312
|
+
&& (isArray(data.requiredExtensionElement) && data.requiredExtensionElement.includes(requiredExtensionElement)
|
|
313
|
+
|| data.requiredExtensionElement === requiredExtensionElement)
|
|
314
|
+
&& (!type || is(data.node, type));
|
|
274
315
|
}
|
|
275
316
|
|
|
276
|
-
function isPropertyDependendRequiredError(
|
|
277
|
-
return
|
|
278
|
-
&&
|
|
279
|
-
&& (!type || is(
|
|
317
|
+
function isPropertyDependendRequiredError(data, dependendRequiredProperty, type) {
|
|
318
|
+
return data.type === ERROR_TYPES.PROPERTY_DEPENDEND_REQUIRED
|
|
319
|
+
&& data.dependendRequiredProperty === dependendRequiredProperty
|
|
320
|
+
&& (!type || is(data.node, type));
|
|
280
321
|
}
|
|
281
322
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
&& (!type || is(
|
|
323
|
+
|
|
324
|
+
function isPropertyError(data, property, type) {
|
|
325
|
+
return getPropertyName(data) === property
|
|
326
|
+
&& (!type || is(data.node, type));
|
|
286
327
|
}
|
|
287
328
|
|
|
288
|
-
function
|
|
289
|
-
return
|
|
290
|
-
&& (isArray(error.requiredProperty) && error.requiredProperty.includes(requiredProperty))
|
|
291
|
-
&& (!type || is(error.node, type));
|
|
329
|
+
function hasType(data, type) {
|
|
330
|
+
return data.node && is(data.node, type);
|
|
292
331
|
}
|
|
293
332
|
|
|
294
|
-
function
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
&& (!type || is(error.node, type));
|
|
333
|
+
function getPropertyName(data) {
|
|
334
|
+
const propertyKey = data.type === ERROR_TYPES.PROPERTY_REQUIRED ? 'requiredProperty' : 'property';
|
|
335
|
+
|
|
336
|
+
return data[ propertyKey ];
|
|
299
337
|
}
|
|
300
338
|
|
|
301
|
-
function
|
|
302
|
-
return
|
|
303
|
-
&&
|
|
304
|
-
&& (!type || is(
|
|
339
|
+
function isOneOfPropertiesRequiredError(data, requiredProperty, type) {
|
|
340
|
+
return data.type === ERROR_TYPES.PROPERTY_REQUIRED
|
|
341
|
+
&& (isArray(data.requiredProperty) && data.requiredProperty.includes(requiredProperty))
|
|
342
|
+
&& (!type || is(data.node, type));
|
|
305
343
|
}
|
|
306
344
|
|
|
307
|
-
function
|
|
308
|
-
return
|
|
345
|
+
function isPropertyValueDuplicatedError(data, propertiesName, duplicatedProperty, type) {
|
|
346
|
+
return data.type === ERROR_TYPES.PROPERTY_VALUE_DUPLICATED
|
|
347
|
+
&& data.propertiesName === propertiesName
|
|
348
|
+
&& data.duplicatedProperty === duplicatedProperty
|
|
349
|
+
&& (!type || is(data.node, type));
|
|
309
350
|
}
|
|
310
351
|
|
|
311
|
-
function
|
|
312
|
-
return
|
|
352
|
+
function isExpressionRequiredError(data, propertyName, type) {
|
|
353
|
+
return data.type === ERROR_TYPES.EXPRESSION_REQUIRED
|
|
354
|
+
&& data.property === propertyName
|
|
355
|
+
&& (!type || is(data.node, type));
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
function isExpressionValueNotAllowedError(data, propertyName, type) {
|
|
359
|
+
return data.type === ERROR_TYPES.EXPRESSION_VALUE_NOT_ALLOWED
|
|
360
|
+
&& data.property === propertyName
|
|
361
|
+
&& (!type || is(data.node, type));
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function getBusinessObject(element) {
|
|
365
|
+
return element.businessObject || element;
|
|
313
366
|
}
|
|
314
367
|
|
|
315
368
|
function hasOnlyDurationTimer(node) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camunda/linting",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Linting for Camunda Platform",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"bpmn-moddle": "^7.1.3",
|
|
29
29
|
"bpmnlint": "^8.0.0",
|
|
30
|
-
"bpmnlint-plugin-camunda-compat": "^0.
|
|
30
|
+
"bpmnlint-plugin-camunda-compat": "^0.14.1",
|
|
31
31
|
"bpmnlint-utils": "^1.0.2",
|
|
32
32
|
"min-dash": "^4.0.0",
|
|
33
33
|
"min-dom": "^4.0.1",
|