├── .github
├── ISSUE_TEMPLATE
│ ├── BUG_REPORT.md
│ ├── FEATURE_REQUEST.md
│ ├── NEW_RULE.md
│ └── config.yml
└── workflows
│ └── CI.yml
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── bin
└── bpmnlint.js
├── config
├── all.js
├── correctness.js
└── recommended.js
├── docs
└── rules
│ ├── README.md
│ ├── ad-hoc-sub-process.md
│ ├── conditional-flows.md
│ ├── end-event-required.md
│ ├── event-sub-process-typed-start-event.md
│ ├── examples
│ ├── ad-hoc-sub-process-correct.bpmn
│ ├── ad-hoc-sub-process-correct.png
│ ├── ad-hoc-sub-process-incorrect.bpmn
│ ├── ad-hoc-sub-process-incorrect.png
│ ├── conditional-flows-correct.bpmn
│ ├── conditional-flows-correct.png
│ ├── conditional-flows-incorrect.bpmn
│ ├── conditional-flows-incorrect.png
│ ├── end-event-required-correct.bpmn
│ ├── end-event-required-correct.png
│ ├── end-event-required-incorrect.bpmn
│ ├── end-event-required-incorrect.png
│ ├── event-sub-process-typed-start-event-correct.bpmn
│ ├── event-sub-process-typed-start-event-correct.png
│ ├── event-sub-process-typed-start-event-incorrect.bpmn
│ ├── event-sub-process-typed-start-event-incorrect.png
│ ├── fake-join-correct.bpmn
│ ├── fake-join-correct.png
│ ├── fake-join-incorrect.bpmn
│ ├── fake-join-incorrect.png
│ ├── label-required-correct.bpmn
│ ├── label-required-correct.png
│ ├── label-required-incorrect.bpmn
│ ├── label-required-incorrect.png
│ ├── link-event-correct.bpmn
│ ├── link-event-correct.png
│ ├── link-event-incorrect.bpmn
│ ├── link-event-incorrect.png
│ ├── no-bpmndi-correct.bpmn
│ ├── no-bpmndi-correct.png
│ ├── no-bpmndi-incorrect.bpmn
│ ├── no-bpmndi-incorrect.png
│ ├── no-complex-gateway-correct.bpmn
│ ├── no-complex-gateway-correct.png
│ ├── no-complex-gateway-incorrect.bpmn
│ ├── no-complex-gateway-incorrect.png
│ ├── no-disconnected-correct.bpmn
│ ├── no-disconnected-correct.png
│ ├── no-disconnected-incorrect.bpmn
│ ├── no-disconnected-incorrect.png
│ ├── no-duplicate-sequence-flows-correct.bpmn
│ ├── no-duplicate-sequence-flows-correct.png
│ ├── no-duplicate-sequence-flows-incorrect.bpmn
│ ├── no-duplicate-sequence-flows-incorrect.png
│ ├── no-gateway-join-fork-correct.bpmn
│ ├── no-gateway-join-fork-correct.png
│ ├── no-gateway-join-fork-incorrect.bpmn
│ ├── no-gateway-join-fork-incorrect.png
│ ├── no-implicit-end-correct.bpmn
│ ├── no-implicit-end-correct.png
│ ├── no-implicit-end-incorrect.bpmn
│ ├── no-implicit-end-incorrect.png
│ ├── no-implicit-split-correct.bpmn
│ ├── no-implicit-split-correct.png
│ ├── no-implicit-split-incorrect.bpmn
│ ├── no-implicit-split-incorrect.png
│ ├── no-implicit-start-correct.bpmn
│ ├── no-implicit-start-correct.png
│ ├── no-implicit-start-incorrect.bpmn
│ ├── no-implicit-start-incorrect.png
│ ├── no-inclusive-gateway-correct.bpmn
│ ├── no-inclusive-gateway-correct.png
│ ├── no-inclusive-gateway-incorrect.bpmn
│ ├── no-inclusive-gateway-incorrect.png
│ ├── no-overlapping-elements-correct.bpmn
│ ├── no-overlapping-elements-correct.png
│ ├── no-overlapping-elements-incorrect.bpmn
│ ├── no-overlapping-elements-incorrect.png
│ ├── single-blank-start-event-correct.bpmn
│ ├── single-blank-start-event-correct.png
│ ├── single-blank-start-event-incorrect.bpmn
│ ├── single-blank-start-event-incorrect.png
│ ├── single-event-definition-correct.bpmn
│ ├── single-event-definition-correct.png
│ ├── single-event-definition-incorrect.bpmn
│ ├── single-event-definition-incorrect.png
│ ├── start-event-required-correct.bpmn
│ ├── start-event-required-correct.png
│ ├── start-event-required-incorrect.bpmn
│ ├── start-event-required-incorrect.png
│ ├── sub-process-blank-start-event-correct.bpmn
│ ├── sub-process-blank-start-event-correct.png
│ ├── sub-process-blank-start-event-incorrect.bpmn
│ ├── sub-process-blank-start-event-incorrect.png
│ ├── superfluous-gateway-correct.bpmn
│ ├── superfluous-gateway-correct.png
│ ├── superfluous-gateway-incorrect.bpmn
│ ├── superfluous-gateway-incorrect.png
│ ├── superfluous-termination-correct.bpmn
│ ├── superfluous-termination-correct.png
│ ├── superfluous-termination-incorrect.bpmn
│ └── superfluous-termination-incorrect.png
│ ├── fake-join.md
│ ├── label-required.md
│ ├── link-event.md
│ ├── no-bpmndi.md
│ ├── no-complex-gateway.md
│ ├── no-disconnected.md
│ ├── no-duplicate-sequence-flows.md
│ ├── no-gateway-join-fork.md
│ ├── no-implicit-end.md
│ ├── no-implicit-split.md
│ ├── no-implicit-start.md
│ ├── no-inclusive-gateway.md
│ ├── no-overlapping-elements.md
│ ├── single-blank-start-event.md
│ ├── single-event-definition.md
│ ├── start-event-required.md
│ ├── sub-process-blank-start-event.md
│ ├── superfluous-gateway.md
│ └── superfluous-termination.md
├── eslint.config.mjs
├── lib
├── index.js
├── linter.js
├── resolver
│ ├── node-resolver.js
│ └── static-resolver.js
├── support
│ └── compile-config.js
├── test-rule.js
├── testers
│ ├── helper.js
│ ├── rule-tester.d.ts
│ └── rule-tester.js
├── traverse.js
└── types.d.ts
├── package-lock.json
├── package.json
├── rules
├── ad-hoc-sub-process.js
├── conditional-flows.js
├── end-event-required.js
├── event-sub-process-typed-start-event.js
├── fake-join.js
├── global.js
├── helper.js
├── label-required.js
├── link-event.js
├── no-bpmndi.js
├── no-complex-gateway.js
├── no-disconnected.js
├── no-duplicate-sequence-flows.js
├── no-gateway-join-fork.js
├── no-implicit-end.js
├── no-implicit-split.js
├── no-implicit-start.js
├── no-inclusive-gateway.js
├── no-overlapping-elements.js
├── single-blank-start-event.js
├── single-event-definition.js
├── start-event-required.js
├── sub-process-blank-start-event.js
├── superfluous-gateway.js
└── superfluous-termination.js
├── test
├── helper.mjs
├── integration
│ ├── bpmnlint-plugin-exported
│ │ ├── package.json
│ │ └── src
│ │ │ ├── bar.js
│ │ │ ├── foo.js
│ │ │ └── index.js
│ ├── bpmnlint-plugin-test-ns
│ │ ├── index.js
│ │ ├── package.json
│ │ └── rules
│ │ │ └── no-label-xxx.js
│ ├── bpmnlint-plugin-test
│ │ ├── index.js
│ │ ├── package.json
│ │ └── rules
│ │ │ ├── no-label-bar.js
│ │ │ └── no-label-foo.js
│ ├── bpmnlint-plugin-test2
│ │ ├── index.js
│ │ ├── package.json
│ │ └── rules
│ │ │ └── no-label-xxx.js
│ ├── bundling-spec.mjs
│ ├── bundling
│ │ ├── .gitignore
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── rollup.config.js
│ │ ├── src
│ │ │ ├── .bpmnlintrc
│ │ │ └── app.js
│ │ ├── test
│ │ │ ├── app.rollup.expected.js
│ │ │ └── app.webpack.expected.js
│ │ └── webpack.config.js
│ ├── cli-spec.mjs
│ ├── cli
│ │ ├── .bpmnlintrc
│ │ ├── child
│ │ │ ├── .bpmnlintrc
│ │ │ ├── diagram.bpmn
│ │ │ └── package.json
│ │ ├── complex.bpmn
│ │ ├── diagram-broken.bpmn
│ │ ├── diagram-import-warnings.bpmn
│ │ ├── diagram-invalid.bpmn
│ │ ├── diagram-warnings.bpmn
│ │ ├── diagram.bpmn
│ │ ├── empty
│ │ │ └── .gitkeep
│ │ ├── exported.json
│ │ ├── extends-builtin.json
│ │ ├── extends-external.json
│ │ ├── glob
│ │ │ ├── diagram-invalid.bpmn
│ │ │ └── subfolder
│ │ │ │ └── diagram-import-warnings.bpmn
│ │ ├── local-rules
│ │ │ ├── .bpmnlintrc
│ │ │ ├── diagram.bpmn
│ │ │ ├── lib
│ │ │ │ └── bpmnlint-plugin
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── package.json
│ │ │ │ │ └── rules
│ │ │ │ │ └── no-label-bar.js
│ │ │ └── package.json
│ │ ├── ns
│ │ │ ├── diagram-invalid.bpmn
│ │ │ ├── diagram.bpmn
│ │ │ ├── extends.json
│ │ │ ├── package.json
│ │ │ └── uses-rules.json
│ │ ├── package.json
│ │ └── test.js
│ ├── compilation
│ │ ├── .gitignore
│ │ ├── compile.js
│ │ ├── package.json
│ │ └── test
│ │ │ └── bpmnlintrc.expected.js
│ └── compile-spec.mjs
├── rules
│ ├── ad-hoc-sub-process.mjs
│ ├── ad-hoc-sub-process
│ │ ├── invalid-intermediate.bpmn
│ │ ├── invalid-start-end.bpmn
│ │ └── valid.bpmn
│ ├── conditional-flows.mjs
│ ├── conditional-flows
│ │ ├── invalid-fork-after-exclusive-gateway-default.bpmn
│ │ ├── invalid-fork-after-exclusive-gateway.bpmn
│ │ ├── invalid-fork-after-task-default.bpmn
│ │ ├── invalid-fork-after-task.bpmn
│ │ ├── valid-conditional-fork.bpmn
│ │ ├── valid-no-condition-after-merge.bpmn
│ │ ├── valid-split-after-task.bpmn
│ │ └── valid-split.bpmn
│ ├── end-event-required.mjs
│ ├── end-event-required
│ │ ├── invalid-sub-process-sub-types.bpmn
│ │ ├── invalid-sub-process.bpmn
│ │ ├── invalid.bpmn
│ │ ├── valid-sub-process-sub-types.bpmn
│ │ ├── valid-sub-process.bpmn
│ │ └── valid.bpmn
│ ├── event-sub-process-typed-start-event.mjs
│ ├── event-sub-process-typed-start-event
│ │ ├── invalid.bpmn
│ │ ├── valid-empty-sub-process.bpmn
│ │ ├── valid-empty.bpmn
│ │ ├── valid-intermediate-event.bpmn
│ │ ├── valid-sub-process.bpmn
│ │ └── valid.bpmn
│ ├── fake-join.mjs
│ ├── fake-join
│ │ ├── invalid-callActivity.bpmn
│ │ ├── invalid-task.bpmn
│ │ ├── valid-gateway.bpmn
│ │ └── valid.bpmn
│ ├── global.mjs
│ ├── global
│ │ ├── invalid-error-duplicate-name.bpmn
│ │ ├── invalid-error-missing-name.bpmn
│ │ ├── invalid-error-missing-reference.bpmn
│ │ ├── invalid-escalation-duplicate-name.bpmn
│ │ ├── invalid-escalation-missing-name.bpmn
│ │ ├── invalid-escalation-missing-reference.bpmn
│ │ ├── invalid-message-duplicate-name.bpmn
│ │ ├── invalid-message-missing-name.bpmn
│ │ ├── invalid-message-missing-reference.bpmn
│ │ ├── invalid-signal-duplicate-name.bpmn
│ │ ├── invalid-signal-missing-name.bpmn
│ │ ├── invalid-signal-missing-reference.bpmn
│ │ ├── valid-error.bpmn
│ │ ├── valid-escalation.bpmn
│ │ ├── valid-message.bpmn
│ │ ├── valid-no-ref.bpmn
│ │ └── valid-signal.bpmn
│ ├── label-required.mjs
│ ├── label-required
│ │ ├── invalid-boundary-event.bpmn
│ │ ├── invalid-conditional-flow.bpmn
│ │ ├── invalid-event.bpmn
│ │ ├── invalid-gateway-split.bpmn
│ │ ├── invalid-lane.bpmn
│ │ ├── invalid-participant.bpmn
│ │ ├── invalid-task.bpmn
│ │ ├── valid-boundary-event.bpmn
│ │ ├── valid-conditional-flow.bpmn
│ │ ├── valid-data-objects.bpmn
│ │ ├── valid-gateways.bpmn
│ │ ├── valid-participant-lanes.bpmn
│ │ └── valid-start-event.bpmn
│ ├── link-event.mjs
│ ├── link-event
│ │ ├── invalid.bpmn
│ │ ├── valid-collaboration.bpmn
│ │ └── valid.bpmn
│ ├── no-bpmndi.mjs
│ ├── no-bpmndi
│ │ ├── ignore-edge-without-bpmn-element.bpmn
│ │ ├── invalid-catch-event.bpmn
│ │ ├── invalid-collapsed-pool.bpmn
│ │ ├── invalid-group.bpmn
│ │ ├── invalid-lane.bpmn
│ │ ├── invalid-message-flow.bpmn
│ │ ├── invalid-missing-nested-lane-deep.bpmn
│ │ ├── invalid-missing-nested-lane.bpmn
│ │ ├── invalid-multiple-nested-levels.bpmn
│ │ ├── invalid-multiple-sub-processes.bpmn
│ │ ├── invalid-nested-boundary.bpmn
│ │ ├── invalid-nested-lanes.bpmn
│ │ ├── invalid-no-bpmn-diagram.bpmn
│ │ ├── invalid-participant.bpmn
│ │ ├── invalid-sequence-flow.bpmn
│ │ ├── invalid-sub-processes.bpmn
│ │ ├── valid-complex.bpmn
│ │ ├── valid-data-object.bpmn
│ │ ├── valid-empty.bpmn
│ │ ├── valid-error.bpmn
│ │ ├── valid-extension-elements.bpmn
│ │ ├── valid-group.bpmn
│ │ ├── valid-lanes.bpmn
│ │ ├── valid-message-flow.bpmn
│ │ ├── valid-multiple-nested-levels.bpmn
│ │ ├── valid-nested-boundary.bpmn
│ │ ├── valid-no-lanes.bpmn
│ │ ├── valid-signavio.bpmn
│ │ ├── valid-sub-processes.bpmn
│ │ └── valid.bpmn
│ ├── no-complex-gateway.mjs
│ ├── no-complex-gateway
│ │ ├── invalid.bpmn
│ │ └── valid.bpmn
│ ├── no-disconnected.mjs
│ ├── no-disconnected
│ │ ├── invalid.bpmn
│ │ ├── valid-adhoc-subprocess.bpmn
│ │ ├── valid-compensation.bpmn
│ │ ├── valid-event-subprocess.bpmn
│ │ ├── valid-text-annotation.bpmn
│ │ └── valid.bpmn
│ ├── no-duplicate-sequence-flows.mjs
│ ├── no-duplicate-sequence-flows
│ │ ├── invalid-condition.bpmn
│ │ ├── invalid-multiple.bpmn
│ │ ├── invalid-no-condition.bpmn
│ │ └── valid.bpmn
│ ├── no-gateway-join-fork.mjs
│ ├── no-gateway-join-fork
│ │ ├── invalid.bpmn
│ │ ├── valid-fork-join-task.bpmn
│ │ ├── valid-fork.bpmn
│ │ └── valid-join.bpmn
│ ├── no-implicit-end.mjs
│ ├── no-implicit-end
│ │ ├── invalid.bpmn
│ │ ├── valid-collaboration.bpmn
│ │ └── valid.bpmn
│ ├── no-implicit-split.mjs
│ ├── no-implicit-split
│ │ ├── invalid-call-activity.bpmn
│ │ ├── invalid-event.bpmn
│ │ ├── invalid-task.bpmn
│ │ ├── valid-default-conditional-flow.bpmn
│ │ └── valid.bpmn
│ ├── no-implicit-start.mjs
│ ├── no-implicit-start
│ │ ├── invalid.bpmn
│ │ ├── valid-collaboration.bpmn
│ │ └── valid.bpmn
│ ├── no-inclusive-gateway.mjs
│ ├── no-inclusive-gateway
│ │ ├── invalid.bpmn
│ │ └── valid.bpmn
│ ├── no-overlapping-elements.mjs
│ ├── no-overlapping-elements
│ │ ├── ignore-missing-bounds.bpmn
│ │ ├── ignore-missing-di.bpmn
│ │ ├── invalid-boundary-event.bpmn
│ │ ├── invalid-collaboration.bpmn
│ │ ├── invalid-process.bpmn
│ │ ├── invalid-subprocess-collapsed.bpmn
│ │ ├── invalid-subprocess.bpmn
│ │ ├── valid-boundary-event.bpmn
│ │ ├── valid-collaboration-subprocess.bpmn
│ │ ├── valid-collaboration.bpmn
│ │ ├── valid-data-objects.bpmn
│ │ ├── valid-process.bpmn
│ │ ├── valid-subprocess-collapsed.bpmn
│ │ └── valid-subprocess.bpmn
│ ├── single-blank-start-event.mjs
│ ├── single-blank-start-event
│ │ ├── invalid-sub-process.bpmn
│ │ ├── invalid.bpmn
│ │ ├── valid-empty.bpmn
│ │ ├── valid-end-event.bpmn
│ │ ├── valid-scopes.bpmn
│ │ ├── valid-sub-process.bpmn
│ │ ├── valid-typed-sub-process.bpmn
│ │ ├── valid-typed.bpmn
│ │ └── valid.bpmn
│ ├── single-event-definition.mjs
│ ├── single-event-definition
│ │ ├── invalid.bpmn
│ │ ├── valid-blank.bpmn
│ │ └── valid.bpmn
│ ├── start-event-required.mjs
│ ├── start-event-required
│ │ ├── invalid-sub-process-sub-types.bpmn
│ │ ├── invalid-sub-process.bpmn
│ │ ├── invalid.bpmn
│ │ ├── valid-sub-process-sub-types.bpmn
│ │ ├── valid-sub-process.bpmn
│ │ └── valid.bpmn
│ ├── sub-process-blank-start-event.mjs
│ ├── sub-process-blank-start-event
│ │ ├── invalid-ad-hoc.bpmn
│ │ ├── invalid.bpmn
│ │ ├── valid-empty.bpmn
│ │ ├── valid-event-sub-process.bpmn
│ │ ├── valid-intermediate-event.bpmn
│ │ └── valid.bpmn
│ ├── superfluous-gateway.mjs
│ ├── superfluous-gateway
│ │ ├── invalid.bpmn
│ │ ├── valid-none-gateway.bpmn
│ │ └── valid.bpmn
│ ├── superfluous-termination.mjs
│ └── superfluous-termination
│ │ ├── invalid-boundary-interrupting.bpmn
│ │ ├── invalid-event-sub-process-interrupting.bpmn
│ │ ├── invalid-exclusive-paths.bpmn
│ │ ├── invalid-sub-process.bpmn
│ │ ├── invalid.bpmn
│ │ ├── valid-boundary-non-interrupting.bpmn
│ │ ├── valid-event-sub-process-non-interrupting.bpmn
│ │ ├── valid-implicit-end.bpmn
│ │ └── valid.bpmn
└── spec
│ ├── config-spec.mjs
│ ├── diagram.bpmn
│ ├── index-spec.js
│ ├── linter-spec.mjs
│ ├── process-diagram.bpmn
│ ├── resolver
│ ├── node-resolver-spec.mjs
│ └── static-resolver-spec.mjs
│ ├── support
│ └── compile-config-spec.mjs
│ ├── test-rule-spec.mjs
│ ├── testers
│ └── rule-tester-spec.mjs
│ └── traverse-spec.mjs
└── tsconfig.json
/.github/ISSUE_TEMPLATE/BUG_REPORT.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Report a problem and help us fix it.
4 | labels: "bug"
5 | ---
6 |
7 |
8 | ### Describe the Bug
9 |
10 |
11 |
12 |
13 | ### Steps to Reproduce
14 |
15 |
16 |
17 | 1. do this
18 | 2. do that
19 | 3. now this happens
20 |
21 |
22 | ### Expected Behavior
23 |
24 |
25 |
26 |
27 | ### Environment
28 |
29 | - Host (Browser/Node version), if applicable: [e.g. MS Edge 18, Chrome 69, Node 10 LTS]
30 | - OS: [e.g. Windows 7]
31 | - Library version: [e.g. 2.0.0]
32 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea or general improvement.
4 | labels: "enhancement"
5 | ---
6 |
7 |
8 | ### Is your feature request related to a problem? Please describe
9 |
10 |
11 |
12 |
13 | ### Describe the solution you'd like
14 |
15 |
16 |
17 |
18 | ### Describe alternatives you've considered
19 |
20 |
21 |
22 |
23 | ### Additional context
24 |
25 |
26 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/NEW_RULE.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Propose new Rule
3 | about: Use this template to propose new modeling rules to be included in the library.
4 | labels: [ "rules" ]
5 | ---
6 |
7 | ### The rule detects the following modeling patterns
8 |
9 |
10 |
11 | *
12 | *
13 |
14 | ### How does the rule improve the BPMN diagram?
15 |
16 |
19 |
20 | ### Rule Details
21 |
22 | * Name:
23 | * Default notification level: `error|warn|off`
24 |
25 |
26 | ### What alternatives did you consider?
27 |
28 |
31 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 | - name: Ask a question
4 | url: https://forum.bpmn.io
5 | about: Head over to our community forum to ask questions and get answers.
6 |
--------------------------------------------------------------------------------
/.github/workflows/CI.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 | on: [ push, pull_request ]
3 | jobs:
4 | build:
5 | runs-on: ${{ matrix.os }}
6 |
7 | strategy:
8 | matrix:
9 | os: [ubuntu-latest]
10 | node-version: [ 20 ]
11 |
12 | steps:
13 | - name: Checkout
14 | uses: actions/checkout@v4
15 | - name: Use Node.js ${{matrix.node-version}}
16 | uses: actions/setup-node@v4
17 | with:
18 | node-version: ${{matrix.node-version}}
19 | cache: 'npm'
20 | - name: Install dependencies
21 | run: npm ci
22 | - name: Build
23 | run: COVERAGE=1 npm run all
24 | - name: Upload coverage
25 | uses: codecov/codecov-action@v3
26 |
27 | build_nodes:
28 | runs-on: ${{ matrix.os }}
29 |
30 | strategy:
31 | matrix:
32 | os: [ubuntu-latest]
33 | node-version: [ 22 ]
34 |
35 | steps:
36 | - name: Checkout
37 | uses: actions/checkout@v4
38 | - name: Use Node.js ${{matrix.node-version}}
39 | uses: actions/setup-node@v4
40 | with:
41 | node-version: ${{matrix.node-version}}
42 | cache: 'npm'
43 | - name: Install dependencies
44 | run: npm ci
45 | - name: Build
46 | run: npm run all
47 | build_platforms:
48 | runs-on: ${{ matrix.os }}
49 |
50 | strategy:
51 | matrix:
52 | os: [macos-latest, windows-latest]
53 | node-version: [ 20 ]
54 |
55 | steps:
56 | - name: Checkout
57 | uses: actions/checkout@v4
58 | - name: Use Node.js ${{matrix.node-version}}
59 | uses: actions/setup-node@v4
60 | with:
61 | node-version: ${{matrix.node-version}}
62 | cache: 'npm'
63 | - name: Install dependencies
64 | run: npm ci
65 | - name: Build
66 | run: npm run all
67 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .nyc_output
2 | node_modules
3 | coverage
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2018-present bpmn.io Contributors
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
--------------------------------------------------------------------------------
/config/all.js:
--------------------------------------------------------------------------------
1 | const allRules = [
2 | 'ad-hoc-sub-process',
3 | 'conditional-flows',
4 | 'end-event-required',
5 | 'event-sub-process-typed-start-event',
6 | 'fake-join',
7 | 'global',
8 | 'label-required',
9 | 'link-event',
10 | 'no-bpmndi',
11 | 'no-complex-gateway',
12 | 'no-disconnected',
13 | 'no-duplicate-sequence-flows',
14 | 'no-gateway-join-fork',
15 | 'no-implicit-end',
16 | 'no-implicit-split',
17 | 'no-implicit-start',
18 | 'no-inclusive-gateway',
19 | 'no-overlapping-elements',
20 | 'single-blank-start-event',
21 | 'single-event-definition',
22 | 'start-event-required',
23 | 'sub-process-blank-start-event',
24 | 'superfluous-gateway',
25 | 'superfluous-termination'
26 | ];
27 |
28 |
29 | module.exports = {
30 | rules: allRules.reduce(function(rules, ruleName) {
31 | rules[ruleName] = 'error';
32 |
33 | return rules;
34 | }, {})
35 | };
36 |
--------------------------------------------------------------------------------
/config/correctness.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | rules: {
3 | 'ad-hoc-sub-process': 'error',
4 | 'event-sub-process-typed-start-event': 'error',
5 | 'link-event': 'error',
6 | 'no-duplicate-sequence-flows': 'warn',
7 | 'sub-process-blank-start-event': 'error'
8 | }
9 | };
10 |
--------------------------------------------------------------------------------
/config/recommended.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | rules: {
3 | 'ad-hoc-sub-process': 'error',
4 | 'conditional-flows': 'error',
5 | 'end-event-required': 'error',
6 | 'event-sub-process-typed-start-event': 'error',
7 | 'fake-join': 'warn',
8 | 'global': 'warn',
9 | 'label-required': 'error',
10 | 'link-event': 'error',
11 | 'no-bpmndi': 'error',
12 | 'no-complex-gateway': 'error',
13 | 'no-disconnected': 'error',
14 | 'no-duplicate-sequence-flows': 'error',
15 | 'no-gateway-join-fork': 'error',
16 | 'no-implicit-split': 'error',
17 | 'no-implicit-end': 'error',
18 | 'no-implicit-start': 'error',
19 | 'no-inclusive-gateway': 'error',
20 | 'no-overlapping-elements': 'warn',
21 | 'single-blank-start-event': 'error',
22 | 'single-event-definition': 'error',
23 | 'start-event-required': 'error',
24 | 'sub-process-blank-start-event': 'error',
25 | 'superfluous-gateway': 'warn',
26 | 'superfluous-termination': 'warn'
27 | }
28 | };
29 |
--------------------------------------------------------------------------------
/docs/rules/README.md:
--------------------------------------------------------------------------------
1 | # Rules
2 |
3 | This library implements the following lint rules:
4 |
5 | * [Ad-Hoc Sub-Process](./ad-hoc-sub-process.md)
6 | * [Conditional Flows](./conditional-flows.md)
7 | * [End Event Required](./end-event-required.md)
8 | * [Event Sub-Process Typed Start Event](./event-sub-process-typed-start-event.md)
9 | * [Fake Join](./fake-join.md)
10 | * [Superfluous Gateway](./superfluous-gateway.md)
11 | * [Label Required](./label-required.md)
12 | * [No Complex Gateway](./no-complex-gateway.md)
13 | * [No Disconnected](./no-disconnected.md)
14 | * [No Duplicate Sequence Flows](./no-duplicate-sequence-flows.md)
15 | * [No Gateway Join Fork](./no-gateway-join-fork.md)
16 | * [No Implicit Start](./no-implicit-start.md)
17 | * [No Implicit Split](./no-implicit-split.md)
18 | * [No Implicit End](./no-implicit-end.md)
19 | * [No Inclusive Gateway](./no-inclusive-gateway.md)
20 | * [No Overlapping Elements](./no-overlapping-elements.md)
21 | * [Single Blank Start Event](./single-blank-start-event.md)
22 | * [Single Event Definition](./single-event-definition.md)
23 | * [Start Event Required](./start-event-required.md)
24 | * [Sub-Process Blank Start Event](./sub-process-blank-start-event.md)
--------------------------------------------------------------------------------
/docs/rules/ad-hoc-sub-process.md:
--------------------------------------------------------------------------------
1 | # Ad-hoc Sub-Process (ad-hoc-sub-process)
2 |
3 | Ensure that an Ad-Hoc Sub-Process is valid according to the BPMN specification:
4 |
5 | - Must not contain start or end events.
6 | - Every intermediate catch event must have an outgoing sequence flow.
7 |
8 |
9 | Example of __incorrect__ usage for this rule:
10 |
11 | 
12 |
13 | Cf. [`ad-hoc-sub-process-incorrect.bpmn`](./examples/no-complex-gateway-incorrect.bpmn).
14 |
15 |
16 | Example of __correct__ usage for this rule:
17 |
18 | 
19 |
20 | Cf. [`ad-hoc-sub-process-correct.bpmn`](./examples/no-complex-gateway-correct.bpmn).
21 |
--------------------------------------------------------------------------------
/docs/rules/conditional-flows.md:
--------------------------------------------------------------------------------
1 | # Conditional Flows (conditional-flows)
2 |
3 | Ensures that conditions on sequence flows are consistently set. If a sequence flow outgoing from a conditional forking gateway or activity is default _or_ any sequence flow has a condition attached, all others have to have to have respective condition meta-data attached, too.
4 |
5 |
6 | Example of __incorrect__ usage for this rule:
7 |
8 | 
9 |
10 | ```xml
11 | ...
12 |
13 | ...
14 | ```
15 |
16 | Cf. [`conditional-flows-incorrect.bpmn`](./examples/conditional-flows-incorrect.bpmn).
17 |
18 |
19 | Example of __correct__ usage for this rule:
20 |
21 | 
22 |
23 | ```xml
24 | ...
25 |
26 | foo
27 |
28 | ...
29 | ```
30 |
31 | Cf. [`conditional-flows-correct.bpmn`](./examples/conditional-flows-correct.bpmn).
--------------------------------------------------------------------------------
/docs/rules/end-event-required.md:
--------------------------------------------------------------------------------
1 | # End Event Required (end-event-required)
2 |
3 | Ensures that every process and sub-process has an end event. Explicitly modeling it improves the understandability of drawn process diagrams.
4 |
5 |
6 | Example of __incorrect__ usage for this rule:
7 |
8 | 
9 |
10 | Cf. [`end-event-required-incorrect.bpmn`](./examples/end-event-required-incorrect.bpmn).
11 |
12 |
13 | Example of __correct__ usage for this rule:
14 |
15 | 
16 |
17 | Cf. [`end-event-required-correct.bpmn`](./examples/end-event-required-correct.bpmn).
--------------------------------------------------------------------------------
/docs/rules/event-sub-process-typed-start-event.md:
--------------------------------------------------------------------------------
1 | # Event Sub Process Typed Start Event (event-sub-process-typed-start-event)
2 |
3 | Ensures that start events inside event sub-processes are typed (have an event definition). This is required by the BPMN 2.0 standard.
4 |
5 |
6 | Example of __incorrect__ usage for this rule:
7 |
8 | 
9 |
10 | Cf. [`event-sub-process-typed-start-event-incorrect.bpmn`](./examples/event-sub-process-typed-start-event-incorrect.bpmn).
11 |
12 |
13 | Example of __correct__ usage for this rule:
14 |
15 | 
16 |
17 | Cf. [`event-sub-process-typed-start-event-correct.bpmn`](./examples/event-sub-process-typed-start-event-correct.bpmn).
--------------------------------------------------------------------------------
/docs/rules/examples/ad-hoc-sub-process-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/ad-hoc-sub-process-correct.png
--------------------------------------------------------------------------------
/docs/rules/examples/ad-hoc-sub-process-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/ad-hoc-sub-process-incorrect.png
--------------------------------------------------------------------------------
/docs/rules/examples/conditional-flows-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/conditional-flows-correct.png
--------------------------------------------------------------------------------
/docs/rules/examples/conditional-flows-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/conditional-flows-incorrect.png
--------------------------------------------------------------------------------
/docs/rules/examples/end-event-required-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/end-event-required-correct.png
--------------------------------------------------------------------------------
/docs/rules/examples/end-event-required-incorrect.bpmn:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SequenceFlow_09dspiw
6 |
7 |
8 | SequenceFlow_09dspiw
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/docs/rules/examples/end-event-required-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/end-event-required-incorrect.png
--------------------------------------------------------------------------------
/docs/rules/examples/event-sub-process-typed-start-event-correct.bpmn:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/docs/rules/examples/event-sub-process-typed-start-event-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/event-sub-process-typed-start-event-correct.png
--------------------------------------------------------------------------------
/docs/rules/examples/event-sub-process-typed-start-event-incorrect.bpmn:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/docs/rules/examples/event-sub-process-typed-start-event-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/event-sub-process-typed-start-event-incorrect.png
--------------------------------------------------------------------------------
/docs/rules/examples/fake-join-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/fake-join-correct.png
--------------------------------------------------------------------------------
/docs/rules/examples/fake-join-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/fake-join-incorrect.png
--------------------------------------------------------------------------------
/docs/rules/examples/label-required-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/label-required-correct.png
--------------------------------------------------------------------------------
/docs/rules/examples/label-required-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/label-required-incorrect.png
--------------------------------------------------------------------------------
/docs/rules/examples/link-event-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/link-event-correct.png
--------------------------------------------------------------------------------
/docs/rules/examples/link-event-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/link-event-incorrect.png
--------------------------------------------------------------------------------
/docs/rules/examples/no-bpmndi-correct.bpmn:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SequenceFlow_1
6 |
7 |
8 |
9 | SequenceFlow_1
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/docs/rules/examples/no-bpmndi-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/no-bpmndi-correct.png
--------------------------------------------------------------------------------
/docs/rules/examples/no-bpmndi-incorrect.bpmn:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SequenceFlow_1
6 |
7 |
8 |
9 | SequenceFlow_1
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/docs/rules/examples/no-bpmndi-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/no-bpmndi-incorrect.png
--------------------------------------------------------------------------------
/docs/rules/examples/no-complex-gateway-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/no-complex-gateway-correct.png
--------------------------------------------------------------------------------
/docs/rules/examples/no-complex-gateway-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/no-complex-gateway-incorrect.png
--------------------------------------------------------------------------------
/docs/rules/examples/no-disconnected-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/no-disconnected-correct.png
--------------------------------------------------------------------------------
/docs/rules/examples/no-disconnected-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/no-disconnected-incorrect.png
--------------------------------------------------------------------------------
/docs/rules/examples/no-duplicate-sequence-flows-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/no-duplicate-sequence-flows-correct.png
--------------------------------------------------------------------------------
/docs/rules/examples/no-duplicate-sequence-flows-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/no-duplicate-sequence-flows-incorrect.png
--------------------------------------------------------------------------------
/docs/rules/examples/no-gateway-join-fork-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/no-gateway-join-fork-correct.png
--------------------------------------------------------------------------------
/docs/rules/examples/no-gateway-join-fork-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/no-gateway-join-fork-incorrect.png
--------------------------------------------------------------------------------
/docs/rules/examples/no-implicit-end-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/no-implicit-end-correct.png
--------------------------------------------------------------------------------
/docs/rules/examples/no-implicit-end-incorrect.bpmn:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SequenceFlow_1
6 |
7 |
8 | SequenceFlow_1
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/docs/rules/examples/no-implicit-end-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/no-implicit-end-incorrect.png
--------------------------------------------------------------------------------
/docs/rules/examples/no-implicit-split-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/no-implicit-split-correct.png
--------------------------------------------------------------------------------
/docs/rules/examples/no-implicit-split-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/no-implicit-split-incorrect.png
--------------------------------------------------------------------------------
/docs/rules/examples/no-implicit-start-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/no-implicit-start-correct.png
--------------------------------------------------------------------------------
/docs/rules/examples/no-implicit-start-incorrect.bpmn:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Flow_09avy1r
6 |
7 |
8 | Flow_09avy1r
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/docs/rules/examples/no-implicit-start-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/no-implicit-start-incorrect.png
--------------------------------------------------------------------------------
/docs/rules/examples/no-inclusive-gateway-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/no-inclusive-gateway-correct.png
--------------------------------------------------------------------------------
/docs/rules/examples/no-inclusive-gateway-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/no-inclusive-gateway-incorrect.png
--------------------------------------------------------------------------------
/docs/rules/examples/no-overlapping-elements-correct.bpmn:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Flow_1h3ws2k
6 |
7 |
8 | Flow_1h3ws2k
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/docs/rules/examples/no-overlapping-elements-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/no-overlapping-elements-correct.png
--------------------------------------------------------------------------------
/docs/rules/examples/no-overlapping-elements-incorrect.bpmn:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Flow_1h3ws2k
6 |
7 |
8 | Flow_1h3ws2k
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/docs/rules/examples/no-overlapping-elements-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/no-overlapping-elements-incorrect.png
--------------------------------------------------------------------------------
/docs/rules/examples/single-blank-start-event-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/single-blank-start-event-correct.png
--------------------------------------------------------------------------------
/docs/rules/examples/single-blank-start-event-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/single-blank-start-event-incorrect.png
--------------------------------------------------------------------------------
/docs/rules/examples/single-event-definition-correct.bpmn:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/rules/examples/single-event-definition-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/single-event-definition-correct.png
--------------------------------------------------------------------------------
/docs/rules/examples/single-event-definition-incorrect.bpmn:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/docs/rules/examples/single-event-definition-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/single-event-definition-incorrect.png
--------------------------------------------------------------------------------
/docs/rules/examples/start-event-required-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/start-event-required-correct.png
--------------------------------------------------------------------------------
/docs/rules/examples/start-event-required-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/start-event-required-incorrect.png
--------------------------------------------------------------------------------
/docs/rules/examples/sub-process-blank-start-event-correct.bpmn:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/docs/rules/examples/sub-process-blank-start-event-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/sub-process-blank-start-event-correct.png
--------------------------------------------------------------------------------
/docs/rules/examples/sub-process-blank-start-event-incorrect.bpmn:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/docs/rules/examples/sub-process-blank-start-event-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/sub-process-blank-start-event-incorrect.png
--------------------------------------------------------------------------------
/docs/rules/examples/superfluous-gateway-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/superfluous-gateway-correct.png
--------------------------------------------------------------------------------
/docs/rules/examples/superfluous-gateway-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/superfluous-gateway-incorrect.png
--------------------------------------------------------------------------------
/docs/rules/examples/superfluous-termination-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/superfluous-termination-correct.png
--------------------------------------------------------------------------------
/docs/rules/examples/superfluous-termination-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bpmn-io/bpmnlint/abfcdddefef48c3b1eaeb0b97ce91d4a70f781ab/docs/rules/examples/superfluous-termination-incorrect.png
--------------------------------------------------------------------------------
/docs/rules/fake-join.md:
--------------------------------------------------------------------------------
1 | # Fake Join (fake-join)
2 |
3 | Checks that no fake join is modeled by attempting to give a task or event join semantics. Users should model a parallel joining gateway to achieve the desired behavior.
4 |
5 |
6 | Example of __incorrect__ usage for this rule:
7 |
8 | 
9 |
10 | ```xml
11 | ...
12 |
13 | SequenceFlow_1
14 | SequenceFlow_2
15 |
16 | ...
17 | ```
18 |
19 | Cf. [`fake-join-incorrect.bpmn`](./examples/fake-join-incorrect.bpmn).
20 |
21 |
22 | Example of __correct__ usage for this rule:
23 |
24 | 
25 |
26 | ```xml
27 | ...
28 |
29 | SequenceFlow_1
30 |
31 | ...
32 | ```
33 |
34 | Cf. [`fake-join-correct.bpmn`](./examples/fake-join-correct.bpmn).
35 |
--------------------------------------------------------------------------------
/docs/rules/label-required.md:
--------------------------------------------------------------------------------
1 | # Label Required (label-required)
2 |
3 | Checks the presence of a label.
4 |
5 |
6 | Example of __incorrect__ usage for this rule:
7 |
8 | 
9 |
10 | ```xml
11 | ...
12 |
13 | SequenceFlow_1
14 | SequenceFlow_2
15 |
16 | ...
17 | ```
18 |
19 | Cf. [`label-required-incorrect.bpmn`](./examples/label-required-incorrect.bpmn).
20 |
21 |
22 | Example of __correct__ usage for this rule:
23 |
24 | 
25 |
26 | ```xml
27 | ...
28 |
29 | SequenceFlow_1
30 | SequenceFlow_2
31 |
32 | ...
33 | ```
34 |
35 | Cf. [`label-required-correct.bpmn`](./examples/label-required-correct.bpmn).
--------------------------------------------------------------------------------
/docs/rules/link-event.md:
--------------------------------------------------------------------------------
1 | # Link Event (link-event)
2 |
3 | A rule that checks that link events are used in accordance with the BPMN specification:
4 |
5 | * A link event definition must be named
6 | * For every link throw event there exists a matching catch event in the same scope
7 |
8 |
9 | Example of __incorrect__ usage for this rule:
10 |
11 | 
12 |
13 | Cf. [`link-event-incorrect.bpmn`](./examples/link-event-incorrect.bpmn).
14 |
15 |
16 | Example of __correct__ usage for this rule:
17 |
18 | 
19 |
20 | Cf. [`link-event-correct.bpmn`](./examples/link-event-correct.bpmn).
21 |
--------------------------------------------------------------------------------
/docs/rules/no-bpmndi.md:
--------------------------------------------------------------------------------
1 | # No BPMNDI information (no-bpmndi)
2 |
3 | Checks that semantic BPMN elements with a visual representation have graphical information (BPMNDI) attached.
4 |
5 | A BPMN element is referenced by a BPMNDI element. The BPMNDI defines how to visually display / render the respective element. It might happen, that a user deletes such an BPMNDI element by accident (e.g., by working in the XML directly). This might lead to errors, since the BPMN element would still be interpreted when executing the process, but it would not be visible anymore in graphical modeling tools. This rule identifies these cases.
6 |
7 | Example of __incorrect__ usage for this rule. See `task1`:
8 |
9 | ```xml
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | ```
18 |
19 |
20 | Example of __correct__ usage for this rule:
21 |
22 | ```xml
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | ```
34 |
--------------------------------------------------------------------------------
/docs/rules/no-complex-gateway.md:
--------------------------------------------------------------------------------
1 | # No Complex Gateway (no-complex-gateway)
2 |
3 | A rule that disallows complex gateways.
4 |
5 |
6 | Example of __incorrect__ usage for this rule:
7 |
8 | 
9 |
10 | Cf. [`no-complex-gateway-incorrect.bpmn`](./examples/no-complex-gateway-incorrect.bpmn).
11 |
12 |
13 | Example of __correct__ usage for this rule:
14 |
15 | 
16 |
17 | Cf. [`no-complex-gateway-correct.bpmn`](./examples/no-complex-gateway-correct.bpmn).
18 |
--------------------------------------------------------------------------------
/docs/rules/no-disconnected.md:
--------------------------------------------------------------------------------
1 | # No Disconnected (no-disconnected)
2 |
3 | Checks that a flow element is connected with other flow elements, either via incoming _or_ outgoing sequence flows.
4 |
5 |
6 | Example of __incorrect__ usage for this rule:
7 |
8 | 
9 |
10 | Cf. [`no-disconnected-incorrect.bpmn`](./examples/no-disconnected-incorrect.bpmn).
11 |
12 |
13 | Example of __correct__ usage for this rule:
14 |
15 | 
16 |
17 | Cf. [`no-disconnected-correct.bpmn`](./examples/no-disconnected-correct.bpmn).
--------------------------------------------------------------------------------
/docs/rules/no-duplicate-sequence-flows.md:
--------------------------------------------------------------------------------
1 | # No Duplicate Sequence Flows (no-duplicate-sequence-flows)
2 |
3 | Checks that sequence flows do not duplicate, leading to an unintentional fork.
4 |
5 |
6 | Example of __incorrect__ usage for this rule:
7 |
8 | 
9 |
10 | Cf. [`no-duplicate-sequence-flows-incorrect.bpmn`](./examples/no-duplicate-sequence-flows-incorrect.bpmn).
11 |
12 |
13 | Example of __correct__ usage for this rule:
14 |
15 | 
16 |
17 | Cf. [`no-duplicate-sequence-flows-correct.bpmn`](./examples/no-duplicate-sequence-flows-correct.bpmn).
--------------------------------------------------------------------------------
/docs/rules/no-gateway-join-fork.md:
--------------------------------------------------------------------------------
1 | # No Gateway Join Fork (no-gateway-join-fork)
2 |
3 | A rule that checks, whether a gateway forks and joins at the same time.
4 |
5 |
6 | Example of __incorrect__ usage for this rule:
7 |
8 | 
9 |
10 | ```xml
11 | ...
12 |
13 | SequenceFlow_1
14 | SequenceFlow_2
15 | SequenceFlow_3
16 | SequenceFlow_4
17 |
18 | ...
19 | ```
20 |
21 | Cf. [`no-gateway-join-fork-incorrect.bpmn`](./examples/no-gateway-join-fork-incorrect.bpmn).
22 |
23 |
24 | Example of __correct__ usage for this rule:
25 |
26 | 
27 |
28 | ```xml
29 | ...
30 |
31 | SequenceFlow_1
32 | SequenceFlow_2
33 | SequenceFlow_3
34 |
35 | ...
36 | ```
37 |
38 | Cf. [`no-gateway-join-fork-correct.bpmn`](./examples/no-gateway-join-fork-correct.bpmn).
--------------------------------------------------------------------------------
/docs/rules/no-implicit-end.md:
--------------------------------------------------------------------------------
1 | # No Implicit End (no-implicit-end)
2 |
3 | Checks that no implicit ends are modeled starting on a diagram. Users should model ends (token sinks) explicitly using end events to promote readability of a diagram.
4 |
5 |
6 | Example of __incorrect__ usage for this rule:
7 |
8 | 
9 |
10 | Cf. [`no-implicit-end-incorrect.bpmn`](./examples/no-implicit-end-incorrect.bpmn).
11 |
12 |
13 | Example of __correct__ usage for this rule:
14 |
15 | 
16 |
17 | Cf. [`no-implicit-end-correct.bpmn`](./examples/no-implicit-end-correct.bpmn).
--------------------------------------------------------------------------------
/docs/rules/no-implicit-split.md:
--------------------------------------------------------------------------------
1 | # No Implicit Split (no-implicit-split)
2 |
3 | Checks that no implicit split is modeled starting from a task. Users should model the parallel splitting gateway explicitly instead.
4 |
5 |
6 | Example of __incorrect__ usage for this rule:
7 |
8 | 
9 |
10 | Cf. [`no-implicit-split-incorrect.bpmn`](./examples/no-implicit-split-incorrect.bpmn).
11 |
12 |
13 | Example of __correct__ usage for this rule:
14 |
15 | 
16 |
17 | Cf. [`no-implicit-split-correct.bpmn`](./examples/no-implicit-split-correct.bpmn).
--------------------------------------------------------------------------------
/docs/rules/no-implicit-start.md:
--------------------------------------------------------------------------------
1 | # No Implicit Start (no-implicit-start)
2 |
3 | Checks that no implicit starts are modeled starting on a diagram. Users should model starts (token spawns) explicitly using start events to promote readability of a diagram.
4 |
5 |
6 | Example of __incorrect__ usage for this rule:
7 |
8 | 
9 |
10 | Cf. [`no-implicit-start-incorrect.bpmn`](./examples/no-implicit-start-incorrect.bpmn).
11 |
12 |
13 | Example of __correct__ usage for this rule:
14 |
15 | 
16 |
17 | Cf. [`no-implicit-start-correct.bpmn`](./examples/no-implicit-start-correct.bpmn).
--------------------------------------------------------------------------------
/docs/rules/no-inclusive-gateway.md:
--------------------------------------------------------------------------------
1 | # No Inclusive Gateway (no-inclusive-gateway)
2 |
3 | Checks for the presence of inclusive gateways. The complex split and join semantics of inclusive gateways make it hard to follow the token flow in bigger diagrams. Furthermore, the inclusive gateway is not well supported by BPMN engines, including [Camunda BPM](https://docs.camunda.org/manual/latest/reference/bpmn20/gateways/inclusive-gateway/#camunda-specific-behavior). In most cases, a combination of exclusive and parallel gateways can express inclusive gateway semantics in a clearer, albeit more verbose manner.
4 |
5 | Example of __incorrect__ usage for this rule:
6 |
7 | 
8 |
9 | Cf. [`no-inclusive-gateway-incorrect.bpmn`](./examples/no-inclusive-gateway-incorrect.bpmn).
10 |
11 |
12 | Example of __correct__ usage for this rule:
13 |
14 | 
15 |
16 | Cf. [`no-inclusive-gateway-correct.bpmn`](./examples/no-inclusive-gateway-correct.bpmn).
17 |
--------------------------------------------------------------------------------
/docs/rules/no-overlapping-elements.md:
--------------------------------------------------------------------------------
1 | # No Overlapping Elements (no-overlapping-elements)
2 |
3 | Checks that elements are not overlapping with each other unintentionally.
4 | To prevent misinterpretation ensure that a diagram is clearly layouted with sufficient space between flow elements.
5 |
6 | Example of __incorrect__ usage for this rule:
7 |
8 | 
9 |
10 | Cf. [`no-overlapping-elements-incorrect.bpmn`](./examples/no-overlapping-elements-incorrect.bpmn).
11 |
12 |
13 | Example of __correct__ usage for this rule:
14 |
15 | 
16 |
17 | Cf. [`no-overlapping-elements-correct.bpmn`](./examples/no-overlapping-elements-correct.bpmn).
--------------------------------------------------------------------------------
/docs/rules/single-blank-start-event.md:
--------------------------------------------------------------------------------
1 | # Single Blank Start Event (single-blank-start-event)
2 |
3 | Checks that there is only a single blank start event per process (or sub-process).
4 |
5 |
6 | Example of __incorrect__ usage for this rule:
7 |
8 | 
9 |
10 | Cf. [`single-blank-start-event-incorrect.bpmn`](./examples/single-blank-start-event-incorrect.bpmn).
11 |
12 |
13 | Example of __correct__ usage for this rule:
14 |
15 | 
16 |
17 | Cf. [`single-blank-start-event-correct.bpmn`](./examples/single-blank-start-event-correct.bpmn).
--------------------------------------------------------------------------------
/docs/rules/single-event-definition.md:
--------------------------------------------------------------------------------
1 | # Single Event Definition (single-event-definition)
2 |
3 | Checks that an event contains no more than one event definition.
4 |
5 | Example of __incorrect__ usage for this rule:
6 |
7 | 
8 |
9 | ```xml
10 | ...
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | ...
20 | ```
21 |
22 | Cf. [`single-event-definition-incorrect.bpmn`](./examples/single-event-definition-incorrect.bpmn).
23 |
24 | Example of __correct__ usage for this rule:
25 |
26 | 
27 |
28 | ```xml
29 | ...
30 |
31 |
32 |
33 |
34 |
35 |
36 | ...
37 | ```
38 |
39 | Cf. [`single-event-definition-correct.bpmn`](./examples/single-event-definition-correct.bpmn).
--------------------------------------------------------------------------------
/docs/rules/start-event-required.md:
--------------------------------------------------------------------------------
1 | # Start Event Required (start-event-required)
2 |
3 | Checks for the presence of a start event in a process or sub-process.
4 |
5 |
6 | Example of __incorrect__ usage for this rule:
7 |
8 | 
9 |
10 | Cf. [`start-event-required-incorrect.bpmn`](./examples/start-event-required-incorrect.bpmn).
11 |
12 |
13 | Example of __correct__ usage for this rule:
14 |
15 | 
16 |
17 | Cf. [`start-event-required-correct.bpmn`](./examples/start-event-required-correct.bpmn).
--------------------------------------------------------------------------------
/docs/rules/sub-process-blank-start-event.md:
--------------------------------------------------------------------------------
1 | # Sub-Process Blank Start Event (sub-process-blank-start-event)
2 |
3 | Checks that start events inside a normal sub-processes are blank (do not have an event definition).
4 |
5 |
6 | Example of __incorrect__ usage for this rule:
7 |
8 | 
9 |
10 | Cf. [`sub-process-blank-start-event-incorrect.bpmn`](./examples/sub-process-blank-start-event-incorrect.bpmn).
11 |
12 |
13 | Example of __correct__ usage for this rule:
14 |
15 | 
16 |
17 | Cf. [`sub-process-blank-start-event-correct.bpmn`](./examples/sub-process-blank-start-event-correct.bpmn).
--------------------------------------------------------------------------------
/docs/rules/superfluous-gateway.md:
--------------------------------------------------------------------------------
1 | # Redundant Gateway (superfluous-gateway)
2 |
3 | A rule that checks, whether a gateway has only one source and target. Those gateways are superfluous since they don't do anything.
4 |
5 | Example of __incorrect__ usage for this rule:
6 |
7 | 
8 |
9 | Cf. [`superfluous-gateway-incorrect.bpmn`](./examples/superfluous-gateway-incorrect.bpmn).
10 |
11 |
12 | Example of __correct__ usage for this rule:
13 |
14 | 
15 |
16 | Cf. [`superfluous-gateway.bpmn`](./examples/superfluous-gateway-correct.bpmn).
--------------------------------------------------------------------------------
/docs/rules/superfluous-termination.md:
--------------------------------------------------------------------------------
1 | # Redundant Termination (superfluous-termination)
2 |
3 | A rule that checks, whether termination is used in a meaningful manner. It cancels other tokens in a running process instance, hence it is superfluous (and potentially missleading) in scenarios where no other tokens to be canceled can exist.
4 |
5 | Example of __incorrect__ usage for this rule:
6 |
7 | 
8 |
9 | Cf. [`superfluous-termination-incorrect.bpmn`](./examples/superfluous-termination-incorrect.bpmn).
10 |
11 |
12 | Example of __correct__ usage for this rule:
13 |
14 | 
15 |
16 | Cf. [`superfluous-termination.bpmn`](./examples/superfluous-termination-correct.bpmn).
--------------------------------------------------------------------------------
/eslint.config.mjs:
--------------------------------------------------------------------------------
1 | import bpmnIoPlugin from 'eslint-plugin-bpmn-io';
2 |
3 | const files = {
4 | lib: [
5 | 'lib/**/*.js',
6 | 'rules/**/*.js',
7 | 'config/**/*.js'
8 | ],
9 | test: [
10 | 'test/**/*.js',
11 | 'test/**/*.mjs'
12 | ],
13 | ignored: [
14 | 'coverage',
15 | '.nyc_output',
16 | 'test/integration/bundling/dist',
17 | 'test/integration/bundling/test',
18 | 'test/integration/compilation/test'
19 | ]
20 | };
21 |
22 | export default [
23 | {
24 | 'ignores': files.ignored
25 | },
26 |
27 | // lib
28 | ...bpmnIoPlugin.configs.recommended.map(config => {
29 |
30 | return {
31 | ...config,
32 | files: files.lib,
33 | languageOptions: {
34 | ...config.languageOptions,
35 | sourceType: 'commonjs'
36 | }
37 | };
38 | }),
39 |
40 | // build + test
41 | ...bpmnIoPlugin.configs.node.map(config => {
42 |
43 | return {
44 | ...config,
45 | ignores: files.lib,
46 | };
47 | }),
48 |
49 | // test
50 | ...bpmnIoPlugin.configs.mocha.map(config => {
51 |
52 | return {
53 | ...config,
54 | files: files.test
55 | };
56 | })
57 | ];
58 |
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 | const Linter = require('./linter');
2 |
3 | module.exports = {
4 | Linter
5 | };
--------------------------------------------------------------------------------
/lib/resolver/static-resolver.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @typedef { import('../types.js').RuleFactory } RuleFactory
3 | * @typedef { import('../types.js').Config } Config
4 | */
5 |
6 |
7 | /**
8 | * A resolver that resolves rules and packages from a static cache.
9 | *
10 | * @param { any } cache
11 | */
12 | function StaticResolver(cache) {
13 | this.cache = cache;
14 | }
15 |
16 | module.exports = StaticResolver;
17 |
18 | /**
19 | * @param { string } pkg
20 | * @param { string } ruleName
21 | *
22 | * @return { RuleFactory }
23 | */
24 | StaticResolver.prototype.resolveRule = function(pkg, ruleName) {
25 | return /** @type { RuleFactory } */ (this.resolve('rule', pkg, ruleName));
26 | };
27 |
28 | /**
29 | * @param { string } pkg
30 | * @param { string } configName
31 | *
32 | * @return { Config }
33 | */
34 | StaticResolver.prototype.resolveConfig = function(pkg, configName) {
35 | return /** @type { Config } */ (this.resolve('config', pkg, configName));
36 | };
37 |
38 | StaticResolver.prototype.resolve = function(type, pkg, name) {
39 | const id = `${pkg}/${name}`;
40 |
41 | const resolved = this.cache[`${type}:${id}`];
42 |
43 | if (!resolved) {
44 | throw new Error(`unknown ${type} <${id}>`);
45 | }
46 |
47 | return resolved;
48 | };
--------------------------------------------------------------------------------
/lib/testers/helper.js:
--------------------------------------------------------------------------------
1 | // @ts-expect-error 'missing types'
2 | const BpmnModdle = require('bpmn-moddle');
3 |
4 | const { readFileSync } = require('node:fs');
5 |
6 |
7 | /**
8 | * Create moddle instance.
9 | *
10 | * @param {String} xml the XML string
11 | *
12 | * @return {Promise