bpmnlint-plugin-camunda-compat 1.2.0 → 1.3.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/package.json +1 -1
- package/rules/timer/config.js +46 -3
- package/rules/timer/index.js +39 -35
- package/rules/utils/element.js +18 -17
package/package.json
CHANGED
package/rules/timer/config.js
CHANGED
@@ -1,4 +1,47 @@
|
|
1
|
+
const { is } = require('bpmnlint-utils');
|
2
|
+
|
1
3
|
module.exports = {
|
2
|
-
|
3
|
-
|
4
|
-
|
4
|
+
expressionType: {
|
5
|
+
'cron': '8.1',
|
6
|
+
'iso8601': '1.0'
|
7
|
+
},
|
8
|
+
elementType: {
|
9
|
+
'bpmn:StartEvent': {
|
10
|
+
'timeCycle': (isInterrupting, parent) => {
|
11
|
+
if (!isInterrupting || !isEventSubProcess(parent)) {
|
12
|
+
return '1.0';
|
13
|
+
}
|
14
|
+
|
15
|
+
return null;
|
16
|
+
},
|
17
|
+
'timeDate': () => '1.0',
|
18
|
+
'timeDuration': (_, parent) => {
|
19
|
+
if (isEventSubProcess(parent)) {
|
20
|
+
return '1.0';
|
21
|
+
}
|
22
|
+
|
23
|
+
return null;
|
24
|
+
}
|
25
|
+
},
|
26
|
+
'bpmn:BoundaryEvent': {
|
27
|
+
'timeCycle': (cancelActivity) => {
|
28
|
+
if (!cancelActivity) {
|
29
|
+
return '1.0';
|
30
|
+
}
|
31
|
+
|
32
|
+
return null;
|
33
|
+
},
|
34
|
+
'timeDate': () => '8.3',
|
35
|
+
'timeDuration': () => '1.0'
|
36
|
+
},
|
37
|
+
'bpmn:IntermediateCatchEvent': {
|
38
|
+
'timeCycle': () => null,
|
39
|
+
'timeDate': () => '8.3',
|
40
|
+
'timeDuration': () => '1.0'
|
41
|
+
}
|
42
|
+
}
|
43
|
+
};
|
44
|
+
|
45
|
+
function isEventSubProcess(element) {
|
46
|
+
return is(element, 'bpmn:SubProcess') && element.get('triggeredByEvent') === true;
|
47
|
+
}
|
package/rules/timer/index.js
CHANGED
@@ -2,14 +2,16 @@ const {
|
|
2
2
|
is
|
3
3
|
} = require('bpmnlint-utils');
|
4
4
|
|
5
|
-
const
|
5
|
+
const {
|
6
|
+
elementType: elementTypeConfig,
|
7
|
+
expressionType: expressionTypeConfig
|
8
|
+
} = require('./config');
|
6
9
|
|
7
10
|
const { greaterOrEqual } = require('../utils/version');
|
8
11
|
|
9
12
|
const {
|
10
13
|
getEventDefinition,
|
11
14
|
hasExpression,
|
12
|
-
hasProperties,
|
13
15
|
hasProperty
|
14
16
|
} = require('../utils/element');
|
15
17
|
|
@@ -37,7 +39,7 @@ module.exports = skipInNonExecutableProcess(function({ version }) {
|
|
37
39
|
return;
|
38
40
|
}
|
39
41
|
|
40
|
-
let errors = checkTimePropertyExists(eventDefinition, node);
|
42
|
+
let errors = checkTimePropertyExists(eventDefinition, node, version);
|
41
43
|
|
42
44
|
if (errors && errors.length) {
|
43
45
|
reportErrors(node, reporter, errors);
|
@@ -57,20 +59,8 @@ module.exports = skipInNonExecutableProcess(function({ version }) {
|
|
57
59
|
};
|
58
60
|
});
|
59
61
|
|
60
|
-
function checkTimePropertyExists(eventDefinition,
|
61
|
-
|
62
|
-
return hasProperty(eventDefinition, [ 'timeCycle', 'timeDate' ], event);
|
63
|
-
} else if (is(event, 'bpmn:IntermediateCatchEvent') || isInterruptingBoundaryEvent(event)) {
|
64
|
-
return hasProperties(eventDefinition, {
|
65
|
-
timeDuration: {
|
66
|
-
required: true
|
67
|
-
}
|
68
|
-
}, event);
|
69
|
-
} else if (is(event, 'bpmn:BoundaryEvent')) {
|
70
|
-
return hasProperty(eventDefinition, [ 'timeCycle', 'timeDuration' ], event);
|
71
|
-
}
|
72
|
-
|
73
|
-
return [];
|
62
|
+
function checkTimePropertyExists(eventDefinition, node, version) {
|
63
|
+
return hasProperty(eventDefinition, getSupportedTimePropertiesForVersion(node, version), node);
|
74
64
|
}
|
75
65
|
|
76
66
|
function checkTimeProperty(eventDefinition, event, version) {
|
@@ -95,32 +85,28 @@ function checkTimeProperty(eventDefinition, event, version) {
|
|
95
85
|
|
96
86
|
|
97
87
|
|
98
|
-
//
|
99
|
-
function isInterruptingBoundaryEvent(event) {
|
100
|
-
return is(event, 'bpmn:BoundaryEvent') && event.get('cancelActivity') !== false;
|
101
|
-
}
|
102
|
-
|
103
|
-
function validateDate(date, version) {
|
104
|
-
if (validateExpression(date)) {
|
105
|
-
return true;
|
106
|
-
}
|
107
|
-
|
108
|
-
if (validateISO8601Date(date)) {
|
109
|
-
return greaterOrEqual(version, config.iso8601);
|
110
|
-
}
|
111
|
-
}
|
112
|
-
|
88
|
+
// helpers //////////
|
113
89
|
function validateCycle(cycle, version) {
|
114
90
|
if (validateExpression(cycle)) {
|
115
91
|
return true;
|
116
92
|
}
|
117
93
|
|
118
94
|
if (validateISO8601Cycle(cycle)) {
|
119
|
-
return greaterOrEqual(version,
|
95
|
+
return greaterOrEqual(version, expressionTypeConfig.iso8601);
|
120
96
|
}
|
121
97
|
|
122
98
|
if (validateCronExpression(cycle)) {
|
123
|
-
return greaterOrEqual(version,
|
99
|
+
return greaterOrEqual(version, expressionTypeConfig.cron) || { allowedVersion: expressionTypeConfig.cron };
|
100
|
+
}
|
101
|
+
}
|
102
|
+
|
103
|
+
function validateDate(date, version) {
|
104
|
+
if (validateExpression(date)) {
|
105
|
+
return true;
|
106
|
+
}
|
107
|
+
|
108
|
+
if (validateISO8601Date(date)) {
|
109
|
+
return greaterOrEqual(version, expressionTypeConfig.iso8601);
|
124
110
|
}
|
125
111
|
}
|
126
112
|
|
@@ -130,7 +116,7 @@ function validateDuration(duration, version) {
|
|
130
116
|
}
|
131
117
|
|
132
118
|
if (validateISO8601Duration(duration)) {
|
133
|
-
return greaterOrEqual(version,
|
119
|
+
return greaterOrEqual(version, expressionTypeConfig.iso8601);
|
134
120
|
}
|
135
121
|
}
|
136
122
|
|
@@ -139,3 +125,21 @@ function validateExpression(text) {
|
|
139
125
|
return true;
|
140
126
|
}
|
141
127
|
}
|
128
|
+
|
129
|
+
function getSupportedTimePropertiesForVersion(element, version) {
|
130
|
+
const config = elementTypeConfig[ element.$type ];
|
131
|
+
|
132
|
+
return Object.keys(config).filter((property) => {
|
133
|
+
const supportedVersion = config[ property ](isInterrupting(element), element.$parent);
|
134
|
+
|
135
|
+
return supportedVersion && greaterOrEqual(version, supportedVersion);
|
136
|
+
});
|
137
|
+
}
|
138
|
+
|
139
|
+
function isInterrupting(element) {
|
140
|
+
if (is(element, 'bpmn:BoundaryEvent')) {
|
141
|
+
return element.get('cancelActivity') !== false;
|
142
|
+
}
|
143
|
+
|
144
|
+
return element.get('isInterrupting') !== false;
|
145
|
+
}
|
package/rules/utils/element.js
CHANGED
@@ -68,24 +68,24 @@ function findExtensionElement(node, types) {
|
|
68
68
|
|
69
69
|
module.exports.findExtensionElement = findExtensionElement;
|
70
70
|
|
71
|
-
function
|
72
|
-
return
|
71
|
+
function formatNames(names, exclusive = false) {
|
72
|
+
return names.reduce((string, name, index) => {
|
73
73
|
|
74
74
|
// first
|
75
75
|
if (index === 0) {
|
76
|
-
return `<${
|
76
|
+
return `<${ name }>`;
|
77
77
|
}
|
78
78
|
|
79
79
|
// last
|
80
|
-
if (index ===
|
81
|
-
return `${ string } ${ exclusive ? 'or' : 'and' } <${
|
80
|
+
if (index === names.length - 1) {
|
81
|
+
return `${ string } ${ exclusive ? 'or' : 'and' } <${ name }>`;
|
82
82
|
}
|
83
83
|
|
84
|
-
return `${ string }, <${
|
84
|
+
return `${ string }, <${ name }>`;
|
85
85
|
}, '');
|
86
86
|
}
|
87
87
|
|
88
|
-
module.exports.
|
88
|
+
module.exports.formatNames = formatNames;
|
89
89
|
|
90
90
|
module.exports.hasDuplicatedPropertyValues = function(node, propertiesName, propertyName, parentNode = null) {
|
91
91
|
const properties = node.get(propertiesName);
|
@@ -276,21 +276,21 @@ module.exports.hasProperties = function(node, properties, parentNode = null) {
|
|
276
276
|
}, []);
|
277
277
|
};
|
278
278
|
|
279
|
-
module.exports.hasProperty = function(node,
|
280
|
-
|
279
|
+
module.exports.hasProperty = function(node, propertyNames, parentNode = null) {
|
280
|
+
propertyNames = isArray(propertyNames) ? propertyNames : [ propertyNames ];
|
281
281
|
|
282
|
-
const properties = findProperties(node,
|
282
|
+
const properties = findProperties(node, propertyNames);
|
283
283
|
|
284
284
|
if (properties.length !== 1) {
|
285
285
|
return [
|
286
286
|
{
|
287
|
-
message: `Element of type <${ node.$type }> must have
|
287
|
+
message: `Element of type <${ node.$type }> must have property ${ formatNames(propertyNames, true) }`,
|
288
288
|
path: getPath(node, parentNode),
|
289
289
|
data: {
|
290
290
|
type: ERROR_TYPES.PROPERTY_REQUIRED,
|
291
291
|
node,
|
292
292
|
parentNode: parentNode == node ? null : parentNode,
|
293
|
-
requiredProperty:
|
293
|
+
requiredProperty: propertyNames
|
294
294
|
}
|
295
295
|
}
|
296
296
|
];
|
@@ -299,11 +299,12 @@ module.exports.hasProperty = function(node, types, parentNode = null) {
|
|
299
299
|
return [];
|
300
300
|
};
|
301
301
|
|
302
|
-
function findProperties(node,
|
302
|
+
function findProperties(node, propertyNames) {
|
303
303
|
const properties = [];
|
304
|
-
|
305
|
-
|
306
|
-
|
304
|
+
|
305
|
+
for (const propertyName of propertyNames) {
|
306
|
+
if (isDefined(node.get(propertyName))) {
|
307
|
+
properties.push(node.get(propertyName));
|
307
308
|
}
|
308
309
|
}
|
309
310
|
|
@@ -318,7 +319,7 @@ module.exports.hasExtensionElement = function(node, types, parentNode = null) {
|
|
318
319
|
if (!extensionElements || extensionElements.length !== 1) {
|
319
320
|
return [
|
320
321
|
{
|
321
|
-
message: `Element of type <${ node.$type }> must have one extension element of type ${
|
322
|
+
message: `Element of type <${ node.$type }> must have one extension element of type ${ formatNames(typesArray, true) }`,
|
322
323
|
path: getPath(node, parentNode),
|
323
324
|
data: {
|
324
325
|
type: ERROR_TYPES.EXTENSION_ELEMENT_REQUIRED,
|