Socket
Socket
Sign inDemoInstall

bpmnlint

Package Overview
Dependencies
Maintainers
2
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 1.0.0-alpha6 to 1.0.0

config/all.js

33

bin/bpmnlint.js

@@ -47,2 +47,5 @@ #!/usr/bin/env node

const logRule = ruleName =>
console.log(`\nrule: ${ruleName}`);
/**

@@ -53,5 +56,29 @@ * Logs errors and warnings properly in the console

*/
const logReports = ({ errors, warnings }) => {
errors.forEach(logError);
warnings.forEach(logWarning);
const logReports = (results) => {
let errorCount = 0;
let warningCount = 0;
Object.entries(results).forEach(function([ ruleName, reports ]) {
logRule(ruleName);
reports.forEach(function(report) {
if (report.category === 'error') {
errorCount++;
logError(report);
} else {
warningCount++;
logWarning(report);
}
});
});
console.log(`\nfound ${errorCount} errors and ${warningCount} warnings`);
if (errorCount > 0) {
process.exit(1);
}
};

@@ -58,0 +85,0 @@

@@ -9,2 +9,13 @@ # Changelog

## 1.0.0
* `FEAT`: add numerous new rules ([#5](https://github.com/bpmn-io/bpmnlint/issues/5))
* `FEAT`: add `bpmnlint:all` configuration
* `FEAT`: improve `label-required` rule ([#11](https://github.com/bpmn-io/bpmnlint/issues/11))
* `FEAT`: group lint results by rule names
* `FEAT`: exit cli with code=1 on lint errors
* `FEAT`: add `isAny(node, [ ... types ])` method to `utils`
* `CHORE`: improve / test cover existing rules
* `CHORE`: include new rules in `bpmnlint:recommended` configuration
## 1.0.0-alpha6

@@ -11,0 +22,0 @@

module.exports = {
rules: {
'label-required': 'warn',
'conditional-flows': 'error',
'end-event-required': 'error',
'event-sub-process-typed-start-event': 'error',
'fake-join': 'warn',
'label-required': 'error',
'no-complex-gateway': 'error',
'no-disconnected': 'error',
'no-gateway-join-fork': 'error',
'no-implicit-split': 'error',
'no-inclusive-gateway': 'error',
'single-blank-start-event': 'error',
'single-event-definition': 'error',
'start-event-required': 'error',
'end-event-required': 'error'
'sub-process-blank-start-event': 'error'
}
};

51

lib/linter.js
const testRule = require('./testRule');
const utils = require('./utils');
const flagsMap = {
1: 'warnings',
2: 'errors',
warn: 'warnings',
error: 'errors'
const flagMap = {
0: 'off',
1: 'warn',
2: 'error'
};

@@ -35,22 +34,15 @@

* @param {ModdleElement} options.moddleRoot
* @param {String|Number} options.ruleFlag
* @param {String} options.ruleFlag
* @param {Rule} options.rule
* @param {Object} options.ruleConfig
*
* @return {Object} lint results, keyed by category name
* @return {Array<ValidationErrors>} lint results
*/
Linter.prototype.applyRule = function applyRule({ moddleRoot, ruleFlag, rule, ruleConfig }) {
if (typeof ruleFlag === 'string') {
ruleFlag = ruleFlag.toLowerCase();
if (ruleFlag === 'off') {
return [];
}
const flagName = flagsMap[ruleFlag];
if (!flagName) {
return {};
}
const reports = testRule({ moddleRoot, rule, ruleConfig });
return { [flagName]: reports };
return testRule({ moddleRoot, rule, ruleConfig });
};

@@ -179,7 +171,16 @@

const ruleResults = this.applyRule({ moddleRoot, ruleFlag, rule, ruleConfig });
const reports = this.applyRule({ moddleRoot, ruleFlag, rule, ruleConfig });
Object.entries(ruleResults).forEach(([category, reports]) => {
finalReport[category] = (finalReport[category] || []).concat(reports);
if (reports.length === 0) {
return;
}
const categorizedReports = reports.map(function(report) {
return {
...report,
category: ruleFlag
};
});
finalReport[name] = categorizedReports;
});

@@ -205,2 +206,10 @@

// normalize rule flag to <error> and <warn> which
// may be upper case or a number at this point
if (typeof ruleFlag === 'string') {
ruleFlag = ruleFlag.toLowerCase();
}
ruleFlag = flagMap[ruleFlag] || ruleFlag;
return {

@@ -207,0 +216,0 @@ ruleConfig,

@@ -45,3 +45,3 @@ /* global it, describe, beforeEach */

.then(lintResults => {
expectEqual(lintResults.errors, []);
expectEqual(lintResults, {});
})

@@ -61,2 +61,8 @@ );

it(`test case #${idx}`, function() {
const expectedResult = {
...report,
category: 'error'
};
return (

@@ -68,3 +74,5 @@ Promise.resolve(moddleElement)

.then(lintResults => {
expectEqual(lintResults.errors, [report]);
expectEqual(lintResults, {
[ruleName]: [ expectedResult ]
});
})

@@ -71,0 +79,0 @@ );

@@ -22,4 +22,20 @@ /**

/**
* Checks whether node has any of the specified types.
*
* @param {ModdleElement} node
* @param {Array<String>} types
*
* @return {Boolean}
*/
function isAny(node, types) {
return types.some(function(type) {
return is(node, type);
});
}
module.exports = {
is
is,
isAny
};
{
"name": "bpmnlint",
"version": "1.0.0-alpha6",
"version": "1.0.0",
"main": "index.js",

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

@@ -12,7 +12,17 @@ # bpmnlint

```bash
```zsh
> bpmnlint diagram.bpmn
error: Process_1 is missing a Start Event
error: Process_1 is missing an End Event
rule: bpmnlint/label-required
error: sid-E391B624-F6E8-428B-9C3E-7026F85C4F24 is missing label/name
error: sid-3E1FA189-AC8C-4CF1-9057-3D2EF8C6D3AF is missing label/name
error: sid-DD0BC4E1-4AA3-4835-A477-373EA263A593 is missing label/name
error: sid-B8B18E3A-EF8D-4D19-B5CD-C666D39E2E0D is missing label/name
error: sid-994BB7B0-64D8-4DC4-B549-0758628F5A16 is missing label/name
rule: bpmnlint/no-gateway-join-fork
warn: sid-545B3227-D12A-43A8-B746-55E8C75F3A8A forks and joins
warn: sid-AB73793C-D47A-4738-B34F-A82C6219A92C forks and joins
found 10 errors and 2 warnings
```

@@ -19,0 +29,0 @@

@@ -5,11 +5,12 @@ /**

module.exports = utils => {
const { is } = utils;
module.exports = function(utils) {
const ERROR = 'is missing an End Event';
const is = utils.is;
const isAny = utils.isAny;
function hasEndEvent(node) {
const flowElements = node.flowElements || [];
return (
(node.flowElements || []).filter(node => is(node, 'bpmn:EndEvent'))
.length > 0
flowElements.some(node => is(node, 'bpmn:EndEvent'))
);

@@ -19,7 +20,13 @@ }

function check(node, reporter) {
if (is(node, 'Process')) {
if (!hasEndEvent(node)) {
reporter.report(node.id, ERROR);
}
if (!isAny(node, [
'bpmn:Process',
'bpmn:SubProcess'
])) {
return;
}
if (!hasEndEvent(node)) {
reporter.report(node.id, 'is missing an end event');
}
}

@@ -26,0 +33,0 @@

@@ -5,15 +5,50 @@ /**

module.exports = utils => {
const { is } = utils;
const ERROR = 'Element is missing a label/name.';
module.exports = function(utils) {
const is = utils.is;
const isAny = utils.isAny;
function check(node, reporter) {
if (is(node, 'bpmn:ParallelGateway')) {
if (isAny(node, [
'bpmn:ParallelGateway',
'bpmn:EventBasedGateway'
])) {
return;
}
if (is(node, 'bpmn:FlowNode') && !(node.name || '').trim().length) {
reporter.report(node.id, ERROR);
// ignore joining gateways
if (is(node, 'bpmn:Gateway') && !isForking(node)) {
return;
}
if (is(node, 'bpmn:BoundaryEvent')) {
return;
}
// ignore sub-processes
if (is(node, 'bpmn:SubProcess')) {
// TODO(nikku): better ignore expanded sub-processes only
return;
}
// ignore sequence flow without condition
if (is(node, 'bpmn:SequenceFlow') && !hasCondition(node)) {
return;
}
// ignore data objects and artifacts for now
if (isAny(node, [
'bpmn:FlowNode',
'bpmn:SequenceFlow',
'bpmn:Participant',
'bpmn:Lane'
])) {
const name = (node.name || '').trim();
if (name.length === 0) {
reporter.report(node.id, 'is missing label/name');
}
}
}

@@ -23,1 +58,14 @@

};
// helpers ////////////////////////
function isForking(node) {
const outgoing = node.outgoing || [];
return outgoing.length > 1;
}
function hasCondition(node) {
return node.conditionExpression;
}

@@ -5,12 +5,12 @@ /**

module.exports = utils => {
const { is } = utils;
module.exports = function(utils) {
const ERROR = 'is missing a Start Event';
const is = utils.is;
const isAny = utils.isAny;
function hasStartEvent(node) {
const flowElements = node.flowElements || [];
return (
(node.flowElements || []).filter(
node => node.$type !== 'String' && is(node, 'bpmn:StartEvent')
).length > 0
flowElements.some(node => is(node, 'bpmn:StartEvent'))
);

@@ -20,7 +20,13 @@ }

function check(node, reporter) {
if (is(node, 'bpmn:Process')) {
if (!hasStartEvent(node)) {
reporter.report(node.id, ERROR);
}
if (!isAny(node, [
'bpmn:Process',
'bpmn:SubProcess'
])) {
return;
}
if (!hasStartEvent(node)) {
reporter.report(node.id, 'is missing a start event');
}
}

@@ -27,0 +33,0 @@

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