Skip to content

Commit

Permalink
feat: support execution listeners
Browse files Browse the repository at this point in the history
Related to camunda/camunda-modeler#3951

deps: update dependencies

feat: adjust duplicated execution listeners message

feat: adjust missing execution listener type message

feat: support execution listeners in properties panel

feat: adjust missing execution listener support message
  • Loading branch information
barmac committed Jul 31, 2024
1 parent c4bd114 commit bb47010
Show file tree
Hide file tree
Showing 8 changed files with 348 additions and 99 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ All notable changes to [@camunda/linting](https://github.com/camunda/linting) ar

___Note:__ Yet to be released changes appear here._

## 3.23.0

* `FEAT`: support execution listeners ([#111](https://github.com/camunda/linting/pull/111))
* `FIX`: improve `no-loop` performance ([bpmnlint-plugin-camunda-compat#165](https://github.com/camunda/bpmnlint-plugin-camunda-compat/pull/165))
* `DEPS`: update to `[email protected]`
* `DEPS`: update to `[email protected]`
* `DEPS`: update to `[email protected]`

## 3.22.0

Expand Down
147 changes: 81 additions & 66 deletions lib/compiled-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@ const rules = {
"camunda-compat/called-element": "error",
"camunda-compat/collapsed-subprocess": "error",
"camunda-compat/connector-properties": "warn",
"camunda-compat/duplicate-execution-listeners": "error",
"camunda-compat/duplicate-task-headers": "error",
"camunda-compat/error-reference": "error",
"camunda-compat/escalation-boundary-event-attached-to-ref": "error",
"camunda-compat/escalation-reference": "error",
"camunda-compat/event-based-gateway-target": "error",
"camunda-compat/executable-process": "error",
"camunda-compat/execution-listener": "error",
"camunda-compat/feel": "error",
"camunda-compat/history-time-to-live": "info",
"camunda-compat/implementation": "error",
Expand All @@ -47,6 +49,7 @@ const rules = {
"camunda-compat/loop-characteristics": "error",
"camunda-compat/message-reference": "error",
"camunda-compat/no-candidate-users": "error",
"camunda-compat/no-execution-listeners": "error",
"camunda-compat/no-expression": "error",
"camunda-compat/no-loop": "error",
"camunda-compat/no-multiple-none-start-events": "error",
Expand Down Expand Up @@ -97,134 +100,146 @@ import rule_3 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/connector

cache['bpmnlint-plugin-camunda-compat/connector-properties'] = rule_3;

import rule_4 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/duplicate-task-headers';
import rule_4 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/duplicate-execution-listeners';

cache['bpmnlint-plugin-camunda-compat/duplicate-task-headers'] = rule_4;
cache['bpmnlint-plugin-camunda-compat/duplicate-execution-listeners'] = rule_4;

import rule_5 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/error-reference';
import rule_5 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/duplicate-task-headers';

cache['bpmnlint-plugin-camunda-compat/error-reference'] = rule_5;
cache['bpmnlint-plugin-camunda-compat/duplicate-task-headers'] = rule_5;

import rule_6 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/escalation-boundary-event-attached-to-ref';
import rule_6 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/error-reference';

cache['bpmnlint-plugin-camunda-compat/escalation-boundary-event-attached-to-ref'] = rule_6;
cache['bpmnlint-plugin-camunda-compat/error-reference'] = rule_6;

import rule_7 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/escalation-reference';
import rule_7 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/escalation-boundary-event-attached-to-ref';

cache['bpmnlint-plugin-camunda-compat/escalation-reference'] = rule_7;
cache['bpmnlint-plugin-camunda-compat/escalation-boundary-event-attached-to-ref'] = rule_7;

import rule_8 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/event-based-gateway-target';
import rule_8 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/escalation-reference';

cache['bpmnlint-plugin-camunda-compat/event-based-gateway-target'] = rule_8;
cache['bpmnlint-plugin-camunda-compat/escalation-reference'] = rule_8;

import rule_9 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/executable-process';
import rule_9 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/event-based-gateway-target';

cache['bpmnlint-plugin-camunda-compat/executable-process'] = rule_9;
cache['bpmnlint-plugin-camunda-compat/event-based-gateway-target'] = rule_9;

import rule_10 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/feel';
import rule_10 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/executable-process';

cache['bpmnlint-plugin-camunda-compat/feel'] = rule_10;
cache['bpmnlint-plugin-camunda-compat/executable-process'] = rule_10;

import rule_11 from 'bpmnlint-plugin-camunda-compat/rules/camunda-platform/history-time-to-live';
import rule_11 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/execution-listener';

cache['bpmnlint-plugin-camunda-compat/history-time-to-live'] = rule_11;
cache['bpmnlint-plugin-camunda-compat/execution-listener'] = rule_11;

import rule_12 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/implementation';
import rule_12 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/feel';

cache['bpmnlint-plugin-camunda-compat/implementation'] = rule_12;
cache['bpmnlint-plugin-camunda-compat/feel'] = rule_12;

import rule_13 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/inclusive-gateway';
import rule_13 from 'bpmnlint-plugin-camunda-compat/rules/camunda-platform/history-time-to-live';

cache['bpmnlint-plugin-camunda-compat/inclusive-gateway'] = rule_13;
cache['bpmnlint-plugin-camunda-compat/history-time-to-live'] = rule_13;

import rule_14 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/link-event';
import rule_14 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/implementation';

cache['bpmnlint-plugin-camunda-compat/link-event'] = rule_14;
cache['bpmnlint-plugin-camunda-compat/implementation'] = rule_14;

import rule_15 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/loop-characteristics';
import rule_15 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/inclusive-gateway';

cache['bpmnlint-plugin-camunda-compat/loop-characteristics'] = rule_15;
cache['bpmnlint-plugin-camunda-compat/inclusive-gateway'] = rule_15;

import rule_16 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/message-reference';
import rule_16 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/link-event';

cache['bpmnlint-plugin-camunda-compat/message-reference'] = rule_16;
cache['bpmnlint-plugin-camunda-compat/link-event'] = rule_16;

import rule_17 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/no-candidate-users';
import rule_17 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/loop-characteristics';

cache['bpmnlint-plugin-camunda-compat/no-candidate-users'] = rule_17;
cache['bpmnlint-plugin-camunda-compat/loop-characteristics'] = rule_17;

import rule_18 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/no-expression';
import rule_18 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/message-reference';

cache['bpmnlint-plugin-camunda-compat/no-expression'] = rule_18;
cache['bpmnlint-plugin-camunda-compat/message-reference'] = rule_18;

import rule_19 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/no-loop';
import rule_19 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/no-candidate-users';

cache['bpmnlint-plugin-camunda-compat/no-loop'] = rule_19;
cache['bpmnlint-plugin-camunda-compat/no-candidate-users'] = rule_19;

import rule_20 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/no-multiple-none-start-events';
import rule_20 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/no-execution-listeners';

cache['bpmnlint-plugin-camunda-compat/no-multiple-none-start-events'] = rule_20;
cache['bpmnlint-plugin-camunda-compat/no-execution-listeners'] = rule_20;

import rule_21 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/no-propagate-all-parent-variables';
import rule_21 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/no-expression';

cache['bpmnlint-plugin-camunda-compat/no-propagate-all-parent-variables'] = rule_21;
cache['bpmnlint-plugin-camunda-compat/no-expression'] = rule_21;

import rule_22 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/no-signal-event-sub-process';
import rule_22 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/no-loop';

cache['bpmnlint-plugin-camunda-compat/no-signal-event-sub-process'] = rule_22;
cache['bpmnlint-plugin-camunda-compat/no-loop'] = rule_22;

import rule_23 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/no-task-schedule';
import rule_23 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/no-multiple-none-start-events';

cache['bpmnlint-plugin-camunda-compat/no-task-schedule'] = rule_23;
cache['bpmnlint-plugin-camunda-compat/no-multiple-none-start-events'] = rule_23;

import rule_24 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/no-template';
import rule_24 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/no-propagate-all-parent-variables';

cache['bpmnlint-plugin-camunda-compat/no-template'] = rule_24;
cache['bpmnlint-plugin-camunda-compat/no-propagate-all-parent-variables'] = rule_24;

import rule_25 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/no-zeebe-properties';
import rule_25 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/no-signal-event-sub-process';

cache['bpmnlint-plugin-camunda-compat/no-zeebe-properties'] = rule_25;
cache['bpmnlint-plugin-camunda-compat/no-signal-event-sub-process'] = rule_25;

import rule_26 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/no-zeebe-user-task';
import rule_26 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/no-task-schedule';

cache['bpmnlint-plugin-camunda-compat/no-zeebe-user-task'] = rule_26;
cache['bpmnlint-plugin-camunda-compat/no-task-schedule'] = rule_26;

import rule_27 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/secrets';
import rule_27 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/no-template';

cache['bpmnlint-plugin-camunda-compat/secrets'] = rule_27;
cache['bpmnlint-plugin-camunda-compat/no-template'] = rule_27;

import rule_28 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/sequence-flow-condition';
import rule_28 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/no-zeebe-properties';

cache['bpmnlint-plugin-camunda-compat/sequence-flow-condition'] = rule_28;
cache['bpmnlint-plugin-camunda-compat/no-zeebe-properties'] = rule_28;

import rule_29 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/signal-reference';
import rule_29 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/no-zeebe-user-task';

cache['bpmnlint-plugin-camunda-compat/signal-reference'] = rule_29;
cache['bpmnlint-plugin-camunda-compat/no-zeebe-user-task'] = rule_29;

import rule_30 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/start-event-form';
import rule_30 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/secrets';

cache['bpmnlint-plugin-camunda-compat/start-event-form'] = rule_30;
cache['bpmnlint-plugin-camunda-compat/secrets'] = rule_30;

import rule_31 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/subscription';
import rule_31 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/sequence-flow-condition';

cache['bpmnlint-plugin-camunda-compat/subscription'] = rule_31;
cache['bpmnlint-plugin-camunda-compat/sequence-flow-condition'] = rule_31;

import rule_32 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/task-schedule';
import rule_32 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/signal-reference';

cache['bpmnlint-plugin-camunda-compat/task-schedule'] = rule_32;
cache['bpmnlint-plugin-camunda-compat/signal-reference'] = rule_32;

import rule_33 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/timer';
import rule_33 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/start-event-form';

cache['bpmnlint-plugin-camunda-compat/timer'] = rule_33;
cache['bpmnlint-plugin-camunda-compat/start-event-form'] = rule_33;

import rule_34 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/user-task-definition';
import rule_34 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/subscription';

cache['bpmnlint-plugin-camunda-compat/user-task-definition'] = rule_34;
cache['bpmnlint-plugin-camunda-compat/subscription'] = rule_34;

import rule_35 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/user-task-form';
import rule_35 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/task-schedule';

cache['bpmnlint-plugin-camunda-compat/user-task-form'] = rule_35;
cache['bpmnlint-plugin-camunda-compat/task-schedule'] = rule_35;

import rule_36 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/wait-for-completion';
import rule_36 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/timer';

cache['bpmnlint-plugin-camunda-compat/wait-for-completion'] = rule_36;
cache['bpmnlint-plugin-camunda-compat/timer'] = rule_36;

import rule_37 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/user-task-definition';

cache['bpmnlint-plugin-camunda-compat/user-task-definition'] = rule_37;

import rule_38 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/user-task-form';

cache['bpmnlint-plugin-camunda-compat/user-task-form'] = rule_38;

import rule_39 from 'bpmnlint-plugin-camunda-compat/rules/camunda-cloud/wait-for-completion';

cache['bpmnlint-plugin-camunda-compat/wait-for-completion'] = rule_39;
39 changes: 39 additions & 0 deletions lib/utils/error-messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ export function getErrorMessage(report, executionPlatform, executionPlatformVers
return getPropertyValueDuplicatedErrorMessage(report);
}

if (type === ERROR_TYPES.PROPERTY_VALUES_DUPLICATED) {
return getPropertyValuesDuplicatedErrorMessage(report);
}

if (type == ERROR_TYPES.PROPERTY_VALUE_NOT_ALLOWED) {
return getPropertyValueNotAllowedErrorMessage(report, executionPlatform, executionPlatformVersion, modeler);
}
Expand Down Expand Up @@ -228,6 +232,33 @@ function getPropertyValueDuplicatedErrorMessage(report) {
return message;
}

function getPropertyValuesDuplicatedErrorMessage(report) {
const {
data,
message
} = report;

const {
node,
parentNode,
duplicatedProperties,
properties
} = data;

const {
eventType,
type
} = duplicatedProperties;

const typeString = getTypeString(parentNode || node);

if (is(node, 'zeebe:ExecutionListeners') && every(properties, property => is(property, 'zeebe:ExecutionListener'))) {
return `${ getIndefiniteArticle(typeString) } <${ typeString }> with two or more <Execution Listeners> with the same <Event Type> (${ eventType }) and <Type> (${ type }) is not supported`;
}

return message;
}

function getPropertyValueRequiredErrorMessage(report, executionPlatform, executionPlatformVersion) {
const {
data,
Expand Down Expand Up @@ -297,6 +328,10 @@ function getExtensionElementNotAllowedErrorMessage(report, executionPlatform, ex
return getSupportedMessage('A <Start Event> with <User Task Form>', executionPlatform, executionPlatformVersion, allowedVersion);
}

if (is(extensionElement, 'zeebe:ExecutionListeners')) {
return getSupportedMessage(`${ getIndefiniteArticle(typeString) } <${ typeString }> with <Execution listeners>`, executionPlatform, executionPlatformVersion, allowedVersion);
}

return message;
}

Expand Down Expand Up @@ -485,6 +520,10 @@ function getPropertyRequiredErrorMessage(report, executionPlatform, executionPla
return `${ getIndefiniteArticle(typeString) } <${ typeString }> with <Implementation: Job worker> must have a defined <Task definition type>`;
}

if (is(node, 'zeebe:ExecutionListener') && requiredProperty === 'type') {
return 'An <Execution Listener> must have a defined <Type>';
}

if (requiredProperty === 'errorRef') {

if (parentNode && is(parentNode, 'bpmn:CatchEvent')) {
Expand Down
29 changes: 29 additions & 0 deletions lib/utils/properties-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,22 @@ export function getEntryIds(report) {
return [ 'waitForCompletion' ];
}

if (isPropertyError(data, 'type', 'zeebe:ExecutionListener')) {
const index = path[ path.length - 2 ];

return [ `${id}-executionListener-${index}-listenerType` ];
}

if (isPropertyValuesDuplicatedError(data, 'zeebe:ExecutionListeners')) {
const { properties, propertiesName } = data;

return properties.map(property => {
const index = data.node.get(propertiesName).indexOf(property);

return `${ id }-executionListener-${ index }-listenerType`;
});
}

return [];
}

Expand Down Expand Up @@ -528,6 +544,14 @@ export function getErrorMessage(id, report) {
if (id === 'waitForCompletion') {
return 'Must wait for completion.';
}

if (/^.+-executionListener-[0-9]+-listenerType$/.test(id)) {
if (type === ERROR_TYPES.PROPERTY_VALUES_DUPLICATED) {
return 'Must be unique.';
} else {
return 'Must be defined.';
}
}
}

function isExtensionElementNotAllowedError(data, extensionElement, type) {
Expand Down Expand Up @@ -580,6 +604,11 @@ function isPropertyValueDuplicatedError(data, propertiesName, duplicatedProperty
&& (!type || is(data.node, type));
}

function isPropertyValuesDuplicatedError(data, type) {
return data.type === ERROR_TYPES.PROPERTY_VALUES_DUPLICATED
&& (!type || is(data.node, type));
}

function isExpressionRequiredError(data, propertyName, type) {
return data.type === ERROR_TYPES.EXPRESSION_REQUIRED
&& data.property === propertyName
Expand Down
Loading

0 comments on commit bb47010

Please sign in to comment.