bpmnlint-plugin-camunda-compat 2.20.1 → 2.21.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 (52) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +39 -39
  3. package/index.js +224 -223
  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 -93
  8. package/rules/camunda-cloud/connector-properties/index.js +47 -47
  9. package/rules/camunda-cloud/duplicate-task-headers.js +58 -58
  10. package/rules/camunda-cloud/element-type/config.js +66 -66
  11. package/rules/camunda-cloud/element-type/index.js +133 -133
  12. package/rules/camunda-cloud/error-reference.js +71 -71
  13. package/rules/camunda-cloud/escalation-boundary-event-attached-to-ref.js +48 -48
  14. package/rules/camunda-cloud/escalation-reference.js +66 -66
  15. package/rules/camunda-cloud/event-based-gateway-target.js +38 -38
  16. package/rules/camunda-cloud/executable-process.js +61 -61
  17. package/rules/camunda-cloud/feel.js +82 -82
  18. package/rules/camunda-cloud/implementation/config.js +16 -16
  19. package/rules/camunda-cloud/implementation/index.js +218 -218
  20. package/rules/camunda-cloud/inclusive-gateway.js +35 -35
  21. package/rules/camunda-cloud/link-event.js +142 -142
  22. package/rules/camunda-cloud/loop-characteristics.js +66 -66
  23. package/rules/camunda-cloud/message-reference.js +60 -60
  24. package/rules/camunda-cloud/no-candidate-users.js +38 -38
  25. package/rules/camunda-cloud/no-expression.js +173 -173
  26. package/rules/camunda-cloud/no-loop.js +145 -145
  27. package/rules/camunda-cloud/no-multiple-none-start-events.js +41 -41
  28. package/rules/camunda-cloud/no-propagate-all-parent-variables.js +44 -44
  29. package/rules/camunda-cloud/no-signal-event-sub-process.js +45 -45
  30. package/rules/camunda-cloud/no-task-schedule.js +18 -18
  31. package/rules/camunda-cloud/no-template.js +23 -23
  32. package/rules/camunda-cloud/no-zeebe-properties.js +18 -18
  33. package/rules/camunda-cloud/no-zeebe-user-task.js +27 -27
  34. package/rules/camunda-cloud/secrets.js +119 -119
  35. package/rules/camunda-cloud/sequence-flow-condition.js +56 -56
  36. package/rules/camunda-cloud/signal-reference.js +64 -64
  37. package/rules/camunda-cloud/start-event-form.js +97 -97
  38. package/rules/camunda-cloud/subscription.js +65 -65
  39. package/rules/camunda-cloud/task-schedule.js +67 -67
  40. package/rules/camunda-cloud/timer/config.js +46 -46
  41. package/rules/camunda-cloud/timer/index.js +183 -183
  42. package/rules/camunda-cloud/user-task-definition.js +24 -24
  43. package/rules/camunda-cloud/user-task-form.js +142 -142
  44. package/rules/camunda-cloud/wait-for-completion.js +46 -46
  45. package/rules/camunda-platform/history-time-to-live.js +19 -19
  46. package/rules/utils/cron.js +95 -95
  47. package/rules/utils/element.js +484 -484
  48. package/rules/utils/error-types.js +24 -24
  49. package/rules/utils/iso8601.js +52 -52
  50. package/rules/utils/reporter.js +37 -37
  51. package/rules/utils/rule.js +46 -46
  52. 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.20.1",
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.1.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.21.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.1.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,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,94 +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
- type: connectorProperty,
87
- properties: {
88
- name: connectorProperty.get('name'),
89
- value: connectorProperty.get('value')
90
- }
91
- }
92
- }
93
- };
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
+ };
94
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,59 +1,59 @@
1
- const {
2
- is,
3
- isAny
4
- } = require('bpmnlint-utils');
5
-
6
- const {
7
- findExtensionElement,
8
- getMessageEventDefinition,
9
- hasDuplicatedPropertyValues
10
- } = require('../utils/element');
11
-
12
- const { reportErrors } = require('../utils/reporter');
13
-
14
- const { skipInNonExecutableProcess } = require('../utils/rule');
15
-
16
- module.exports = skipInNonExecutableProcess(function() {
17
- function check(node, reporter) {
18
- if (!is(node, 'bpmn:UserTask') && !isZeebeServiceTask(node)) {
19
- return;
20
- }
21
-
22
- const taskHeaders = findExtensionElement(node, 'zeebe:TaskHeaders');
23
-
24
- if (!taskHeaders) {
25
- return;
26
- }
27
-
28
- const errors = hasDuplicatedPropertyValues(taskHeaders, 'values', 'key', node);
29
-
30
- if (errors && errors.length) {
31
- reportErrors(node, reporter, errors);
32
- }
33
- }
34
-
35
- return {
36
- check
37
- };
38
- });
39
-
40
- // helpers //////////
41
-
42
- function isZeebeServiceTask(element) {
43
- if (is(element, 'zeebe:ZeebeServiceTask')) {
44
- return true;
45
- }
46
-
47
- if (isAny(element, [
48
- 'bpmn:EndEvent',
49
- 'bpmn:IntermediateThrowEvent'
50
- ])) {
51
- return getMessageEventDefinition(element);
52
- }
53
-
54
- if (is(element, 'bpmn:BusinessRuleTask')) {
55
- return findExtensionElement(element, 'zeebe:TaskDefinition');
56
- }
57
-
58
- return false;
1
+ const {
2
+ is,
3
+ isAny
4
+ } = require('bpmnlint-utils');
5
+
6
+ const {
7
+ findExtensionElement,
8
+ getMessageEventDefinition,
9
+ hasDuplicatedPropertyValues
10
+ } = require('../utils/element');
11
+
12
+ const { reportErrors } = require('../utils/reporter');
13
+
14
+ const { skipInNonExecutableProcess } = require('../utils/rule');
15
+
16
+ module.exports = skipInNonExecutableProcess(function() {
17
+ function check(node, reporter) {
18
+ if (!is(node, 'bpmn:UserTask') && !isZeebeServiceTask(node)) {
19
+ return;
20
+ }
21
+
22
+ const taskHeaders = findExtensionElement(node, 'zeebe:TaskHeaders');
23
+
24
+ if (!taskHeaders) {
25
+ return;
26
+ }
27
+
28
+ const errors = hasDuplicatedPropertyValues(taskHeaders, 'values', 'key', node);
29
+
30
+ if (errors && errors.length) {
31
+ reportErrors(node, reporter, errors);
32
+ }
33
+ }
34
+
35
+ return {
36
+ check
37
+ };
38
+ });
39
+
40
+ // helpers //////////
41
+
42
+ function isZeebeServiceTask(element) {
43
+ if (is(element, 'zeebe:ZeebeServiceTask')) {
44
+ return true;
45
+ }
46
+
47
+ if (isAny(element, [
48
+ 'bpmn:EndEvent',
49
+ 'bpmn:IntermediateThrowEvent'
50
+ ])) {
51
+ return getMessageEventDefinition(element);
52
+ }
53
+
54
+ if (is(element, 'bpmn:BusinessRuleTask')) {
55
+ return findExtensionElement(element, 'zeebe:TaskDefinition');
56
+ }
57
+
58
+ return false;
59
59
  }