@onify/flow-extensions 1.1.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -5,23 +5,14 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.extendFn = extendFn;
7
7
  exports.extensions = extensions;
8
-
9
8
  var _cronParser = _interopRequireDefault(require("cron-parser"));
10
-
11
9
  var _IOProperties = _interopRequireDefault(require("./src/IOProperties"));
12
-
13
10
  var _IOForm = _interopRequireDefault(require("./src/IOForm"));
14
-
15
11
  var _Connector = _interopRequireDefault(require("./src/Connector"));
16
-
17
12
  var _ServiceExpression = _interopRequireDefault(require("./src/ServiceExpression"));
18
-
19
13
  var _IO = require("./src/IO");
20
-
21
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22
-
23
15
  const iso8601cycle = /^\s*(R\d+\/)?P\w+/i;
24
-
25
16
  class FormatError extends Error {
26
17
  constructor(elementId, err) {
27
18
  super(`<${elementId}> ${err.message}`);
@@ -30,33 +21,28 @@ class FormatError extends Error {
30
21
  statusCode: 500
31
22
  };
32
23
  }
33
-
34
24
  }
35
-
36
25
  function extensions(element, context) {
37
26
  if (element.type === 'bpmn:Process') return new OnifyProcessExtensions(element, context);
38
27
  return new OnifyElementExtensions(element, context);
39
28
  }
