@camunda/linting 3.19.0 → 3.20.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/LICENSE +21 -21
- package/README.md +75 -75
- package/assets/linting.css +37 -37
- package/lib/Linter.js +201 -199
- package/lib/Resolver.js +31 -31
- package/lib/modeler/Linting.js +124 -124
- package/lib/modeler/LintingAnnotations.js +95 -95
- package/lib/modeler/OverlayComponent.js +60 -60
- package/lib/modeler/index.js +10 -10
- package/lib/plugins/bpmnLintPlugin.js +11 -0
- package/lib/plugins/index.js +5 -0
- package/lib/utils/documentation.js +36 -36
- package/lib/utils/error-messages.js +722 -722
- package/lib/utils/properties-panel.js +601 -601
- package/lib/utils/types.js +46 -46
- package/lib/utils/version.js +8 -8
- package/package.json +85 -85
|
@@ -1,602 +1,602 @@
|
|
|
1
|
-
import {
|
|
2
|
-
isArray,
|
|
3
|
-
isString
|
|
4
|
-
} from 'min-dash';
|
|
5
|
-
|
|
6
|
-
import { is } from 'bpmnlint-utils';
|
|
7
|
-
|
|
8
|
-
import { ERROR_TYPES } from 'bpmnlint-plugin-camunda-compat/rules/utils/error-types';
|
|
9
|
-
|
|
10
|
-
import { greaterOrEqual } from './version';
|
|
11
|
-
|
|
12
|
-
const TIMER_PROPERTIES = [
|
|
13
|
-
'timeDate',
|
|
14
|
-
'timeDuration',
|
|
15
|
-
'timeCycle'
|
|
16
|
-
];
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Get errors for a given element.
|
|
20
|
-
*
|
|
21
|
-
* @param {Object[]} reports
|
|
22
|
-
* @param {Object} element
|
|
23
|
-
*
|
|
24
|
-
* @returns {Object}
|
|
25
|
-
*/
|
|
26
|
-
export function getErrors(reports, element) {
|
|
27
|
-
return reports.reduce((errors, report) => {
|
|
28
|
-
const { category } = report;
|
|
29
|
-
|
|
30
|
-
if (!element
|
|
31
|
-
|| getBusinessObject(element).get('id') !== report.id
|
|
32
|
-
|| category !== 'error') {
|
|
33
|
-
return errors;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const ids = getEntryIds(report);
|
|
37
|
-
|
|
38
|
-
if (!ids.length) {
|
|
39
|
-
return errors;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
let { message } = report;
|
|
43
|
-
|
|
44
|
-
return {
|
|
45
|
-
...errors,
|
|
46
|
-
...ids.reduce((errors, id) => {
|
|
47
|
-
return {
|
|
48
|
-
...errors,
|
|
49
|
-
[ id ]: getErrorMessage(id, report) || message
|
|
50
|
-
};
|
|
51
|
-
}, {})
|
|
52
|
-
};
|
|
53
|
-
}, {});
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export function getEntryIds(report) {
|
|
57
|
-
const {
|
|
58
|
-
data = {},
|
|
59
|
-
id,
|
|
60
|
-
path,
|
|
61
|
-
propertiesPanel = {}
|
|
62
|
-
} = report;
|
|
63
|
-
|
|
64
|
-
if (propertiesPanel.entryIds) {
|
|
65
|
-
return propertiesPanel.entryIds;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (isPropertyError(data, 'isExecutable')) {
|
|
69
|
-
return [ 'isExecutable' ];
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (isExtensionElementRequiredError(data, 'zeebe:CalledDecision', 'bpmn:BusinessRuleTask')) {
|
|
73
|
-
return [ 'businessRuleImplementation' ];
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// script task
|
|
77
|
-
if (isExtensionElementRequiredError(data, 'zeebe:Script', 'bpmn:ScriptTask')) {
|
|
78
|
-
return [ 'scriptImplementation' ];
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (isPropertyError(data, 'errorRef')) {
|
|
82
|
-
return [ 'errorRef' ];
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (isPropertyError(data, 'escalationRef')) {
|
|
86
|
-
return [ 'escalationRef' ];
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (isPropertyError(data, 'messageRef')) {
|
|
90
|
-
return [ 'messageRef' ];
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (isPropertyError(data, 'signalRef')) {
|
|
94
|
-
return [ 'signalRef' ];
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (isPropertyError(data, 'historyTimeToLive')) {
|
|
98
|
-
return [ 'historyTimeToLive' ];
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (isPropertyError(data, 'decisionId', 'zeebe:CalledDecision')) {
|
|
102
|
-
return [ 'decisionId' ];
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (isPropertyError(data, 'resultVariable')) {
|
|
106
|
-
return [ 'resultVariable' ];
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (isPropertyError(data, 'expression', 'zeebe:Script')) {
|
|
110
|
-
return [ 'scriptExpression' ];
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (isPropertyError(data, 'errorCode', 'bpmn:Error')) {
|
|
114
|
-
return [ 'errorCode' ];
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
if (isPropertyError(data, 'escalationCode', 'bpmn:Escalation')) {
|
|
118
|
-
return [ 'escalationCode' ];
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
if (isPropertyError(data, 'name', 'bpmn:Message')) {
|
|
122
|
-
return [ 'messageName' ];
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
if (isPropertyError(data, 'name', 'bpmn:Signal')) {
|
|
126
|
-
return [ 'signalName' ];
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (isExtensionElementRequiredError(data, 'zeebe:LoopCharacteristics', 'bpmn:MultiInstanceLoopCharacteristics')
|
|
130
|
-
|| isPropertyError(data, 'inputCollection', 'zeebe:LoopCharacteristics')) {
|
|
131
|
-
return [ 'multiInstance-inputCollection' ];
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (isPropertyDependentRequiredError(data, 'outputCollection', 'zeebe:LoopCharacteristics')) {
|
|
135
|
-
return [ 'multiInstance-outputCollection' ];
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
if (isPropertyDependentRequiredError(data, 'outputElement', 'zeebe:LoopCharacteristics')) {
|
|
139
|
-
return [ 'multiInstance-outputElement' ];
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (isExtensionElementRequiredError(data, 'zeebe:CalledElement', 'bpmn:CallActivity')
|
|
143
|
-
|| isPropertyError(data, 'processId', 'zeebe:CalledElement')) {
|
|
144
|
-
return [ 'targetProcessId' ];
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (isExtensionElementRequiredError(data, 'zeebe:TaskDefinition')
|
|
148
|
-
|| isPropertyError(data, 'type', 'zeebe:TaskDefinition')) {
|
|
149
|
-
return [ 'taskDefinitionType' ];
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
if (isPropertyError(data, 'retries', 'zeebe:TaskDefinition')) {
|
|
153
|
-
return [ 'taskDefinitionRetries' ];
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (isExtensionElementRequiredError(data, 'zeebe:Subscription')
|
|
157
|
-
|| isPropertyError(data, 'correlationKey', 'zeebe:Subscription')) {
|
|
158
|
-
return [ 'messageSubscriptionCorrelationKey' ];
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
if (isPropertyError(data, 'formKey', 'zeebe:FormDefinition')) {
|
|
162
|
-
return [ 'customFormKey' ];
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if (isType(data, 'zeebe:FormDefinition')) {
|
|
166
|
-
const {
|
|
167
|
-
node,
|
|
168
|
-
requiredProperty
|
|
169
|
-
} = data;
|
|
170
|
-
|
|
171
|
-
if (isArray(requiredProperty)) {
|
|
172
|
-
if (requiredProperty.includes('formKey') && isEmptyString(node.get('formKey'))) {
|
|
173
|
-
return [ 'customFormKey' ];
|
|
174
|
-
} else if (requiredProperty.includes('formId') && isEmptyString(node.get('formId'))) {
|
|
175
|
-
return [ 'formId' ];
|
|
176
|
-
} else if (requiredProperty.includes('externalReference') && isEmptyString(node.get('externalReference'))) {
|
|
177
|
-
return [ 'externalReference' ];
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
if (isPropertyError(data, 'formId', 'zeebe:FormDefinition')) {
|
|
183
|
-
return [ 'formId' ];
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
if (isPropertyError(data, 'body', 'zeebe:UserTaskForm')) {
|
|
187
|
-
return [ 'formConfiguration' ];
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
if (isPropertyValueDuplicatedError(data, 'values', 'key', 'zeebe:TaskHeaders')) {
|
|
191
|
-
const {
|
|
192
|
-
node,
|
|
193
|
-
properties,
|
|
194
|
-
propertiesName
|
|
195
|
-
} = data;
|
|
196
|
-
|
|
197
|
-
return properties.map(property => {
|
|
198
|
-
const index = node.get(propertiesName).indexOf(property);
|
|
199
|
-
|
|
200
|
-
return `${ id }-header-${ index }-key`;
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
if (isExtensionElementNotAllowedError(data, 'zeebe:Properties')) {
|
|
205
|
-
const { extensionElement } = data;
|
|
206
|
-
|
|
207
|
-
return extensionElement.get('zeebe:properties').map((zeebeProperty, index) => {
|
|
208
|
-
return `${ id }-extensionProperty-${ index }-name`;
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
if (isExtensionElementNotAllowedError(data, 'zeebe:UserTask')) {
|
|
213
|
-
return [ 'userTaskImplementation' ];
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
if (isExtensionElementNotAllowedError(data, 'zeebe:FormDefinition', 'bpmn:StartEvent')) {
|
|
217
|
-
return [ 'formType' ];
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
if (isPropertyError(data, 'conditionExpression', 'bpmn:SequenceFlow')) {
|
|
222
|
-
return [ 'conditionExpression' ];
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
if (isPropertyError(data, 'completionCondition', 'bpmn:MultiInstanceLoopCharacteristics')) {
|
|
226
|
-
return [ 'multiInstance-completionCondition' ];
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
if (TIMER_PROPERTIES.some(property =>
|
|
230
|
-
isOneOfPropertiesRequiredError(data, property, 'bpmn:TimerEventDefinition'))
|
|
231
|
-
) {
|
|
232
|
-
return [ 'timerEventDefinitionType' ];
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
if (isExpressionRequiredError(data, 'timeCycle', 'bpmn:FormalExpression')
|
|
236
|
-
|| isExpressionRequiredError(data, 'timeDate', 'bpmn:FormalExpression')
|
|
237
|
-
|| isExpressionRequiredError(data, 'timeDuration', 'bpmn:FormalExpression')) {
|
|
238
|
-
return [ 'timerEventDefinitionValue' ];
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
if (isExpressionValueNotAllowedError(data, 'timeCycle', 'bpmn:FormalExpression')
|
|
242
|
-
|| isExpressionValueNotAllowedError(data, 'timeDate', 'bpmn:FormalExpression')
|
|
243
|
-
|| isExpressionValueNotAllowedError(data, 'timeDuration', 'bpmn:FormalExpression')) {
|
|
244
|
-
return [ 'timerEventDefinitionValue' ];
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
if (isPropertyError(data, 'timeCycle', 'bpmn:TimerEventDefinition')
|
|
248
|
-
|| isPropertyError(data, 'timeDate', 'bpmn:TimerEventDefinition')
|
|
249
|
-
|| isPropertyError(data, 'timeDuration', 'bpmn:TimerEventDefinition')) {
|
|
250
|
-
return [ 'timerEventDefinitionType' ];
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
const LIST_PROPERTIES = [
|
|
254
|
-
[ 'zeebe:Input', 'input' ],
|
|
255
|
-
[ 'zeebe:Output', 'output' ],
|
|
256
|
-
[ 'zeebe:Property', 'extensionProperty' ],
|
|
257
|
-
[ 'zeebe:Header', 'header' ]
|
|
258
|
-
];
|
|
259
|
-
|
|
260
|
-
for (const [ type, prefix ] of LIST_PROPERTIES) {
|
|
261
|
-
if (isType(data, type)
|
|
262
|
-
&& getPropertyName(data)) {
|
|
263
|
-
|
|
264
|
-
const index = path[ path.length - 2 ];
|
|
265
|
-
|
|
266
|
-
return [ `${ id }-${ prefix }-${ index }-${ getPropertyName(data) }` ];
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
if (isType(data, 'zeebe:LoopCharacteristics')) {
|
|
271
|
-
return [ `multiInstance-${getPropertyName(data)}` ];
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
if (isPropertyError(data, 'candidateUsers', 'zeebe:AssignmentDefinition')) {
|
|
275
|
-
return [ 'assignmentDefinitionCandidateUsers' ];
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
if (isPropertyError(data, 'historyTimeToLive', 'bpmn:Process')) {
|
|
279
|
-
return [ 'historyTimeToLive' ];
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
if (isExpressionValueNotAllowedError(data, 'dueDate', 'zeebe:TaskSchedule')) {
|
|
283
|
-
return [ 'taskScheduleDueDate' ];
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
if (isExpressionValueNotAllowedError(data, 'followUpDate', 'zeebe:TaskSchedule')) {
|
|
287
|
-
return [ 'taskScheduleFollowUpDate' ];
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
if (isExtensionElementNotAllowedError(data, 'zeebe:TaskSchedule', 'bpmn:UserTask')) {
|
|
291
|
-
const { extensionElement: taskSchedule } = data;
|
|
292
|
-
|
|
293
|
-
let ids = [];
|
|
294
|
-
|
|
295
|
-
if (taskSchedule.get('dueDate')) {
|
|
296
|
-
ids = [ ...ids, 'taskScheduleDueDate' ];
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
if (taskSchedule.get('followUpDate')) {
|
|
300
|
-
ids = [ ...ids, 'taskScheduleFollowUpDate' ];
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
return ids;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
if (isPropertyError(data, 'propagateAllParentVariables', 'zeebe:CalledElement')) {
|
|
307
|
-
return [ 'propagateAllParentVariables' ];
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
if (isPropertyError(data, 'name', 'bpmn:LinkEventDefinition')
|
|
311
|
-
|| isElementPropertyValueDuplicated(data, 'name', 'bpmn:LinkEventDefinition')) {
|
|
312
|
-
return [ 'linkName' ];
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
if (isPropertyError(data, 'waitForCompletion', 'bpmn:CompensateEventDefinition')) {
|
|
316
|
-
return [ 'waitForCompletion' ];
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
return [];
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
export function getErrorMessage(id, report) {
|
|
323
|
-
const {
|
|
324
|
-
data = {},
|
|
325
|
-
executionPlatformVersion
|
|
326
|
-
} = report;
|
|
327
|
-
|
|
328
|
-
// adjust FEEL message
|
|
329
|
-
if (data.type === ERROR_TYPES.FEEL_EXPRESSION_INVALID) {
|
|
330
|
-
return 'Unparsable FEEL expression.';
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
if (data.type === ERROR_TYPES.EXPRESSION_NOT_ALLOWED) {
|
|
334
|
-
return 'Cannot be an expression.';
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
if (id === 'isExecutable') {
|
|
338
|
-
const { parentNode } = data;
|
|
339
|
-
|
|
340
|
-
if (parentNode && is(parentNode, 'bpmn:Participant')) {
|
|
341
|
-
return 'One process must be executable.';
|
|
342
|
-
} else {
|
|
343
|
-
return 'Process must be executable.';
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
if ([ 'businessRuleImplementation', 'scriptImplementation' ].includes(id)) {
|
|
348
|
-
return 'Implementation must be defined.';
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
if (id === 'errorRef') {
|
|
352
|
-
return 'Global error reference must be defined.';
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
if (id === 'escalationRef') {
|
|
356
|
-
return 'Global escalation reference must be defined.';
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
if (id === 'messageRef') {
|
|
360
|
-
return 'Global message reference must be defined.';
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
if (id === 'signalRef') {
|
|
364
|
-
return 'Global signal reference must be defined.';
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
if (id === 'decisionId') {
|
|
368
|
-
return 'Decision ID must be defined.';
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
if (id === 'scriptExpression') {
|
|
372
|
-
return 'FEEL expression must be defined.';
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
if (id === 'resultVariable') {
|
|
376
|
-
return 'Result variable must be defined.';
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
if (id === 'errorCode' && data.type === ERROR_TYPES.PROPERTY_REQUIRED) {
|
|
380
|
-
return 'Code must be defined.';
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
if (id === 'escalationCode' && data.type === ERROR_TYPES.PROPERTY_REQUIRED) {
|
|
384
|
-
return 'Code must be defined.';
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
if (id === 'messageName') {
|
|
388
|
-
return 'Name must be defined.';
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
if (id === 'signalName') {
|
|
392
|
-
return 'Name must be defined.';
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
if (id === 'multiInstance-inputCollection') {
|
|
396
|
-
return 'Input collection must be defined.';
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
if (id === 'multiInstance-outputCollection') {
|
|
400
|
-
return 'Output collection must be defined.';
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
if (id === 'multiInstance-outputElement') {
|
|
404
|
-
return 'Output element must be defined.';
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
if (id === 'targetProcessId') {
|
|
408
|
-
return 'Process ID must be defined.';
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
if (id === 'taskDefinitionType') {
|
|
412
|
-
return 'Type must be defined.';
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
if (id === 'timerEventDefinitionType' && data.type === ERROR_TYPES.PROPERTY_REQUIRED) {
|
|
416
|
-
return 'Type must be defined.';
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
if (id === 'messageSubscriptionCorrelationKey'
|
|
420
|
-
&& [
|
|
421
|
-
ERROR_TYPES.EXTENSION_ELEMENT_REQUIRED,
|
|
422
|
-
ERROR_TYPES.PROPERTY_REQUIRED
|
|
423
|
-
].includes(data.type)) {
|
|
424
|
-
return 'Subscription correlation key must be defined.';
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
if (id === 'customFormKey') {
|
|
428
|
-
return 'Form key must be defined.';
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
if (id === 'formId') {
|
|
432
|
-
if (data.type === ERROR_TYPES.PROPERTY_REQUIRED) {
|
|
433
|
-
return 'Form ID must be defined.';
|
|
434
|
-
} else if (data.type === ERROR_TYPES.PROPERTY_NOT_ALLOWED) {
|
|
435
|
-
return 'Form ID not supported.';
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
if (id === 'externalReference') {
|
|
440
|
-
return 'External reference must be defined.';
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
if (id === 'formConfiguration') {
|
|
444
|
-
return 'Form JSON configuration must be defined.';
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
if (/^.+-header-[0-9]+-key$/.test(id)) {
|
|
448
|
-
return 'Must be unique.';
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
if (/^.+-extensionProperty-[0-9]+-name$/.test(id)) {
|
|
452
|
-
return 'Not supported.';
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
if (id === 'userTaskImplementation') {
|
|
456
|
-
return 'Supported only in Camunda 8.5 or newer.';
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
if (id === 'conditionExpression') {
|
|
460
|
-
return 'Condition expression must be defined.';
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
if (id === 'timerEventDefinitionType' && data.type === ERROR_TYPES.PROPERTY_NOT_ALLOWED) {
|
|
464
|
-
return 'Type not supported.';
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
if (id === 'timerEventDefinitionValue') {
|
|
468
|
-
if (data.type === ERROR_TYPES.EXPRESSION_REQUIRED) {
|
|
469
|
-
return 'Value must be defined.';
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
const { property } = data;
|
|
473
|
-
|
|
474
|
-
if (property === 'timeCycle') {
|
|
475
|
-
if (!greaterOrEqual(executionPlatformVersion, '8.1')) {
|
|
476
|
-
return 'Must be an expression, an ISO 8601 repeating interval, or a cron expression (cron only supported by Camunda 8.1 or newer).';
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
return 'Must be an expression, an ISO 8601 repeating interval, or a cron expression.';
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
if (property === 'timeDate') {
|
|
483
|
-
return 'Must be an expression, or an ISO 8601 date.';
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
if (property === 'timeDuration') {
|
|
487
|
-
return 'Must be an expression, or an ISO 8601 interval.';
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
if (id === 'assignmentDefinitionCandidateUsers') {
|
|
492
|
-
return 'Not supported.';
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
if (id === 'taskScheduleDueDate') {
|
|
496
|
-
if (data.type === ERROR_TYPES.EXTENSION_ELEMENT_NOT_ALLOWED) {
|
|
497
|
-
return 'Not supported.';
|
|
498
|
-
} else {
|
|
499
|
-
return 'Must be an ISO 8601 date.';
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
if (id === 'taskScheduleFollowUpDate') {
|
|
504
|
-
if (data.type === ERROR_TYPES.EXTENSION_ELEMENT_NOT_ALLOWED) {
|
|
505
|
-
return 'Not supported.';
|
|
506
|
-
} else {
|
|
507
|
-
return 'Must be an ISO 8601 date.';
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
if (id === 'propagateAllParentVariables') {
|
|
512
|
-
return 'Not supported.';
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
if (id === 'linkName') {
|
|
516
|
-
if (data.type === ERROR_TYPES.ELEMENT_PROPERTY_VALUE_DUPLICATED) {
|
|
517
|
-
return 'Must be unique.';
|
|
518
|
-
} else {
|
|
519
|
-
return 'Must be defined.';
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
if (id === 'waitForCompletion') {
|
|
524
|
-
return 'Must wait for completion.';
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
function isExtensionElementNotAllowedError(data, extensionElement, type) {
|
|
529
|
-
return data.type === ERROR_TYPES.EXTENSION_ELEMENT_NOT_ALLOWED
|
|
530
|
-
&& is(data.extensionElement, extensionElement)
|
|
531
|
-
&& (!type || is(data.node, type));
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
function isExtensionElementRequiredError(data, requiredExtensionElement, type) {
|
|
535
|
-
return data.type === ERROR_TYPES.EXTENSION_ELEMENT_REQUIRED
|
|
536
|
-
&& (isArray(data.requiredExtensionElement) && data.requiredExtensionElement.includes(requiredExtensionElement)
|
|
537
|
-
|| data.requiredExtensionElement === requiredExtensionElement)
|
|
538
|
-
&& (!type || is(data.node, type));
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
function isPropertyDependentRequiredError(data, dependentRequiredProperty, type) {
|
|
542
|
-
return data.type === ERROR_TYPES.PROPERTY_DEPENDENT_REQUIRED
|
|
543
|
-
&& data.dependentRequiredProperty === dependentRequiredProperty
|
|
544
|
-
&& (!type || is(data.node, type));
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
function isPropertyError(data, property, type) {
|
|
549
|
-
return getPropertyName(data) === property
|
|
550
|
-
&& (!type || is(data.node, type));
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
function getPropertyName(data) {
|
|
554
|
-
if (data.type === ERROR_TYPES.PROPERTY_REQUIRED) {
|
|
555
|
-
return data.requiredProperty;
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
return data.property;
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
function isType(data, type) {
|
|
562
|
-
return data.node && is(data.node, type);
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
function isOneOfPropertiesRequiredError(data, requiredProperty, type) {
|
|
566
|
-
return data.type === ERROR_TYPES.PROPERTY_REQUIRED
|
|
567
|
-
&& (isArray(data.requiredProperty) && data.requiredProperty.includes(requiredProperty))
|
|
568
|
-
&& (!type || is(data.node, type));
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
function isPropertyValueDuplicatedError(data, propertiesName, duplicatedProperty, type) {
|
|
572
|
-
return data.type === ERROR_TYPES.PROPERTY_VALUE_DUPLICATED
|
|
573
|
-
&& data.propertiesName === propertiesName
|
|
574
|
-
&& data.duplicatedProperty === duplicatedProperty
|
|
575
|
-
&& (!type || is(data.node, type));
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
function isExpressionRequiredError(data, propertyName, type) {
|
|
579
|
-
return data.type === ERROR_TYPES.EXPRESSION_REQUIRED
|
|
580
|
-
&& data.property === propertyName
|
|
581
|
-
&& (!type || is(data.node, type));
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
function isExpressionValueNotAllowedError(data, propertyName, type) {
|
|
585
|
-
return data.type === ERROR_TYPES.EXPRESSION_VALUE_NOT_ALLOWED
|
|
586
|
-
&& data.property === propertyName
|
|
587
|
-
&& (!type || is(data.node, type));
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
function isElementPropertyValueDuplicated(data, propertyName, type) {
|
|
591
|
-
return data.type === ERROR_TYPES.ELEMENT_PROPERTY_VALUE_DUPLICATED
|
|
592
|
-
&& data.duplicatedProperty === propertyName
|
|
593
|
-
&& (!type || is(data.node, type));
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
function getBusinessObject(element) {
|
|
597
|
-
return element.businessObject || element;
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
function isEmptyString(value) {
|
|
601
|
-
return isString(value) && value.trim() === '';
|
|
1
|
+
import {
|
|
2
|
+
isArray,
|
|
3
|
+
isString
|
|
4
|
+
} from 'min-dash';
|
|
5
|
+
|
|
6
|
+
import { is } from 'bpmnlint-utils';
|
|
7
|
+
|
|
8
|
+
import { ERROR_TYPES } from 'bpmnlint-plugin-camunda-compat/rules/utils/error-types';
|
|
9
|
+
|
|
10
|
+
import { greaterOrEqual } from './version';
|
|
11
|
+
|
|
12
|
+
const TIMER_PROPERTIES = [
|
|
13
|
+
'timeDate',
|
|
14
|
+
'timeDuration',
|
|
15
|
+
'timeCycle'
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Get errors for a given element.
|
|
20
|
+
*
|
|
21
|
+
* @param {Object[]} reports
|
|
22
|
+
* @param {Object} element
|
|
23
|
+
*
|
|
24
|
+
* @returns {Object}
|
|
25
|
+
*/
|
|
26
|
+
export function getErrors(reports, element) {
|
|
27
|
+
return reports.reduce((errors, report) => {
|
|
28
|
+
const { category } = report;
|
|
29
|
+
|
|
30
|
+
if (!element
|
|
31
|
+
|| getBusinessObject(element).get('id') !== report.id
|
|
32
|
+
|| category !== 'error') {
|
|
33
|
+
return errors;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const ids = getEntryIds(report);
|
|
37
|
+
|
|
38
|
+
if (!ids.length) {
|
|
39
|
+
return errors;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let { message } = report;
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
...errors,
|
|
46
|
+
...ids.reduce((errors, id) => {
|
|
47
|
+
return {
|
|
48
|
+
...errors,
|
|
49
|
+
[ id ]: getErrorMessage(id, report) || message
|
|
50
|
+
};
|
|
51
|
+
}, {})
|
|
52
|
+
};
|
|
53
|
+
}, {});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function getEntryIds(report) {
|
|
57
|
+
const {
|
|
58
|
+
data = {},
|
|
59
|
+
id,
|
|
60
|
+
path,
|
|
61
|
+
propertiesPanel = {}
|
|
62
|
+
} = report;
|
|
63
|
+
|
|
64
|
+
if (propertiesPanel.entryIds) {
|
|
65
|
+
return propertiesPanel.entryIds;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (isPropertyError(data, 'isExecutable')) {
|
|
69
|
+
return [ 'isExecutable' ];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (isExtensionElementRequiredError(data, 'zeebe:CalledDecision', 'bpmn:BusinessRuleTask')) {
|
|
73
|
+
return [ 'businessRuleImplementation' ];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// script task
|
|
77
|
+
if (isExtensionElementRequiredError(data, 'zeebe:Script', 'bpmn:ScriptTask')) {
|
|
78
|
+
return [ 'scriptImplementation' ];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (isPropertyError(data, 'errorRef')) {
|
|
82
|
+
return [ 'errorRef' ];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (isPropertyError(data, 'escalationRef')) {
|
|
86
|
+
return [ 'escalationRef' ];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (isPropertyError(data, 'messageRef')) {
|
|
90
|
+
return [ 'messageRef' ];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (isPropertyError(data, 'signalRef')) {
|
|
94
|
+
return [ 'signalRef' ];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (isPropertyError(data, 'historyTimeToLive')) {
|
|
98
|
+
return [ 'historyTimeToLive' ];
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (isPropertyError(data, 'decisionId', 'zeebe:CalledDecision')) {
|
|
102
|
+
return [ 'decisionId' ];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (isPropertyError(data, 'resultVariable')) {
|
|
106
|
+
return [ 'resultVariable' ];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (isPropertyError(data, 'expression', 'zeebe:Script')) {
|
|
110
|
+
return [ 'scriptExpression' ];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (isPropertyError(data, 'errorCode', 'bpmn:Error')) {
|
|
114
|
+
return [ 'errorCode' ];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (isPropertyError(data, 'escalationCode', 'bpmn:Escalation')) {
|
|
118
|
+
return [ 'escalationCode' ];
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (isPropertyError(data, 'name', 'bpmn:Message')) {
|
|
122
|
+
return [ 'messageName' ];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (isPropertyError(data, 'name', 'bpmn:Signal')) {
|
|
126
|
+
return [ 'signalName' ];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (isExtensionElementRequiredError(data, 'zeebe:LoopCharacteristics', 'bpmn:MultiInstanceLoopCharacteristics')
|
|
130
|
+
|| isPropertyError(data, 'inputCollection', 'zeebe:LoopCharacteristics')) {
|
|
131
|
+
return [ 'multiInstance-inputCollection' ];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (isPropertyDependentRequiredError(data, 'outputCollection', 'zeebe:LoopCharacteristics')) {
|
|
135
|
+
return [ 'multiInstance-outputCollection' ];
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (isPropertyDependentRequiredError(data, 'outputElement', 'zeebe:LoopCharacteristics')) {
|
|
139
|
+
return [ 'multiInstance-outputElement' ];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (isExtensionElementRequiredError(data, 'zeebe:CalledElement', 'bpmn:CallActivity')
|
|
143
|
+
|| isPropertyError(data, 'processId', 'zeebe:CalledElement')) {
|
|
144
|
+
return [ 'targetProcessId' ];
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (isExtensionElementRequiredError(data, 'zeebe:TaskDefinition')
|
|
148
|
+
|| isPropertyError(data, 'type', 'zeebe:TaskDefinition')) {
|
|
149
|
+
return [ 'taskDefinitionType' ];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (isPropertyError(data, 'retries', 'zeebe:TaskDefinition')) {
|
|
153
|
+
return [ 'taskDefinitionRetries' ];
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (isExtensionElementRequiredError(data, 'zeebe:Subscription')
|
|
157
|
+
|| isPropertyError(data, 'correlationKey', 'zeebe:Subscription')) {
|
|
158
|
+
return [ 'messageSubscriptionCorrelationKey' ];
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (isPropertyError(data, 'formKey', 'zeebe:FormDefinition')) {
|
|
162
|
+
return [ 'customFormKey' ];
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (isType(data, 'zeebe:FormDefinition')) {
|
|
166
|
+
const {
|
|
167
|
+
node,
|
|
168
|
+
requiredProperty
|
|
169
|
+
} = data;
|
|
170
|
+
|
|
171
|
+
if (isArray(requiredProperty)) {
|
|
172
|
+
if (requiredProperty.includes('formKey') && isEmptyString(node.get('formKey'))) {
|
|
173
|
+
return [ 'customFormKey' ];
|
|
174
|
+
} else if (requiredProperty.includes('formId') && isEmptyString(node.get('formId'))) {
|
|
175
|
+
return [ 'formId' ];
|
|
176
|
+
} else if (requiredProperty.includes('externalReference') && isEmptyString(node.get('externalReference'))) {
|
|
177
|
+
return [ 'externalReference' ];
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (isPropertyError(data, 'formId', 'zeebe:FormDefinition')) {
|
|
183
|
+
return [ 'formId' ];
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (isPropertyError(data, 'body', 'zeebe:UserTaskForm')) {
|
|
187
|
+
return [ 'formConfiguration' ];
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (isPropertyValueDuplicatedError(data, 'values', 'key', 'zeebe:TaskHeaders')) {
|
|
191
|
+
const {
|
|
192
|
+
node,
|
|
193
|
+
properties,
|
|
194
|
+
propertiesName
|
|
195
|
+
} = data;
|
|
196
|
+
|
|
197
|
+
return properties.map(property => {
|
|
198
|
+
const index = node.get(propertiesName).indexOf(property);
|
|
199
|
+
|
|
200
|
+
return `${ id }-header-${ index }-key`;
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (isExtensionElementNotAllowedError(data, 'zeebe:Properties')) {
|
|
205
|
+
const { extensionElement } = data;
|
|
206
|
+
|
|
207
|
+
return extensionElement.get('zeebe:properties').map((zeebeProperty, index) => {
|
|
208
|
+
return `${ id }-extensionProperty-${ index }-name`;
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (isExtensionElementNotAllowedError(data, 'zeebe:UserTask')) {
|
|
213
|
+
return [ 'userTaskImplementation' ];
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (isExtensionElementNotAllowedError(data, 'zeebe:FormDefinition', 'bpmn:StartEvent')) {
|
|
217
|
+
return [ 'formType' ];
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
if (isPropertyError(data, 'conditionExpression', 'bpmn:SequenceFlow')) {
|
|
222
|
+
return [ 'conditionExpression' ];
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (isPropertyError(data, 'completionCondition', 'bpmn:MultiInstanceLoopCharacteristics')) {
|
|
226
|
+
return [ 'multiInstance-completionCondition' ];
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (TIMER_PROPERTIES.some(property =>
|
|
230
|
+
isOneOfPropertiesRequiredError(data, property, 'bpmn:TimerEventDefinition'))
|
|
231
|
+
) {
|
|
232
|
+
return [ 'timerEventDefinitionType' ];
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (isExpressionRequiredError(data, 'timeCycle', 'bpmn:FormalExpression')
|
|
236
|
+
|| isExpressionRequiredError(data, 'timeDate', 'bpmn:FormalExpression')
|
|
237
|
+
|| isExpressionRequiredError(data, 'timeDuration', 'bpmn:FormalExpression')) {
|
|
238
|
+
return [ 'timerEventDefinitionValue' ];
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (isExpressionValueNotAllowedError(data, 'timeCycle', 'bpmn:FormalExpression')
|
|
242
|
+
|| isExpressionValueNotAllowedError(data, 'timeDate', 'bpmn:FormalExpression')
|
|
243
|
+
|| isExpressionValueNotAllowedError(data, 'timeDuration', 'bpmn:FormalExpression')) {
|
|
244
|
+
return [ 'timerEventDefinitionValue' ];
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (isPropertyError(data, 'timeCycle', 'bpmn:TimerEventDefinition')
|
|
248
|
+
|| isPropertyError(data, 'timeDate', 'bpmn:TimerEventDefinition')
|
|
249
|
+
|| isPropertyError(data, 'timeDuration', 'bpmn:TimerEventDefinition')) {
|
|
250
|
+
return [ 'timerEventDefinitionType' ];
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const LIST_PROPERTIES = [
|
|
254
|
+
[ 'zeebe:Input', 'input' ],
|
|
255
|
+
[ 'zeebe:Output', 'output' ],
|
|
256
|
+
[ 'zeebe:Property', 'extensionProperty' ],
|
|
257
|
+
[ 'zeebe:Header', 'header' ]
|
|
258
|
+
];
|
|
259
|
+
|
|
260
|
+
for (const [ type, prefix ] of LIST_PROPERTIES) {
|
|
261
|
+
if (isType(data, type)
|
|
262
|
+
&& getPropertyName(data)) {
|
|
263
|
+
|
|
264
|
+
const index = path[ path.length - 2 ];
|
|
265
|
+
|
|
266
|
+
return [ `${ id }-${ prefix }-${ index }-${ getPropertyName(data) }` ];
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (isType(data, 'zeebe:LoopCharacteristics')) {
|
|
271
|
+
return [ `multiInstance-${getPropertyName(data)}` ];
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (isPropertyError(data, 'candidateUsers', 'zeebe:AssignmentDefinition')) {
|
|
275
|
+
return [ 'assignmentDefinitionCandidateUsers' ];
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (isPropertyError(data, 'historyTimeToLive', 'bpmn:Process')) {
|
|
279
|
+
return [ 'historyTimeToLive' ];
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
if (isExpressionValueNotAllowedError(data, 'dueDate', 'zeebe:TaskSchedule')) {
|
|
283
|
+
return [ 'taskScheduleDueDate' ];
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
if (isExpressionValueNotAllowedError(data, 'followUpDate', 'zeebe:TaskSchedule')) {
|
|
287
|
+
return [ 'taskScheduleFollowUpDate' ];
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (isExtensionElementNotAllowedError(data, 'zeebe:TaskSchedule', 'bpmn:UserTask')) {
|
|
291
|
+
const { extensionElement: taskSchedule } = data;
|
|
292
|
+
|
|
293
|
+
let ids = [];
|
|
294
|
+
|
|
295
|
+
if (taskSchedule.get('dueDate')) {
|
|
296
|
+
ids = [ ...ids, 'taskScheduleDueDate' ];
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
if (taskSchedule.get('followUpDate')) {
|
|
300
|
+
ids = [ ...ids, 'taskScheduleFollowUpDate' ];
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return ids;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (isPropertyError(data, 'propagateAllParentVariables', 'zeebe:CalledElement')) {
|
|
307
|
+
return [ 'propagateAllParentVariables' ];
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
if (isPropertyError(data, 'name', 'bpmn:LinkEventDefinition')
|
|
311
|
+
|| isElementPropertyValueDuplicated(data, 'name', 'bpmn:LinkEventDefinition')) {
|
|
312
|
+
return [ 'linkName' ];
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
if (isPropertyError(data, 'waitForCompletion', 'bpmn:CompensateEventDefinition')) {
|
|
316
|
+
return [ 'waitForCompletion' ];
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
return [];
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
export function getErrorMessage(id, report) {
|
|
323
|
+
const {
|
|
324
|
+
data = {},
|
|
325
|
+
executionPlatformVersion
|
|
326
|
+
} = report;
|
|
327
|
+
|
|
328
|
+
// adjust FEEL message
|
|
329
|
+
if (data.type === ERROR_TYPES.FEEL_EXPRESSION_INVALID) {
|
|
330
|
+
return 'Unparsable FEEL expression.';
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
if (data.type === ERROR_TYPES.EXPRESSION_NOT_ALLOWED) {
|
|
334
|
+
return 'Cannot be an expression.';
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if (id === 'isExecutable') {
|
|
338
|
+
const { parentNode } = data;
|
|
339
|
+
|
|
340
|
+
if (parentNode && is(parentNode, 'bpmn:Participant')) {
|
|
341
|
+
return 'One process must be executable.';
|
|
342
|
+
} else {
|
|
343
|
+
return 'Process must be executable.';
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
if ([ 'businessRuleImplementation', 'scriptImplementation' ].includes(id)) {
|
|
348
|
+
return 'Implementation must be defined.';
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
if (id === 'errorRef') {
|
|
352
|
+
return 'Global error reference must be defined.';
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
if (id === 'escalationRef') {
|
|
356
|
+
return 'Global escalation reference must be defined.';
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
if (id === 'messageRef') {
|
|
360
|
+
return 'Global message reference must be defined.';
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (id === 'signalRef') {
|
|
364
|
+
return 'Global signal reference must be defined.';
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
if (id === 'decisionId') {
|
|
368
|
+
return 'Decision ID must be defined.';
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
if (id === 'scriptExpression') {
|
|
372
|
+
return 'FEEL expression must be defined.';
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if (id === 'resultVariable') {
|
|
376
|
+
return 'Result variable must be defined.';
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
if (id === 'errorCode' && data.type === ERROR_TYPES.PROPERTY_REQUIRED) {
|
|
380
|
+
return 'Code must be defined.';
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
if (id === 'escalationCode' && data.type === ERROR_TYPES.PROPERTY_REQUIRED) {
|
|
384
|
+
return 'Code must be defined.';
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
if (id === 'messageName') {
|
|
388
|
+
return 'Name must be defined.';
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
if (id === 'signalName') {
|
|
392
|
+
return 'Name must be defined.';
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
if (id === 'multiInstance-inputCollection') {
|
|
396
|
+
return 'Input collection must be defined.';
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
if (id === 'multiInstance-outputCollection') {
|
|
400
|
+
return 'Output collection must be defined.';
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if (id === 'multiInstance-outputElement') {
|
|
404
|
+
return 'Output element must be defined.';
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
if (id === 'targetProcessId') {
|
|
408
|
+
return 'Process ID must be defined.';
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
if (id === 'taskDefinitionType') {
|
|
412
|
+
return 'Type must be defined.';
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
if (id === 'timerEventDefinitionType' && data.type === ERROR_TYPES.PROPERTY_REQUIRED) {
|
|
416
|
+
return 'Type must be defined.';
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
if (id === 'messageSubscriptionCorrelationKey'
|
|
420
|
+
&& [
|
|
421
|
+
ERROR_TYPES.EXTENSION_ELEMENT_REQUIRED,
|
|
422
|
+
ERROR_TYPES.PROPERTY_REQUIRED
|
|
423
|
+
].includes(data.type)) {
|
|
424
|
+
return 'Subscription correlation key must be defined.';
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
if (id === 'customFormKey') {
|
|
428
|
+
return 'Form key must be defined.';
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
if (id === 'formId') {
|
|
432
|
+
if (data.type === ERROR_TYPES.PROPERTY_REQUIRED) {
|
|
433
|
+
return 'Form ID must be defined.';
|
|
434
|
+
} else if (data.type === ERROR_TYPES.PROPERTY_NOT_ALLOWED) {
|
|
435
|
+
return 'Form ID not supported.';
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
if (id === 'externalReference') {
|
|
440
|
+
return 'External reference must be defined.';
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if (id === 'formConfiguration') {
|
|
444
|
+
return 'Form JSON configuration must be defined.';
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
if (/^.+-header-[0-9]+-key$/.test(id)) {
|
|
448
|
+
return 'Must be unique.';
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
if (/^.+-extensionProperty-[0-9]+-name$/.test(id)) {
|
|
452
|
+
return 'Not supported.';
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
if (id === 'userTaskImplementation') {
|
|
456
|
+
return 'Supported only in Camunda 8.5 or newer.';
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
if (id === 'conditionExpression') {
|
|
460
|
+
return 'Condition expression must be defined.';
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
if (id === 'timerEventDefinitionType' && data.type === ERROR_TYPES.PROPERTY_NOT_ALLOWED) {
|
|
464
|
+
return 'Type not supported.';
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
if (id === 'timerEventDefinitionValue') {
|
|
468
|
+
if (data.type === ERROR_TYPES.EXPRESSION_REQUIRED) {
|
|
469
|
+
return 'Value must be defined.';
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
const { property } = data;
|
|
473
|
+
|
|
474
|
+
if (property === 'timeCycle') {
|
|
475
|
+
if (!greaterOrEqual(executionPlatformVersion, '8.1')) {
|
|
476
|
+
return 'Must be an expression, an ISO 8601 repeating interval, or a cron expression (cron only supported by Camunda 8.1 or newer).';
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
return 'Must be an expression, an ISO 8601 repeating interval, or a cron expression.';
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
if (property === 'timeDate') {
|
|
483
|
+
return 'Must be an expression, or an ISO 8601 date.';
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
if (property === 'timeDuration') {
|
|
487
|
+
return 'Must be an expression, or an ISO 8601 interval.';
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
if (id === 'assignmentDefinitionCandidateUsers') {
|
|
492
|
+
return 'Not supported.';
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
if (id === 'taskScheduleDueDate') {
|
|
496
|
+
if (data.type === ERROR_TYPES.EXTENSION_ELEMENT_NOT_ALLOWED) {
|
|
497
|
+
return 'Not supported.';
|
|
498
|
+
} else {
|
|
499
|
+
return 'Must be an ISO 8601 date.';
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
if (id === 'taskScheduleFollowUpDate') {
|
|
504
|
+
if (data.type === ERROR_TYPES.EXTENSION_ELEMENT_NOT_ALLOWED) {
|
|
505
|
+
return 'Not supported.';
|
|
506
|
+
} else {
|
|
507
|
+
return 'Must be an ISO 8601 date.';
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
if (id === 'propagateAllParentVariables') {
|
|
512
|
+
return 'Not supported.';
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
if (id === 'linkName') {
|
|
516
|
+
if (data.type === ERROR_TYPES.ELEMENT_PROPERTY_VALUE_DUPLICATED) {
|
|
517
|
+
return 'Must be unique.';
|
|
518
|
+
} else {
|
|
519
|
+
return 'Must be defined.';
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
if (id === 'waitForCompletion') {
|
|
524
|
+
return 'Must wait for completion.';
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
function isExtensionElementNotAllowedError(data, extensionElement, type) {
|
|
529
|
+
return data.type === ERROR_TYPES.EXTENSION_ELEMENT_NOT_ALLOWED
|
|
530
|
+
&& is(data.extensionElement, extensionElement)
|
|
531
|
+
&& (!type || is(data.node, type));
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
function isExtensionElementRequiredError(data, requiredExtensionElement, type) {
|
|
535
|
+
return data.type === ERROR_TYPES.EXTENSION_ELEMENT_REQUIRED
|
|
536
|
+
&& (isArray(data.requiredExtensionElement) && data.requiredExtensionElement.includes(requiredExtensionElement)
|
|
537
|
+
|| data.requiredExtensionElement === requiredExtensionElement)
|
|
538
|
+
&& (!type || is(data.node, type));
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
function isPropertyDependentRequiredError(data, dependentRequiredProperty, type) {
|
|
542
|
+
return data.type === ERROR_TYPES.PROPERTY_DEPENDENT_REQUIRED
|
|
543
|
+
&& data.dependentRequiredProperty === dependentRequiredProperty
|
|
544
|
+
&& (!type || is(data.node, type));
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
|
|
548
|
+
function isPropertyError(data, property, type) {
|
|
549
|
+
return getPropertyName(data) === property
|
|
550
|
+
&& (!type || is(data.node, type));
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
function getPropertyName(data) {
|
|
554
|
+
if (data.type === ERROR_TYPES.PROPERTY_REQUIRED) {
|
|
555
|
+
return data.requiredProperty;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
return data.property;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
function isType(data, type) {
|
|
562
|
+
return data.node && is(data.node, type);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
function isOneOfPropertiesRequiredError(data, requiredProperty, type) {
|
|
566
|
+
return data.type === ERROR_TYPES.PROPERTY_REQUIRED
|
|
567
|
+
&& (isArray(data.requiredProperty) && data.requiredProperty.includes(requiredProperty))
|
|
568
|
+
&& (!type || is(data.node, type));
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
function isPropertyValueDuplicatedError(data, propertiesName, duplicatedProperty, type) {
|
|
572
|
+
return data.type === ERROR_TYPES.PROPERTY_VALUE_DUPLICATED
|
|
573
|
+
&& data.propertiesName === propertiesName
|
|
574
|
+
&& data.duplicatedProperty === duplicatedProperty
|
|
575
|
+
&& (!type || is(data.node, type));
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
function isExpressionRequiredError(data, propertyName, type) {
|
|
579
|
+
return data.type === ERROR_TYPES.EXPRESSION_REQUIRED
|
|
580
|
+
&& data.property === propertyName
|
|
581
|
+
&& (!type || is(data.node, type));
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
function isExpressionValueNotAllowedError(data, propertyName, type) {
|
|
585
|
+
return data.type === ERROR_TYPES.EXPRESSION_VALUE_NOT_ALLOWED
|
|
586
|
+
&& data.property === propertyName
|
|
587
|
+
&& (!type || is(data.node, type));
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
function isElementPropertyValueDuplicated(data, propertyName, type) {
|
|
591
|
+
return data.type === ERROR_TYPES.ELEMENT_PROPERTY_VALUE_DUPLICATED
|
|
592
|
+
&& data.duplicatedProperty === propertyName
|
|
593
|
+
&& (!type || is(data.node, type));
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
function getBusinessObject(element) {
|
|
597
|
+
return element.businessObject || element;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
function isEmptyString(value) {
|
|
601
|
+
return isString(value) && value.trim() === '';
|
|
602
602
|
}
|