bpmnlint-plugin-camunda-compat 2.23.0 → 2.24.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.
Files changed (58) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +39 -39
  3. package/index.js +242 -237
  4. package/package.json +53 -53
  5. package/rules/camunda-cloud/called-element.js +42 -42
  6. package/rules/camunda-cloud/collapsed-subprocess.js +40 -40
  7. package/rules/camunda-cloud/connector-properties/config.js +90 -90
  8. package/rules/camunda-cloud/connector-properties/index.js +47 -47
  9. package/rules/camunda-cloud/duplicate-execution-listeners.js +33 -33
  10. package/rules/camunda-cloud/duplicate-task-headers.js +58 -58
  11. package/rules/camunda-cloud/element-type/config.js +66 -66
  12. package/rules/camunda-cloud/element-type/index.js +133 -133
  13. package/rules/camunda-cloud/error-reference.js +71 -71
  14. package/rules/camunda-cloud/escalation-boundary-event-attached-to-ref.js +48 -48
  15. package/rules/camunda-cloud/escalation-reference.js +66 -66
  16. package/rules/camunda-cloud/event-based-gateway-target.js +38 -38
  17. package/rules/camunda-cloud/executable-process.js +61 -61
  18. package/rules/camunda-cloud/execution-listener.js +34 -34
  19. package/rules/camunda-cloud/feel.js +82 -82
  20. package/rules/camunda-cloud/implementation/config.js +16 -16
  21. package/rules/camunda-cloud/implementation/index.js +218 -218
  22. package/rules/camunda-cloud/inclusive-gateway.js +35 -35
  23. package/rules/camunda-cloud/link-event.js +142 -142
  24. package/rules/camunda-cloud/loop-characteristics.js +66 -66
  25. package/rules/camunda-cloud/message-reference.js +60 -60
  26. package/rules/camunda-cloud/no-binding-type.js +43 -43
  27. package/rules/camunda-cloud/no-candidate-users.js +38 -38
  28. package/rules/camunda-cloud/no-execution-listeners.js +21 -21
  29. package/rules/camunda-cloud/no-expression.js +173 -173
  30. package/rules/camunda-cloud/no-loop.js +316 -316
  31. package/rules/camunda-cloud/no-multiple-none-start-events.js +41 -41
  32. package/rules/camunda-cloud/no-priority-definition.js +19 -0
  33. package/rules/camunda-cloud/no-propagate-all-parent-variables.js +44 -44
  34. package/rules/camunda-cloud/no-signal-event-sub-process.js +45 -45
  35. package/rules/camunda-cloud/no-task-schedule.js +18 -18
  36. package/rules/camunda-cloud/no-template.js +23 -23
  37. package/rules/camunda-cloud/no-zeebe-properties.js +18 -18
  38. package/rules/camunda-cloud/no-zeebe-user-task.js +27 -27
  39. package/rules/camunda-cloud/priority-definition.js +62 -0
  40. package/rules/camunda-cloud/secrets.js +119 -119
  41. package/rules/camunda-cloud/sequence-flow-condition.js +56 -56
  42. package/rules/camunda-cloud/signal-reference.js +64 -64
  43. package/rules/camunda-cloud/start-event-form.js +97 -97
  44. package/rules/camunda-cloud/subscription.js +65 -65
  45. package/rules/camunda-cloud/task-schedule.js +67 -67
  46. package/rules/camunda-cloud/timer/config.js +46 -46
  47. package/rules/camunda-cloud/timer/index.js +183 -183
  48. package/rules/camunda-cloud/user-task-definition.js +24 -24
  49. package/rules/camunda-cloud/user-task-form.js +142 -142
  50. package/rules/camunda-cloud/wait-for-completion.js +46 -46
  51. package/rules/camunda-platform/history-time-to-live.js +19 -19
  52. package/rules/utils/cron.js +95 -95
  53. package/rules/utils/element.js +533 -533
  54. package/rules/utils/error-types.js +25 -25
  55. package/rules/utils/iso8601.js +52 -52
  56. package/rules/utils/reporter.js +37 -37
  57. package/rules/utils/rule.js +46 -46
  58. package/rules/utils/version.js +4 -4
