bpmnlint 7.3.0 → 7.6.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,6 +6,21 @@ 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.6.0
10
+
11
+ * `FEAT`: allow passing object as third parameter to `Reporter#report` ([#75](https://github.com/bpmn-io/bpmnlint/pull/75))
12
+
13
+
14
+ ## 7.5.0
15
+
16
+ * `FEAT`: add optional `path` parameter to `Reporter#report` ([#73](https://github.com/bpmn-io/bpmnlint/pull/73))
17
+ * `FEAT`: add optional `name` parameter to `RuleTester#verify` ([#68](https://github.com/bpmn-io/bpmnlint/pull/68))
18
+ * `CHORE`: update to `bpmn-moddle@7.1.2`
19
+
20
+ ## 7.4.0
21
+
22
+ * `FEAT`: resolve local package by name ([#64](https://github.com/bpmn-io/bpmnlint/pull/64))
23
+
9
24
  ## 7.3.0
10
25
 
11
26
  * `FEAT`: support `--version` command line flag ([#65](https://github.com/bpmn-io/bpmnlint/pull/65))
package/README.md CHANGED
@@ -73,7 +73,9 @@ To try out visual validation, checkout the [bpmnlint playground](https://github.
73
73
 
74
74
  Use the [bpmnlint playground](https://github.com/bpmn-io/bpmnlint-playground) to implement new rules with quick visual feedback.
75
75
 
76
- 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.
77
79
 
78
80
 
79
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() {
@@ -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
@@ -1,5 +1,11 @@
1
1
  const traverse = require('./traverse');
2
2
 
3
+ const {
4
+ isArray,
5
+ isObject
6
+ } = require('min-dash');
7
+
8
+
3
9
  class Reporter {
4
10
  constructor({ moddleRoot, rule }) {
5
11
  this.rule = rule;
@@ -8,8 +14,43 @@ class Reporter {
8
14
  this.report = this.report.bind(this);
9
15
  }
10
16
 
11
- report(id, message) {
12
- this.messages.push({ id, message });
17
+ /**
18
+ * @param {string} id
19
+ * @param {string} message
20
+ * @param {string[]|Object} path
21
+ *
22
+ * @example
23
+ *
24
+ * Reporter.report('foo', 'Foo error', [ 'foo', 'bar', 'baz' ]);
25
+ *
26
+ * @example
27
+ *
28
+ * Reporter.report('foo', 'Foo error', {
29
+ * path: [ 'foo', 'bar', 'baz' ],
30
+ * foo: 'foo'
31
+ * });
32
+ */
33
+ report(id, message, path) {
34
+ let report = {
35
+ id,
36
+ message
37
+ };
38
+
39
+ if (path && isArray(path)) {
40
+ report = {
41
+ ...report,
42
+ path
43
+ };
44
+ }
45
+
46
+ if (path && isObject(path)) {
47
+ report = {
48
+ ...report,
49
+ ...path
50
+ };
51
+ }
52
+
53
+ this.messages.push(report);
13
54
  }
14
55
  }
15
56
 
@@ -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, it: _it }, idx) => (
36
+ testCases.valid.forEach(({ moddleElement, name, it: _it }, idx) => (
37
37
 
38
- (_it || 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, it: _it }, idx) => (
57
+ testCases.invalid.forEach(({ moddleElement, name, report, it: _it }, idx) => (
58
58
 
59
- (_it || 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.3.0",
4
+ "version": "7.6.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
  }
@@ -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
  }