@onify/flow-extensions 3.0.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/README.md +89 -0
- package/dist/index.js +15 -415
- package/dist/src/Connector.js +1 -1
- package/dist/src/Errors.js +12 -2
- package/dist/src/ExecutionListeners.js +11 -5
- package/dist/src/FlowScripts.js +1 -1
- package/dist/src/IO.js +75 -76
- package/dist/src/OnifyElementExtensions.js +224 -0
- package/dist/src/OnifyProcessExtensions.js +51 -0
- package/dist/src/OnifySequenceFlow.js +52 -0
- package/dist/src/ServiceExpression.js +1 -1
- package/dist/src/formatters.js +112 -0
- package/dist/src/getExtensions.js +62 -0
- package/index.js +8 -333
- package/package.json +13 -13
- package/src/Connector.js +1 -1
- package/src/Errors.js +8 -4
- package/src/ExecutionListeners.js +17 -11
- package/src/IO.js +66 -74
- package/src/OnifyElementExtensions.js +150 -0
- package/src/OnifyProcessExtensions.js +40 -0
- package/src/OnifySequenceFlow.js +45 -0
- package/src/ServiceExpression.js +1 -1
- package/src/formatters.js +97 -0
- package/src/getExtensions.js +57 -0
package/index.js
CHANGED
|
@@ -1,24 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import Connector from './src/Connector.js';
|
|
5
|
-
import ServiceExpression from './src/ServiceExpression.js';
|
|
6
|
-
import {InputOutput} from './src/IO.js';
|
|
7
|
-
import ExtensionListeners from './src/ExecutionListeners.js';
|
|
8
|
-
|
|
9
|
-
const iso8601cycle = /^\s*(R\d+\/)?P\w+/i;
|
|
10
|
-
|
|
11
|
-
class FormatError extends Error {
|
|
12
|
-
constructor(elementId, err) {
|
|
13
|
-
super(`<${elementId}> ${err.message}`);
|
|
14
|
-
this.code = 'EFLOW_FORMAT';
|
|
15
|
-
this.output = {statusCode: 500};
|
|
16
|
-
}
|
|
17
|
-
}
|
|
1
|
+
import {OnifyProcessExtensions} from './src/OnifyProcessExtensions.js';
|
|
2
|
+
import {OnifyElementExtensions} from './src/OnifyElementExtensions.js';
|
|
3
|
+
import {OnifySequenceFlow} from './src/OnifySequenceFlow.js';
|
|
18
4
|
|
|
19
5
|
export {
|
|
20
6
|
extensions,
|
|
21
7
|
extendFn,
|
|
8
|
+
OnifySequenceFlow,
|
|
22
9
|
};
|
|
23
10
|
|
|
24
11
|
function extensions(element, context) {
|
|
@@ -26,321 +13,6 @@ function extensions(element, context) {
|
|
|
26
13
|
return new OnifyElementExtensions(element, context);
|
|
27
14
|
}
|
|
28
15
|
|
|
29
|
-
class OnifyProcessExtensions {
|
|
30
|
-
constructor(bp, context) {
|
|
31
|
-
this.process = bp;
|
|
32
|
-
this.context = context;
|
|
33
|
-
this.extensions = getExtensions(bp, context);
|
|
34
|
-
this._activate();
|
|
35
|
-
}
|
|
36
|
-
_activate() {
|
|
37
|
-
const bp = this.process;
|
|
38
|
-
bp.on('process.enter', (elementApi) => {
|
|
39
|
-
try {
|
|
40
|
-
const result = this._onEnter(elementApi);
|
|
41
|
-
const environment = elementApi.environment;
|
|
42
|
-
environment.assignVariables(result);
|
|
43
|
-
} catch (err) {
|
|
44
|
-
elementApi.broker.publish('event', 'process.error', {
|
|
45
|
-
...elementApi.content,
|
|
46
|
-
error: new FormatError(bp.id, err)
|
|
47
|
-
}, {mandatory: true, type: 'error'});
|
|
48
|
-
}
|
|
49
|
-
}, {consumerTag: '_onify-extension-on-enter'});
|
|
50
|
-
}
|
|
51
|
-
_onEnter(elementApi) {
|
|
52
|
-
const {format, properties} = this.extensions;
|
|
53
|
-
const result = {};
|
|
54
|
-
|
|
55
|
-
Object.assign(result, format.resolve(elementApi));
|
|
56
|
-
Object.assign(elementApi.content, result);
|
|
57
|
-
|
|
58
|
-
if (properties) {
|
|
59
|
-
Object.assign(result, properties.resolve(elementApi));
|
|
60
|
-
Object.assign(elementApi.content, result);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return result;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
class OnifyElementExtensions {
|
|
68
|
-
constructor(activity, context) {
|
|
69
|
-
this.activity = activity;
|
|
70
|
-
this.context = context;
|
|
71
|
-
const {Service} = this.extensions = getExtensions(activity, context);
|
|
72
|
-
if (Service) {
|
|
73
|
-
activity.behaviour.Service = Service;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
activate(message) {
|
|
77
|
-
const activity = this.activity;
|
|
78
|
-
const broker = activity.broker;
|
|
79
|
-
const formatQ = activity.broker.getQueue('format-run-q');
|
|
80
|
-
|
|
81
|
-
if (message.fields.redelivered && message.fields.routingKey === 'run.start') {
|
|
82
|
-
activity.on('start', (elementApi) => {
|
|
83
|
-
this._formatOnEnter(broker, formatQ, elementApi);
|
|
84
|
-
}, {consumerTag: '_onify-extension-on-enter'});
|
|
85
|
-
} else {
|
|
86
|
-
activity.on('enter', (elementApi) => {
|
|
87
|
-
this._formatOnEnter(broker, formatQ, elementApi);
|
|
88
|
-
}, {consumerTag: '_onify-extension-on-enter'});
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
activity.on('activity.execution.completed', async (elementApi) => {
|
|
92
|
-
formatQ.queueMessage({routingKey: 'run.end.format'}, {endRoutingKey: 'run.end.complete'}, {persistent: false});
|
|
93
|
-
|
|
94
|
-
try {
|
|
95
|
-
var format = await this._onExecuted(elementApi);
|
|
96
|
-
} catch (err) {
|
|
97
|
-
return broker.publish('format', 'run.end.error', {error: err}, {persistent: false});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
broker.publish('format', 'run.end.complete', {...format}, {persistent: false});
|
|
101
|
-
}, {consumerTag: '_onify-extension-on-executed'});
|
|
102
|
-
|
|
103
|
-
const executionListeners = this.extensions.listeners;
|
|
104
|
-
if (executionListeners?.onStart) {
|
|
105
|
-
activity.on('start', async (elementApi) => {
|
|
106
|
-
formatQ.queueMessage({routingKey: 'run.listener.start'}, {endRoutingKey: 'run.listener.start.complete'}, {persistent: false});
|
|
107
|
-
|
|
108
|
-
try {
|
|
109
|
-
var format = await executionListeners.execute('start', elementApi);
|
|
110
|
-
} catch (err) {
|
|
111
|
-
return broker.publish('format', 'run.listener.start.error', {error: err}, {persistent: false});
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
broker.publish('format', 'run.listener.start.complete', {...format}, {persistent: false});
|
|
115
|
-
}, {consumerTag: '_onify-extension-on-listenerstart'});
|
|
116
|
-
}
|
|
117
|
-
if (executionListeners?.onEnd) {
|
|
118
|
-
activity.on('end', async (elementApi) => {
|
|
119
|
-
formatQ.queueMessage({routingKey: 'run.listener.end'}, {endRoutingKey: 'run.listener.end.complete'}, {persistent: false});
|
|
120
|
-
|
|
121
|
-
try {
|
|
122
|
-
var format = await executionListeners.execute('end', elementApi);
|
|
123
|
-
} catch (err) {
|
|
124
|
-
return broker.publish('format', 'run.listener.end.error', {error: err}, {persistent: false});
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
broker.publish('format', 'run.listener.end.complete', {...format}, {persistent: false});
|
|
128
|
-
}, {consumerTag: '_onify-extension-on-listenerend'});
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
deactivate() {
|
|
132
|
-
const broker = this.activity.broker;
|
|
133
|
-
broker.cancel('_onify-extension-on-enter');
|
|
134
|
-
broker.cancel('_onify-extension-on-executed');
|
|
135
|
-
broker.cancel('_onify-extension-on-listenerstart');
|
|
136
|
-
broker.cancel('_onify-extension-on-listenerend');
|
|
137
|
-
}
|
|
138
|
-
async _formatOnEnter(broker, formatQ, elementApi) {
|
|
139
|
-
formatQ.queueMessage({routingKey: 'run.enter.format'}, {endRoutingKey: 'run.enter.complete'}, {persistent: false});
|
|
140
|
-
|
|
141
|
-
try {
|
|
142
|
-
var format = await this._onEnter(elementApi);
|
|
143
|
-
} catch (err) {
|
|
144
|
-
return broker.publish('format', 'run.enter.error', {error: err}, {persistent: false});
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
broker.publish('format', 'run.enter.complete', format, {persistent: false});
|
|
148
|
-
}
|
|
149
|
-
async _onEnter(elementApi) {
|
|
150
|
-
const {format, properties, io, form} = this.extensions;
|
|
151
|
-
|
|
152
|
-
const result = {};
|
|
153
|
-
Object.assign(result, format.resolve(elementApi));
|
|
154
|
-
Object.assign(elementApi.content, result);
|
|
155
|
-
|
|
156
|
-
if (properties) {
|
|
157
|
-
Object.assign(result, {properties: properties.resolve(elementApi)});
|
|
158
|
-
Object.assign(elementApi.content, result);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
if (io) {
|
|
162
|
-
if (io.input?.length) {
|
|
163
|
-
const input = await io.getInput(this.activity, elementApi);
|
|
164
|
-
Object.assign(result, {input});
|
|
165
|
-
Object.assign(elementApi.content, result);
|
|
166
|
-
}
|
|
167
|
-
if (io.output?.length) {
|
|
168
|
-
result.assignToOutput = true;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
if (form) {
|
|
173
|
-
Object.assign(result, {form: form.resolve(elementApi)});
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
return result;
|
|
177
|
-
}
|
|
178
|
-
async _onExecuted(elementApi) {
|
|
179
|
-
const {properties, io} = this.extensions;
|
|
180
|
-
|
|
181
|
-
const result = {};
|
|
182
|
-
if (io?.output.length) {
|
|
183
|
-
const output = await io.getOutput(this.activity, elementApi);
|
|
184
|
-
Object.assign(result, {output});
|
|
185
|
-
Object.assign(elementApi.content, {output});
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
if (properties) {
|
|
189
|
-
const props = properties.resolve(elementApi);
|
|
190
|
-
Object.assign(result, {properties: props});
|
|
191
|
-
Object.assign(elementApi.content, {properties: props});
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
const {output, assignToOutput, resultVariable} = elementApi.content;
|
|
195
|
-
|
|
196
|
-
if (output === undefined || output === null) return result;
|
|
197
|
-
|
|
198
|
-
if (assignToOutput && typeof output === 'object') {
|
|
199
|
-
Object.assign(this.activity.environment.output, output);
|
|
200
|
-
} else if (resultVariable) {
|
|
201
|
-
elementApi.environment.output[resultVariable] = output;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
return result;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
function getExtensions(element, context) {
|
|
209
|
-
const result = {
|
|
210
|
-
format: element.type === 'bpmn:Process' ? new FormatProcess(element) : new FormatActivity(element),
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
const expression = element.behaviour.expression;
|
|
214
|
-
if (expression) result.Service = ServiceExpression;
|
|
215
|
-
|
|
216
|
-
const extensions = element.behaviour.extensionElements?.values;
|
|
217
|
-
if (!extensions) return result;
|
|
218
|
-
|
|
219
|
-
const listeners = new ExtensionListeners(element, context);
|
|
220
|
-
|
|
221
|
-
let listener = 0;
|
|
222
|
-
for (const ext of extensions) {
|
|
223
|
-
switch (ext.$type) {
|
|
224
|
-
case 'camunda:Properties':
|
|
225
|
-
if (ext.values?.length) result.properties = new IOProperties(element, ext);
|
|
226
|
-
break;
|
|
227
|
-
case 'camunda:InputOutput':
|
|
228
|
-
result.io = new InputOutput(element.id, ext, context);
|
|
229
|
-
break;
|
|
230
|
-
case 'camunda:FormData':
|
|
231
|
-
if (ext.fields?.length) result.form = new IOForm(element, ext);
|
|
232
|
-
break;
|
|
233
|
-
case 'camunda:Connector': {
|
|
234
|
-
const {connectorId, inputOutput} = ext;
|
|
235
|
-
const io = inputOutput && new InputOutput(`${element.id}/${ext.$type.toLowerCase()}`, inputOutput, context);
|
|
236
|
-
result.Service = Connector.bind(Connector, connectorId, io);
|
|
237
|
-
break;
|
|
238
|
-
}
|
|
239
|
-
case 'camunda:ExecutionListener':
|
|
240
|
-
listeners.add(ext, listener++);
|
|
241
|
-
break;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
if (listeners.length) result.listeners = listeners;
|
|
246
|
-
|
|
247
|
-
return result;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
class FormatActivity {
|
|
251
|
-
constructor(activity) {
|
|
252
|
-
this.activity = activity;
|
|
253
|
-
this.resultVariable = activity.behaviour.resultVariable;
|
|
254
|
-
|
|
255
|
-
let timeCycles;
|
|
256
|
-
if (activity.eventDefinitions) {
|
|
257
|
-
for (const ed of activity.eventDefinitions.filter((e) => e.type === 'bpmn:TimerEventDefinition')) {
|
|
258
|
-
if (!('timeCycle' in ed)) continue;
|
|
259
|
-
timeCycles = timeCycles || [];
|
|
260
|
-
timeCycles.push(ed.timeCycle);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
this.timeCycles = timeCycles;
|
|
264
|
-
}
|
|
265
|
-
resolve(elementApi) {
|
|
266
|
-
let user, groups, assigneeValue, description;
|
|
267
|
-
const activity = this.activity;
|
|
268
|
-
const {
|
|
269
|
-
documentation,
|
|
270
|
-
candidateUsers,
|
|
271
|
-
candidateGroups,
|
|
272
|
-
scheduledStart,
|
|
273
|
-
assignee,
|
|
274
|
-
} = activity.behaviour;
|
|
275
|
-
|
|
276
|
-
if (candidateUsers) user = resolveAndSplit(elementApi, candidateUsers);
|
|
277
|
-
if (candidateGroups) groups = resolveAndSplit(elementApi, candidateGroups);
|
|
278
|
-
if (assignee) assigneeValue = elementApi.resolveExpression(assignee);
|
|
279
|
-
if (documentation) description = documentation[0]?.text;
|
|
280
|
-
|
|
281
|
-
let expireAt;
|
|
282
|
-
let timeCycles = this.timeCycles;
|
|
283
|
-
if (timeCycles) {
|
|
284
|
-
for (const cycle of timeCycles) {
|
|
285
|
-
const cron = elementApi.resolveExpression(cycle);
|
|
286
|
-
if (!cron || iso8601cycle.test(cron)) continue;
|
|
287
|
-
|
|
288
|
-
const expireAtDt = cronParser.parseExpression(cron).next().toDate();
|
|
289
|
-
if (!expireAt || expireAtDt < expireAt) expireAt = expireAtDt;
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
return {
|
|
294
|
-
...(this.resultVariable && {resultVariable: this.resultVariable}),
|
|
295
|
-
...(scheduledStart && activity.parent.type === 'bpmn:Process' && {scheduledStart}),
|
|
296
|
-
...(user?.length && {candidateUsers: user}),
|
|
297
|
-
...(groups?.length && {candidateGroups: groups}),
|
|
298
|
-
...(!elementApi.content.description && description && {description: elementApi.resolveExpression(description)}),
|
|
299
|
-
...(expireAt && {expireAt}),
|
|
300
|
-
...(assigneeValue && {assignee: assigneeValue}),
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
class FormatProcess {
|
|
306
|
-
constructor(bp) {
|
|
307
|
-
this.process = bp;
|
|
308
|
-
}
|
|
309
|
-
resolve(elementApi) {
|
|
310
|
-
let user, groups, description;
|
|
311
|
-
const bp = this.process;
|
|
312
|
-
const {
|
|
313
|
-
documentation,
|
|
314
|
-
candidateStarterUsers,
|
|
315
|
-
candidateStarterGroups,
|
|
316
|
-
} = bp.behaviour;
|
|
317
|
-
|
|
318
|
-
if (candidateStarterUsers) user = resolveAndSplit(elementApi, candidateStarterUsers);
|
|
319
|
-
if (candidateStarterGroups) groups = resolveAndSplit(elementApi, candidateStarterGroups);
|
|
320
|
-
if (documentation) description = documentation[0]?.text;
|
|
321
|
-
|
|
322
|
-
return {
|
|
323
|
-
...(user?.length && {candidateStarterUsers: user}),
|
|
324
|
-
...(groups?.length && {candidateStarterGroups: groups}),
|
|
325
|
-
...(!elementApi.content.description && description && {description: elementApi.resolveExpression(description)}),
|
|
326
|
-
};
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
function resolveAndSplit(elementApi, str) {
|
|
331
|
-
if (Array.isArray(str)) return str.filter(Boolean);
|
|
332
|
-
if (typeof str !== 'string') return;
|
|
333
|
-
|
|
334
|
-
const resolved = elementApi.resolveExpression(str);
|
|
335
|
-
if (Array.isArray(resolved)) return resolved.filter(Boolean);
|
|
336
|
-
if (typeof resolved !== 'string') return;
|
|
337
|
-
|
|
338
|
-
return resolved
|
|
339
|
-
.split(',')
|
|
340
|
-
.map((g) => g.trim && g.trim().toLowerCase())
|
|
341
|
-
.filter(Boolean);
|
|
342
|
-
}
|
|
343
|
-
|
|
344
16
|
function extendFn(behaviour, context) {
|
|
345
17
|
if (behaviour.$type === 'bpmn:StartEvent' && behaviour.eventDefinitions) {
|
|
346
18
|
const timer = behaviour.eventDefinitions.find(({type, behaviour: edBehaviour}) => edBehaviour && type === 'bpmn:TimerEventDefinition');
|
|
@@ -373,11 +45,13 @@ function registerIOScripts(parentId, context, type, ioBehaviour) {
|
|
|
373
45
|
if (!definition) continue;
|
|
374
46
|
if (definition.$type !== 'camunda:Script') continue;
|
|
375
47
|
|
|
376
|
-
const
|
|
48
|
+
const ioType = `${type}/${$type}`;
|
|
49
|
+
const filename = `${parentId}/${ioType}/${name}`;
|
|
377
50
|
|
|
378
51
|
context.addScript(filename, {
|
|
379
52
|
id: filename,
|
|
380
53
|
scriptFormat: definition.scriptFormat,
|
|
54
|
+
type: ioType,
|
|
381
55
|
...(definition.value && {body: definition.value}),
|
|
382
56
|
...(definition.resource && {resource: definition.resource}),
|
|
383
57
|
});
|
|
@@ -392,6 +66,7 @@ function registerListenerScript(parentId, context, type, listener, pos) {
|
|
|
392
66
|
context.addScript(id, {
|
|
393
67
|
id,
|
|
394
68
|
scriptFormat: script.scriptFormat,
|
|
69
|
+
type,
|
|
395
70
|
...(script.value && {body: script.value}),
|
|
396
71
|
...(script.resource && {resource: script.resource}),
|
|
397
72
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onify/flow-extensions",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.1.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.
|
|
39
|
-
"@babel/core": "^7.
|
|
40
|
-
"@babel/preset-env": "^7.
|
|
41
|
-
"@babel/register": "^7.
|
|
38
|
+
"@babel/cli": "^7.21.5",
|
|
39
|
+
"@babel/core": "^7.21.5",
|
|
40
|
+
"@babel/preset-env": "^7.21.5",
|
|
41
|
+
"@babel/register": "^7.21.0",
|
|
42
42
|
"bpmn-elements-8-1": "npm:bpmn-elements@8.1",
|
|
43
|
-
"bpmn-engine": "^
|
|
43
|
+
"bpmn-engine": "^16.0.0",
|
|
44
44
|
"bpmn-engine-14": "npm:bpmn-engine@14",
|
|
45
|
-
"bpmn-moddle": "^
|
|
46
|
-
"c8": "^7.
|
|
45
|
+
"bpmn-moddle": "^8.0.1",
|
|
46
|
+
"c8": "^7.13.0",
|
|
47
47
|
"camunda-bpmn-moddle": "^7.0.1",
|
|
48
48
|
"chai": "^4.3.7",
|
|
49
|
-
"chronokinesis": "^
|
|
49
|
+
"chronokinesis": "^5.0.2",
|
|
50
50
|
"debug": "^4.3.4",
|
|
51
|
-
"eslint": "^8.
|
|
52
|
-
"mocha": "^10.
|
|
51
|
+
"eslint": "^8.39.0",
|
|
52
|
+
"mocha": "^10.2.0",
|
|
53
53
|
"mocha-cakes-2": "^3.3.0",
|
|
54
|
-
"moddle-context-serializer": "^2.
|
|
54
|
+
"moddle-context-serializer": "^3.2.2"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"cron-parser": "^4.
|
|
57
|
+
"cron-parser": "^4.8.1"
|
|
58
58
|
},
|
|
59
59
|
"files": [
|
|
60
60
|
"src",
|
package/src/Connector.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {NotImplemented} from './Errors';
|
|
1
|
+
import {NotImplemented} from './Errors.js';
|
|
2
2
|
|
|
3
3
|
export default function Connector(connectorId, io, activity, executionMessage) {
|
|
4
4
|
if (!(this instanceof Connector)) return new Connector(connectorId, io, activity, executionMessage);
|
package/src/Errors.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class NotImplemented extends Error {
|
|
1
|
+
export class NotImplemented extends Error {
|
|
2
2
|
constructor(serviceId) {
|
|
3
3
|
super(`${serviceId} service function not found`);
|
|
4
4
|
this.code = 'EFLOW_NOT_IMPLEMENTED';
|
|
@@ -6,6 +6,10 @@ class NotImplemented extends Error {
|
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export {
|
|
10
|
-
|
|
11
|
-
};
|
|
9
|
+
export class FormatError extends Error {
|
|
10
|
+
constructor(elementId, err) {
|
|
11
|
+
super(`<${elementId}> ${err.message}`);
|
|
12
|
+
this.code = 'EFLOW_FORMAT';
|
|
13
|
+
this.output = {statusCode: 500};
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -49,6 +49,8 @@ class ScriptListener extends Listener {
|
|
|
49
49
|
execute(api) {
|
|
50
50
|
const environment = this.environment;
|
|
51
51
|
const scope = this._getScope(api, {id: this.id, resolveExpression});
|
|
52
|
+
const listenerFields = this._getFields(environment, scope);
|
|
53
|
+
if (listenerFields) scope.listener.fields = listenerFields;
|
|
52
54
|
const script = this.environment.scripts.getScript(this.extension.scriptFormat, {id: this.id});
|
|
53
55
|
|
|
54
56
|
return new Promise((resolve, reject) => {
|
|
@@ -66,7 +68,7 @@ class ScriptListener extends Listener {
|
|
|
66
68
|
const {
|
|
67
69
|
scriptFormat,
|
|
68
70
|
value,
|
|
69
|
-
resource
|
|
71
|
+
resource,
|
|
70
72
|
} = script;
|
|
71
73
|
|
|
72
74
|
context.environment.scripts.register({
|
|
@@ -75,12 +77,12 @@ class ScriptListener extends Listener {
|
|
|
75
77
|
behaviour: {
|
|
76
78
|
scriptFormat,
|
|
77
79
|
...(value && {
|
|
78
|
-
script: value
|
|
80
|
+
script: value,
|
|
79
81
|
}),
|
|
80
82
|
...(resource && {
|
|
81
|
-
resource
|
|
82
|
-
})
|
|
83
|
-
}
|
|
83
|
+
resource,
|
|
84
|
+
}),
|
|
85
|
+
},
|
|
84
86
|
});
|
|
85
87
|
}
|
|
86
88
|
}
|
|
@@ -97,22 +99,26 @@ export default class ExecutionListeners {
|
|
|
97
99
|
this.activity = activity;
|
|
98
100
|
this.context = context;
|
|
99
101
|
this.listeners = [];
|
|
100
|
-
this.onStart = false;
|
|
101
|
-
this.onEnd = false;
|
|
102
102
|
}
|
|
103
103
|
get length() {
|
|
104
104
|
return this.listeners.length;
|
|
105
105
|
}
|
|
106
|
+
get onStart() {
|
|
107
|
+
return this.listeners.some((l) => l.event === 'start');
|
|
108
|
+
}
|
|
109
|
+
get onEnd() {
|
|
110
|
+
return this.listeners.some((l) => l.event === 'end');
|
|
111
|
+
}
|
|
112
|
+
get onTake() {
|
|
113
|
+
return this.listeners.some((l) => l.event === 'take');
|
|
114
|
+
}
|
|
106
115
|
add(extension, pos) {
|
|
107
|
-
const {
|
|
116
|
+
const {script, expression} = extension;
|
|
108
117
|
if (!script && !expression) return;
|
|
109
118
|
|
|
110
119
|
const list = this.listeners;
|
|
111
120
|
if (script && (script.value || script.resource)) list.push(new ScriptListener(this.activity, this.context, extension, pos));
|
|
112
121
|
else if (expression) list.push(new ExpressionListener(this.activity, this.context, extension));
|
|
113
|
-
|
|
114
|
-
if (event === 'start') this.onStart = true;
|
|
115
|
-
if (event === 'end') this.onEnd = true;
|
|
116
122
|
}
|
|
117
123
|
async execute(event, message) {
|
|
118
124
|
const found = this.listeners.filter((l) => l.event === event);
|
package/src/IO.js
CHANGED
|
@@ -1,75 +1,4 @@
|
|
|
1
|
-
export {
|
|
2
|
-
InputOutput,
|
|
3
|
-
IOBase,
|
|
4
|
-
IOMap,
|
|
5
|
-
IOList,
|
|
6
|
-
IOScript,
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
class InputOutput {
|
|
10
|
-
constructor(parentId, behaviour, context) {
|
|
11
|
-
this.parentId = parentId;
|
|
12
|
-
this.context = context;
|
|
13
|
-
const {inputParameters, outputParameters} = behaviour;
|
|
14
|
-
this.input = this._map(parentId, inputParameters, 'input', context);
|
|
15
|
-
this.output = this._map(parentId, outputParameters, 'output', context);
|
|
16
|
-
}
|
|
17
|
-
async getInput(activity, executionMessage) {
|
|
18
|
-
const input = this.input;
|
|
19
|
-
const values = await Promise.all(input.map((parm) => parm.getValue(activity, executionMessage)));
|
|
20
|
-
return values.reduce((result, parm) => Object.assign(result, parm), {});
|
|
21
|
-
}
|
|
22
|
-
async getOutput(activity, executionMessage) {
|
|
23
|
-
const output = this.output;
|
|
24
|
-
const values = await Promise.all(output.map((parm) => parm.getValue(activity, executionMessage)));
|
|
25
|
-
return values.reduce((result, parm) => Object.assign(result, parm), {});
|
|
26
|
-
}
|
|
27
|
-
_map(parentId, list, ioType, context) {
|
|
28
|
-
const mapped = [];
|
|
29
|
-
if (!list) return mapped;
|
|
30
|
-
|
|
31
|
-
for (const parm of list) {
|
|
32
|
-
const definition = parm.definition;
|
|
33
|
-
const type = definition && definition.$type;
|
|
34
|
-
switch (type) {
|
|
35
|
-
case 'camunda:Map': {
|
|
36
|
-
mapped.push(new IOMap(parm));
|
|
37
|
-
break;
|
|
38
|
-
}
|
|
39
|
-
case 'camunda:List': {
|
|
40
|
-
mapped.push(new IOList(parm));
|
|
41
|
-
break;
|
|
42
|
-
}
|
|
43
|
-
case 'camunda:Script': {
|
|
44
|
-
const id = `${parentId}/${ioType}/${type}/${parm.name}`;
|
|
45
|
-
const {scriptFormat, value, resource} = definition;
|
|
46
|
-
|
|
47
|
-
if (!value && !resource) break;
|
|
48
|
-
|
|
49
|
-
context.environment.scripts.register({
|
|
50
|
-
id,
|
|
51
|
-
type: parm.$type,
|
|
52
|
-
behaviour: {
|
|
53
|
-
scriptFormat,
|
|
54
|
-
...(value && {script: value}),
|
|
55
|
-
...(resource && {resource}),
|
|
56
|
-
},
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
mapped.push(new IOScript(parm, id));
|
|
60
|
-
break;
|
|
61
|
-
}
|
|
62
|
-
default: {
|
|
63
|
-
mapped.push(new IOBase(parm));
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return mapped;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
class IOBase {
|
|
1
|
+
export class IOBase {
|
|
73
2
|
constructor(parm) {
|
|
74
3
|
this.name = parm.name;
|
|
75
4
|
this.type = parm.definition && parm.definition.$type || 'string';
|
|
@@ -117,7 +46,7 @@ class IOMap extends IOBase {
|
|
|
117
46
|
}
|
|
118
47
|
}
|
|
119
48
|
|
|
120
|
-
class IOList extends IOBase {
|
|
49
|
+
export class IOList extends IOBase {
|
|
121
50
|
constructor(parm) {
|
|
122
51
|
super(parm);
|
|
123
52
|
}
|
|
@@ -140,7 +69,7 @@ class IOList extends IOBase {
|
|
|
140
69
|
}
|
|
141
70
|
}
|
|
142
71
|
|
|
143
|
-
class IOScript extends IOBase {
|
|
72
|
+
export class IOScript extends IOBase {
|
|
144
73
|
constructor(parm, scriptId) {
|
|
145
74
|
super(parm);
|
|
146
75
|
this.id = scriptId;
|
|
@@ -179,3 +108,66 @@ class IOScript extends IOBase {
|
|
|
179
108
|
}
|
|
180
109
|
}
|
|
181
110
|
}
|
|
111
|
+
|
|
112
|
+
export class InputOutput {
|
|
113
|
+
constructor(parentId, behaviour, context) {
|
|
114
|
+
this.parentId = parentId;
|
|
115
|
+
this.context = context;
|
|
116
|
+
const {inputParameters, outputParameters} = behaviour;
|
|
117
|
+
this.input = this._map(parentId, inputParameters, 'input', context);
|
|
118
|
+
this.output = this._map(parentId, outputParameters, 'output', context);
|
|
119
|
+
}
|
|
120
|
+
async getInput(activity, executionMessage) {
|
|
121
|
+
const input = this.input;
|
|
122
|
+
const values = await Promise.all(input.map((parm) => parm.getValue(activity, executionMessage)));
|
|
123
|
+
return values.reduce((result, parm) => Object.assign(result, parm), {});
|
|
124
|
+
}
|
|
125
|
+
async getOutput(activity, executionMessage) {
|
|
126
|
+
const output = this.output;
|
|
127
|
+
const values = await Promise.all(output.map((parm) => parm.getValue(activity, executionMessage)));
|
|
128
|
+
return values.reduce((result, parm) => Object.assign(result, parm), {});
|
|
129
|
+
}
|
|
130
|
+
_map(parentId, list, ioType, context) {
|
|
131
|
+
const mapped = [];
|
|
132
|
+
if (!list) return mapped;
|
|
133
|
+
|
|
134
|
+
for (const parm of list) {
|
|
135
|
+
const definition = parm.definition;
|
|
136
|
+
const type = definition && definition.$type;
|
|
137
|
+
switch (type) {
|
|
138
|
+
case 'camunda:Map': {
|
|
139
|
+
mapped.push(new IOMap(parm));
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
case 'camunda:List': {
|
|
143
|
+
mapped.push(new IOList(parm));
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
case 'camunda:Script': {
|
|
147
|
+
const id = `${parentId}/${ioType}/${type}/${parm.name}`;
|
|
148
|
+
const {scriptFormat, value, resource} = definition;
|
|
149
|
+
|
|
150
|
+
if (!value && !resource) break;
|
|
151
|
+
|
|
152
|
+
context.environment.scripts.register({
|
|
153
|
+
id,
|
|
154
|
+
type: parm.$type,
|
|
155
|
+
behaviour: {
|
|
156
|
+
scriptFormat,
|
|
157
|
+
...(value && {script: value}),
|
|
158
|
+
...(resource && {resource}),
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
mapped.push(new IOScript(parm, id));
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
default: {
|
|
166
|
+
mapped.push(new IOBase(parm));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return mapped;
|
|
172
|
+
}
|
|
173
|
+
}
|