package/package.json CHANGED
@@ -1,53 +1,53 @@
1
- {
2
- "name": "bpmnlint-plugin-camunda-compat",
3
- "version": "2.23.0",
4
- "description": "A bpmnlint plug-in for Camunda compatibility",
5
- "main": "index.js",
6
- "scripts": {
7
- "all": "npm run lint && npm test",
8
- "dev": "npm run test:watch",
9
- "lint": "eslint .",
10
- "test": "mocha 'test/**/*.spec.js'",
11
- "test:watch": "npm run test -- --watch"
12
- },
13
- "repository": {
14
- "type": "git",
15
- "url": "https://github.com/camunda/bpmnlint-plugin-camunda-compat"
16
- },
17
- "keywords": [
18
- "bpmnlint",
19
- "plugin"
20
- ],
21
- "author": {
22
- "name": "Philipp Fromme",
23
- "url": "https://github.com/philippfromme"
24
- },
25
- "license": "MIT",
26
- "devDependencies": {
27
- "bpmn-moddle": "^8.1.0",
28
- "bpmnlint": "^10.2.0",
29
- "camunda-bpmn-moddle": "^7.0.1",
30
- "chai": "^4.4.1",
31
- "eslint": "^8.56.0",
32
- "eslint-plugin-bpmn-io": "^1.0.0",
33
- "mocha": "^10.2.0",
34
- "modeler-moddle": "^0.2.0",
35
- "sinon": "^17.0.1",
36
- "sinon-chai": "^3.7.0",
37
- "zeebe-bpmn-moddle": "^1.4.0"
38
- },
39
- "dependencies": {
40
- "@bpmn-io/feel-lint": "^1.2.0",
41
- "@bpmn-io/moddle-utils": "^0.2.1",
42
- "bpmnlint-utils": "^1.0.2",
43
- "min-dash": "^4.1.1",
44
- "semver-compare": "^1.0.0"
45
- },
46
- "files": [
47
- "rules",
48
- "index.js"
49
- ],
50
- "engines": {
51
- "node": "*"
52
- }
53
- }
1
+ {
2
+ "name": "bpmnlint-plugin-camunda-compat",
3
+ "version": "2.24.0",
4
+ "description": "A bpmnlint plug-in for Camunda compatibility",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "all": "npm run lint && npm test",
8
+ "dev": "npm run test:watch",
9
+ "lint": "eslint .",
10
+ "test": "mocha 'test/**/*.spec.js'",
11
+ "test:watch": "npm run test -- --watch"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/camunda/bpmnlint-plugin-camunda-compat"
16
+ },
17
+ "keywords": [
18
+ "bpmnlint",
19
+ "plugin"
20
+ ],
21
+ "author": {
22
+ "name": "Philipp Fromme",
23
+ "url": "https://github.com/philippfromme"
24
+ },
25
+ "license": "MIT",
26
+ "devDependencies": {
27
+ "bpmn-moddle": "^8.1.0",
28
+ "bpmnlint": "^10.2.0",
29
+ "camunda-bpmn-moddle": "^7.0.1",
30
+ "chai": "^4.4.1",
31
+ "eslint": "^8.56.0",
32
+ "eslint-plugin-bpmn-io": "^1.0.0",
33
+ "mocha": "^10.2.0",
34
+ "modeler-moddle": "^0.2.0",
35
+ "sinon": "^17.0.1",
36
+ "sinon-chai": "^3.7.0",
37
+ "zeebe-bpmn-moddle": "^1.5.1"
38
+ },
39
+ "dependencies": {
40
+ "@bpmn-io/feel-lint": "^1.2.0",
41
+ "@bpmn-io/moddle-utils": "^0.2.1",
42
+ "bpmnlint-utils": "^1.0.2",
43
+ "min-dash": "^4.1.1",
44
+ "semver-compare": "^1.0.0"
45
+ },
46
+ "files": [
47
+ "rules",
48
+ "index.js"
49
+ ],
50
+ "engines": {
51
+ "node": "*"
52
+ }
53
+ }
@@ -1,43 +1,43 @@
1
- const { is } = require('bpmnlint-utils');
2
-
3
- const {
4
- findExtensionElement,
5
- hasExtensionElement,
6
- hasProperties
7
- } = require('../utils/element');
8
-
9
- const { reportErrors } = require('../utils/reporter');
10
-
11
- const { skipInNonExecutableProcess } = require('../utils/rule');
12
-
13
- module.exports = skipInNonExecutableProcess(function() {
14
- function check(node, reporter) {
15
- if (!is(node, 'bpmn:CallActivity')) {
16
- return;
17
- }
18
-
19
- let errors = hasExtensionElement(node, 'zeebe:CalledElement', node);
20
-
21
- if (errors && errors.length) {
22
- reportErrors(node, reporter, errors);
23
-
24
- return;
25
- }
26
-
27
- const calledElement = findExtensionElement(node, 'zeebe:CalledElement');
28
-
29
- errors = hasProperties(calledElement, {
30
- processId: {
31
- required: true
32
- }
33
- }, node);
34
-
35
- if (errors && errors.length) {
36
- reportErrors(node, reporter, errors);
37
- }
38
- }
39
-
40
- return {
41
- check
42
- };
1
+ const { is } = require('bpmnlint-utils');
2
+
3
+ const {
4
+ findExtensionElement,
5
+ hasExtensionElement,
6
+ hasProperties
7
+ } = require('../utils/element');
8
+
9
+ const { reportErrors } = require('../utils/reporter');
10
+
11
+ const { skipInNonExecutableProcess } = require('../utils/rule');
12
+
13
+ module.exports = skipInNonExecutableProcess(function() {
14
+ function check(node, reporter) {
15
+ if (!is(node, 'bpmn:CallActivity')) {
16
+ return;
17
+ }
18
+
19
+ let errors = hasExtensionElement(node, 'zeebe:CalledElement', node);
20
+
21
+ if (errors && errors.length) {
22
+ reportErrors(node, reporter, errors);
23
+
24
+ return;
25
+ }
26
+
27
+ const calledElement = findExtensionElement(node, 'zeebe:CalledElement');
28
+
29
+ errors = hasProperties(calledElement, {
30
+ processId: {
31
+ required: true
32
+ }
33
+ }, node);
34
+
35
+ if (errors && errors.length) {
36
+ reportErrors(node, reporter, errors);
37
+ }
38
+ }
39
+
40
+ return {
41
+ check
42
+ };
43
43
  });
@@ -1,40 +1,40 @@
1
- const { is } = require('bpmnlint-utils');
2
-
3
- const { ERROR_TYPES } = require('../utils/element');
4
-
5
- const { reportErrors } = require('../utils/reporter');
6
-
7
- const { skipInNonExecutableProcess } = require('../utils/rule');
8
-
9
- module.exports = skipInNonExecutableProcess(function() {
10
- function check(di, reporter) {
11
-
12
- if (!isCollapsedSubProcess(di)) {
13
- return;
14
- }
15
-
16
- const node = di.bpmnElement;
17
-
18
- const error = {
19
- message: `A <${ node.$type }> must be expanded`,
20
- data: {
21
- type: ERROR_TYPES.ELEMENT_COLLAPSED_NOT_ALLOWED,
22
- node: node,
23
- parentNode: null,
24
- allowedVersion: '8.4'
25
- }
26
- };
27
-
28
- reportErrors(node, reporter, error);
29
- }
30
-
31
- return {
32
- check
33
- };
34
- });
35
-
36
- function isCollapsedSubProcess(di) {
37
- return is(di, 'bpmndi:BPMNShape') &&
38
- is(di.get('bpmnElement'), 'bpmn:SubProcess') &&
39
- di.get('isExpanded') !== true;
40
- }
1
+ const { is } = require('bpmnlint-utils');
2
+
3
+ const { ERROR_TYPES } = require('../utils/element');
4
+
5
+ const { reportErrors } = require('../utils/reporter');
6
+
7
+ const { skipInNonExecutableProcess } = require('../utils/rule');
8
+
9
+ module.exports = skipInNonExecutableProcess(function() {
10
+ function check(di, reporter) {
11
+
12
+ if (!isCollapsedSubProcess(di)) {
13
+ return;
14
+ }
15
+
16
+ const node = di.bpmnElement;
17
+
18
+ const error = {
19
+ message: `A <${ node.$type }> must be expanded`,
20
+ data: {
21
+ type: ERROR_TYPES.ELEMENT_COLLAPSED_NOT_ALLOWED,
22
+ node: node,
23
+ parentNode: null,
24
+ allowedVersion: '8.4'
25
+ }
26
+ };
27
+
28
+ reportErrors(node, reporter, error);
29
+ }
30
+
31
+ return {
32
+ check
33
+ };
34
+ });
35
+
36
+ function isCollapsedSubProcess(di) {
37
+ return is(di, 'bpmndi:BPMNShape') &&
38
+ is(di.get('bpmnElement'), 'bpmn:SubProcess') &&
39
+ di.get('isExpanded') !== true;
40
+ }
@@ -1,91 +1,91 @@
1
- const { getPath } = require('@bpmn-io/moddle-utils');
2
-
3
- const { findExtensionElement } = require('../../utils/element');
4
-
5
- const { ERROR_TYPES } = require('../../utils/error-types');
6
-
7
- const INBOUND_CONNECTOR_PROPERTY = 'inbound.type';
8
-
9
- module.exports = {
10
- messageTtl: {
11
- version: '8.6',
12
- getError: (node) => getInboundConnectorError(node, 'messageTtl', '8.6'),
13
- getProperty: (node) => getZeebeProperty(node, 'messageTtl'),
14
- isConnector: (node) => isInboundConnector(node, [
15
- 'io.camunda:webhook:1',
16
- 'io.camunda:connector-rabbitmq-inbound:1',
17
- 'io.camunda:http-polling:1',
18
- 'io.camunda:connector-kafka-inbound:1',
19
- 'io.camunda:slack-webhook:1',
20
- 'io.camunda:aws-sqs-inbound:1',
21
- 'io.camunda:aws-sns-webhook:1'
22
- ])
23
- },
24
- consumeUnmatchedEvents: {
25
- version: '8.6',
26
- getError: (node) => getInboundConnectorError(node, 'consumeUnmatchedEvents', '8.6'),
27
- getProperty: (node) => getZeebeProperty(node, 'consumeUnmatchedEvents'),
28
- isConnector: (node) => isInboundConnector(node, [
29
- 'io.camunda:webhook:1',
30
- 'io.camunda:connector-rabbitmq-inbound:1',
31
- 'io.camunda:http-polling:1',
32
- 'io.camunda:connector-kafka-inbound:1',
33
- 'io.camunda:slack-webhook:1',
34
- 'io.camunda:aws-sqs-inbound:1',
35
- 'io.camunda:aws-sns-webhook:1'
36
- ])
37
- },
38
- deduplicationModeManualFlag: {
39
- version: '8.6',
40
- getError: (node) => getInboundConnectorError(node, 'deduplicationModeManualFlag', '8.6'),
41
- getProperty: (node) => getZeebeProperty(node, 'deduplicationModeManualFlag'),
42
- isConnector: (node) => isInboundConnector(node, [
43
- 'io.camunda:connector-rabbitmq-inbound:1',
44
- 'io.camunda:http-polling:1',
45
- 'io.camunda:connector-kafka-inbound:1',
46
- 'io.camunda:aws-sqs-inbound:1'
47
- ])
48
- }
49
- };
50
-
51
- function isInboundConnector(node, names) {
52
- const zeebeProperty = getZeebeProperty(node, INBOUND_CONNECTOR_PROPERTY);
53
-
54
- return zeebeProperty && names.includes(zeebeProperty.get('value'));
55
- }
56
-
57
- function getZeebeProperty(node, propertyName) {
58
- const zeebeProperties = findExtensionElement(node, 'zeebe:Properties');
59
-
60
- if (!zeebeProperties) {
61
- return false;
62
- }
63
-
64
- return zeebeProperties.get('properties').find(property => {
65
- return property.get('name') === propertyName;
66
- });
67
- }
68
-
69
- function getInboundConnectorError(node, propertyName, allowedVersion) {
70
- const property = getZeebeProperty(node, propertyName);
71
-
72
- const connectorProperty = getZeebeProperty(node, INBOUND_CONNECTOR_PROPERTY);
73
-
74
- const path = getPath(property, node);
75
-
76
- return {
77
- message: `Connector property <name> with value <${ propertyName }> only allowed by Camunda ${ allowedVersion } or newer.`,
78
- path: path ? [ ...path, 'name' ] : [ 'name' ],
79
- data: {
80
- type: ERROR_TYPES.CONNECTORS_PROPERTY_VALUE_NOT_ALLOWED,
81
- node: property,
82
- parentNode: node,
83
- property: 'name',
84
- allowedVersion,
85
- connectorProperty: {
86
- node: connectorProperty,
87
- properties: [ 'name', 'value' ]
88
- }
89
- }
90
- };
1
+ const { getPath } = require('@bpmn-io/moddle-utils');
2
+
3
+ const { findExtensionElement } = require('../../utils/element');
4
+
5
+ const { ERROR_TYPES } = require('../../utils/error-types');
6
+
7
+ const INBOUND_CONNECTOR_PROPERTY = 'inbound.type';
8
+
9
+ module.exports = {
10
+ messageTtl: {
11
+ version: '8.6',
12
+ getError: (node) => getInboundConnectorError(node, 'messageTtl', '8.6'),
13
+ getProperty: (node) => getZeebeProperty(node, 'messageTtl'),
14
+ isConnector: (node) => isInboundConnector(node, [
15
+ 'io.camunda:webhook:1',
16
+ 'io.camunda:connector-rabbitmq-inbound:1',
17
+ 'io.camunda:http-polling:1',
18
+ 'io.camunda:connector-kafka-inbound:1',
19
+ 'io.camunda:slack-webhook:1',
20
+ 'io.camunda:aws-sqs-inbound:1',
21
+ 'io.camunda:aws-sns-webhook:1'
22
+ ])
23
+ },
24
+ consumeUnmatchedEvents: {
25
+ version: '8.6',
26
+ getError: (node) => getInboundConnectorError(node, 'consumeUnmatchedEvents', '8.6'),
27
+ getProperty: (node) => getZeebeProperty(node, 'consumeUnmatchedEvents'),
28
+ isConnector: (node) => isInboundConnector(node, [
29
+ 'io.camunda:webhook:1',
30
+ 'io.camunda:connector-rabbitmq-inbound:1',
31
+ 'io.camunda:http-polling:1',
32
+ 'io.camunda:connector-kafka-inbound:1',
33
+ 'io.camunda:slack-webhook:1',
34
+ 'io.camunda:aws-sqs-inbound:1',
35
+ 'io.camunda:aws-sns-webhook:1'
36
+ ])
37
+ },
38
+ deduplicationModeManualFlag: {
39
+ version: '8.6',
40
+ getError: (node) => getInboundConnectorError(node, 'deduplicationModeManualFlag', '8.6'),
41
+ getProperty: (node) => getZeebeProperty(node, 'deduplicationModeManualFlag'),
42
+ isConnector: (node) => isInboundConnector(node, [
43
+ 'io.camunda:connector-rabbitmq-inbound:1',
44
+ 'io.camunda:http-polling:1',
45
+ 'io.camunda:connector-kafka-inbound:1',
46
+ 'io.camunda:aws-sqs-inbound:1'
47
+ ])
48
+ }
49
+ };
50
+
51
+ function isInboundConnector(node, names) {
52
+ const zeebeProperty = getZeebeProperty(node, INBOUND_CONNECTOR_PROPERTY);
53
+
54
+ return zeebeProperty && names.includes(zeebeProperty.get('value'));
55
+ }
56
+
57
+ function getZeebeProperty(node, propertyName) {
58
+ const zeebeProperties = findExtensionElement(node, 'zeebe:Properties');
59
+
60
+ if (!zeebeProperties) {
61
+ return false;
62
+ }
63
+
64
+ return zeebeProperties.get('properties').find(property => {
65
+ return property.get('name') === propertyName;
66
+ });
67
+ }
68
+
69
+ function getInboundConnectorError(node, propertyName, allowedVersion) {
70
+ const property = getZeebeProperty(node, propertyName);
71
+
72
+ const connectorProperty = getZeebeProperty(node, INBOUND_CONNECTOR_PROPERTY);
73
+
74
+ const path = getPath(property, node);
75
+
76
+ return {
77
+ message: `Connector property <name> with value <${ propertyName }> only allowed by Camunda ${ allowedVersion } or newer.`,
78
+ path: path ? [ ...path, 'name' ] : [ 'name' ],
79
+ data: {
80
+ type: ERROR_TYPES.CONNECTORS_PROPERTY_VALUE_NOT_ALLOWED,
81
+ node: property,
82
+ parentNode: node,
83
+ property: 'name',
84
+ allowedVersion,
85
+ connectorProperty: {
86
+ node: connectorProperty,
87
+ properties: [ 'name', 'value' ]
88
+ }
89
+ }
90
+ };
91
91
  }
@@ -1,47 +1,47 @@
1
- const { isAny } = require('bpmnlint-utils');
2
-
3
- const config = require('./config');
4
-
5
- const { reportErrors } = require('../../utils/reporter');
6
-
7
- const { skipInNonExecutableProcess } = require('../../utils/rule');
8
-
9
- const { greaterOrEqual } = require('../../utils/version');
10
-
11
- module.exports = skipInNonExecutableProcess(function({ version }) {
12
- function check(node, reporter) {
13
- if (!isAny(node, [ 'bpmn:FlowElement', 'bpmn:FlowElementsContainer' ])) {
14
- return;
15
- }
16
-
17
- const errors = Object.entries(config).reduce((errors, [ propertyName, {
18
- getError,
19
- getProperty,
20
- isConnector,
21
- version: allowedVersion
22
- } ]) => {
23
- if (greaterOrEqual(version, allowedVersion) || !isConnector(node)) {
24
- return errors;
25
- }
26
-
27
- const property = getProperty(node);
28
-
29
- if (property) {
30
- return [
31
- ...errors,
32
- getError(node)
33
- ];
34
- }
35
-
36
- return errors;
37
- }, []);
38
-
39
- if (errors.length) {
40
- reportErrors(node, reporter, errors);
41
- }
42
- }
43
-
44
- return {
45
- check
46
- };
47
- });
1
+ const { isAny } = require('bpmnlint-utils');
2
+
3
+ const config = require('./config');
4
+
5
+ const { reportErrors } = require('../../utils/reporter');
6
+
7
+ const { skipInNonExecutableProcess } = require('../../utils/rule');
8
+
9
+ const { greaterOrEqual } = require('../../utils/version');
10
+
11
+ module.exports = skipInNonExecutableProcess(function({ version }) {
12
+ function check(node, reporter) {
13
+ if (!isAny(node, [ 'bpmn:FlowElement', 'bpmn:FlowElementsContainer' ])) {
14
+ return;
15
+ }
16
+
17
+ const errors = Object.entries(config).reduce((errors, [ propertyName, {
18
+ getError,
19
+ getProperty,
20
+ isConnector,
21
+ version: allowedVersion
22
+ } ]) => {
23
+ if (greaterOrEqual(version, allowedVersion) || !isConnector(node)) {
24
+ return errors;
25
+ }
26
+
27
+ const property = getProperty(node);
28
+
29
+ if (property) {
30
+ return [
31
+ ...errors,
32
+ getError(node)
33
+ ];
34
+ }
35
+
36
+ return errors;
37
+ }, []);
38
+
39
+ if (errors.length) {
40
+ reportErrors(node, reporter, errors);
41
+ }
42
+ }
43
+
44
+ return {
45
+ check
46
+ };
47
+ });
@@ -1,33 +1,33 @@
1
- const {
2
- findExtensionElement,
3
- hasDuplicatedPropertiesValues
4
- } = require('../utils/element');
5
-
6
- const { reportErrors } = require('../utils/reporter');
7
-
8
- const { skipInNonExecutableProcess } = require('../utils/rule');
9
-
10
- module.exports = skipInNonExecutableProcess(function() {
11
- function check(node, reporter) {
12
- const executionListeners = findExtensionElement(node, 'zeebe:ExecutionListeners');
13
-
14
- if (!executionListeners) {
15
- return;
16
- }
17
-
18
- const errors = hasDuplicatedExecutionListeners(executionListeners, node);
19
-
20
- if (errors && errors.length) {
21
- reportErrors(node, reporter, errors);
22
- }
23
- }
24
-
25
- return {
26
- check
27
- };
28
- });
29
-
30
- // helpers //////////
31
- function hasDuplicatedExecutionListeners(executionListeners, parentNode = null) {
32
- return hasDuplicatedPropertiesValues(executionListeners, 'listeners', [ 'eventType', 'type' ], parentNode);
33
- }
1
+ const {
2
+ findExtensionElement,
3
+ hasDuplicatedPropertiesValues
4
+ } = require('../utils/element');
5
+
6
+ const { reportErrors } = require('../utils/reporter');
7
+
8
+ const { skipInNonExecutableProcess } = require('../utils/rule');
9
+
10
+ module.exports = skipInNonExecutableProcess(function() {
11
+ function check(node, reporter) {
12
+ const executionListeners = findExtensionElement(node, 'zeebe:ExecutionListeners');
13
+
14
+ if (!executionListeners) {
15
+ return;
16
+ }
17
+
18
+ const errors = hasDuplicatedExecutionListeners(executionListeners, node);
19
+
20
+ if (errors && errors.length) {
21
+ reportErrors(node, reporter, errors);
22
+ }
23
+ }
24
+
25
+ return {
26
+ check
27
+ };
28
+ });
29
+
30
+ // helpers //////////
31
+ function hasDuplicatedExecutionListeners(executionListeners, parentNode = null) {
32
+ return hasDuplicatedPropertiesValues(executionListeners, 'listeners', [ 'eventType', 'type' ], parentNode);
33
+ }