bpmnlint 7.2.1 → 7.5.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.
- package/CHANGELOG.md +17 -1
- package/README.md +7 -2
- package/bin/bpmnlint.js +25 -2
- package/lib/resolver/node-resolver.js +23 -2
- package/lib/support/compile-config.js +6 -4
- package/lib/test-rule.js +14 -2
- package/lib/testers/rule-tester.js +9 -5
- package/package.json +11 -10
- package/rules/conditional-flows.js +1 -1
- package/rules/event-sub-process-typed-start-event.js +1 -1
- package/rules/label-required.js +1 -1
- package/rules/no-bpmndi.js +5 -4
- package/rules/single-event-definition.js +1 -1
- package/rules/sub-process-blank-start-event.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,9 +6,25 @@ All notable changes to [bpmnlint](https://github.com/bpmn-io/bpmnlint) are docum
|
|
|
6
6
|
|
|
7
7
|
___Note:__ Yet to be released changes appear here._
|
|
8
8
|
|
|
9
|
+
## 7.5.0
|
|
10
|
+
|
|
11
|
+
* `FEAT`: add optional `path` parameter to `Reporter#report` ([#73](https://github.com/bpmn-io/bpmnlint/pull/73))
|
|
12
|
+
* `FEAT`: add optional `name` parameter to `RuleTester#verify` ([#68](https://github.com/bpmn-io/bpmnlint/pull/68))
|
|
13
|
+
* `CHORE`: update to `bpmn-moddle@7.1.2`
|
|
14
|
+
|
|
15
|
+
## 7.4.0
|
|
16
|
+
|
|
17
|
+
* `FEAT`: resolve local package by name ([#64](https://github.com/bpmn-io/bpmnlint/pull/64))
|
|
18
|
+
|
|
19
|
+
## 7.3.0
|
|
20
|
+
|
|
21
|
+
* `FEAT`: support `--version` command line flag ([#65](https://github.com/bpmn-io/bpmnlint/pull/65))
|
|
22
|
+
* `FEAT`: allow rule testers to provide custom `it`
|
|
23
|
+
* `FIX`: make `no-bpmndi` handle missing `LaneSet#lanes` gracefully ([#63](https://github.com/bpmn-io/bpmnlint/issues/63), [#66](https://github.com/bpmn-io/bpmnlint/pull/66))
|
|
24
|
+
|
|
9
25
|
## 7.2.1
|
|
10
26
|
|
|
11
|
-
* `FIX`: exclude compensation boundary and activity in `no-disconnected` check ([#
|
|
27
|
+
* `FIX`: exclude compensation boundary and activity in `no-disconnected` check ([#60](https://github.com/bpmn-io/bpmnlint/pull/60))
|
|
12
28
|
|
|
13
29
|
## 7.2.0
|
|
14
30
|
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
Validate your BPMN diagrams based on configurable lint rules.
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## Installation
|
|
9
9
|
|
|
10
10
|
Install the utility via [npm](https://www.npmjs.com/package/bpmnlint):
|
|
11
11
|
|
|
@@ -13,6 +13,9 @@ Install the utility via [npm](https://www.npmjs.com/package/bpmnlint):
|
|
|
13
13
|
npm install -g bpmnlint
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
16
19
|
Validate your diagrams via the commandline:
|
|
17
20
|
|
|
18
21
|
```sh
|
|
@@ -70,7 +73,9 @@ To try out visual validation, checkout the [bpmnlint playground](https://github.
|
|
|
70
73
|
|
|
71
74
|
Use the [bpmnlint playground](https://github.com/bpmn-io/bpmnlint-playground) to implement new rules with quick visual feedback.
|
|
72
75
|
|
|
73
|
-
|
|
76
|
+
Create your first plug-in using the [plugin creator](https://github.com/nikku/create-bpmnlint-plugin).
|
|
77
|
+
|
|
78
|
+
Checkout the [bpmnlint-plugin-example](https://github.com/bpmn-io/bpmnlint-plugin-example) for details on how to define, test, and consume custom lint rules.
|
|
74
79
|
|
|
75
80
|
|
|
76
81
|
## License
|
package/bin/bpmnlint.js
CHANGED
|
@@ -28,6 +28,8 @@ const Table = require('cli-table');
|
|
|
28
28
|
|
|
29
29
|
const pluralize = require('pluralize');
|
|
30
30
|
|
|
31
|
+
const { pathStringify } = require('@philippfromme/moddle-helpers');
|
|
32
|
+
|
|
31
33
|
const CONFIG_NAME = '.bpmnlintrc';
|
|
32
34
|
|
|
33
35
|
const DEFAULT_CONFIG_CONTENTS = `{
|
|
@@ -107,11 +109,21 @@ const categoryMap = {
|
|
|
107
109
|
* Logs a formatted message
|
|
108
110
|
*/
|
|
109
111
|
function tableEntry(report) {
|
|
110
|
-
|
|
112
|
+
let {
|
|
113
|
+
category,
|
|
114
|
+
id = '',
|
|
115
|
+
message,
|
|
116
|
+
name = '',
|
|
117
|
+
path
|
|
118
|
+
} = report;
|
|
119
|
+
|
|
120
|
+
if (path) {
|
|
121
|
+
id = `${ id }#${ pathStringify(path) }`;
|
|
122
|
+
}
|
|
111
123
|
|
|
112
124
|
const color = category === 'error' ? red : yellow;
|
|
113
125
|
|
|
114
|
-
return [
|
|
126
|
+
return [ id, color(categoryMap[ category ] || category), message, name ];
|
|
115
127
|
}
|
|
116
128
|
|
|
117
129
|
function createTable() {
|
|
@@ -146,6 +158,12 @@ function errorAndExit(...args) {
|
|
|
146
158
|
process.exit(1);
|
|
147
159
|
}
|
|
148
160
|
|
|
161
|
+
function showVersionAndExit() {
|
|
162
|
+
console.log(require('../package.json').version);
|
|
163
|
+
|
|
164
|
+
process.exit(0);
|
|
165
|
+
}
|
|
166
|
+
|
|
149
167
|
function infoAndExit(...args) {
|
|
150
168
|
console.log(...args);
|
|
151
169
|
|
|
@@ -314,6 +332,7 @@ async function run() {
|
|
|
314
332
|
const {
|
|
315
333
|
help,
|
|
316
334
|
init,
|
|
335
|
+
version,
|
|
317
336
|
config: configOverridePath,
|
|
318
337
|
_: files
|
|
319
338
|
} = mri(process.argv.slice(2), {
|
|
@@ -323,6 +342,10 @@ async function run() {
|
|
|
323
342
|
}
|
|
324
343
|
});
|
|
325
344
|
|
|
345
|
+
if (version) {
|
|
346
|
+
return showVersionAndExit();
|
|
347
|
+
}
|
|
348
|
+
|
|
326
349
|
if (help) {
|
|
327
350
|
return infoAndExit(HELP_STRING);
|
|
328
351
|
}
|
|
@@ -9,6 +9,12 @@ function NodeResolver(options) {
|
|
|
9
9
|
this.require = options && options.require || createScopedRequire(process.cwd());
|
|
10
10
|
|
|
11
11
|
this.requireLocal = options && options.requireLocal || require;
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
this.pkg = this.require('./package.json').name;
|
|
15
|
+
} catch (err) {
|
|
16
|
+
this.pkg = '__unknown';
|
|
17
|
+
}
|
|
12
18
|
}
|
|
13
19
|
|
|
14
20
|
module.exports = NodeResolver;
|
|
@@ -16,6 +22,10 @@ module.exports = NodeResolver;
|
|
|
16
22
|
|
|
17
23
|
NodeResolver.prototype.resolveRule = function(pkg, ruleName) {
|
|
18
24
|
|
|
25
|
+
const originalPkg = pkg;
|
|
26
|
+
|
|
27
|
+
pkg = this.normalizePkg(pkg);
|
|
28
|
+
|
|
19
29
|
try {
|
|
20
30
|
if (pkg === 'bpmnlint') {
|
|
21
31
|
return this.requireLocal(`../../rules/${ruleName}`);
|
|
@@ -23,12 +33,16 @@ NodeResolver.prototype.resolveRule = function(pkg, ruleName) {
|
|
|
23
33
|
return this.require(`${pkg}/rules/${ruleName}`);
|
|
24
34
|
}
|
|
25
35
|
} catch (err) {
|
|
26
|
-
throw new Error('Cannot resolve rule <' + ruleName + '> from <' +
|
|
36
|
+
throw new Error('Cannot resolve rule <' + ruleName + '> from <' + originalPkg + '>');
|
|
27
37
|
}
|
|
28
38
|
};
|
|
29
39
|
|
|
30
40
|
NodeResolver.prototype.resolveConfig = function(pkg, configName) {
|
|
31
41
|
|
|
42
|
+
const originalPkg = pkg;
|
|
43
|
+
|
|
44
|
+
pkg = this.normalizePkg(pkg);
|
|
45
|
+
|
|
32
46
|
// resolve config via $PKG/config/$NAME
|
|
33
47
|
try {
|
|
34
48
|
if (pkg === 'bpmnlint') {
|
|
@@ -53,10 +67,17 @@ NodeResolver.prototype.resolveConfig = function(pkg, configName) {
|
|
|
53
67
|
}
|
|
54
68
|
|
|
55
69
|
throw new Error(
|
|
56
|
-
'Cannot resolve config <' + configName + '> from <' +
|
|
70
|
+
'Cannot resolve config <' + configName + '> from <' + originalPkg + '>'
|
|
57
71
|
);
|
|
58
72
|
};
|
|
59
73
|
|
|
74
|
+
NodeResolver.prototype.normalizePkg = function(pkg) {
|
|
75
|
+
if (pkg !== 'bpmnlint' && pkg === this.pkg) {
|
|
76
|
+
pkg = '.';
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return pkg;
|
|
80
|
+
};
|
|
60
81
|
|
|
61
82
|
// helpers ////////////////////
|
|
62
83
|
|
|
@@ -7,13 +7,15 @@ const NodeResolver = require('../resolver/node-resolver');
|
|
|
7
7
|
* a { config, resolver } bundle, resolving all enabled rules.
|
|
8
8
|
*
|
|
9
9
|
* @param {Object} config the parsed bpmnlint configuration
|
|
10
|
-
*
|
|
10
|
+
* @param {NodeResolver} [resolver]
|
|
11
11
|
* @return {Promise<String>} the configuration compiled to a JS file
|
|
12
12
|
*/
|
|
13
|
-
async function compileConfig(config) {
|
|
13
|
+
async function compileConfig(config, resolver) {
|
|
14
|
+
|
|
15
|
+
resolver = resolver || new NodeResolver();
|
|
14
16
|
|
|
15
17
|
const linter = new Linter({
|
|
16
|
-
resolver
|
|
18
|
+
resolver
|
|
17
19
|
});
|
|
18
20
|
|
|
19
21
|
const resolvedRules = await linter.resolveConfiguredRules(config);
|
|
@@ -86,7 +88,7 @@ export default bundle;
|
|
|
86
88
|
} = linter.parseRuleName(key);
|
|
87
89
|
|
|
88
90
|
return `
|
|
89
|
-
import rule_${idx} from '${pkg}/rules/${ruleName}';
|
|
91
|
+
import rule_${idx} from '${resolver.normalizePkg(pkg)}/rules/${ruleName}';
|
|
90
92
|
cache['${pkg}/${ruleName}'] = rule_${idx};`;
|
|
91
93
|
}).join('\n');
|
|
92
94
|
|
package/lib/test-rule.js
CHANGED
|
@@ -8,8 +8,20 @@ class Reporter {
|
|
|
8
8
|
this.report = this.report.bind(this);
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
report(id, message) {
|
|
12
|
-
|
|
11
|
+
report(id, message, path) {
|
|
12
|
+
let report = {
|
|
13
|
+
id,
|
|
14
|
+
message
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
if (path) {
|
|
18
|
+
report = {
|
|
19
|
+
...report,
|
|
20
|
+
path
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
this.messages.push(report);
|
|
13
25
|
}
|
|
14
26
|
}
|
|
15
27
|
|
|
@@ -33,9 +33,9 @@ function verify(ruleName, rule, testCases) {
|
|
|
33
33
|
|
|
34
34
|
describe('should lint valid', function() {
|
|
35
35
|
|
|
36
|
-
testCases.valid.forEach(({ moddleElement }, idx) => (
|
|
36
|
+
testCases.valid.forEach(({ moddleElement, name, it: _it }, idx) => (
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
(_it || it)(getTitle(idx, name), function() {
|
|
39
39
|
return (
|
|
40
40
|
Promise.resolve(moddleElement)
|
|
41
41
|
.then(moddleRoot => {
|
|
@@ -54,9 +54,9 @@ function verify(ruleName, rule, testCases) {
|
|
|
54
54
|
|
|
55
55
|
describe('should lint invalid', function() {
|
|
56
56
|
|
|
57
|
-
testCases.invalid.forEach(({ moddleElement, report }, idx) => (
|
|
57
|
+
testCases.invalid.forEach(({ moddleElement, name, report, it: _it }, idx) => (
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
(_it || it)(getTitle(idx, name), function() {
|
|
60
60
|
|
|
61
61
|
if (!Array.isArray(report)) {
|
|
62
62
|
report = [
|
|
@@ -94,7 +94,11 @@ function verify(ruleName, rule, testCases) {
|
|
|
94
94
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
function getTitle(idx, name) {
|
|
98
|
+
return `test case #${ idx + 1 }${ name ? ` ${ name }`: '' }`;
|
|
99
|
+
}
|
|
97
100
|
|
|
98
101
|
module.exports = {
|
|
99
|
-
verify
|
|
102
|
+
verify,
|
|
103
|
+
getTitle
|
|
100
104
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bpmnlint",
|
|
3
3
|
"description": "Validate your BPMN diagrams based on configurable lint rules",
|
|
4
|
-
"version": "7.
|
|
4
|
+
"version": "7.5.0",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"bpmnlint",
|
|
@@ -37,24 +37,25 @@
|
|
|
37
37
|
"bpmnlint": "./bin/bpmnlint.js"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
+
"@philippfromme/moddle-helpers": "^0.1.0",
|
|
40
41
|
"ansi-colors": "^4.1.1",
|
|
41
|
-
"bpmn-moddle": "^7.
|
|
42
|
+
"bpmn-moddle": "^7.1.2",
|
|
42
43
|
"bpmnlint-utils": "^1.0.2",
|
|
43
|
-
"cli-table": "^0.3.
|
|
44
|
+
"cli-table": "^0.3.9",
|
|
44
45
|
"color-support": "^1.1.3",
|
|
45
|
-
"min-dash": "^3.
|
|
46
|
-
"mri": "^1.
|
|
46
|
+
"min-dash": "^3.8.0",
|
|
47
|
+
"mri": "^1.2.0",
|
|
47
48
|
"pluralize": "^7.0.0",
|
|
48
|
-
"tiny-glob": "^0.2.
|
|
49
|
+
"tiny-glob": "^0.2.9"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
51
|
-
"chai": "^4.
|
|
52
|
-
"eslint": "^7.
|
|
52
|
+
"chai": "^4.3.4",
|
|
53
|
+
"eslint": "^7.32.0",
|
|
53
54
|
"eslint-plugin-bpmn-io": "^0.11.0",
|
|
54
55
|
"esm": "^3.2.25",
|
|
55
|
-
"execa": "^2.0
|
|
56
|
+
"execa": "^2.1.0",
|
|
56
57
|
"install-local": "^1.0.0",
|
|
57
|
-
"mocha": "^8.
|
|
58
|
+
"mocha": "^8.4.0",
|
|
58
59
|
"npm-run-all": "^4.1.5",
|
|
59
60
|
"nyc": "^15.1.0",
|
|
60
61
|
"strip-indent": "^2.0.0"
|
|
@@ -25,7 +25,7 @@ module.exports = function() {
|
|
|
25
25
|
const eventDefinitions = flowElement.eventDefinitions || [];
|
|
26
26
|
|
|
27
27
|
if (eventDefinitions.length === 0) {
|
|
28
|
-
reporter.report(flowElement.id, 'Start event is missing event definition');
|
|
28
|
+
reporter.report(flowElement.id, 'Start event is missing event definition', [ 'eventDefinitions' ]);
|
|
29
29
|
}
|
|
30
30
|
});
|
|
31
31
|
}
|
package/rules/label-required.js
CHANGED
package/rules/no-bpmndi.js
CHANGED
|
@@ -54,6 +54,9 @@ module.exports = function() {
|
|
|
54
54
|
function getAllBpmnElements(rootElements) {
|
|
55
55
|
return flatten(rootElements.map((rootElement) => {
|
|
56
56
|
|
|
57
|
+
const laneSet =
|
|
58
|
+
rootElement.laneSets && rootElement.laneSets[0] || rootElement.childLaneSet;
|
|
59
|
+
|
|
57
60
|
// Include
|
|
58
61
|
// * flowElements (e.g., tasks, sequenceFlows),
|
|
59
62
|
// * nested flowElements,
|
|
@@ -68,10 +71,8 @@ function getAllBpmnElements(rootElements) {
|
|
|
68
71
|
(rootElement.flowElements && getAllBpmnElements(rootElement.flowElements.filter(hasFlowElements))) || [],
|
|
69
72
|
rootElement.participants || [],
|
|
70
73
|
rootElement.artifacts || [],
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
(rootElement.childLaneSet && rootElement.childLaneSet.lanes) || [],
|
|
74
|
-
(rootElement.childLaneSet && getAllBpmnElements(rootElement.childLaneSet.lanes.filter(hasChildLaneSet))) || []
|
|
74
|
+
laneSet && laneSet.lanes || [],
|
|
75
|
+
laneSet && laneSet.lanes && getAllBpmnElements(laneSet.lanes.filter(hasChildLaneSet)) || []
|
|
75
76
|
));
|
|
76
77
|
|
|
77
78
|
if (elements.length > 0) {
|
|
@@ -17,7 +17,7 @@ module.exports = function() {
|
|
|
17
17
|
const eventDefinitions = node.eventDefinitions || [];
|
|
18
18
|
|
|
19
19
|
if (eventDefinitions.length > 1) {
|
|
20
|
-
reporter.report(node.id, 'Event has multiple event definitions');
|
|
20
|
+
reporter.report(node.id, 'Event has multiple event definitions', [ 'eventDefinitions' ]);
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -26,7 +26,7 @@ module.exports = function() {
|
|
|
26
26
|
const eventDefinitions = flowElement.eventDefinitions || [];
|
|
27
27
|
|
|
28
28
|
if (eventDefinitions.length > 0) {
|
|
29
|
-
reporter.report(flowElement.id, 'Start event must be blank');
|
|
29
|
+
reporter.report(flowElement.id, 'Start event must be blank', [ 'eventDefinitions' ]);
|
|
30
30
|
}
|
|
31
31
|
});
|
|
32
32
|
}
|