40
-
41
29
  class OnifyProcessExtensions {
42
30
  constructor(bp, context) {
43
31
  this.process = bp;
44
32
  this.context = context;
45
33
  this.extensions = getExtensions(bp, context);
46
-
47
34
  this._activate();
48
35
  }
49
-
50
36
  _activate() {
51
37
  const bp = this.process;
52
38
  bp.on('process.enter', elementApi => {
53
39
  try {
54
40
  const result = this._onEnter(elementApi);
55
-
56
41
  const environment = elementApi.environment;
57
42
  environment.assignVariables(result);
58
43
  } catch (err) {
59
- elementApi.broker.publish('event', 'process.error', { ...elementApi.content,
44
+ elementApi.broker.publish('event', 'process.error', {
45
+ ...elementApi.content,
60
46
  error: new FormatError(bp.id, err)
61
47
  }, {
62
48
  mandatory: true,
@@ -67,7 +53,6 @@ class OnifyProcessExtensions {
67
53
  consumerTag: '_onify-extension-on-enter'
68
54
  });
69
55
  }
70
-
71
56
  _onEnter(elementApi) {
72
57
  const {
73
58
  format,
@@ -76,17 +61,13 @@ class OnifyProcessExtensions {
76
61
  const result = {};
77
62
  Object.assign(result, format.resolve(elementApi));
78
63
  Object.assign(elementApi.content, result);
79
-
80
64
  if (properties) {
81
65
  Object.assign(result, properties.resolve(elementApi));
82
66
  Object.assign(elementApi.content, result);
83
67
  }
84
-
85
68
  return result;
86
69
  }
87
-
88
70
  }
89
-
90
71
  class OnifyElementExtensions {
91
72
  constructor(activity, context) {
92
73
  this.activity = activity;
@@ -94,43 +75,28 @@ class OnifyElementExtensions {
94
75
  const {
95
76
  Service
96
77
  } = this.extensions = getExtensions(activity, context);
97
-
98
78
  if (Service) {
99
79
  activity.behaviour.Service = Service;
100
80
  }
101
81
  }
102
-
103
- activate() {
82
+ activate(message) {
104
83
  const activity = this.activity;
105
84
  const broker = activity.broker;
106
85
  const formatQ = activity.broker.getQueue('format-run-q');
107
- activity.on('enter', async elementApi => {
108
- formatQ.queueMessage({
109
- routingKey: 'run.enter.format'
110
- }, {
111
- endRoutingKey: 'run.enter.complete'
86
+ if (message.fields.redelivered && message.fields.routingKey === 'run.start') {
87
+ activity.on('start', elementApi => {
88
+ this._formatOnEnter(broker, formatQ, elementApi);
112
89
  }, {
113
- persistent: false
90
+ consumerTag: '_onify-extension-on-enter'
114
91
  });
115
-
116
- try {
117
- var format = await this._onEnter(elementApi);
118
- } catch (err) {
119
- return broker.publish('format', 'run.enter.error', {
120
- error: err
121
- }, {
122
- persistent: false
123
- });
124
- }
125
-
126
- broker.publish('format', 'run.enter.complete', format, {
127
- persistent: false
92
+ } else {
93
+ activity.on('enter', elementApi => {
94
+ this._formatOnEnter(broker, formatQ, elementApi);
95
+ }, {
96
+ consumerTag: '_onify-extension-on-enter'
128
97
  });
129
- }, {
130
- consumerTag: '_onify-extension-on-enter'
131
- });
98
+ }
132
99
  activity.on('activity.execution.completed', async elementApi => {
133
- if (elementApi.fields.redelivered) return;
134
100
  formatQ.queueMessage({
135
101
  routingKey: 'run.end.format'
136
102
  }, {
@@ -138,7 +104,6 @@ class OnifyElementExtensions {
138
104
  }, {
139
105
  persistent: false
140
106
  });
141
-
142
107
  try {
143
108
  var format = await this._onExecuted(elementApi);
144
109
  } catch (err) {
@@ -148,8 +113,8 @@ class OnifyElementExtensions {
148
113
  persistent: false
149
114
  });
150
115
  }
151
-
152
- broker.publish('format', 'run.end.complete', { ...format
116
+ broker.publish('format', 'run.end.complete', {
117
+ ...format
153
118
  }, {
154
119
  persistent: false
155
120
  });
@@ -157,13 +122,32 @@ class OnifyElementExtensions {
157
122
  consumerTag: '_onify-extension-on-executed'
158
123
  });
159
124
  }
160
-
161
125
  deactivate() {
162
126
  const broker = this.activity.broker;
163
127
  broker.cancel('_onify-extension-on-enter');
164
128
  broker.cancel('_onify-extension-on-executed');
165
129
  }
166
-
130
+ async _formatOnEnter(broker, formatQ, elementApi) {
131
+ formatQ.queueMessage({
132
+ routingKey: 'run.enter.format'
133
+ }, {
134
+ endRoutingKey: 'run.enter.complete'
135
+ }, {
136
+ persistent: false
137
+ });
138
+ try {
139
+ var format = await this._onEnter(elementApi);
140
+ } catch (err) {
141
+ return broker.publish('format', 'run.enter.error', {
142
+ error: err
143
+ }, {
144
+ persistent: false
145
+ });
146
+ }
147
+ broker.publish('format', 'run.enter.complete', format, {
148
+ persistent: false
149
+ });
150
+ }
167
151
  async _onEnter(elementApi) {
168
152
  const {
169
153
  format,
@@ -174,47 +158,38 @@ class OnifyElementExtensions {
174
158
  const result = {};
175
159
  Object.assign(result, format.resolve(elementApi));
176
160
  Object.assign(elementApi.content, result);
177
-
178
161
  if (properties) {
179
162
  Object.assign(result, {
180
163
  properties: properties.resolve(elementApi)
181
164
  });
182
165
  Object.assign(elementApi.content, result);
183
166
  }
184
-
185
167
  if (io) {
186
- var _io$input, _io$output;
187
-
188
- if ((_io$input = io.input) !== null && _io$input !== void 0 && _io$input.length) {
168
+ if (io.input?.length) {
189
169
  const input = await io.getInput(this.activity, elementApi);
190
170
  Object.assign(result, {
191
171
  input
192
172
  });
193
173
  Object.assign(elementApi.content, result);
194
174
  }
195
-
196
- if ((_io$output = io.output) !== null && _io$output !== void 0 && _io$output.length) {
175
+ if (io.output?.length) {
197
176
  result.assignToOutput = true;
198
177
  }
199
178
  }
200
-
201
179
  if (form) {
202
180
  Object.assign(result, {
203
181
  form: form.resolve(elementApi)
204
182
  });
205
183
  }
206
-
207
184
  return result;
208
185
  }
209
-
210
186
  async _onExecuted(elementApi) {
211
187
  const {
212
188
  properties,
213
189
  io
214
190
  } = this.extensions;
215
191
  const result = {};
216
-
217
- if (io !== null && io !== void 0 && io.output.length) {
192
+ if (io?.output.length) {
218
193
  const output = await io.getOutput(this.activity, elementApi);
219
194
  Object.assign(result, {
220
195
  output
@@ -223,7 +198,6 @@ class OnifyElementExtensions {
223
198
  output
224
199
  });
225
200
  }
226
-
227
201
  if (properties) {
228
202
  const props = properties.resolve(elementApi);
229
203
  Object.assign(result, {
@@ -233,50 +207,39 @@ class OnifyElementExtensions {
233
207
  properties: props
234
208
  });
235
209
  }
236
-
237
210
  const {
238
211
  output,
239
212
  assignToOutput,
240
213
  resultVariable
241
214
  } = elementApi.content;
242
215
  if (output === undefined || output === null) return result;
243
-
244
216
  if (assignToOutput && typeof output === 'object') {
245
217
  Object.assign(this.activity.environment.output, output);
246
218
  } else if (resultVariable) {
247
219
  elementApi.environment.output[resultVariable] = output;
248
220
  }
249
-
250
221
  return result;
251
222
  }
252
-
253
223
  }
254
-
255
224
  function getExtensions(element, context) {
256
- var _element$behaviour$ex, _ext$values, _ext$fields;
257
-
258
225
  const result = {
259
226
  format: element.type === 'bpmn:Process' ? new FormatProcess(element) : new FormatActivity(element)
260
227
  };
261
228
  const expression = element.behaviour.expression;
262
229
  if (expression) result.Service = _ServiceExpression.default;
263
- const extensions = (_element$behaviour$ex = element.behaviour.extensionElements) === null || _element$behaviour$ex === void 0 ? void 0 : _element$behaviour$ex.values;
230
+ const extensions = element.behaviour.extensionElements?.values;
264
231
  if (!extensions) return result;
265
-
266
232
  for (const ext of extensions) {
267
233
  switch (ext.$type) {
268
234
  case 'camunda:Properties':
269
- if ((_ext$values = ext.values) !== null && _ext$values !== void 0 && _ext$values.length) result.properties = new _IOProperties.default(element, ext);
235
+ if (ext.values?.length) result.properties = new _IOProperties.default(element, ext);
270
236
  break;
271
-
272
237
  case 'camunda:InputOutput':
273
238
  result.io = new _IO.InputOutput(element.id, ext, context);
274
239
  break;
275
-
276
240
  case 'camunda:FormData':
277
- if ((_ext$fields = ext.fields) !== null && _ext$fields !== void 0 && _ext$fields.length) result.form = new _IOForm.default(element, ext);
241
+ if (ext.fields?.length) result.form = new _IOForm.default(element, ext);
278
242
  break;
279
-
280
243
  case 'camunda:Connector':
281
244
  {
282
245
  const {
@@ -289,16 +252,13 @@ function getExtensions(element, context) {
289
252
  }
290
253
  }
291
254
  }
292
-
293
255
  return result;
294
256
  }
295
-
296
257
  class FormatActivity {
297
258
  constructor(activity) {
298
259
  this.activity = activity;
299
260
  this.resultVariable = activity.behaviour.resultVariable || '_' + activity.id;
300
261
  let timeCycles;
301
-
302
262
  if (activity.eventDefinitions) {
303
263
  for (const ed of activity.eventDefinitions.filter(e => e.type === 'bpmn:TimerEventDefinition')) {
304
264
  if (!('timeCycle' in ed)) continue;
@@ -306,13 +266,9 @@ class FormatActivity {
306
266
  timeCycles.push(ed.timeCycle);
307
267
  }
308
268
  }
309
-
310
269
  this.timeCycles = timeCycles;
311
270
  }
312
-
313
271
  resolve(elementApi) {
314
- var _documentation$, _user, _groups;
315
-
316
272
  let user, groups, assigneeValue, description;
317
273
  const activity = this.activity;
318
274
  const {
@@ -325,30 +281,26 @@ class FormatActivity {
325
281
  if (candidateUsers) user = resolveAndSplit(elementApi, candidateUsers);
326
282
  if (candidateGroups) groups = resolveAndSplit(elementApi, candidateGroups);
327
283
  if (assignee) assigneeValue = elementApi.resolveExpression(assignee);
328
- if (documentation) description = (_documentation$ = documentation[0]) === null || _documentation$ === void 0 ? void 0 : _documentation$.text;
284
+ if (documentation) description = documentation[0]?.text;
329
285
  let expireAt;
330
286
  let timeCycles = this.timeCycles;
331
-
332
287
  if (timeCycles) {
333
288
  for (const cycle of timeCycles) {
334
289
  const cron = elementApi.resolveExpression(cycle);
335
290
  if (!cron || iso8601cycle.test(cron)) continue;
336
-
337
291
  const expireAtDt = _cronParser.default.parseExpression(cron).next().toDate();
338
-
339
292
  if (!expireAt || expireAtDt < expireAt) expireAt = expireAtDt;
340
293
  }
341
294
  }
342
-
343
295
  return {
344
296
  resultVariable: this.resultVariable,
345
297
  ...(scheduledStart && activity.parent.type === 'bpmn:Process' && {
346
298
  scheduledStart
347
299
  }),
348
- ...(((_user = user) === null || _user === void 0 ? void 0 : _user.length) && {
300
+ ...(user?.length && {
349
301
  candidateUsers: user
350
302
  }),
351
- ...(((_groups = groups) === null || _groups === void 0 ? void 0 : _groups.length) && {
303
+ ...(groups?.length && {
352
304
  candidateGroups: groups
353
305
  }),
354
306
  ...(!elementApi.content.description && description && {
@@ -362,17 +314,12 @@ class FormatActivity {
362
314
  })
363
315
  };
364
316
  }
365
-
366
317
  }
367
-
368
318
  class FormatProcess {
369
319
  constructor(bp) {
370
320
  this.process = bp;
371
321
  }
372
-
373
322
  resolve(elementApi) {
374
- var _documentation$2, _user2, _groups2;
375
-
376
323
  let user, groups, description;
377
324
  const bp = this.process;
378
325
  const {
@@ -382,13 +329,13 @@ class FormatProcess {
382
329
  } = bp.behaviour;
383
330
  if (candidateStarterUsers) user = resolveAndSplit(elementApi, candidateStarterUsers);
384
331
  if (candidateStarterGroups) groups = resolveAndSplit(elementApi, candidateStarterGroups);
385
- if (documentation) description = (_documentation$2 = documentation[0]) === null || _documentation$2 === void 0 ? void 0 : _documentation$2.text;
332
+ if (documentation) description = documentation[0]?.text;
386
333
  return {
387
334
  resultVariable: this.resultVariable,
388
- ...(((_user2 = user) === null || _user2 === void 0 ? void 0 : _user2.length) && {
335
+ ...(user?.length && {
389
336
  candidateStarterUsers: user
390
337
  }),
391
- ...(((_groups2 = groups) === null || _groups2 === void 0 ? void 0 : _groups2.length) && {
338
+ ...(groups?.length && {
392
339
  candidateStarterGroups: groups
393
340
  }),
394
341
  ...(!elementApi.content.description && description && {
@@ -396,9 +343,7 @@ class FormatProcess {
396
343
  })
397
344
  };
398
345
  }
399
-
400
346
  }
401
-
402
347
  function resolveAndSplit(elementApi, str) {
403
348
  if (Array.isArray(str)) return str.filter(Boolean);
404
349
  if (typeof str !== 'string') return;
@@ -407,10 +352,7 @@ function resolveAndSplit(elementApi, str) {
407
352
  if (typeof resolved !== 'string') return;
408
353
  return resolved.split(',').map(g => g.trim && g.trim().toLowerCase()).filter(Boolean);
409
354
  }
410
-
411
355
  function extendFn(behaviour, context) {
412
- var _behaviour$extensionE;
413
-
414
356
  if (behaviour.$type === 'bpmn:StartEvent' && behaviour.eventDefinitions) {
415
357
  const timer = behaviour.eventDefinitions.find(({
416
358
  type,
@@ -420,21 +362,18 @@ function extendFn(behaviour, context) {
420
362
  scheduledStart: timer.behaviour.timeCycle
421
363
  });
422
364
  }
423
-
424
- if (!Array.isArray((_behaviour$extensionE = behaviour.extensionElements) === null || _behaviour$extensionE === void 0 ? void 0 : _behaviour$extensionE.values)) return;
365
+ if (!Array.isArray(behaviour.extensionElements?.values)) return;
425
366
  const inputOutput = behaviour.extensionElements.values.find(el => el.$type === 'camunda:InputOutput');
426
367
  const connector = behaviour.extensionElements.values.find(el => el.$type === 'camunda:Connector');
427
368
  if (inputOutput) registerIOScripts(behaviour.id, context, inputOutput.$type, inputOutput);
428
369
  if (connector) registerIOScripts(behaviour.id, context, connector.$type, connector.inputOutput);
429
370
  }
430
-
431
371
  function registerIOScripts(parentId, context, type, ioBehaviour) {
432
372
  if (!ioBehaviour) return;
433
373
  const {
434
374
  inputParameters = [],
435
375
  outputParameters = []
436
376
  } = ioBehaviour;
437
-
438
377
  for (const {
439
378
  $type,
440
379
  name,
@@ -4,9 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = Connector;
7
-
8
7
  var _Errors = require("./Errors");
9
-
10
8
  function Connector(connectorId, io, activity, executionMessage) {
11
9
  if (!(this instanceof Connector)) return new Connector(connectorId, io, activity, executionMessage);
12
10
  this.connectorId = connectorId;
@@ -14,7 +12,6 @@ function Connector(connectorId, io, activity, executionMessage) {
14
12
  this.activity = activity;
15
13
  this.executionMessage = executionMessage;
16
14
  }
17
-
18
15
  Connector.prototype.execute = async function execute(...args) {
19
16
  const callback = args.pop();
20
17
  args.push(formatCallback);
@@ -25,20 +22,18 @@ Connector.prototype.execute = async function execute(...args) {
25
22
  const executionMessage = this.executionMessage;
26
23
  const serviceFunction = environment.services[connectorId];
27
24
  if (!serviceFunction) return callback(new _Errors.NotImplemented(connectorId));
28
-
29
25
  try {
30
26
  const input = io && (await io.getInput(activity, executionMessage));
31
27
  await serviceFunction.call(activity, input, ...args);
32
28
  } catch (err) {
33
29
  return callback(err);
34
30
  }
35
-
36
31
  async function formatCallback(serviceErr, result) {
37
32
  if (serviceErr) return callback(serviceErr);
38
- if (!(io !== null && io !== void 0 && io.output.length)) return callback(null, result);
39
-
33
+ if (!io?.output.length) return callback(null, result);
40
34
  try {
41
- const formattedResult = await io.getOutput(activity, { ...executionMessage,
35
+ const formattedResult = await io.getOutput(activity, {
36
+ ...executionMessage,
42
37
  ...result
43
38
  });
44
39
  return callback(null, formattedResult);
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.NotImplemented = void 0;
7
-
8
7
  class NotImplemented extends Error {
9
8
  constructor(serviceId) {
10
9
  super(`${serviceId} service function not found`);
@@ -13,7 +12,5 @@ class NotImplemented extends Error {
13
12
  statusCode: 501
14
13
  };
15
14
  }
16
-
17
15
  }
18
-
19
16
  exports.NotImplemented = NotImplemented;
@@ -6,16 +6,11 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.FlowScripts = FlowScripts;
7
7
  exports.JavaScript = JavaScript;
8
8
  exports.JavaScriptResource = JavaScriptResource;
9
-
10
9
  var _path = require("path");
11
-
12
10
  var _fs = require("fs");
13
-
14
11
  var _vm = require("vm");
15
-
16
12
  const kSyntaxError = Symbol.for('syntax error');
17
13
  const kResources = Symbol.for('resources base');
18
-
19
14
  class FlowScriptError extends Error {
20
15
  constructor(fromErr) {
21
16
  super(fromErr.message);
@@ -25,22 +20,17 @@ class FlowScriptError extends Error {
25
20
  get() {
26
21
  return fromErr.stack && fromErr.stack.split('\n').slice(0, 7).join('\n');
27
22
  }
28
-
29
23
  });
30
24
  Object.defineProperty(this, 'code', {
31
25
  get() {
32
26
  return 'EFLOW_SCRIPT';
33
27
  }
34
-
35
28
  });
36
29
  }
37
-
38
30
  toString() {
39
31
  return '[FlowScriptError] ' + this.message + '\n' + this.stack;
40
32
  }
41
-
42
33
  }
43
-
44
34
  class FlowSyntaxError extends Error {
45
35
  constructor(fromErr) {
46
36
  super(fromErr.message);
@@ -50,22 +40,17 @@ class FlowSyntaxError extends Error {
50
40
  get() {
51
41
  return fromErr.stack && fromErr.stack.split('\n').slice(0, 6).join('\n');
52
42
  }
53
-
54
43
  });
55
44
  Object.defineProperty(this, 'code', {
56
45
  get() {
57
46
  return 'EFLOW_SCRIPT';
58
47
  }
59
-
60
48
  });
61
49
  }
62
-
63
50
  toString() {
64
51
  return '[FlowSyntaxError] ' + this.message + '\n' + this.stack;
65
52
  }
66
-
67
53
  }
68
-
69
54
  function FlowScripts(flowName, resourceBase, runContext, timeout = 60000) {
70
55
  this._name = flowName;
71
56
  this._scripts = {};
@@ -73,14 +58,12 @@ function FlowScripts(flowName, resourceBase, runContext, timeout = 60000) {
73
58
  this._runContext = runContext;
74
59
  this[kResources] = resourceBase;
75
60
  }
76
-
77
61
  FlowScripts.prototype.register = function register({
78
62
  id,
79
63
  type,
80
64
  behaviour
81
65
  }) {
82
66
  let language, scriptBody, resource;
83
-
84
67
  switch (type) {
85
68
  case 'bpmn:SequenceFlow':
86
69
  {
@@ -90,7 +73,6 @@ FlowScripts.prototype.register = function register({
90
73
  resource = behaviour.conditionExpression.resource;
91
74
  break;
92
75
  }
93
-
94
76
  default:
95
77
  {
96
78
  language = behaviour.scriptFormat;
@@ -98,13 +80,11 @@ FlowScripts.prototype.register = function register({
98
80
  resource = behaviour.resource;
99
81
  }
100
82
  }
101
-
102
83
  if (!language) language = 'javascript';
103
84
  if (!['js', 'javascript'].includes(language.toLowerCase().trim())) return;
104
85
  language = 'javascript';
105
86
  const name = this._name;
106
87
  const filename = `${name}/${type}/${id}`;
107
-
108
88
  if (scriptBody) {
109
89
  this._scripts[id] = new JavaScript(name, scriptBody, this._runContext, {
110
90
  filename,
@@ -117,37 +97,33 @@ FlowScripts.prototype.register = function register({
117
97
  });
118
98
  }
119
99
  };
120
-
121
100
  FlowScripts.prototype.getScript = function getScript(scriptType, {
122
101
  id
123
102
  }) {
124
103
  return this._scripts[id];
125
104
  };
126
-
127
105
  function JavaScript(flowName, scriptBody, runContext, options) {
128
106
  this.flowName = flowName;
129
107
  this._runContext = runContext;
130
108
  this.timeout = options && options.timeout;
131
-
132
109
  try {
133
110
  this.script = new _vm.Script(scriptBody, options);
134
111
  } catch (err) {
135
112
  this[kSyntaxError] = new FlowSyntaxError(err);
136
113
  }
137
114
  }
138
-
139
115
  JavaScript.prototype.execute = async function execute(executionContext, callback) {
140
116
  let callbackCalled;
141
117
  const syntaxError = this[kSyntaxError];
142
118
  if (syntaxError) return next(syntaxError);
143
-
144
119
  try {
145
- await this.script.runInNewContext({ ...executionContext,
120
+ await this.script.runInNewContext({
121
+ ...executionContext,
146
122
  Date,
147
123
  console: {
148
124
  log: console.log // eslint-disable-line no-console
149
-
150
125
  },
126
+
151
127
  Buffer: {
152
128
  from: Buffer.from
153
129
  },
@@ -160,15 +136,13 @@ JavaScript.prototype.execute = async function execute(executionContext, callback
160
136
  } catch (err) {
161
137
  return next(new FlowScriptError(err));
162
138
  }
163
-
164
- async function next(err, ...args) {
139
+ function next(err, ...args) {
165
140
  if (callbackCalled) return;
166
141
  callbackCalled = true;
167
142
  if (err) return callback(err);
168
143
  callback(null, ...args);
169
144
  }
170
145
  };
171
-
172
146
  function JavaScriptResource(flowName, resource, resourceBase, runContext, options) {
173
147
  this.flowName = flowName;
174
148
  this.resource = resource;
@@ -176,7 +150,6 @@ function JavaScriptResource(flowName, resource, resourceBase, runContext, option
176
150
  this._runContext = runContext;
177
151
  this[kResources] = resourceBase;
178
152
  }
179
-
180
153
  JavaScriptResource.prototype.execute = async function execute(executionContext, callback) {
181
154
  try {
182
155
  var scriptBody = await _fs.promises.readFile((0, _path.join)(this[kResources], executionContext.resolveExpression(this.resource))); // eslint-disable-line no-var
@@ -186,8 +159,8 @@ JavaScriptResource.prototype.execute = async function execute(executionContext,
186
159
  } = this.options;
187
160
  return callback(new Error(`${filename}: script resource ${this.resource} not found`));
188
161
  }
189
-
190
- const script = new JavaScript(this.flowName, scriptBody, this._runContext, { ...this.options,
162
+ const script = new JavaScript(this.flowName, scriptBody, this._runContext, {
163
+ ...this.options,
191
164
  filename: this.resource
192
165
  });
193
166
  return script.execute(executionContext, callback);
package/dist/src/IO.js CHANGED
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.InputOutput = exports.IOScript = exports.IOMap = exports.IOList = exports.IOBase = void 0;
7
-
8
7
  class InputOutput {
9
8
  constructor(parentId, behaviour, context) {
10
9
  this.parentId = parentId;
@@ -16,40 +15,33 @@ class InputOutput {
16
15
  this.input = this._map(parentId, inputParameters, 'input', context);
17
16
  this.output = this._map(parentId, outputParameters, 'output', context);
18
17
  }
19
-
20
18
  async getInput(activity, executionMessage) {
21
19
  const input = this.input;
22
20
  const values = await Promise.all(input.map(parm => parm.getValue(activity, executionMessage)));
23
21
  return values.reduce((result, parm) => Object.assign(result, parm), {});
24
22
  }
25
-
26
23
  async getOutput(activity, executionMessage) {
27
24
  const output = this.output;
28
25
  const values = await Promise.all(output.map(parm => parm.getValue(activity, executionMessage)));
29
26
  return values.reduce((result, parm) => Object.assign(result, parm), {});
30
27
  }
31
-
32
28
  _map(parentId, list, ioType, context) {
33
29
  const mapped = [];
34
30
  if (!list) return mapped;
35
-
36
31
  for (const parm of list) {
37
32
  const definition = parm.definition;
38
33
  const type = definition && definition.$type;
39
-
40
34
  switch (type) {
41
35
  case 'camunda:Map':
42
36
  {
43
37
  mapped.push(new IOMap(parm));
44
38
  break;
45
39
  }
46
-
47
40
  case 'camunda:List':
48
41
  {
49
42
  mapped.push(new IOList(parm));
50
43
  break;
51
44
  }
52
-
53
45
  case 'camunda:Script':
54
46
  {
55
47
  const id = `${parentId}/${ioType}/${type}/${parm.name}`;
@@ -75,43 +67,33 @@ class InputOutput {
75
67
  mapped.push(new IOScript(parm, id));
76
68
  break;
77
69
  }
78
-
79
70
  default:
80
71
  {
81
72
  mapped.push(new IOBase(parm));
82
73
  }
83
74
  }
84
75
  }
85
-
86
76
  return mapped;
87
77
  }
88
-
89
78
  }
90
-
91
79
  exports.InputOutput = InputOutput;
92
-
93
80
  class IOBase {
94
81
  constructor(parm) {
95
82
  this.name = parm.name;
96
83
  this.type = parm.definition && parm.definition.$type || 'string';
97
84
  this.behaviour = parm;
98
85
  }
99
-
100
86
  getValue(activity, executionMessage) {
101
87
  return {
102
88
  [this.name]: activity.environment.resolveExpression(this.behaviour.value, executionMessage)
103
89
  };
104
90
  }
105
-
106
91
  }
107
-
108
92
  exports.IOBase = IOBase;
109
-
110
93
  class IOMap extends IOBase {
111
94
  constructor(parm) {
112
95
  super(parm);
113
96
  }
114
-
115
97
  getValue(activity, executionMessage) {
116
98
  const name = this.name;
117
99
  const entries = this.behaviour.definition.entries;
@@ -120,18 +102,15 @@ class IOMap extends IOBase {
120
102
  };
121
103
  const environment = activity.environment;
122
104
  const result = {};
123
-
124
105
  for (const {
125
106
  key,
126
107
  value
127
108
  } of entries) {
128
109
  if (!key) continue;
129
110
  const val = environment.resolveExpression(value, executionMessage);
130
-
131
111
  if (key in result) {
132
112
  if (val === undefined) continue;
133
113
  const current = result[key];
134
-
135
114
  if (Array.isArray(current)) {
136
115
  current.push(val);
137
116
  } else {
@@ -143,21 +122,16 @@ class IOMap extends IOBase {
143
122
  result[key] = val;
144
123
  }
145
124
  }
146
-
147
125
  return {
148
126
  [name]: result
149
127
  };
150
128
  }
151
-
152
129
  }
153
-
154
130
  exports.IOMap = IOMap;
155
-
156
131
  class IOList extends IOBase {
157
132
  constructor(parm) {
158
133
  super(parm);
159
134
  }
160
-
161
135
  getValue(activity, executionMessage) {
162
136
  const name = this.name;
163
137
  const items = this.behaviour.definition.items;
@@ -166,28 +140,22 @@ class IOList extends IOBase {
166
140
  [name]: result
167
141
  };
168
142
  const environment = activity.environment;
169
-
170
143
  for (const item of items) {
171
144
  const val = environment.resolveExpression(item.value, executionMessage);
172
145
  if (val !== undefined) result.push(val);
173
146
  }
174
-
175
147
  return {
176
148
  [name]: result
177
149
  };
178
150
  }
179
-
180
151
  }
181
-
182
152
  exports.IOList = IOList;
183
-
184
153
  class IOScript extends IOBase {
185
154
  constructor(parm, scriptId) {
186
155
  super(parm);
187
156
  this.id = scriptId;
188
157
  this.script = true;
189
158
  }
190
-
191
159
  getValue(activity, executionMessage) {
192
160
  const definition = this.behaviour.definition;
193
161
  const name = this.name;
@@ -221,12 +189,9 @@ class IOScript extends IOBase {
221
189
  });
222
190
  });
223
191
  });
224
-
225
192
  function resolveExpression(expression) {
226
193
  return environment.resolveExpression(expression, scope);
227
194
  }
228
195
  }
229
-
230
196
  }
231
-
232
197
  exports.IOScript = IOScript;
@@ -4,22 +4,18 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
-
8
7
  var _IOProperties = _interopRequireDefault(require("./IOProperties.js"));
9
-
10
8
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
-
12
9
  class IOForm {
13
10
  constructor(activity, behaviour) {
14
11
  this.activity = activity;
15
12
  this.behaviour = behaviour;
16
13
  }
17
-
18
14
  resolve(elementApi) {
19
15
  const form = {};
20
-
21
16
  for (const field of this.behaviour.fields) {
22
- const f = form[field.id] = { ...field,
17
+ const f = form[field.id] = {
18
+ ...field,
23
19
  ...(field.label && {
24
20
  defaultValue: elementApi.resolveExpression(field.label)
25
21
  }),
@@ -27,15 +23,11 @@ class IOForm {
27
23
  defaultValue: elementApi.resolveExpression(field.defaultValue)
28
24
  })
29
25
  };
30
-
31
26
  if (f.properties) {
32
27
  f.properties = new _IOProperties.default(this.activity, f.properties).resolve(elementApi);
33
28
  }
34
29
  }
35
-
36
30
  return form;
37
31
  }
38
-
39
32
  }
40
-
41
33
  exports.default = IOForm;
@@ -4,16 +4,13 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
-
8
7
  class IOProperties {
9
8
  constructor(activity, behaviour) {
10
9
  this.activity = activity;
11
10
  this.behaviour = behaviour;
12
11
  }
13
-
14
12
  resolve(elementApi) {
15
13
  const properties = {};
16
-
17
14
  for (const {
18
15
  id,
19
16
  name,
@@ -21,10 +18,7 @@ class IOProperties {
21
18
  } of this.behaviour.values) {
22
19
  properties[id || name] = elementApi.resolveExpression(value);
23
20
  }
24
-
25
21
  return properties;
26
22
  }
27
-
28
23
  }
29
-
30
24
  exports.default = IOProperties;
@@ -4,16 +4,13 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = ServiceExpression;
7
-
8
7
  var _Errors = require("./Errors");
9
-
10
8
  function ServiceExpression(activity) {
11
9
  if (!(this instanceof ServiceExpression)) return new ServiceExpression(activity);
12
10
  this.activity = activity;
13
11
  this.type = `${activity.type}:expression`;
14
12
  this.expression = activity.behaviour.expression;
15
13
  }
16
-
17
14
  ServiceExpression.prototype.execute = function execute(executionMessage, callback) {
18
15
  try {
19
16
  const expression = this.expression;
@@ -22,7 +19,6 @@ ServiceExpression.prototype.execute = function execute(executionMessage, callbac
22
19
  } catch (err) {
23
20
  return callback(err);
24
21
  }
25
-
26
22
  serviceFn.call(this.activity, executionMessage, (err, result) => {
27
23
  callback(err, result);
28
24
  });
package/index.js CHANGED
@@ -72,26 +72,22 @@ class OnifyElementExtensions {
72
72
  activity.behaviour.Service = Service;
73
73
  }
74
74
  }
75
- activate() {
75
+ activate(message) {
76
76
  const activity = this.activity;
77
77
  const broker = activity.broker;
78
78
  const formatQ = activity.broker.getQueue('format-run-q');
79
79
 
80
- activity.on('enter', async (elementApi) => {
81
- formatQ.queueMessage({routingKey: 'run.enter.format'}, {endRoutingKey: 'run.enter.complete'}, {persistent: false});
82
-
83
- try {
84
- var format = await this._onEnter(elementApi);
85
- } catch (err) {
86
- return broker.publish('format', 'run.enter.error', {error: err}, {persistent: false});
87
- }
88
-
89
- broker.publish('format', 'run.enter.complete', format, {persistent: false});
90
- }, {consumerTag: '_onify-extension-on-enter'});
80
+ if (message.fields.redelivered && message.fields.routingKey === 'run.start') {
81
+ activity.on('start', (elementApi) => {
82
+ this._formatOnEnter(broker, formatQ, elementApi);
83
+ }, {consumerTag: '_onify-extension-on-enter'});
84
+ } else {
85
+ activity.on('enter', (elementApi) => {
86
+ this._formatOnEnter(broker, formatQ, elementApi);
87
+ }, {consumerTag: '_onify-extension-on-enter'});
88
+ }
91
89
 
92
90
  activity.on('activity.execution.completed', async (elementApi) => {
93
- if (elementApi.fields.redelivered) return;
94
-
95
91
  formatQ.queueMessage({routingKey: 'run.end.format'}, {endRoutingKey: 'run.end.complete'}, {persistent: false});
96
92
 
97
93
  try {
@@ -108,6 +104,17 @@ class OnifyElementExtensions {
108
104
  broker.cancel('_onify-extension-on-enter');
109
105
  broker.cancel('_onify-extension-on-executed');
110
106
  }
107
+ async _formatOnEnter(broker, formatQ, elementApi) {
108
+ formatQ.queueMessage({routingKey: 'run.enter.format'}, {endRoutingKey: 'run.enter.complete'}, {persistent: false});
109
+
110
+ try {
111
+ var format = await this._onEnter(elementApi);
112
+ } catch (err) {
113
+ return broker.publish('format', 'run.enter.error', {error: err}, {persistent: false});
114
+ }
115
+
116
+ broker.publish('format', 'run.enter.complete', format, {persistent: false});
117
+ }
111
118
  async _onEnter(elementApi) {
112
119
  const {format, properties, io, form} = this.extensions;
113
120
 
@@ -178,7 +185,6 @@ function getExtensions(element, context) {
178
185
  const extensions = element.behaviour.extensionElements?.values;
179
186
  if (!extensions) return result;
180
187
 
181
-
182
188
  for (const ext of extensions) {
183
189
  switch (ext.$type) {
184
190
  case 'camunda:Properties':
@@ -270,7 +276,6 @@ class FormatProcess {
270
276
  candidateStarterGroups,
271
277
  } = bp.behaviour;
272
278
 
273
-
274
279
  if (candidateStarterUsers) user = resolveAndSplit(elementApi, candidateStarterUsers);
275
280
  if (candidateStarterGroups) groups = resolveAndSplit(elementApi, candidateStarterGroups);
276
281
  if (documentation) description = documentation[0]?.text;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onify/flow-extensions",
3
- "version": "1.1.0",
3
+ "version": "2.0.0",
4
4
  "description": "Onify Flow extensions",
5
5
  "module": "index.js",
6
6
  "main": "dist/index.js",
@@ -35,26 +35,26 @@
35
35
  "license": "MIT",
36
36
  "devDependencies": {
37
37
  "@aircall/expression-parser": "^1.0.4",
38
- "@babel/cli": "^7.18.6",
39
- "@babel/core": "^7.18.6",
40
- "@babel/preset-env": "^7.18.6",
41
- "@babel/register": "^7.18.6",
42
- "bpmn-elements": "^8.1.0",
43
- "bpmn-engine": "^14.1.0",
44
- "bpmn-moddle": "^7.1.2",
45
- "c8": "^7.11.3",
46
- "camunda-bpmn-moddle": "^6.1.2",
47
- "chai": "^4.3.6",
38
+ "@babel/cli": "^7.19.3",
39
+ "@babel/core": "^7.20.2",
40
+ "@babel/preset-env": "^7.20.2",
41
+ "@babel/register": "^7.18.9",
42
+ "bpmn-elements-8-1": "npm:bpmn-elements@8.1",
43
+ "bpmn-engine": "^15.1.0",
44
+ "bpmn-engine-14": "npm:bpmn-engine@14",
45
+ "bpmn-moddle": "^7.1.3",
46
+ "c8": "^7.12.0",
47
+ "camunda-bpmn-moddle": "^7.0.1",
48
+ "chai": "^4.3.7",
48
49
  "chronokinesis": "^3.1.2",
49
50
  "debug": "^4.3.4",
50
- "eslint": "^7.32.0",
51
- "mocha": "^10.0.0",
51
+ "eslint": "^8.27.0",
52
+ "mocha": "^10.1.0",
52
53
  "mocha-cakes-2": "^3.3.0",
53
- "moddle-context-serializer": "^2.1.0",
54
- "nock": "^13.2.8"
54
+ "moddle-context-serializer": "^2.1.0"
55
55
  },
56
56
  "dependencies": {
57
- "cron-parser": "^4.5.0"
57
+ "cron-parser": "^4.6.0"
58
58
  },
59
59
  "files": [
60
60
  "src",
package/CHANGELOG.md DELETED
@@ -1,21 +0,0 @@
1
- Changelog
2
- =========
3
-
4
- # 1.0.1
5
-
6
- - allow ISO8601 repeating interval and duration in timeCycle
7
-
8
- # 1.0.0
9
-
10
- - proper routing keys for end formatting
11
-
12
- # 0.1.0
13
-
14
- - catch errors when resolving service expression
15
- - test with bpmn-engine@14
16
-
17
- # 0.0.2
18
-
19
- - allow expressions in timeCycle
20
- - test with bpmn-engine@13
21
- - error message changed in node 16