@onify/flow-extensions 9.1.1 → 10.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,12 +7,18 @@ exports.OnifyTimerEventDefinition = void 0;
7
7
  var _croner = require("croner");
8
8
  var _bpmnElements = require("bpmn-elements");
9
9
  class OnifyTimerEventDefinition extends _bpmnElements.TimerEventDefinition {
10
- constructor(activity, def) {
11
- super(activity, def);
12
- Object.defineProperty(this, 'supports', {
13
- value: ['cron', 'iso8601']
14
- });
10
+ /**
11
+ * Supported timeCycle formats
12
+ * @returns {string[]}
13
+ */
14
+ get supports() {
15
+ return ['cron', 'iso8601'];
15
16
  }
17
+ /**
18
+ * @param {import('bpmn-elements').TimerType} timerType
19
+ * @param {string} value
20
+ * @returns {import('bpmn-elements').parsedTimer}
21
+ */
16
22
  parse(timerType, value) {
17
23
  if (timerType === 'timeCycle') {
18
24
  try {
@@ -29,7 +35,9 @@ class OnifyTimerEventDefinition extends _bpmnElements.TimerEventDefinition {
29
35
  } catch (err) {
30
36
  this.logger.error(`<${this.activity?.id}> failed to parse timeCycle: ${rangeError.message}`);
31
37
  this.logger.error(`<${this.activity?.id}> failed to parse timeCycle as cron: ${err.message}`);
32
- throw new RangeError(`Failed to parse timeCycle <${value?.substring(0, 255)}> as ISO 8601 interval or cron`);
38
+ throw new RangeError(`Failed to parse timeCycle <${value?.substring(0, 255)}> as ISO 8601 interval or cron`, {
39
+ cause: err
40
+ });
33
41
  }
34
42
  }
35
43
  return super.parse(timerType, value);
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = ServiceExpression;
6
+ exports.ServiceExpression = ServiceExpression;
7
7
  var _Errors = require("./Errors.js");
8
8
  function ServiceExpression(activity) {
9
9
  if (!(this instanceof ServiceExpression)) return new ServiceExpression(activity);
@@ -5,6 +5,9 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.FormatProcess = exports.FormatActivity = void 0;
7
7
  class FormatActivity {
8
+ /**
9
+ * @param {import('bpmn-elements').Activity} activity
10
+ */
8
11
  constructor(activity) {
9
12
  this.activity = activity;
10
13
  this.resultVariable = activity.behaviour.resultVariable;
@@ -18,7 +21,18 @@ class FormatActivity {
18
21
  }
19
22
  }
20
23
  this.timeCycles = timeCycles;
24
+ const {
25
+ documentation,
26
+ candidateUsers,
27
+ candidateGroups,
28
+ scheduledStart,
29
+ assignee
30
+ } = activity.behaviour;
31
+ this.hasFormatting = Boolean(this.resultVariable || candidateUsers || candidateGroups || assignee || documentation?.[0]?.text || scheduledStart && activity.parent?.type === 'bpmn:Process');
21
32
  }
33
+ /**
34
+ * @param {import('bpmn-elements').IApi<import('bpmn-elements').Activity>} elementApi
35
+ */
22
36
  resolve(elementApi) {
23
37
  let user, groups, assigneeValue, description;
24
38
  const activity = this.activity;
@@ -57,6 +71,9 @@ class FormatActivity {
57
71
  }
58
72
  exports.FormatActivity = FormatActivity;
59
73
  class FormatProcess {
74
+ /**
75
+ * @param {import('bpmn-elements').Process} bp
76
+ */
60
77
  constructor(bp) {
61
78
  this.process = bp;
62
79
  this._historyTTL = undefined;
@@ -64,6 +81,9 @@ class FormatProcess {
64
81
  this._historyTTL = bp.context.definitionContext.getTimersByElementId(bp.id).find(t => t.timer.type === 'historyTimeToLive');
65
82
  }
66
83
  }
84
+ /**
85
+ * @param {import('bpmn-elements').IApi<import('bpmn-elements').Process>} elementApi
86
+ */
67
87
  resolve(elementApi) {
68
88
  let user, groups, description;
69
89
  const bp = this.process;
@@ -91,6 +111,12 @@ class FormatProcess {
91
111
  };
92
112
  }
93
113
  }
114
+
115
+ /**
116
+ * @param {import('bpmn-elements').IApi<import('bpmn-elements').Activity>} elementApi
117
+ * @param {string} str
118
+ * @returns {string[] | undefined}
119
+ */
94
120
  exports.FormatProcess = FormatProcess;
95
121
  function resolveAndSplit(elementApi, str) {
96
122
  if (Array.isArray(str)) return str.filter(Boolean);
@@ -6,13 +6,29 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.getExtensions = getExtensions;
7
7
  var _formatters = require("./formatters.js");
8
8
  var _IO = require("./IO.js");
9
- var _Connector = _interopRequireDefault(require("./Connector.js"));
10
- var _ExecutionListeners = _interopRequireDefault(require("./ExecutionListeners.js"));
11
- var _IOForm = _interopRequireDefault(require("./IOForm.js"));
12
- var _IOProperties = _interopRequireDefault(require("./IOProperties.js"));
13
- var _ServiceExpression = _interopRequireDefault(require("./ServiceExpression.js"));
14
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
+ var _Connector = require("./Connector.js");
10
+ var _ExecutionListeners = require("./ExecutionListeners.js");
11
+ var _IOForm = require("./IOForm.js");
12
+ var _IOProperties = require("./IOProperties.js");
13
+ var _ServiceExpression = require("./ServiceExpression.js");
14
+ /**
15
+ * @typedef {object} OnifyExtensions assembled element extensions
16
+ * @property {FormatActivity | FormatProcess} [format] enter/end formatting
17
+ * @property {import('bpmn-elements').IActivityBehaviour} [Service] service factory
18
+ * @property {InputOutput} [io] camunda:InputOutput
19
+ * @property {IOProperties} [properties] camunda:Properties
20
+ * @property {IOForm} [form] camunda:FormData
21
+ * @property {ExecutionListeners} [listeners] camunda:ExecutionListener
22
+ */
23
+
24
+ /**
25
+ * Assemble extensions for an element
26
+ * @param {import('bpmn-elements').Activity | import('bpmn-elements').Process} element
27
+ * @param {import('bpmn-elements').ContextInstance} context
28
+ * @returns {OnifyExtensions}
29
+ */
15
30
  function getExtensions(element, context) {
31
+ /** @type {OnifyExtensions} */
16
32
  const result = {};
17
33
  switch (element.type) {
18
34
  case 'bpmn:SequenceFlow':
@@ -24,21 +40,22 @@ function getExtensions(element, context) {
24
40
  result.format = new _formatters.FormatActivity(element);
25
41
  }
26
42
  let listenerPosition = 0;
27
- const listeners = new _ExecutionListeners.default(element, context);
43
+ const listeners = new _ExecutionListeners.ExecutionListeners(element, context);
28
44
  const expression = element.behaviour.expression;
29
- if (expression) result.Service = _ServiceExpression.default;
45
+ if (expression) result.Service = _ServiceExpression.ServiceExpression;
30
46
  const extensions = element.behaviour.extensionElements?.values;
31
- if (extensions) {
47
+ if (Array.isArray(extensions)) {
32
48
  for (const ext of extensions) {
49
+ if (!ext) continue;
33
50
  switch (ext.$type) {
34
51
  case 'camunda:Properties':
35
- if (ext.values?.length) result.properties = new _IOProperties.default(element, ext);
52
+ if (ext.values?.length) result.properties = new _IOProperties.IOProperties(element, ext);
36
53
  break;
37
54
  case 'camunda:InputOutput':
38
55
  result.io = new _IO.InputOutput(element.id, ext, context);
39
56
  break;
40
57
  case 'camunda:FormData':
41
- if (ext.fields?.length) result.form = new _IOForm.default(element, ext);
58
+ if (ext.fields?.length) result.form = new _IOForm.IOForm(element, ext);
42
59
  break;
43
60
  case 'camunda:Connector':
44
61
  {
@@ -47,7 +64,7 @@ function getExtensions(element, context) {
47
64
  inputOutput
48
65
  } = ext;
49
66
  const io = inputOutput && new _IO.InputOutput(`${element.id}/${ext.$type.toLowerCase()}`, inputOutput, context);
50
- result.Service = _Connector.default.bind(_Connector.default, connectorId, io);
67
+ result.Service = _Connector.Connector.bind(_Connector.Connector, connectorId, io);
51
68
  break;
52
69
  }
53
70
  case 'camunda:ExecutionListener':
package/dist/index.js CHANGED
@@ -23,6 +23,12 @@ var _OnifyBoundaryEventExtensions = require("./OnifyBoundaryEventExtensions.js")
23
23
  var _OnifySubProcessExtensions = require("./OnifySubProcessExtensions.js");
24
24
  var _OnifySequenceFlow = require("./OnifySequenceFlow.js");
25
25
  var _OnifyTimerEventDefinition = require("./OnifyTimerEventDefinition.js");
26
+ /**
27
+ * Onify flow extensions factory, pass to the engine as `extensions: { onify: extensions }`
28
+ * @param {import('bpmn-elements').ElementBase} element
29
+ * @param {import('bpmn-elements').ContextInstance} context
30
+ * @returns {import('bpmn-elements').IExtension | undefined} undefined for an element without camunda extension data, letting bpmn-elements skip it (and e.g. attach its built-in `assignOutput` extension)
31
+ */
26
32
  function extensions(element, context) {
27
33
  switch (element.type) {
28
34
  case 'bpmn:Process':
@@ -34,18 +40,25 @@ function extensions(element, context) {
34
40
  case 'bpmn:BoundaryEvent':
35
41
  return new _OnifyBoundaryEventExtensions.OnifyBoundaryEventExtensions(element, context);
36
42
  default:
37
- return new _OnifyElementExtensions.OnifyElementExtensions(element, context);
43
+ {
44
+ const elementExtensions = new _OnifyElementExtensions.OnifyElementExtensions(element, context);
45
+ if (elementExtensions.isEmpty) return undefined;
46
+ return elementExtensions;
47
+ }
38
48
  }
39
49
  }
50
+
51
+ /**
52
+ * Extend function for moddle-context-serializer, registers scripts and timers at serialize time
53
+ * @param {import('bpmn-moddle').BaseElement & Record<string, any>} behaviour
54
+ * @param {import('moddle-context-serializer').ExtendContext} context
55
+ */
40
56
  function extendFn(behaviour, context) {
41
57
  switch (behaviour.$type) {
42
58
  case 'bpmn:StartEvent':
43
59
  {
44
- if (!behaviour.eventDefinitions) break;
45
- const timer = behaviour.eventDefinitions.find(({
46
- type,
47
- behaviour: edBehaviour
48
- }) => edBehaviour && type === 'bpmn:TimerEventDefinition');
60
+ if (!Array.isArray(behaviour.eventDefinitions)) break;
61
+ const timer = behaviour.eventDefinitions.find(ed => ed?.behaviour && ed.type === 'bpmn:TimerEventDefinition');
49
62
  if (timer && timer.behaviour.timeCycle) Object.assign(behaviour, {
50
63
  scheduledStart: timer.behaviour.timeCycle
51
64
  });
@@ -67,6 +80,7 @@ function extendFn(behaviour, context) {
67
80
  if (!Array.isArray(behaviour.extensionElements?.values)) return;
68
81
  let listener = 0;
69
82
  for (const extension of behaviour.extensionElements.values) {
83
+ if (!extension) continue;
70
84
  switch (extension.$type) {
71
85
  case 'camunda:InputOutput':
72
86
  registerIOScripts(behaviour.id, context, extension.$type, extension);
@@ -80,21 +94,26 @@ function extendFn(behaviour, context) {
80
94
  }
81
95
  }
82
96
  }
97
+
98
+ /**
99
+ * @param {string} parentId
100
+ * @param {import('bpmn-elements').ContextInstance} context
101
+ * @param {string} type
102
+ * @param {{ inputParameters?: any[], outputParameters?: any[], [x:string]: any }} ioBehaviour
103
+ */
83
104
  function registerIOScripts(parentId, context, type, ioBehaviour) {
84
105
  if (!ioBehaviour) return;
85
106
  const {
86
- inputParameters = [],
87
- outputParameters = []
107
+ inputParameters,
108
+ outputParameters
88
109
  } = ioBehaviour;
89
- for (const {
90
- $type,
91
- name,
92
- definition
93
- } of inputParameters.concat(outputParameters)) {
110
+ const parameters = [...(Array.isArray(inputParameters) ? inputParameters : []), ...(Array.isArray(outputParameters) ? outputParameters : [])];
111
+ for (const parm of parameters) {
112
+ const definition = parm?.definition;
94
113
  if (!definition) continue;
95
114
  if (definition.$type !== 'camunda:Script') continue;
96
- const ioType = `${type}/${$type}`;
97
- const filename = `${parentId}/${ioType}/${name}`;
115
+ const ioType = `${type}/${parm.$type}`;
116
+ const filename = `${parentId}/${ioType}/${parm.name}`;
98
117
  context.addScript(filename, {
99
118
  id: filename,
100
119
  scriptFormat: definition.scriptFormat,
@@ -108,6 +127,14 @@ function registerIOScripts(parentId, context, type, ioBehaviour) {
108
127
  });
109
128
  }
110
129
  }
130
+
131
+ /**
132
+ * @param {string} parentId script parent id
133
+ * @param {import('bpmn-elements').ContextInstance} context
134
+ * @param {string} type
135
+ * @param {{event:string, script?: {scriptFormat:string, value?:string, resource?:string, [x:string]: any}, [x:string]: any}} listener
136
+ * @param {Number} pos
137
+ */
111
138
  function registerListenerScript(parentId, context, type, listener, pos) {
112
139
  const {
113
140
  event,
@@ -127,6 +154,10 @@ function registerListenerScript(parentId, context, type, listener, pos) {
127
154
  })
128
155
  });
129
156
  }
157
+
158
+ /**
159
+ * @param {{id:string, $type:string, historyTimeToLive?:string, [x:string]: any}} behaviour
160
+ */
130
161
  function getHistoryTimeToLiveTimer(behaviour) {
131
162
  const {
132
163
  id,
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@onify/flow-extensions",
3
- "version": "9.1.1",
3
+ "version": "10.0.1",
4
4
  "description": "Onify Flow extensions",
5
5
  "type": "module",
6
6
  "module": "src/index.js",
7
7
  "main": "dist/index.js",
8
- "types": "./index.d.ts",
8
+ "types": "./types/index.d.ts",
9
9
  "sideEffects": false,
10
10
  "exports": {
11
11
  ".": {
@@ -21,10 +21,11 @@
21
21
  },
22
22
  "scripts": {
23
23
  "test": "mocha",
24
- "posttest": "npm run lint && npm run dist && texample",
24
+ "posttest": "npm run lint && npm run types && npm run dist && texample",
25
25
  "lint": "eslint . --cache && prettier . --check --cache",
26
- "prepare": "npm run dist",
26
+ "prepare": "npm run dist && npm run types",
27
27
  "dist": "babel src -d dist && babel test/helpers/FlowScripts.js -d dist",
28
+ "types": "dts-buddy types/index.d.ts -m @onify/flow-extensions:src/index.js -m @onify/flow-extensions/FlowScripts:test/helpers/FlowScripts.js",
28
29
  "test:lcov": "c8 -r lcov mocha && npm run lint",
29
30
  "cov:html": "c8 mocha && c8 report --reporter html"
30
31
  },
@@ -50,25 +51,33 @@
50
51
  "@babel/core": "^7.23.9",
51
52
  "@babel/preset-env": "^7.23.9",
52
53
  "@babel/register": "^7.23.7",
54
+ "@eslint/js": "^10.0.1",
55
+ "@types/node": "^26.2.0",
56
+ "bpmn-elements": "^18.0.22",
57
+ "bpmn-elements-17": "npm:bpmn-elements@^17",
53
58
  "bpmn-elements-8-1": "npm:bpmn-elements@8.1",
54
- "bpmn-engine": "^25.0.0",
55
- "bpmn-engine-14": "npm:bpmn-engine@14",
59
+ "bpmn-engine": "^26.0.0",
60
+ "bpmn-engine-14": "npm:bpmn-engine@^14",
61
+ "bpmn-engine-25": "npm:bpmn-engine@^25",
56
62
  "bpmn-moddle": "^9.0.1",
57
- "c8": "^10.1.2",
63
+ "c8": "^12.0.0",
58
64
  "camunda-bpmn-moddle": "^7.0.1",
59
65
  "chai": "^6.2.1",
60
- "chronokinesis": "^7.0.0",
66
+ "chronokinesis": "^8.0.0",
61
67
  "debug": "^4.3.4",
62
- "eslint": "^9.3.0",
68
+ "dts-buddy": "^0.8.3",
69
+ "eslint": "^10.5.0",
70
+ "globals": "^17.6.0",
63
71
  "mocha": "^11.0.1",
64
72
  "mocha-cakes-2": "^3.3.0",
65
- "moddle-context-serializer": "^4.1.1",
73
+ "moddle-context-serializer": "^6.0.1",
66
74
  "prettier": "^3.2.4",
67
- "texample": "^0.1.0"
75
+ "texample": "^1.0.2",
76
+ "typescript": "^6.0.3"
68
77
  },
69
78
  "peerDependencies": {
70
79
  "@0dep/piso": ">=2",
71
- "bpmn-elements": ">=14",
80
+ "bpmn-elements": ">=17",
72
81
  "croner": ">=9.0.0"
73
82
  },
74
83
  "files": [
package/src/Connector.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { NotImplemented } from './Errors.js';
2
2
 
3
- export default function Connector(connectorId, io, activity, executionMessage) {
3
+ export function Connector(connectorId, io, activity, executionMessage) {
4
4
  if (!(this instanceof Connector)) return new Connector(connectorId, io, activity, executionMessage);
5
5
  this.connectorId = connectorId;
6
6
  this.io = io;
@@ -1,4 +1,9 @@
1
1
  class Listener {
2
+ /**
3
+ * @param {import('bpmn-elements').Activity | import('bpmn-elements').SequenceFlow} activity
4
+ * @param {import('bpmn-elements').ContextInstance} context
5
+ * @param {{$type:string, event:string, [x:string]: any}} extension
6
+ */
2
7
  constructor(activity, context, extension) {
3
8
  this.activity = activity;
4
9
  this.environment = this.activity.environment;
@@ -7,10 +12,21 @@ class Listener {
7
12
  this.type = extension.$type;
8
13
  this.event = extension.event;
9
14
  }
10
- _getScope(message, extend) {
15
+ /**
16
+ * @param {import('bpmn-elements').IApi<any>} _api
17
+ * @returns {Promise<any>}
18
+ */
19
+ // eslint-disable-next-line no-unused-vars
20
+ execute(_api) {}
21
+ /**
22
+ * @internal
23
+ * @param {import('bpmn-elements').IApi<any>} api
24
+ * @param {Record<string, any>} [extend]
25
+ */
26
+ _getScope(api, extend) {
11
27
  const environment = this.environment;
12
28
 
13
- const { fields, content, properties } = message;
29
+ const { fields, content, properties } = api;
14
30
  const scope = {
15
31
  ...extend,
16
32
  type: this.type,
@@ -29,6 +45,12 @@ class Listener {
29
45
 
30
46
  return scope;
31
47
  }
48
+ /**
49
+ * @internal
50
+ * @param {import('bpmn-elements').Environment} environment
51
+ * @param {any} scope
52
+ * @returns {Record<string, any>}
53
+ */
32
54
  _getFields(environment, scope) {
33
55
  const fields = this.extension.fields;
34
56
  if (!fields?.length) return;
@@ -41,6 +63,12 @@ class Listener {
41
63
  }
42
64
 
43
65
  class ScriptListener extends Listener {
66
+ /**
67
+ * @param {import('bpmn-elements').Activity | import('bpmn-elements').SequenceFlow} activity
68
+ * @param {import('bpmn-elements').ContextInstance} context
69
+ * @param {{script: {$type:string, [x:string]: any}, [x:string]: any}} extension
70
+ * @param {Number} pos execution listener position
71
+ */
44
72
  constructor(activity, context, extension, pos) {
45
73
  super(activity, context, extension);
46
74
  const id = (this.id = `${activity.id}/${extension.script.$type}/${this.event}/${pos}`);
@@ -85,16 +113,22 @@ class ScriptListener extends Listener {
85
113
  }
86
114
 
87
115
  class ExpressionListener extends Listener {
88
- execute(message) {
89
- const scope = this._getScope(message);
90
- return { expression: this.environment.resolveExpression(this.extension.expression, scope) };
116
+ execute(api) {
117
+ const scope = this._getScope(api);
118
+ return Promise.resolve({ expression: this.environment.resolveExpression(this.extension.expression, scope) });
91
119
  }
92
120
  }
93
121
 
94
- export default class ExecutionListeners {
122
+ export class ExecutionListeners {
123
+ /**
124
+ *
125
+ * @param {import('bpmn-elements').Activity | import('bpmn-elements').SequenceFlow} activity
126
+ * @param {import('bpmn-elements').ContextInstance} context
127
+ */
95
128
  constructor(activity, context) {
96
129
  this.activity = activity;
97
130
  this.context = context;
131
+ /** @type {(ScriptListener | ExpressionListener)[]} */
98
132
  this.listeners = [];
99
133
  }
100
134
  get length() {
package/src/IO.js CHANGED
@@ -1,9 +1,17 @@
1
1
  export class IOBase {
2
2
  constructor(parm) {
3
+ /** @type {string} */
3
4
  this.name = parm.name;
5
+ /** @type {string} */
4
6
  this.type = (parm.definition && parm.definition.$type) || 'string';
7
+ /** @type {any} */
5
8
  this.behaviour = parm;
6
9
  }
10
+ /**
11
+ * @param {import('bpmn-elements').Activity} activity
12
+ * @param {import('bpmn-elements').ElementBrokerMessage} executionMessage
13
+ * @returns {Promise<{name: any}>}
14
+ */
7
15
  getValue(activity, executionMessage) {
8
16
  return {
9
17
  [this.name]: activity.environment.resolveExpression(this.behaviour.value, executionMessage),
@@ -12,9 +20,6 @@ export class IOBase {
12
20
  }
13
21
 
14
22
  class IOMap extends IOBase {
15
- constructor(parm) {
16
- super(parm);
17
- }
18
23
  getValue(activity, executionMessage) {
19
24
  const name = this.name;
20
25
  const entries = this.behaviour.definition.entries;
@@ -110,28 +115,52 @@ export class IOScript extends IOBase {
110
115
  }
111
116
 
112
117
  export class InputOutput {
118
+ /**
119
+ * @param {string} parentId
120
+ * @param {any} behaviour
121
+ * @param {import('bpmn-elements').ContextInstance} context
122
+ */
113
123
  constructor(parentId, behaviour, context) {
114
124
  this.parentId = parentId;
115
125
  this.context = context;
116
- const { inputParameters, outputParameters } = behaviour;
126
+ const { inputParameters, outputParameters } = behaviour ?? {};
117
127
  this.input = this._map(parentId, inputParameters, 'input', context);
118
128
  this.output = this._map(parentId, outputParameters, 'output', context);
119
129
  }
130
+ /**
131
+ * @param {import('bpmn-elements').Activity} activity
132
+ * @param {import('bpmn-elements').ElementBrokerMessage} executionMessage
133
+ * @returns {Promise<Record<string, any>}
134
+ */
120
135
  async getInput(activity, executionMessage) {
121
136
  const input = this.input;
122
137
  const values = await Promise.all(input.map((parm) => parm.getValue(activity, executionMessage)));
123
138
  return values.reduce((result, parm) => Object.assign(result, parm), {});
124
139
  }
140
+ /**
141
+ * @param {import('bpmn-elements').Activity} activity
142
+ * @param {import('bpmn-elements').ElementBrokerMessage} executionMessage
143
+ * @returns {Promise<Record<string, any>}
144
+ */
125
145
  async getOutput(activity, executionMessage) {
126
146
  const output = this.output;
127
147
  const values = await Promise.all(output.map((parm) => parm.getValue(activity, executionMessage)));
128
148
  return values.reduce((result, parm) => Object.assign(result, parm), {});
129
149
  }
150
+ /**
151
+ * @internal
152
+ * @param {string} parentId parent element id
153
+ * @param {any[]} list list of IO behaviours
154
+ * @param {string} ioType type of IO
155
+ * @param {import('bpmn-elements').ContextInstance} context
156
+ * @returns {IOBase[]}
157
+ */
130
158
  _map(parentId, list, ioType, context) {
131
159
  const mapped = [];
132
- if (!list) return mapped;
160
+ if (!Array.isArray(list)) return mapped;
133
161
 
134
162
  for (const parm of list) {
163
+ if (!parm) continue;
135
164
  const definition = parm.definition;
136
165
  const type = definition && definition.$type;
137
166
  switch (type) {
package/src/IOForm.js CHANGED
@@ -1,10 +1,14 @@
1
- import IOProperties from './IOProperties.js';
1
+ import { IOProperties } from './IOProperties.js';
2
2
 
3
- export default class IOForm {
3
+ export class IOForm {
4
4
  constructor(activity, behaviour) {
5
5
  this.activity = activity;
6
6
  this.behaviour = behaviour;
7
7
  }
8
+ /**
9
+ * @param {import('bpmn-elements').IApi<import('bpmn-elements').Activity>} elementApi
10
+ * @returns {Record<string, any>}
11
+ */
8
12
  resolve(elementApi) {
9
13
  const form = {};
10
14
  for (const field of this.behaviour.fields) {
@@ -1,8 +1,12 @@
1
- export default class IOProperties {
1
+ export class IOProperties {
2
2
  constructor(activity, behaviour) {
3
3
  this.activity = activity;
4
4
  this.behaviour = behaviour;
5
5
  }
6
+ /**
7
+ * @param {elementApi: import('bpmn-elements').IApi<any>} elementApi
8
+ * @returns {Record<string, any>}
9
+ */
6
10
  resolve(elementApi) {
7
11
  const properties = {};
8
12
 
@@ -1,28 +1,33 @@
1
1
  import { OnifyElementExtensions } from './OnifyElementExtensions.js';
2
2
 
3
3
  export class OnifyBoundaryEventExtensions extends OnifyElementExtensions {
4
+ #syncFormatOnEnter;
4
5
  constructor(activity, context) {
5
6
  super(activity, context);
6
- this._syncFormatOnEnter = this._syncFormatOnEnter.bind(this);
7
+ this.#syncFormatOnEnter = this._syncFormatOnEnter.bind(this);
7
8
  }
8
9
  activate(message) {
9
10
  const activity = this.activity;
10
11
  const formatQ = activity.broker.getQueue('format-run-q');
11
12
  const executionListeners = this.extensions.listeners;
12
13
 
13
- if (message.fields.redelivered && message.fields.routingKey === 'run.start') {
14
- activity.on('start', this._syncFormatOnEnter, { consumerTag: '_onify-extension-on-enter' });
15
- } else {
16
- activity.on('enter', this._syncFormatOnEnter, { consumerTag: '_onify-extension-on-enter' });
14
+ if (this._formatOnEnter) {
15
+ if (message.fields.redelivered && message.fields.routingKey === 'run.start') {
16
+ activity.on('start', this.#syncFormatOnEnter, { consumerTag: '_onify-extension-on-enter' });
17
+ } else {
18
+ activity.on('enter', this.#syncFormatOnEnter, { consumerTag: '_onify-extension-on-enter' });
19
+ }
17
20
  }
18
21
 
19
- activity.on(
20
- 'activity.execution.completed',
21
- (elementApi) => {
22
- return this._onExecutionCompleted(elementApi, formatQ);
23
- },
24
- { consumerTag: '_onify-extension-on-executed' }
25
- );
22
+ if (this._formatOnEnd) {
23
+ activity.on(
24
+ 'activity.execution.completed',
25
+ (elementApi) => {
26
+ return this._onExecutionCompleted(elementApi, formatQ);
27
+ },
28
+ { consumerTag: '_onify-extension-on-executed' }
29
+ );
30
+ }
26
31
 
27
32
  if (executionListeners?.onStart) {
28
33
  activity.on(
@@ -47,6 +52,11 @@ export class OnifyBoundaryEventExtensions extends OnifyElementExtensions {
47
52
  );
48
53
  }
49
54
  }
55
+ /**
56
+ * @internal
57
+ * @param {import('bpmn-elements').IApi<import('bpmn-elements').Activity>} elementApi
58
+ * @returns {void}
59
+ */
50
60
  _syncFormatOnEnter(elementApi) {
51
61
  try {
52
62
  var format = this._onEnterSync(elementApi);
@@ -56,6 +66,11 @@ export class OnifyBoundaryEventExtensions extends OnifyElementExtensions {
56
66
 
57
67
  elementApi.broker.publish('format', 'run.enter.complete', format, { persistent: false });
58
68
  }
69
+ /**
70
+ * @internal
71
+ * @param {import('bpmn-elements').IApi<import('bpmn-elements').Activity>} elementApi
72
+ * @returns {void}
73
+ */
59
74
  _onEnterSync(elementApi) {
60
75
  const { format, properties, io } = this.extensions;
61
76