8.3.1 • Published 6 months ago
@onify/flow-extensions v8.3.1
Onify Flow Extensions
Api
extensions
: Flow extensionsextendFn
: extend function to pass to serializer
Examples
Bpmn engine example
import { createRequire } from 'node:module';
import { fileURLToPath } from 'node:url';
import { Engine } from 'bpmn-engine';
import { extensions } from '@onify/flow-extensions';
import { FlowScripts } from '@onify/flow-extensions/FlowScripts';
const nodeRequire = createRequire(fileURLToPath(import.meta.url));
const source = `
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camunda="http://camunda.org/schema/1.0/bpmn">
<process id="theProcess" isExecutable="true">
<serviceTask id="task1" camunda:expression="\${environment.services.serviceFn}" camunda:resultVariable="result" />
<sequenceFlow id="to-task2" sourceRef="task1" targetRef="task2" />
<scriptTask id="task2" camunda:resultVariable="out" scriptFormat="js">
<script>
next(null, myContextFn());
</script>
</scriptTask>
</process>
</definitions>`;
const name = 'onify flow';
const engine = new Engine({
name,
source,
moddleOptions: {
camunda: nodeRequire('camunda-bpmn-moddle/resources/camunda.json'),
},
services: {
serviceFn(scope, callback) {
callback(null, { data: 1 });
},
},
extensions: {
onify: extensions,
},
scripts: new FlowScripts(name, './script-resources', {
myContextFn() {
return 2;
},
}),
});
engine.execute((err, instance) => {
if (err) throw err;
console.log(instance.name, instance.environment.output);
});
Extract scripts with extend function
import { createRequire } from 'node:module';
import { fileURLToPath } from 'node:url';
import BpmnModdle from 'bpmn-moddle';
import * as Elements from 'bpmn-elements';
import { Serializer, TypeResolver } from 'moddle-context-serializer';
import { extendFn } from '@onify/flow-extensions';
const nodeRequire = createRequire(fileURLToPath(import.meta.url));
const source = `
<definitions id="Def_0" xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:camunda="http://camunda.org/schema/1.0/bpmn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
targetNamespace="http://bpmn.io/schema/bpmn">
<process id="process-1" name="Onify Flow" isExecutable="true">
<serviceTask id="task1">
<extensionElements>
<camunda:connector>
<camunda:connectorId>onifyApiRequest</camunda:connectorId>
<camunda:inputOutput>
<camunda:inputParameter name="method">GET</camunda:inputParameter>
<camunda:inputParameter name="url">/my/items/workspace-1</camunda:inputParameter>
<camunda:outputParameter name="result">
<camunda:script scriptFormat="js">
next(null, {
id: content.id,
statuscode,
});
</camunda:script>
</camunda:outputParameter>
</camunda:inputOutput>
</camunda:connector>
<camunda:inputOutput>
<camunda:outputParameter name="result">\${content.output.result.statuscode}</camunda:outputParameter>
</camunda:inputOutput>
</extensionElements>
</serviceTask>
<sequenceFlow id="to-task2" sourceRef="task1" targetRef="task2" />
<scriptTask id="task2" camunda:resultVariable="out" scriptFormat="js">
<script>
next(null, 2);
</script>
</scriptTask>
</process>
</definitions>`;
getScripts(source).then(console.log).catch(console.error);
async function getScripts(bpmnSource) {
const moddle = await getModdleContext(bpmnSource, {
camunda: nodeRequire('camunda-bpmn-moddle/resources/camunda.json'),
});
const serialized = Serializer(moddle, TypeResolver(Elements), extendFn);
return serialized.elements.scripts;
}
function getModdleContext(source, options) {
const bpmnModdle = new BpmnModdle(options);
return bpmnModdle.fromXML(Buffer.isBuffer(source) ? source.toString() : source.trim());
}
Extract timers
import { createRequire } from 'node:module';
import { fileURLToPath } from 'node:url';
import BpmnModdle from 'bpmn-moddle';
import * as Elements from 'bpmn-elements';
import { Serializer, TypeResolver } from 'moddle-context-serializer';
import { extendFn, OnifyTimerEventDefinition } from '@onify/flow-extensions';
const nodeRequire = createRequire(fileURLToPath(import.meta.url));
const source = `
<definitions id="Def_0" xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:camunda="http://camunda.org/schema/1.0/bpmn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
targetNamespace="http://bpmn.io/schema/bpmn">
<process id="cycle-1" name="Onify start at time cycle" isExecutable="true" camunda:historyTimeToLive="PT180M">
<startEvent id="start">
<timerEventDefinition>
<timeCycle xsi:type="tFormalExpression">0 1 * * *</timeCycle>
</timerEventDefinition>
</startEvent>
<sequenceFlow id="to-task" sourceRef="start" targetRef="task" />
<userTask id="task" />
<boundaryEvent id="bound-timer" cancelActivity="false" attachedToRef="task">
<timerEventDefinition>
<timeDuration xsi:type="tFormalExpression">R3/PT1M</timeDuration>
</timerEventDefinition>
</boundaryEvent>
<sequenceFlow id="to-wait" sourceRef="task" targetRef="wait" />
<intermediateThrowEvent id="timer">
<timerEventDefinition>
<timeCycle xsi:type="tFormalExpression">\${environment.settings.postpone}</timeCycle>
</timerEventDefinition>
</intermediateThrowEvent>
<sequenceFlow id="to-end" sourceRef="wait" targetRef="end" />
<endEvent id="end" />
</process>
</definitions>`;
getTimers(source).then(console.log).catch(console.error);
const dummyEventActivity = { broker: {}, environment: { Logger() {} } };
async function getTimers(bpmnSource) {
const moddle = await getModdleContext(bpmnSource, {
camunda: nodeRequire('camunda-bpmn-moddle/resources/camunda.json'),
});
const serialized = Serializer(moddle, TypeResolver(Elements), extendFn);
for (const t of serialized.elements.timers) {
const ed = new OnifyTimerEventDefinition(dummyEventActivity, t.timer);
try {
t.parsed = ed.parse(t.timer.timerType, t.timer.value);
} catch {}
}
return serialized.elements.timers;
}
function getModdleContext(source, options) {
const bpmnModdle = new BpmnModdle(options);
return bpmnModdle.fromXML(Buffer.isBuffer(source) ? source.toString() : source.trim());
}
Extend sequence flow with properties and take listeners
import { createRequire } from 'node:module';
import { fileURLToPath } from 'node:url';
import { Engine } from 'bpmn-engine';
import * as Elements from 'bpmn-elements';
import { OnifySequenceFlow, extensions } from '@onify/flow-extensions';
import { FlowScripts } from '@onify/flow-extensions/FlowScripts';
const nodeRequire = createRequire(fileURLToPath(import.meta.url));
const source = `
<?xml version="1.0" encoding="UTF-8"?>
<definitions
id="Def_0"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:camunda="http://camunda.org/schema/1.0/bpmn"
targetNamespace="http://bpmn.io/schema/bpmn">
<process id="Process_1kk79yr" isExecutable="true">
<startEvent id="start" />
<sequenceFlow id="to-script" sourceRef="start" targetRef="script">
<extensionElements>
<camunda:properties>
<camunda:property name="source" value="\${content.id}" />
</camunda:properties>
<camunda:executionListener event="take">
<camunda:script scriptFormat="js">environment.output.fields = listener.fields; next();</camunda:script>
<camunda:field name="taken">
<camunda:expression>\${true}</camunda:expression>
</camunda:field>
<camunda:field name="bar">
<camunda:string>baz</camunda:string>
</camunda:field>
</camunda:executionListener>
</extensionElements>
</sequenceFlow>
<sequenceFlow id="to-end" sourceRef="script" targetRef="end">
<extensionElements>
<camunda:properties>
<camunda:property name="foo" value="bar" />
</camunda:properties>
</extensionElements>
</sequenceFlow>
<scriptTask id="script" name="script" scriptFormat="js">
<script>next(null, { foo: environment.variables.required.input });</script>
</scriptTask>
<boundaryEvent id="catch-err" attachedToRef="script">
<errorEventDefinition />
</boundaryEvent>
<endEvent id="end-err">
<extensionElements>
<camunda:executionListener event="start">
<camunda:script scriptFormat="js">
environment.output.failedBy = content.inbound[0].properties.error;
if (next) next();
</camunda:script>
</camunda:executionListener>
</extensionElements>
</endEvent>
<sequenceFlow id="to-end-err" sourceRef="catch-err" targetRef="end-err">
<extensionElements>
<camunda:properties>
<camunda:property name="error" value="\${content.output}" />
</camunda:properties>
</extensionElements>
</sequenceFlow>
<endEvent id="end" />
</process>
</definitions>`;
const engine = new Engine({
name: 'sequence flow extension',
source,
moddleOptions: {
camunda: nodeRequire('camunda-bpmn-moddle/resources/camunda.json'),
},
extensions: {
onify: extensions,
},
scripts: new FlowScripts('sequence flow extension'),
elements: {
...Elements,
SequenceFlow: OnifySequenceFlow,
},
variables: {
required: {
input: true,
},
},
});
engine.execute((err, instance) => {
if (err) throw err;
console.log(instance.name, instance.environment.output);
});
8.3.1
6 months ago
8.2.2
10 months ago
8.1.0
11 months ago
8.3.0
10 months ago
8.2.1
10 months ago
8.0.3
11 months ago
8.2.0
11 months ago
8.0.2
12 months ago
8.0.1
12 months ago
8.0.0
12 months ago
7.1.0
1 year ago
7.0.0
1 year ago
6.0.0
1 year ago
5.0.2
2 years ago
5.0.1
2 years ago
5.0.0
2 years ago
4.1.0
2 years ago
4.0.0
2 years ago
3.0.0
2 years ago
2.0.0
2 years ago
1.1.0
3 years ago
1.0.0
3 years ago
0.1.0
3 years ago
0.0.2
3 years ago
0.0.1
3 years ago