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 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 ([#https://github.com/bpmn-io/bpmnlint/pull/60](https://github.com/bpmn-io/bpmnlint/pull/60))
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
- ## Usage
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
- For more details on how to define and consume custom lint rules check out the [bpmnlint-plugin-example](https://github.com/bpmn-io/bpmnlint-plugin-example).
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
- const category = report.category;
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 [ report.id || '', color(categoryMap[category] || category), report.message, report.name || '' ];
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 <' + pkg + '>');
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 <' + pkg + '>'
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: new NodeResolver()
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
- this.messages.push({ id, message });
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
- it(`test case #${idx + 1}`, function() {
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
- it(`test case #${idx}`, function() {
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.2.1",
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.0.3",
42
+ "bpmn-moddle": "^7.1.2",
42
43
  "bpmnlint-utils": "^1.0.2",
43
- "cli-table": "^0.3.1",
44
+ "cli-table": "^0.3.9",
44
45
  "color-support": "^1.1.3",
45
- "min-dash": "^3.5.2",
46
- "mri": "^1.1.6",
46
+ "min-dash": "^3.8.0",
47
+ "mri": "^1.2.0",
47
48
  "pluralize": "^7.0.0",
48
- "tiny-glob": "^0.2.8"
49
+ "tiny-glob": "^0.2.9"
49
50
  },
50
51
  "devDependencies": {
51
- "chai": "^4.2.0",
52
- "eslint": "^7.14.0",
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.3",
56
+ "execa": "^2.1.0",
56
57
  "install-local": "^1.0.0",
57
- "mocha": "^8.2.1",
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"
@@ -20,7 +20,7 @@ module.exports = function() {
20
20
  );
21
21
 
22
22
  if (missingCondition) {
23
- reporter.report(flow.id, 'Sequence flow is missing condition');
23
+ reporter.report(flow.id, 'Sequence flow is missing condition', [ 'conditionExpression' ]);
24
24
  }
25
25
  });
26
26
  }
@@ -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
  }
@@ -50,7 +50,7 @@ module.exports = function() {
50
50
  const name = (node.name || '').trim();
51
51
 
52
52
  if (name.length === 0) {
53
- reporter.report(node.id, 'Element is missing label/name');
53
+ reporter.report(node.id, 'Element is missing label/name', [ 'name' ]);
54
54
  }
55
55
  }
56
56
  }
@@ -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
- (rootElement.laneSets && rootElement.laneSets[0].lanes) || [],
72
- (rootElement.laneSets && getAllBpmnElements(rootElement.laneSets[0].lanes.filter(hasChildLaneSet))) || [],
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
  }