├── .github
└── workflows
│ └── CI.yml
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── eslint.config.mjs
├── index.js
├── karma.conf.js
├── lib
├── Cli.js
├── Initializer.js
├── commands
│ ├── append.js
│ ├── color.js
│ ├── connect.js
│ ├── create.js
│ ├── element.js
│ ├── elements.js
│ ├── index.js
│ ├── move.js
│ ├── redo.js
│ ├── remove.js
│ ├── removeConnection.js
│ ├── removeShape.js
│ ├── save.js
│ ├── set-label.js
│ ├── set-root.js
│ └── undo.js
├── index.js
└── parsers
│ ├── element.js
│ ├── elements.js
│ ├── index.js
│ ├── point.js
│ ├── shape.js
│ └── shapes.js
├── package-lock.json
├── package.json
├── renovate.json
├── resources
├── collapsed.bpmn
├── demo.js
├── screencast.gif
├── simple.bpmn
└── start.bpmn
└── test
├── TestHelper.js
├── spec
└── CliSpec.js
└── suite.js
/.github/workflows/CI.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 | on: [ push, pull_request ]
3 | jobs:
4 | Build:
5 |
6 | strategy:
7 | matrix:
8 | os: [ ubuntu-latest ]
9 | node-version: [ 20 ]
10 | integration-deps:
11 | - diagram-js@7.x bpmn-js@8.x
12 | - "" # as defined in package.json
13 |
14 | runs-on: ${{ matrix.os }}
15 |
16 | steps:
17 | - name: Checkout
18 | uses: actions/checkout@v4
19 | - name: Use Node.js
20 | uses: actions/setup-node@v4
21 | with:
22 | node-version: ${{ matrix.node-version }}
23 | cache: 'npm'
24 | - name: Install dependencies
25 | run: npm ci
26 | - name: Setup project
27 | uses: bpmn-io/actions/setup@latest
28 | - name: Install dependencies for integration test
29 | if: ${{ matrix.integration-deps != '' }}
30 | run: npm install ${{ matrix.integration-deps }}
31 | - name: Build
32 | run: npm run all
33 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .idea/
3 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to [bpmn-js-cli](https://github.com/bpmn-io/bpmn-js-cli) are documented here. We use [semantic versioning](http://semver.org/) for releases.
4 |
5 | ## Unreleased
6 |
7 | ___Note:__ Yet to be released changes appear here._
8 |
9 | # 2.4.0
10 |
11 | * `DEPS`: dependency updates
12 | * `CHORE`: consistently use ES modules internally
13 |
14 | # 2.3.0
15 |
16 | * `DEPS`: widen `bpmn-js` peerDependency range ([e71a09f](https://github.com/bpmn-io/bpmn-js-cli/commit/e71a09f))
17 |
18 | ## 2.2.1
19 |
20 | * `DEPS`: support `bpmn-js@10`
21 |
22 | ## 2.2.0
23 |
24 | * `FEAT`: add `setRoot` command ([#42](https://github.com/bpmn-io/bpmn-js-cli/pull/42))
25 |
26 | ## 2.1.0
27 |
28 | * `FEAT`: add `color` command
29 | * `FEAT`: add generic `remove` command
30 | * `FEAT`: add `elements` param
31 |
32 | ## 2.0.2
33 |
34 | * `CHORE`: clean up published files
35 |
36 | ## 2.0.1
37 |
38 | * `CHORE`: mark as `bpmn-js@8` compatible
39 |
40 | ## 2.0.0
41 |
42 | ### Breaking Changes
43 |
44 | * The toolkit now requires the ES6 `Promise` to be present. To support IE11 you must polyfill it.
45 |
46 | ## 1.4.1
47 |
48 | * `CHORE`: fix CHANGELOG
49 |
50 | ## 1.4.0
51 |
52 | _Republish of `v1.2.0`._
53 |
54 | ## 1.2.0
55 |
56 | * `CHORE`: support `bpmn-js@6`
57 |
58 | ## 1.1.0
59 |
60 | * `CHORE`: support `bpmn-js@4` and `bpmn-js@5`
61 |
62 | ## 1.0.0
63 |
64 | * `FEAT`: expose ES modules
65 | * `FEAT`: mark as `bpmn-js@3` compatible
66 | * `CHORE`: drop `bpmn-js@0.x` compatibility
67 |
68 | ### Breaking Changes
69 |
70 | * You must now use an ES module aware bundler such as Webpack or Rollup to consume this library.
71 |
72 | ## ...
73 |
74 | Check `git log` for earlier history.
75 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Nico Rehwaldt
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.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | > As of version `1.0.0` this library exposes [ES modules](http://exploringjs.com/es6/ch_modules.html#sec_basics-of-es6-modules). Use an ES module aware bundler such as [Webpack](https://webpack.js.org) or [Rollup](https://rollupjs.org) to bundle it for the browser.
2 |
3 | # bpmn-js-cli
4 |
5 | [](https://github.com/bpmn-io/bpmn-js-cli/actions?query=workflow%3ACI)
6 |
7 | An extensible command line interface for [bpmn-js](https://github.com/bpmn-io/bpmn-js).
8 |
9 |
10 | ## Demo
11 |
12 |
13 |
14 | Checkout [`demo.js`](./resources/demo.js) for the commands powering this demo.
15 |
16 |
17 | ## Features
18 |
19 | * Model BPMN 2.0 diagrams in the browser, without a mouse
20 | * Full undo and redo functionality
21 | * Extensible through your own commands
22 | * [Numerous built-in commands](#built-in-commands)
23 |
24 |
25 | ## Built in Commands
26 |
27 | Out of the box, the cli supports the following commands:
28 |
29 | * `append source type [deltaPos]`
30 | * `connect source target type`
31 | * `create type position parent`
32 | * `element id`
33 | * `elements`
34 | * `move shape delta [newParentId]`
35 | * `undo`
36 | * `redo`
37 | * `save svg|bpmn`
38 | * `setLabel element label`
39 | * `setRoot element|elementId`
40 | * `removeShape shape|elementId`
41 | * `removeConnection connection|connectionId`
42 |
43 |
44 | ## Quickstart
45 |
46 | Get the list of available commands:
47 |
48 | ```
49 | cli.help();
50 | ```
51 |
52 | Get the list of elements:
53 |
54 | ```
55 | cli.elements();
56 | ```
57 |
58 | Export SVG or BPMN 2.0 xml
59 |
60 | ```
61 | cli.save('svg' || 'bpmn');
62 | ```
63 |
64 |
65 | ## Usage
66 |
67 | Deploy the cli with [bpmn-js](https://github.com/bpmn-io/bpmn-js):
68 |
69 | ```
70 | var BpmnModeler = require('bpmn-js/lib/Modeler'),
71 | CliModule = require('bpmn-js-cli');
72 |
73 | var modeler = new BpmnModeler({
74 | container: document.body,
75 | additionalModules: [
76 | CliModule
77 | ],
78 | cli: {
79 | bindTo: 'cli'
80 | }
81 | });
82 |
83 | modeler.importXML('some-bpmn-xml')
84 | .then(({ warnings }) => {
85 | // ...
86 | })
87 | .catch(err => {
88 | console.error(err);
89 | });
90 | ```
91 |
92 | Access the cli as `cli` in your developer console (open via `F12` in most browsers).
93 |
94 | Use the cli to model BPMN 2.0 diagrams in your browser. Pain free.
95 |
96 |
97 | ## License
98 |
99 | MIT
100 |
--------------------------------------------------------------------------------
/eslint.config.mjs:
--------------------------------------------------------------------------------
1 | import bpmnIoPlugin from 'eslint-plugin-bpmn-io';
2 |
3 | export default [
4 | ...bpmnIoPlugin.configs.browser,
5 | ...bpmnIoPlugin.configs.node.map(config => {
6 | return {
7 | ...config,
8 | files: [
9 | 'karma.conf.js',
10 | '**/test/**/*.js'
11 | ]
12 | };
13 | }),
14 | ...bpmnIoPlugin.configs.mocha.map(config => {
15 | return {
16 | ...config,
17 | files: [
18 | '**/test/**/*.js'
19 | ]
20 | };
21 | })
22 | ];
23 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | export {
2 | default
3 | } from './lib';
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | /* eslint-env node */
2 |
3 | var path = require('path');
4 |
5 | var singleStart = process.env.SINGLE_START;
6 |
7 | // configures browsers to run test against
8 | // any of [ 'ChromeHeadless', 'Chrome', 'Firefox' ]
9 | var browsers = (process.env.TEST_BROWSERS || 'ChromeHeadless').split(',');
10 |
11 | // use puppeteer provided Chrome for testing
12 | process.env.CHROME_BIN = require('puppeteer').executablePath();
13 |
14 | module.exports = function(karma) {
15 | var config = {
16 |
17 | frameworks: [
18 | 'mocha',
19 | 'chai',
20 | 'webpack'
21 | ],
22 |
23 | files: [
24 | 'test/suite.js'
25 | ],
26 |
27 | preprocessors: {
28 | 'test/suite.js': [ 'webpack', 'env' ]
29 | },
30 |
31 | reporters: [ 'dots' ],
32 |
33 | browsers,
34 |
35 | browserNoActivityTimeout: 30000,
36 |
37 | singleRun: true,
38 | autoWatch: false,
39 |
40 | webpack: {
41 | mode: 'development',
42 | module: {
43 | rules: [
44 | {
45 | test: /(\.css|\.bpmn)$/,
46 | type: 'asset/source'
47 | }
48 | ]
49 | },
50 | resolve: {
51 | modules: [
52 | 'node_modules',
53 | path.resolve(__dirname)
54 | ]
55 | }
56 | }
57 | };
58 |
59 | if (singleStart) {
60 | config.browsers = [].concat(config.browsers, 'Debug');
61 | config.envPreprocessor = [].concat(config.envPreprocessor || [], 'SINGLE_START');
62 | }
63 |
64 | karma.set(config);
65 | };
66 |
--------------------------------------------------------------------------------
/lib/Cli.js:
--------------------------------------------------------------------------------
1 | import {
2 | isArray,
3 | isNumber,
4 | isString,
5 | isFunction,
6 | forEach
7 | } from 'min-dash';
8 |
9 | function asArray(args) {
10 | return Array.prototype.slice.call(args);
11 | }
12 |
13 | function asParam(parse) {
14 | return function(name, options) {
15 | return {
16 | name: name,
17 | parse: function(val) {
18 | return parse(val, options || {});
19 | }
20 | };
21 | };
22 | }
23 |
24 | function StringParser() {
25 | return function(arg, options) {
26 |
27 | // support variable arguments
28 | if (isArray(arg)) {
29 | arg = arg.join(' ');
30 | }
31 |
32 | if (arg !== '' && !arg) {
33 | if (options.defaultValue) {
34 | return options.defaultValue;
35 | } else {
36 | throw new Error('no value given');
37 | }
38 | } else {
39 | return arg;
40 | }
41 | };
42 | }
43 |
44 | function BooleanParser() {
45 | return function(arg, options) {
46 | if (!arg) {
47 | if (options.defaultValue) {
48 | return options.defaultValue;
49 | }
50 |
51 | if (options.optional) {
52 | return undefined;
53 | }
54 |
55 | throw new Error('no value given');
56 | } else {
57 | return arg && arg !== 'false';
58 | }
59 | };
60 | }
61 |
62 | function NumberParser() {
63 | return function(arg, options) {
64 | if (arg !== 0 && !arg) {
65 | if (options.defaultValue) {
66 | return options.defaultValue;
67 | } else {
68 | throw new Error('no value given');
69 | }
70 | } else {
71 | return isNumber(arg) ? arg : parseFloat(arg, 10);
72 | }
73 | };
74 | }
75 |
76 | /**
77 | * The CLI.
78 | *
79 | * @param {Object} config
80 | * @param {didi.Injector} injector
81 | */
82 | export default function Cli(config, injector) {
83 |
84 | this._commands = {};
85 | this._params = {};
86 |
87 | this._injector = injector;
88 |
89 | this._registerParsers();
90 | this._registerCommands();
91 |
92 | this._bind(config);
93 | }
94 |
95 | Cli.$inject = [
96 | 'config',
97 | 'injector'
98 | ];
99 |
100 |
101 | // reset prototype (ain't gonna inherit from object)
102 |
103 | Cli.prototype = {};
104 |
105 |
106 | // helpers //////////////////////////
107 |
108 | Cli.prototype._bind = function(config) {
109 | if (config.cli && config.cli.bindTo) {
110 | console.info('bpmn-js-cli is available via window.' + config.cli.bindTo);
111 | window[config.cli.bindTo] = this;
112 | }
113 | };
114 |
115 | Cli.prototype._registerParser = function(name, Parser) {
116 | var parser = this._injector.invoke(Parser);
117 |
118 | // must return a function(val, options) -> result
119 | if (!isFunction(parser)) {
120 | throw new Error(
121 | 'parser must be a Function -> Object'
122 | );
123 | }
124 |
125 | this._params[name] = asParam(parser);
126 | };
127 |
128 | Cli.prototype._registerCommand = function(name, Command) {
129 |
130 | var command = (
131 | isFunction(Command) ?
132 | this._injector.invoke(Command) :
133 | Command
134 | );
135 |
136 | command.args = command.args || [];
137 |
138 | this._commands[name] = command;
139 |
140 | var self = this;
141 |
142 | this[name] = function() {
143 | var args = asArray(arguments);
144 | args.unshift(name);
145 |
146 | return self.exec.apply(self, args);
147 | };
148 | };
149 |
150 | Cli.prototype._registerParsers = function() {
151 | this._registerParser('string', StringParser);
152 | this._registerParser('number', NumberParser);
153 | this._registerParser('bool', BooleanParser);
154 | };
155 |
156 | Cli.prototype._registerCommands = function() {
157 |
158 | var self = this;
159 |
160 | // special command
161 | this._registerCommand('help', {
162 | exec: function() {
163 | var help = 'available commands:\n';
164 |
165 | forEach(self._commands, function(c, name) {
166 | help += '\n\t' + name;
167 | });
168 |
169 | return help;
170 | }
171 | });
172 | };
173 |
174 | Cli.prototype.parseArguments = function(args, command) {
175 |
176 | var results = [];
177 |
178 | var last = command.args.length - 1;
179 |
180 | forEach(command.args, function(c, i) {
181 |
182 | var val;
183 |
184 | // last arg receives array of all remaining parameters
185 | if (i === last && args.length > command.args.length) {
186 | val = args.slice(i);
187 | } else {
188 | val = args[i];
189 | }
190 |
191 | try {
192 | results.push(c.parse(val));
193 | } catch (e) {
194 | throw new Error('could not parse <' + c.name + '>: ' + e.message);
195 | }
196 | });
197 |
198 | return results;
199 | };
200 |
201 | Cli.prototype.exec = function() {
202 |
203 | var args = [];
204 |
205 | // convert mixed whitespace separated string / object assignments in args list
206 | // to correct argument representation
207 | asArray(arguments).forEach(function(arg) {
208 | if (isString(arg)) {
209 | args = args.concat(arg.split(/\s+/));
210 | } else {
211 | args.push(arg);
212 | }
213 | });
214 |
215 | var name = args.shift();
216 |
217 | var command = this._commands[name];
218 | if (!command) {
219 | throw new Error(
220 | 'no command <' + name + '>, ' +
221 | 'execute to get a list of available commands'
222 | );
223 | }
224 |
225 | var values, result;
226 |
227 | try {
228 | values = this.parseArguments(args, command);
229 | result = command.exec.apply(this, values);
230 | } catch (e) {
231 | throw new Error(
232 | 'failed to execute <' + name + '> ' +
233 | 'with args <[' + args.join(', ') + ']> : ' +
234 | e.stack
235 | );
236 | }
237 |
238 | return result;
239 | };
--------------------------------------------------------------------------------
/lib/Initializer.js:
--------------------------------------------------------------------------------
1 | import {
2 | PointParser,
3 | ElementParser,
4 | ElementsParser,
5 | ShapeParser,
6 | ShapesParser
7 | } from './parsers';
8 |
9 | import {
10 | AppendCommand,
11 | ConnectCommand,
12 | ColorCommand,
13 | CreateCommand,
14 | ElementCommand,
15 | ElementsCommand,
16 | MoveCommand,
17 | RedoCommand,
18 | SaveCommand,
19 | SetLabelCommand,
20 | SetRootCommand,
21 | UndoCommand,
22 | RemoveShapeCommand,
23 | RemoveConnectionCommand,
24 | RemoveCommand
25 | } from './commands';
26 |
27 | /**
28 | * The default CLI initializer that sets up available
29 | * parsers and commands.
30 | *
31 | * @param {Cli} cli
32 | */
33 | export default function Initializer(cli) {
34 |
35 | // parsers
36 | cli._registerParser('point', PointParser);
37 | cli._registerParser('element', ElementParser);
38 | cli._registerParser('elements', ElementsParser);
39 | cli._registerParser('shape', ShapeParser);
40 | cli._registerParser('shapes', ShapesParser);
41 |
42 | // commands
43 | cli._registerCommand('append', AppendCommand);
44 | cli._registerCommand('connect', ConnectCommand);
45 | cli._registerCommand('color', ColorCommand);
46 | cli._registerCommand('create', CreateCommand);
47 | cli._registerCommand('element', ElementCommand);
48 | cli._registerCommand('elements', ElementsCommand);
49 | cli._registerCommand('move', MoveCommand);
50 | cli._registerCommand('redo', RedoCommand);
51 | cli._registerCommand('save', SaveCommand);
52 | cli._registerCommand('setLabel', SetLabelCommand);
53 | cli._registerCommand('setRoot', SetRootCommand);
54 | cli._registerCommand('undo', UndoCommand);
55 | cli._registerCommand('removeShape', RemoveShapeCommand);
56 | cli._registerCommand('removeConnection', RemoveConnectionCommand);
57 | cli._registerCommand('remove', RemoveCommand);
58 | }
59 |
60 | Initializer.$inject = [ 'cli' ];
--------------------------------------------------------------------------------
/lib/commands/append.js:
--------------------------------------------------------------------------------
1 | export default function AppendCommand(params, modeling) {
2 |
3 | return {
4 | args: [
5 | params.shape('source'),
6 | params.string('type'),
7 | params.point('delta', { defaultValue: { x: 200, y: 0 } })
8 | ],
9 | exec: function(source, type, delta) {
10 | var newPosition = {
11 | x: source.x + source.width / 2 + delta.x,
12 | y: source.y + source.height / 2 + delta.y
13 | };
14 |
15 | return modeling.appendShape(source, { type: type }, newPosition).id;
16 | }
17 | };
18 | }
19 |
20 | AppendCommand.$inject = [ 'cli._params', 'modeling' ];
--------------------------------------------------------------------------------
/lib/commands/color.js:
--------------------------------------------------------------------------------
1 | import {
2 | isArray,
3 | isObject
4 | } from 'min-dash';
5 |
6 |
7 | /**
8 | * Colors a number of elements
9 | */
10 | export default function ColorCommand(params, modeling) {
11 |
12 | function parseColors(colors) {
13 |
14 | // directly pass colors = { fill?, stroke? }
15 | if (isObject(colors)) {
16 | return colors;
17 | }
18 |
19 | var parts = isArray(colors) ? colors : colors.split(',');
20 |
21 | var opts = {};
22 |
23 | [ 'fill', 'stroke' ].forEach(function(part, idx) {
24 |
25 | var color = parts[idx];
26 |
27 | if (color) {
28 | opts[part] = color === 'unset' ? undefined : color;
29 | }
30 | });
31 |
32 | return opts;
33 | }
34 |
35 | return {
36 | args: [
37 | params.elements('elements'),
38 | params.string('colors')
39 | ],
40 | exec: function(elements, colors) {
41 | modeling.setColor(elements, parseColors(colors));
42 | }
43 | };
44 | }
45 |
46 | ColorCommand.$inject = [ 'cli._params', 'modeling' ];
--------------------------------------------------------------------------------
/lib/commands/connect.js:
--------------------------------------------------------------------------------
1 | export default function ConnectCommand(params, modeling) {
2 |
3 | return {
4 | args: [
5 | params.shape('source'),
6 | params.shape('target'),
7 | params.string('type'),
8 | params.shape('parent', { optional: true }),
9 | ],
10 | exec: function(source, target, type, parent) {
11 | return modeling.createConnection(source, target, {
12 | type: type,
13 | }, parent || source.parent).id;
14 | }
15 | };
16 | }
17 |
18 | ConnectCommand.$inject = [ 'cli._params', 'modeling' ];
--------------------------------------------------------------------------------
/lib/commands/create.js:
--------------------------------------------------------------------------------
1 | export default function CreateCommand(params, modeling) {
2 |
3 | return {
4 | args: [
5 | params.string('type'),
6 | params.point('position'),
7 | params.shape('parent'),
8 | params.bool('isAttach', { optional: true })
9 | ],
10 | exec: function(type, position, parent, isAttach) {
11 |
12 | var hints;
13 |
14 | if (isAttach) {
15 | hints = {
16 | attach: true
17 | };
18 | }
19 |
20 | return modeling.createShape({ type: type }, position, parent, hints).id;
21 | }
22 | };
23 | }
24 |
25 | CreateCommand.$inject = [ 'cli._params', 'modeling' ];
--------------------------------------------------------------------------------
/lib/commands/element.js:
--------------------------------------------------------------------------------
1 | export default function ElementCommand(params) {
2 |
3 | return {
4 | args: [ params.element('element') ],
5 | exec: function(element) {
6 | return element;
7 | }
8 | };
9 | }
10 |
11 | ElementCommand.$inject = [ 'cli._params' ];
--------------------------------------------------------------------------------
/lib/commands/elements.js:
--------------------------------------------------------------------------------
1 | export default function ElementsCommand(params, elementRegistry) {
2 |
3 | return {
4 | exec: function() {
5 | function all() {
6 | return true;
7 | }
8 |
9 | function ids(e) {
10 | return e.id;
11 | }
12 |
13 | return elementRegistry.filter(all).map(ids);
14 | }
15 | };
16 | }
17 |
18 | ElementsCommand.$inject = [ 'cli._params', 'elementRegistry' ];
--------------------------------------------------------------------------------
/lib/commands/index.js:
--------------------------------------------------------------------------------
1 | export { default as AppendCommand } from './append';
2 | export { default as ColorCommand } from './color';
3 | export { default as ConnectCommand } from './connect';
4 | export { default as CreateCommand } from './create';
5 | export { default as ElementCommand } from './element';
6 | export { default as ElementsCommand } from './elements';
7 | export { default as MoveCommand } from './move';
8 | export { default as RedoCommand } from './redo';
9 | export { default as SaveCommand } from './save';
10 | export { default as SetLabelCommand } from './set-label';
11 | export { default as SetRootCommand } from './set-root';
12 | export { default as UndoCommand } from './undo';
13 | export { default as RemoveShapeCommand } from './removeShape';
14 | export { default as RemoveConnectionCommand } from './removeConnection';
15 | export { default as RemoveCommand } from './remove';
--------------------------------------------------------------------------------
/lib/commands/move.js:
--------------------------------------------------------------------------------
1 | export default function MoveCommand(params, modeling) {
2 |
3 | return {
4 | args: [
5 | params.shapes('shapes'),
6 | params.point('delta'),
7 | params.shape('newParent', { optional: true }),
8 | params.bool('isAttach', { optional: true })
9 | ],
10 | exec: function(shapes, delta, newParent, isAttach) {
11 |
12 | var hints;
13 |
14 | if (isAttach) {
15 | hints = {
16 | attach: true
17 | };
18 | }
19 |
20 | modeling.moveElements(shapes, delta, newParent, hints);
21 | return shapes;
22 | }
23 | };
24 | }
25 |
26 | MoveCommand.$inject = [ 'cli._params', 'modeling' ];
--------------------------------------------------------------------------------
/lib/commands/redo.js:
--------------------------------------------------------------------------------
1 | export default function RedoCommand(commandStack) {
2 |
3 | return {
4 | exec: function() {
5 | commandStack.redo();
6 | }
7 | };
8 | }
9 |
10 | RedoCommand.$inject = [ 'commandStack' ];
--------------------------------------------------------------------------------
/lib/commands/remove.js:
--------------------------------------------------------------------------------
1 | export default function RemoveCommand(params, modeling) {
2 |
3 | return {
4 | args: [
5 | params.elements('elements')
6 | ],
7 | exec: function(elements) {
8 | return modeling.removeElements(elements);
9 | }
10 | };
11 | }
12 |
13 | RemoveCommand.$inject = [ 'cli._params', 'modeling' ];
--------------------------------------------------------------------------------
/lib/commands/removeConnection.js:
--------------------------------------------------------------------------------
1 | export default function RemoveConnectionCommand(params, modeling) {
2 |
3 | return {
4 | args: [
5 | params.element('connection')
6 | ],
7 | exec: function(connection) {
8 | return modeling.removeConnection(connection);
9 | }
10 | };
11 | }
12 |
13 | RemoveConnectionCommand.$inject = [ 'cli._params', 'modeling' ];
--------------------------------------------------------------------------------
/lib/commands/removeShape.js:
--------------------------------------------------------------------------------
1 | export default function RemoveShapeCommand(params, modeling) {
2 |
3 | return {
4 | args: [
5 | params.shape('shape')
6 | ],
7 | exec: function(shape) {
8 | return modeling.removeShape(shape);
9 | }
10 | };
11 | }
12 |
13 | RemoveShapeCommand.$inject = [ 'cli._params', 'modeling' ];
--------------------------------------------------------------------------------
/lib/commands/save.js:
--------------------------------------------------------------------------------
1 | export default function SaveCommand(params, bpmnjs) {
2 |
3 | return {
4 | args: [ params.string('format') ],
5 | exec: function(format) {
6 | if (format === 'svg') {
7 | bpmnjs.saveSVG()
8 | .then(({ svg }) => {
9 | console.info(svg);
10 | })
11 | .catch(err => {
12 | console.error(err);
13 | });
14 | } else if (format === 'bpmn') {
15 | bpmnjs.saveXML()
16 | .then(({ xml }) => {
17 | console.info(xml);
18 | })
19 | .catch(err => {
20 | console.error(err);
21 | });
22 | } else {
23 | throw new Error('unknown format,