Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

bpmnlint

Package Overview
Dependencies
Maintainers
0
Versions
61
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bpmnlint - npm Package Compare versions

Comparing version 10.3.0 to 10.3.1

2

package.json
{
"name": "bpmnlint",
"description": "Validate your BPMN diagrams based on configurable lint rules",
"version": "10.3.0",
"version": "10.3.1",
"main": "lib/index.js",

@@ -6,0 +6,0 @@ "keywords": [

const {
isAny, is
is,
isAny
} = require('bpmnlint-utils');

@@ -13,4 +14,4 @@

* * `bpmn:Escalation`
* * `bpmn:Message`
* * `bpmn:Signal`
* * `bpmn:Message`
*

@@ -20,3 +21,3 @@ * For each of these elements proper usage implies:

* * element must have a name
* * element is used (referenced) from event definitions
* * element is referenced by at least one element
* * there exists only a single element per type with a given name

@@ -32,16 +33,17 @@ */

const events = getEvents(node);
const eventDefinitions = getEventDefinitions(node);
const rootElements = getRootElements(node);
events.forEach(event => {
if (!hasName(event)) {
reporter.report(event.id, 'Element is missing name');
const referencingElements = getReferencingElements(node);
rootElements.forEach(rootElement => {
if (!hasName(rootElement)) {
reporter.report(rootElement.id, 'Element is missing name');
}
if (!isReferenced(event, eventDefinitions)) {
reporter.report(event.id, 'Element is unused');
if (!isReferenced(rootElement, referencingElements)) {
reporter.report(rootElement.id, 'Element is unused');
}
if (!isUnique(event, events)) {
reporter.report(event.id, 'Element name is not unique');
if (!isUnique(rootElement, rootElements)) {
reporter.report(rootElement.id, 'Element name is not unique');
}

@@ -58,25 +60,38 @@ });

function getEvents(definition) {
return definition.rootElements.filter(node => isAny(node, [ 'bpmn:Error', 'bpmn:Escalation', 'bpmn:Message', 'bpmn:Signal' ]));
function getRootElements(definitions) {
return definitions.rootElements.filter(node => isAny(node, [ 'bpmn:Error', 'bpmn:Escalation', 'bpmn:Message', 'bpmn:Signal' ]));
}
function getEventDefinitions(definition) {
const eventDefinitions = [];
function getReferencingElements(definitions) {
const referencingElements = [];
function traverse(element) {
if (element.rootElements) {
element.rootElements.forEach(traverse);
if (is(element, 'bpmn:Definitions') && element.get('rootElements').length) {
element.get('rootElements').forEach(traverse);
}
if (element.flowElements) {
element.flowElements.forEach(traverse);
if (is(element, 'bpmn:FlowElementsContainer') && element.get('flowElements').length) {
element.get('flowElements').forEach(traverse);
}
if (element.eventDefinitions) {
element.eventDefinitions.forEach(eventDefinition => eventDefinitions.push(eventDefinition));
if (is(element, 'bpmn:Event') && element.get('eventDefinitions').length) {
element.get('eventDefinitions').forEach(eventDefinition => referencingElements.push(eventDefinition));
}
if (is(element, 'bpmn:Collaboration') && element.get('messageFlows').length) {
element.get('messageFlows').forEach(traverse);
}
if (isAny(element, [
'bpmn:MessageFlow',
'bpmn:ReceiveTask',
'bpmn:SendTask'
])) {
referencingElements.push(element);
}
}
traverse(definition);
return eventDefinitions;
traverse(definitions);
return referencingElements;
}

@@ -90,33 +105,41 @@

function isReferenced(event, eventDefinitions) {
if (is(event, 'bpmn:Error')) {
return (
eventDefinitions.some(node => is(node, 'bpmn:ErrorEventDefinition') && event.id === node.errorRef?.id)
);
function isReferenced(rootElement, referencingElements) {
if (is(rootElement, 'bpmn:Error')) {
return referencingElements.some(referencingElement => {
return is(referencingElement, 'bpmn:ErrorEventDefinition')
&& rootElement.get('id') === referencingElement.get('errorRef')?.get('id');
});
}
if (is(event, 'bpmn:Escalation')) {
return (
eventDefinitions.some(node => is(node, 'bpmn:EscalationEventDefinition') && event.id === node.escalationRef?.id)
);
if (is(rootElement, 'bpmn:Escalation')) {
return referencingElements.some(referencingElement => {
return is(referencingElement, 'bpmn:EscalationEventDefinition')
&& rootElement.get('id') === referencingElement.get('escalationRef')?.get('id');
});
}
if (is(event, 'bpmn:Message')) {
return (
eventDefinitions.some(node => is(node, 'bpmn:MessageEventDefinition') && event.id === node.messageRef?.id)
);
if (is(rootElement, 'bpmn:Message')) {
return referencingElements.some(referencingElement => {
return isAny(referencingElement, [
'bpmn:MessageEventDefinition',
'bpmn:MessageFlow',
'bpmn:ReceiveTask',
'bpmn:SendTask'
]) && rootElement.get('id') === referencingElement.get('messageRef')?.get('id');
});
}
if (is(event, 'bpmn:Signal')) {
return (
eventDefinitions.some(node => is(node, 'bpmn:SignalEventDefinition') && event.id === node.signalRef?.id)
);
if (is(rootElement, 'bpmn:Signal')) {
return referencingElements.some(referencingElement => {
return is(referencingElement, 'bpmn:SignalEventDefinition')
&& rootElement.get('id') === referencingElement.get('signalRef')?.get('id');
});
}
}
function isUnique(event, events) {
function isUnique(rootElement, rootElements) {
return (
events.filter(node => is(node, event.$type) && event.name === node.name).length === 1
rootElements.filter(otherRootElement => is(otherRootElement, rootElement.$type) && rootElement.name === otherRootElement.name).length === 1
);
}
};

@@ -31,2 +31,32 @@ const {

module.exports.disallowNodeType = disallowNodeType;
module.exports.disallowNodeType = disallowNodeType;
/**
* Find a parent for the given element
*
* @param {ModdleElement} node
*
* @param {String} type
*
* @return {ModdleElement} element
*/
function findParent(node, type) {
if (!node) {
return null;
}
const parent = node.$parent;
if (!parent) {
return node;
}
if (is(parent, type)) {
return parent;
}
return findParent(parent, type);
}
module.exports.findParent = findParent;

@@ -26,6 +26,2 @@ const {

if (is(node, 'bpmn:BoundaryEvent')) {
return;
}
// ignore sub-processes

@@ -32,0 +28,0 @@ if (is(node, 'bpmn:SubProcess')) {

@@ -6,2 +6,5 @@ const {

const {
findParent
} = require('./helper');

@@ -21,2 +24,30 @@ /**

function isCompensationEvent(node) {
const eventDefinitions = node.eventDefinitions || [];
return eventDefinitions.length && eventDefinitions.every(
definition => is(definition, 'bpmn:CompensateEventDefinition')
);
}
function hasCompensationActivity(node) {
const parent = findParent(node, 'bpmn:Process');
const artifacts = parent.artifacts || [];
return artifacts.some((element) => {
if (!is(element, 'bpmn:Association')) {
return false;
}
const source = element.sourceRef;
return source.id === node.id;
});
}
function isForCompensation(node) {
return node.isForCompensation;
}
function isImplicitEnd(node) {

@@ -37,2 +68,10 @@ const outgoing = node.outgoing || [];

if (is(node, 'bpmn:BoundaryEvent') && isCompensationEvent(node) && hasCompensationActivity(node)) {
return false;
}
if (is(node, 'bpmn:Task') && isForCompensation(node)) {
return false;
}
return outgoing.length === 0;

@@ -53,2 +92,2 @@ }

return { check };
};
};
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc