@aranzatech/diagrams-bpmn 0.2.5 → 0.2.7
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 +19 -0
- package/dist/{catalog-D2AcvrDO.d.cts → catalog-CjGdTFxc.d.cts} +1 -1
- package/dist/{catalog-CQtKEV7q.d.ts → catalog-DW0Hknp2.d.ts} +1 -1
- package/dist/{chunk-ASZ3TFNQ.js → chunk-KW2QVBOB.js} +149 -6
- package/dist/chunk-KW2QVBOB.js.map +1 -0
- package/dist/{chunk-QOGZITWB.js → chunk-M46UDUN3.js} +2 -2
- package/dist/{chunk-QOGZITWB.js.map → chunk-M46UDUN3.js.map} +1 -1
- package/dist/{chunk-7MKU37XQ.js → chunk-XTUYPA3E.js} +191 -15
- package/dist/chunk-XTUYPA3E.js.map +1 -0
- package/dist/elements/index.d.cts +3 -3
- package/dist/elements/index.d.ts +3 -3
- package/dist/index.cjs +336 -227
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +3 -4
- package/dist/modeling/index.cjs +197 -10
- package/dist/modeling/index.cjs.map +1 -1
- package/dist/modeling/index.d.cts +103 -7
- package/dist/modeling/index.d.ts +103 -7
- package/dist/modeling/index.js +1 -1
- package/dist/simulation/index.cjs.map +1 -1
- package/dist/simulation/index.d.cts +36 -0
- package/dist/simulation/index.d.ts +36 -0
- package/dist/simulation/index.js +1 -1
- package/dist/{types-fDlPLIHd.d.cts → types-BjVERSZn.d.cts} +1 -1
- package/dist/{types-CIBColRi.d.ts → types-CBgWMl9p.d.ts} +1 -1
- package/dist/{types-rWbKYrHH.d.cts → types-wFn_tJLY.d.cts} +20 -0
- package/dist/{types-rWbKYrHH.d.ts → types-wFn_tJLY.d.ts} +20 -0
- package/dist/validation/index.cjs.map +1 -1
- package/dist/validation/index.d.cts +7 -2
- package/dist/validation/index.d.ts +7 -2
- package/dist/validation/index.js +224 -3
- package/dist/validation/index.js.map +1 -1
- package/dist/xml/index.cjs +146 -6
- package/dist/xml/index.cjs.map +1 -1
- package/dist/xml/index.d.cts +18 -3
- package/dist/xml/index.d.ts +18 -3
- package/dist/xml/index.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-7MKU37XQ.js.map +0 -1
- package/dist/chunk-ASZ3TFNQ.js.map +0 -1
- package/dist/chunk-ZFGQVLHB.js +0 -226
- package/dist/chunk-ZFGQVLHB.js.map +0 -1
package/dist/validation/index.js
CHANGED
|
@@ -1,5 +1,226 @@
|
|
|
1
|
-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
|
|
1
|
+
import { isDataType, isGatewayType, isEventType } from '../chunk-RLAJNRF2.js';
|
|
2
|
+
import { BPMN_ELEMENT_CATALOG } from '../chunk-L5Z22RLX.js';
|
|
3
|
+
|
|
4
|
+
// src/validation/index.ts
|
|
5
|
+
function isFlowNode(type) {
|
|
6
|
+
return isEventType(type) || isGatewayType(type) || type.includes("Task") || type === "CallActivity" || type === "SubProcess" || type === "Transaction" || type === "EventSubProcess" || type === "AdHocSubProcess" || type === "ChoreographyTask" || type === "SubChoreography" || type === "CallChoreography";
|
|
7
|
+
}
|
|
8
|
+
function isProcessNode(type) {
|
|
9
|
+
return isFlowNode(type) && type !== "BoundaryEvent";
|
|
10
|
+
}
|
|
11
|
+
function isSubProcess(type) {
|
|
12
|
+
return type === "SubProcess" || type === "Transaction" || type === "EventSubProcess" || type === "AdHocSubProcess";
|
|
13
|
+
}
|
|
14
|
+
function isCatchTarget(type) {
|
|
15
|
+
return type === "IntermediateCatchEvent" || type === "ReceiveTask";
|
|
16
|
+
}
|
|
17
|
+
function poolAncestor(node, nodeById) {
|
|
18
|
+
let current = node;
|
|
19
|
+
const visited = /* @__PURE__ */ new Set();
|
|
20
|
+
while (current?.parentId && !visited.has(current.id)) {
|
|
21
|
+
visited.add(current.id);
|
|
22
|
+
const parent = nodeById.get(current.parentId);
|
|
23
|
+
if (parent?.data.elementType === "Pool") return parent.id;
|
|
24
|
+
current = parent;
|
|
25
|
+
}
|
|
26
|
+
return void 0;
|
|
27
|
+
}
|
|
28
|
+
function countSequenceEdges(edges, nodeId, direction) {
|
|
29
|
+
return edges.filter((edge) => {
|
|
30
|
+
if (edge.data?.edgeType !== "sequenceFlow") return false;
|
|
31
|
+
return direction === "in" ? edge.target === nodeId : edge.source === nodeId;
|
|
32
|
+
}).length;
|
|
33
|
+
}
|
|
34
|
+
function sequenceEdges(edges) {
|
|
35
|
+
return edges.filter((edge) => (edge.data?.edgeType ?? edge.type) === "sequenceFlow");
|
|
36
|
+
}
|
|
37
|
+
function sequenceOut(edges, nodeId) {
|
|
38
|
+
return sequenceEdges(edges).filter((edge) => edge.source === nodeId);
|
|
39
|
+
}
|
|
40
|
+
function sequenceIn(edges, nodeId) {
|
|
41
|
+
return sequenceEdges(edges).filter((edge) => edge.target === nodeId);
|
|
42
|
+
}
|
|
43
|
+
function issue(code, severity, message, elementId, relatedElementIds) {
|
|
44
|
+
return {
|
|
45
|
+
id: `${code}:${elementId ?? relatedElementIds?.join(",") ?? "diagram"}`,
|
|
46
|
+
code,
|
|
47
|
+
severity,
|
|
48
|
+
message,
|
|
49
|
+
...elementId ? { elementId } : {},
|
|
50
|
+
...relatedElementIds ? { relatedElementIds } : {}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function validateBpmnDiagram(nodes, edges, options = {}) {
|
|
54
|
+
const opts = {
|
|
55
|
+
requireStartEvent: true,
|
|
56
|
+
requireEndEvent: true,
|
|
57
|
+
strictNames: false,
|
|
58
|
+
...options
|
|
59
|
+
};
|
|
60
|
+
const issues = [];
|
|
61
|
+
const nodeById = new Map(nodes.map((node) => [node.id, node]));
|
|
62
|
+
const seqEdges = sequenceEdges(edges);
|
|
63
|
+
const processNodes = nodes.filter((node) => isProcessNode(node.data.elementType));
|
|
64
|
+
if (opts.requireStartEvent && !processNodes.some((node) => node.data.elementType === "StartEvent")) {
|
|
65
|
+
issues.push(issue("bpmn/start-event-required", "error", "The diagram must contain at least one start event."));
|
|
66
|
+
}
|
|
67
|
+
if (opts.requireEndEvent && !processNodes.some((node) => node.data.elementType === "EndEvent")) {
|
|
68
|
+
issues.push(issue("bpmn/end-event-required", "error", "The diagram must contain at least one end event."));
|
|
69
|
+
}
|
|
70
|
+
for (const edge of edges) {
|
|
71
|
+
const edgeType = edge.data?.edgeType ?? edge.type;
|
|
72
|
+
const source = nodeById.get(edge.source);
|
|
73
|
+
const target = nodeById.get(edge.target);
|
|
74
|
+
if (!source || !target) {
|
|
75
|
+
issues.push(issue(
|
|
76
|
+
"bpmn/no-orphan-edges",
|
|
77
|
+
"error",
|
|
78
|
+
`Edge "${edge.id}" references a missing ${!source ? "source" : "target"} node.`,
|
|
79
|
+
edge.id,
|
|
80
|
+
[edge.source, edge.target]
|
|
81
|
+
));
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (edge.source === edge.target) {
|
|
85
|
+
issues.push(issue("bpmn/no-self-loop", "error", "BPMN edges cannot connect an element to itself.", edge.id, [edge.source]));
|
|
86
|
+
}
|
|
87
|
+
if (edgeType === "sequenceFlow") {
|
|
88
|
+
if (!isFlowNode(source.data.elementType) || !isFlowNode(target.data.elementType) || isDataType(source.data.elementType) || isDataType(target.data.elementType)) {
|
|
89
|
+
issues.push(issue("bpmn/sequence-flow-valid-endpoints", "error", "Sequence flows must connect BPMN flow nodes.", edge.id, [source.id, target.id]));
|
|
90
|
+
}
|
|
91
|
+
const sourcePool = poolAncestor(source, nodeById);
|
|
92
|
+
const targetPool = poolAncestor(target, nodeById);
|
|
93
|
+
if (sourcePool && targetPool && sourcePool !== targetPool) {
|
|
94
|
+
issues.push(issue("bpmn/sequence-flow-no-cross-pool", "error", "Sequence flows cannot cross pools. Use message flow between participants.", edge.id, [source.id, target.id]));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (edgeType === "messageFlow") {
|
|
98
|
+
const sourcePool = poolAncestor(source, nodeById);
|
|
99
|
+
const targetPool = poolAncestor(target, nodeById);
|
|
100
|
+
if (!sourcePool || !targetPool || sourcePool === targetPool) {
|
|
101
|
+
issues.push(issue("bpmn/message-flow-valid-endpoints", "error", "Message flows must connect flow nodes in different pools.", edge.id, [source.id, target.id]));
|
|
102
|
+
}
|
|
103
|
+
if (!isFlowNode(source.data.elementType) || !isFlowNode(target.data.elementType)) {
|
|
104
|
+
issues.push(issue("bpmn/message-flow-valid-endpoints", "error", "Message flows must connect BPMN flow nodes, not containers.", edge.id, [source.id, target.id]));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (edgeType === "dataAssociation") {
|
|
108
|
+
const hasDataEndpoint = isDataType(source.data.elementType) || isDataType(target.data.elementType);
|
|
109
|
+
const hasFlowEndpoint = isFlowNode(source.data.elementType) || isFlowNode(target.data.elementType);
|
|
110
|
+
if (!hasDataEndpoint || !hasFlowEndpoint) {
|
|
111
|
+
issues.push(issue("bpmn/data-association-valid-endpoints", "error", "Data associations must connect data elements with flow nodes.", edge.id, [source.id, target.id]));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const duplicateSequenceKeys = /* @__PURE__ */ new Set();
|
|
116
|
+
const reportedDuplicateKeys = /* @__PURE__ */ new Set();
|
|
117
|
+
for (const edge of seqEdges) {
|
|
118
|
+
const key = `${edge.source}->${edge.target}`;
|
|
119
|
+
if (duplicateSequenceKeys.has(key) && !reportedDuplicateKeys.has(key)) {
|
|
120
|
+
reportedDuplicateKeys.add(key);
|
|
121
|
+
issues.push(issue("bpmn/no-duplicate-sequence-flow", "error", "Only one sequence flow is allowed between the same source and target.", edge.id, [edge.source, edge.target]));
|
|
122
|
+
}
|
|
123
|
+
duplicateSequenceKeys.add(key);
|
|
124
|
+
}
|
|
125
|
+
for (const node of nodes) {
|
|
126
|
+
const type = node.data.elementType;
|
|
127
|
+
const incoming = countSequenceEdges(edges, node.id, "in");
|
|
128
|
+
const outgoing = countSequenceEdges(edges, node.id, "out");
|
|
129
|
+
const meta = BPMN_ELEMENT_CATALOG[type];
|
|
130
|
+
if (type === "StartEvent" && incoming > 0) {
|
|
131
|
+
issues.push(issue("bpmn/start-event-no-incoming", "error", "Start events cannot have incoming sequence flows.", node.id));
|
|
132
|
+
}
|
|
133
|
+
if (type === "EndEvent") {
|
|
134
|
+
if (outgoing > 0) issues.push(issue("bpmn/no-outgoing-from-end-event", "error", "End events cannot have outgoing sequence flows.", node.id));
|
|
135
|
+
if (incoming === 0) issues.push(issue("bpmn/end-event-has-incoming", "error", "End events should have at least one incoming sequence flow.", node.id));
|
|
136
|
+
}
|
|
137
|
+
if ((type === "IntermediateCatchEvent" || type === "IntermediateThrowEvent") && (incoming === 0 || outgoing === 0)) {
|
|
138
|
+
issues.push(issue("bpmn/intermediate-event-both-flows", "error", "Intermediate events should have both incoming and outgoing sequence flows.", node.id));
|
|
139
|
+
}
|
|
140
|
+
if (type === "BoundaryEvent") {
|
|
141
|
+
const hostId = node.data.attachedToRef ?? node.parentId;
|
|
142
|
+
const host = hostId ? nodeById.get(hostId) : void 0;
|
|
143
|
+
if (!host || !BPMN_ELEMENT_CATALOG[host.data.elementType]?.acceptsBoundaryEvents) {
|
|
144
|
+
issues.push(issue("bpmn/boundary-event-attached", "error", "Boundary events must be attached to an activity or subprocess.", node.id, hostId ? [hostId] : void 0));
|
|
145
|
+
}
|
|
146
|
+
if (sequenceIn(edges, node.id).length > 0) {
|
|
147
|
+
issues.push(issue("bpmn/boundary-no-incoming", "error", "Boundary events cannot have incoming sequence flows.", node.id));
|
|
148
|
+
}
|
|
149
|
+
if (sequenceOut(edges, node.id).length === 0) {
|
|
150
|
+
issues.push(issue("bpmn/boundary-has-outgoing", "warning", "Boundary events should define an outgoing exception path.", node.id));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (isGatewayType(type)) {
|
|
154
|
+
if (incoming === 0) issues.push(issue("bpmn/gateway-has-incoming", "error", "Gateways should have at least one incoming sequence flow.", node.id));
|
|
155
|
+
if (outgoing === 0) issues.push(issue("bpmn/gateway-has-outgoing", "error", "Gateways should have at least one outgoing sequence flow.", node.id));
|
|
156
|
+
}
|
|
157
|
+
if (type === "ExclusiveGateway" || type === "InclusiveGateway" || type === "ComplexGateway") {
|
|
158
|
+
const outgoingEdges = sequenceOut(edges, node.id);
|
|
159
|
+
const defaults = outgoingEdges.filter((edge) => edge.data?.isDefault);
|
|
160
|
+
if (defaults.length > 1) {
|
|
161
|
+
issues.push(issue("bpmn/gateway-single-default", "error", "Gateways can have at most one default sequence flow.", node.id, defaults.map((edge) => edge.id)));
|
|
162
|
+
}
|
|
163
|
+
if (outgoingEdges.length >= 2) {
|
|
164
|
+
for (const edge of outgoingEdges) {
|
|
165
|
+
if (!edge.data?.isDefault && !edge.data?.conditionExpression) {
|
|
166
|
+
issues.push(issue("bpmn/gateway-condition", "error", "Conditional gateway branches should have a condition or be marked as default.", edge.id, [node.id, edge.target]));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (type === "EventBasedGateway") {
|
|
172
|
+
const outgoingEdges = edges.filter((edge) => edge.data?.edgeType === "sequenceFlow" && edge.source === node.id);
|
|
173
|
+
if (outgoingEdges.length < 2) {
|
|
174
|
+
issues.push(issue("bpmn/event-based-gateway-min-outgoing", "error", "Event-based gateways should have at least two outgoing sequence flows.", node.id));
|
|
175
|
+
}
|
|
176
|
+
for (const edge of outgoingEdges) {
|
|
177
|
+
const target = nodeById.get(edge.target);
|
|
178
|
+
if (target && !isCatchTarget(target.data.elementType)) {
|
|
179
|
+
issues.push(issue("bpmn/event-based-gateway-valid-targets", "error", "Event-based gateways must target catch events or receive tasks.", edge.id, [node.id, target.id]));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (meta.maxIncoming !== void 0 && incoming > meta.maxIncoming) {
|
|
184
|
+
issues.push(issue("bpmn/max-incoming", "error", `${type} cannot have more than ${meta.maxIncoming} incoming sequence flow(s).`, node.id));
|
|
185
|
+
}
|
|
186
|
+
if (meta.maxOutgoing !== void 0 && outgoing > meta.maxOutgoing) {
|
|
187
|
+
issues.push(issue("bpmn/max-outgoing", "error", `${type} cannot have more than ${meta.maxOutgoing} outgoing sequence flow(s).`, node.id));
|
|
188
|
+
}
|
|
189
|
+
if (opts.strictNames && (type.includes("Task") || isGatewayType(type)) && !node.data.label) {
|
|
190
|
+
issues.push(issue("bpmn/name-required", "warning", `${type} should have a label.`, node.id));
|
|
191
|
+
}
|
|
192
|
+
if (isSubProcess(type)) {
|
|
193
|
+
const childNodes = nodes.filter((child) => child.parentId === node.id);
|
|
194
|
+
if (childNodes.length > 0) {
|
|
195
|
+
if (!childNodes.some((child) => child.data.elementType === "StartEvent")) {
|
|
196
|
+
issues.push(issue("bpmn/subprocess-has-start-end", "error", "Expanded subprocesses should contain a start event.", node.id));
|
|
197
|
+
}
|
|
198
|
+
if (!childNodes.some((child) => child.data.elementType === "EndEvent")) {
|
|
199
|
+
issues.push(issue("bpmn/subprocess-has-start-end", "error", "Expanded subprocesses should contain an end event.", node.id));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
if (type === "EventSubProcess") {
|
|
203
|
+
const starts = childNodes.filter((child) => child.data.elementType === "StartEvent");
|
|
204
|
+
for (const start of starts) {
|
|
205
|
+
if (!start.data.trigger || start.data.trigger === "none") {
|
|
206
|
+
issues.push(issue("bpmn/event-subprocess-triggered-start", "error", "Event subprocess start events must define an event trigger.", start.id, [node.id]));
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (type === "Lane") {
|
|
212
|
+
const parent = node.parentId ? nodeById.get(node.parentId) : void 0;
|
|
213
|
+
if (parent?.data.elementType !== "Pool") {
|
|
214
|
+
issues.push(issue("bpmn/lane-parent-pool", "error", "Lanes must be contained by a pool.", node.id));
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return {
|
|
219
|
+
valid: issues.every((item) => item.severity !== "error"),
|
|
220
|
+
issues
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export { validateBpmnDiagram };
|
|
4
225
|
//# sourceMappingURL=index.js.map
|
|
5
226
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
|
1
|
+
{"version":3,"sources":["../../src/validation/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { BPMN_ELEMENT_CATALOG } from \"../elements/catalog\";\nimport {\n isDataType,\n isEventType,\n isGatewayType,\n} from \"../elements/guards\";\nimport type { BpmnElementType } from \"../elements/types\";\nimport type { BpmnRFEdge, BpmnRFNode } from \"../xml/types\";\n\nexport type BpmnValidationSeverity = \"error\" | \"warning\" | \"info\";\n\nexport interface BpmnValidationIssue {\n id: string;\n severity: BpmnValidationSeverity;\n code: string;\n message: string;\n elementId?: string;\n relatedElementIds?: string[];\n}\n\nexport interface BpmnValidationResult {\n valid: boolean;\n issues: BpmnValidationIssue[];\n}\n\nexport interface BpmnValidationOptions {\n requireStartEvent?: boolean;\n requireEndEvent?: boolean;\n strictNames?: boolean;\n}\n\nfunction isFlowNode(type: BpmnElementType): boolean {\n return (\n isEventType(type) ||\n isGatewayType(type) ||\n type.includes(\"Task\") ||\n type === \"CallActivity\" ||\n type === \"SubProcess\" ||\n type === \"Transaction\" ||\n type === \"EventSubProcess\" ||\n type === \"AdHocSubProcess\" ||\n type === \"ChoreographyTask\" ||\n type === \"SubChoreography\" ||\n type === \"CallChoreography\"\n );\n}\n\nfunction isProcessNode(type: BpmnElementType): boolean {\n return isFlowNode(type) && type !== \"BoundaryEvent\";\n}\n\nfunction isSubProcess(type: BpmnElementType): boolean {\n return (\n type === \"SubProcess\" ||\n type === \"Transaction\" ||\n type === \"EventSubProcess\" ||\n type === \"AdHocSubProcess\"\n );\n}\n\nfunction isCatchTarget(type: BpmnElementType): boolean {\n return type === \"IntermediateCatchEvent\" || type === \"ReceiveTask\";\n}\n\nfunction poolAncestor(\n node: BpmnRFNode | undefined,\n nodeById: Map<string, BpmnRFNode>,\n): string | undefined {\n let current = node;\n const visited = new Set<string>();\n while (current?.parentId && !visited.has(current.id)) {\n visited.add(current.id);\n const parent = nodeById.get(current.parentId);\n if (parent?.data.elementType === \"Pool\") return parent.id;\n current = parent;\n }\n return undefined;\n}\n\nfunction countSequenceEdges(edges: BpmnRFEdge[], nodeId: string, direction: \"in\" | \"out\"): number {\n return edges.filter((edge) => {\n if (edge.data?.edgeType !== \"sequenceFlow\") return false;\n return direction === \"in\" ? edge.target === nodeId : edge.source === nodeId;\n }).length;\n}\n\nfunction sequenceEdges(edges: BpmnRFEdge[]): BpmnRFEdge[] {\n return edges.filter((edge) => (edge.data?.edgeType ?? edge.type) === \"sequenceFlow\");\n}\n\nfunction sequenceOut(edges: BpmnRFEdge[], nodeId: string): BpmnRFEdge[] {\n return sequenceEdges(edges).filter((edge) => edge.source === nodeId);\n}\n\nfunction sequenceIn(edges: BpmnRFEdge[], nodeId: string): BpmnRFEdge[] {\n return sequenceEdges(edges).filter((edge) => edge.target === nodeId);\n}\n\nfunction issue(\n code: string,\n severity: BpmnValidationSeverity,\n message: string,\n elementId?: string,\n relatedElementIds?: string[],\n): BpmnValidationIssue {\n return {\n id: `${code}:${elementId ?? relatedElementIds?.join(\",\") ?? \"diagram\"}`,\n code,\n severity,\n message,\n ...(elementId ? { elementId } : {}),\n ...(relatedElementIds ? { relatedElementIds } : {}),\n };\n}\n\n/**\n * @deprecated Use `@aranzatech/flowslint` with `runBpmnLint` instead.\n * This function will be removed in v0.4.0.\n * Import it from the `/validation` subpath if you still need it temporarily.\n */\nexport function validateBpmnDiagram(\n nodes: BpmnRFNode[],\n edges: BpmnRFEdge[],\n options: BpmnValidationOptions = {},\n): BpmnValidationResult {\n const opts = {\n requireStartEvent: true,\n requireEndEvent: true,\n strictNames: false,\n ...options,\n };\n const issues: BpmnValidationIssue[] = [];\n const nodeById = new Map(nodes.map((node) => [node.id, node]));\n const seqEdges = sequenceEdges(edges);\n\n const processNodes = nodes.filter((node) => isProcessNode(node.data.elementType));\n if (opts.requireStartEvent && !processNodes.some((node) => node.data.elementType === \"StartEvent\")) {\n issues.push(issue(\"bpmn/start-event-required\", \"error\", \"The diagram must contain at least one start event.\"));\n }\n if (opts.requireEndEvent && !processNodes.some((node) => node.data.elementType === \"EndEvent\")) {\n issues.push(issue(\"bpmn/end-event-required\", \"error\", \"The diagram must contain at least one end event.\"));\n }\n\n for (const edge of edges) {\n const edgeType = edge.data?.edgeType ?? edge.type;\n const source = nodeById.get(edge.source);\n const target = nodeById.get(edge.target);\n\n if (!source || !target) {\n issues.push(issue(\n \"bpmn/no-orphan-edges\",\n \"error\",\n `Edge \"${edge.id}\" references a missing ${!source ? \"source\" : \"target\"} node.`,\n edge.id,\n [edge.source, edge.target],\n ));\n continue;\n }\n\n if (edge.source === edge.target) {\n issues.push(issue(\"bpmn/no-self-loop\", \"error\", \"BPMN edges cannot connect an element to itself.\", edge.id, [edge.source]));\n }\n\n if (edgeType === \"sequenceFlow\") {\n if (!isFlowNode(source.data.elementType) || !isFlowNode(target.data.elementType) || isDataType(source.data.elementType) || isDataType(target.data.elementType)) {\n issues.push(issue(\"bpmn/sequence-flow-valid-endpoints\", \"error\", \"Sequence flows must connect BPMN flow nodes.\", edge.id, [source.id, target.id]));\n }\n const sourcePool = poolAncestor(source, nodeById);\n const targetPool = poolAncestor(target, nodeById);\n if (sourcePool && targetPool && sourcePool !== targetPool) {\n issues.push(issue(\"bpmn/sequence-flow-no-cross-pool\", \"error\", \"Sequence flows cannot cross pools. Use message flow between participants.\", edge.id, [source.id, target.id]));\n }\n }\n\n if (edgeType === \"messageFlow\") {\n const sourcePool = poolAncestor(source, nodeById);\n const targetPool = poolAncestor(target, nodeById);\n if (!sourcePool || !targetPool || sourcePool === targetPool) {\n issues.push(issue(\"bpmn/message-flow-valid-endpoints\", \"error\", \"Message flows must connect flow nodes in different pools.\", edge.id, [source.id, target.id]));\n }\n if (!isFlowNode(source.data.elementType) || !isFlowNode(target.data.elementType)) {\n issues.push(issue(\"bpmn/message-flow-valid-endpoints\", \"error\", \"Message flows must connect BPMN flow nodes, not containers.\", edge.id, [source.id, target.id]));\n }\n }\n\n if (edgeType === \"dataAssociation\") {\n const hasDataEndpoint = isDataType(source.data.elementType) || isDataType(target.data.elementType);\n const hasFlowEndpoint = isFlowNode(source.data.elementType) || isFlowNode(target.data.elementType);\n if (!hasDataEndpoint || !hasFlowEndpoint) {\n issues.push(issue(\"bpmn/data-association-valid-endpoints\", \"error\", \"Data associations must connect data elements with flow nodes.\", edge.id, [source.id, target.id]));\n }\n }\n }\n\n const duplicateSequenceKeys = new Set<string>();\n const reportedDuplicateKeys = new Set<string>();\n for (const edge of seqEdges) {\n const key = `${edge.source}->${edge.target}`;\n if (duplicateSequenceKeys.has(key) && !reportedDuplicateKeys.has(key)) {\n reportedDuplicateKeys.add(key);\n issues.push(issue(\"bpmn/no-duplicate-sequence-flow\", \"error\", \"Only one sequence flow is allowed between the same source and target.\", edge.id, [edge.source, edge.target]));\n }\n duplicateSequenceKeys.add(key);\n }\n\n for (const node of nodes) {\n const type = node.data.elementType;\n const incoming = countSequenceEdges(edges, node.id, \"in\");\n const outgoing = countSequenceEdges(edges, node.id, \"out\");\n const meta = BPMN_ELEMENT_CATALOG[type];\n\n if (type === \"StartEvent\" && incoming > 0) {\n issues.push(issue(\"bpmn/start-event-no-incoming\", \"error\", \"Start events cannot have incoming sequence flows.\", node.id));\n }\n if (type === \"EndEvent\") {\n if (outgoing > 0) issues.push(issue(\"bpmn/no-outgoing-from-end-event\", \"error\", \"End events cannot have outgoing sequence flows.\", node.id));\n if (incoming === 0) issues.push(issue(\"bpmn/end-event-has-incoming\", \"error\", \"End events should have at least one incoming sequence flow.\", node.id));\n }\n if ((type === \"IntermediateCatchEvent\" || type === \"IntermediateThrowEvent\") && (incoming === 0 || outgoing === 0)) {\n issues.push(issue(\"bpmn/intermediate-event-both-flows\", \"error\", \"Intermediate events should have both incoming and outgoing sequence flows.\", node.id));\n }\n if (type === \"BoundaryEvent\") {\n const hostId = node.data.attachedToRef ?? node.parentId;\n const host = hostId ? nodeById.get(hostId) : undefined;\n if (!host || !BPMN_ELEMENT_CATALOG[host.data.elementType]?.acceptsBoundaryEvents) {\n issues.push(issue(\"bpmn/boundary-event-attached\", \"error\", \"Boundary events must be attached to an activity or subprocess.\", node.id, hostId ? [hostId] : undefined));\n }\n if (sequenceIn(edges, node.id).length > 0) {\n issues.push(issue(\"bpmn/boundary-no-incoming\", \"error\", \"Boundary events cannot have incoming sequence flows.\", node.id));\n }\n if (sequenceOut(edges, node.id).length === 0) {\n issues.push(issue(\"bpmn/boundary-has-outgoing\", \"warning\", \"Boundary events should define an outgoing exception path.\", node.id));\n }\n }\n if (isGatewayType(type)) {\n if (incoming === 0) issues.push(issue(\"bpmn/gateway-has-incoming\", \"error\", \"Gateways should have at least one incoming sequence flow.\", node.id));\n if (outgoing === 0) issues.push(issue(\"bpmn/gateway-has-outgoing\", \"error\", \"Gateways should have at least one outgoing sequence flow.\", node.id));\n }\n if (type === \"ExclusiveGateway\" || type === \"InclusiveGateway\" || type === \"ComplexGateway\") {\n const outgoingEdges = sequenceOut(edges, node.id);\n const defaults = outgoingEdges.filter((edge) => edge.data?.isDefault);\n if (defaults.length > 1) {\n issues.push(issue(\"bpmn/gateway-single-default\", \"error\", \"Gateways can have at most one default sequence flow.\", node.id, defaults.map((edge) => edge.id)));\n }\n if (outgoingEdges.length >= 2) {\n for (const edge of outgoingEdges) {\n if (!edge.data?.isDefault && !edge.data?.conditionExpression) {\n issues.push(issue(\"bpmn/gateway-condition\", \"error\", \"Conditional gateway branches should have a condition or be marked as default.\", edge.id, [node.id, edge.target]));\n }\n }\n }\n }\n if (type === \"EventBasedGateway\") {\n const outgoingEdges = edges.filter((edge) => edge.data?.edgeType === \"sequenceFlow\" && edge.source === node.id);\n if (outgoingEdges.length < 2) {\n issues.push(issue(\"bpmn/event-based-gateway-min-outgoing\", \"error\", \"Event-based gateways should have at least two outgoing sequence flows.\", node.id));\n }\n for (const edge of outgoingEdges) {\n const target = nodeById.get(edge.target);\n if (target && !isCatchTarget(target.data.elementType)) {\n issues.push(issue(\"bpmn/event-based-gateway-valid-targets\", \"error\", \"Event-based gateways must target catch events or receive tasks.\", edge.id, [node.id, target.id]));\n }\n }\n }\n if (meta.maxIncoming !== undefined && incoming > meta.maxIncoming) {\n issues.push(issue(\"bpmn/max-incoming\", \"error\", `${type} cannot have more than ${meta.maxIncoming} incoming sequence flow(s).`, node.id));\n }\n if (meta.maxOutgoing !== undefined && outgoing > meta.maxOutgoing) {\n issues.push(issue(\"bpmn/max-outgoing\", \"error\", `${type} cannot have more than ${meta.maxOutgoing} outgoing sequence flow(s).`, node.id));\n }\n if (opts.strictNames && (type.includes(\"Task\") || isGatewayType(type)) && !node.data.label) {\n issues.push(issue(\"bpmn/name-required\", \"warning\", `${type} should have a label.`, node.id));\n }\n if (isSubProcess(type)) {\n const childNodes = nodes.filter((child) => child.parentId === node.id);\n if (childNodes.length > 0) {\n if (!childNodes.some((child) => child.data.elementType === \"StartEvent\")) {\n issues.push(issue(\"bpmn/subprocess-has-start-end\", \"error\", \"Expanded subprocesses should contain a start event.\", node.id));\n }\n if (!childNodes.some((child) => child.data.elementType === \"EndEvent\")) {\n issues.push(issue(\"bpmn/subprocess-has-start-end\", \"error\", \"Expanded subprocesses should contain an end event.\", node.id));\n }\n }\n if (type === \"EventSubProcess\") {\n const starts = childNodes.filter((child) => child.data.elementType === \"StartEvent\");\n for (const start of starts) {\n if (!start.data.trigger || start.data.trigger === \"none\") {\n issues.push(issue(\"bpmn/event-subprocess-triggered-start\", \"error\", \"Event subprocess start events must define an event trigger.\", start.id, [node.id]));\n }\n }\n }\n }\n if (type === \"Lane\") {\n const parent = node.parentId ? nodeById.get(node.parentId) : undefined;\n if (parent?.data.elementType !== \"Pool\") {\n issues.push(issue(\"bpmn/lane-parent-pool\", \"error\", \"Lanes must be contained by a pool.\", node.id));\n }\n }\n }\n\n return {\n valid: issues.every((item) => item.severity !== \"error\"),\n issues,\n };\n}\n"]}
|
package/dist/xml/index.cjs
CHANGED
|
@@ -1,8 +1,35 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
// src/xml/aranza-descriptor.ts
|
|
4
|
+
var ARANZA_DESCRIPTOR = {
|
|
5
|
+
name: "Aranza",
|
|
6
|
+
uri: "http://aranzatech.io/schema/bpmn-extension/1.0",
|
|
7
|
+
prefix: "aranza",
|
|
8
|
+
xml: { tagAlias: "lowerCase" },
|
|
9
|
+
types: [
|
|
10
|
+
{
|
|
11
|
+
name: "TaskConfig",
|
|
12
|
+
superClass: ["Element"],
|
|
13
|
+
properties: [
|
|
14
|
+
{ name: "priority", isAttr: true, type: "String" },
|
|
15
|
+
{ name: "owner", isAttr: true, type: "String" },
|
|
16
|
+
{ name: "sla", isAttr: true, type: "String" },
|
|
17
|
+
// Aranza connector execution config (resolved at runtime by the Flowable delegate)
|
|
18
|
+
{ name: "connector", isAttr: true, type: "String" },
|
|
19
|
+
{ name: "action", isAttr: true, type: "String" },
|
|
20
|
+
// Flowable implementation hints stored for round-trip fidelity
|
|
21
|
+
{ name: "flowableType", isAttr: true, type: "String" },
|
|
22
|
+
{ name: "flowableDelegateExpression", isAttr: true, type: "String" },
|
|
23
|
+
// BusinessRuleTask: reference to a DMN decision table id
|
|
24
|
+
{ name: "decisionRef", isAttr: true, type: "String" },
|
|
25
|
+
// UserTask: form key resolved to a FormDefinition name at runtime
|
|
26
|
+
{ name: "formKey", isAttr: true, type: "String" }
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
enumerations: [],
|
|
31
|
+
associations: []
|
|
32
|
+
};
|
|
6
33
|
|
|
7
34
|
// src/elements/catalog.ts
|
|
8
35
|
var BPMN_ELEMENT_CATALOG = {
|
|
@@ -860,6 +887,49 @@ function extractSubProcessVariant(el) {
|
|
|
860
887
|
if (el.triggeredByEvent === true) return "event";
|
|
861
888
|
return "embedded";
|
|
862
889
|
}
|
|
890
|
+
function extractAranzaExtensions(el) {
|
|
891
|
+
const result = {};
|
|
892
|
+
const elAttrs = el.$attrs;
|
|
893
|
+
if (elAttrs) {
|
|
894
|
+
const ft = asString(elAttrs["flowable:type"]);
|
|
895
|
+
if (ft) result.flowableType = ft;
|
|
896
|
+
const fde = asString(elAttrs["flowable:delegateExpression"]);
|
|
897
|
+
if (fde) result.flowableDelegateExpression = fde;
|
|
898
|
+
const fk = asString(elAttrs["flowable:formKey"]);
|
|
899
|
+
if (fk) result.formKey = fk;
|
|
900
|
+
}
|
|
901
|
+
const ext = el.extensionElements;
|
|
902
|
+
if (!ext) return result;
|
|
903
|
+
const taskConfig = asElements(ext.values).find((v) => v.$type === "aranza:TaskConfig");
|
|
904
|
+
if (!taskConfig) return result;
|
|
905
|
+
const priority = asString(taskConfig.priority);
|
|
906
|
+
if (priority === "critical" || priority === "high" || priority === "medium" || priority === "low") {
|
|
907
|
+
result.priority = priority;
|
|
908
|
+
}
|
|
909
|
+
const owner = asString(taskConfig.owner);
|
|
910
|
+
if (owner) result.owner = owner;
|
|
911
|
+
const sla = asString(taskConfig.sla);
|
|
912
|
+
if (sla) result.sla = sla;
|
|
913
|
+
const connector = asString(taskConfig.connector);
|
|
914
|
+
if (connector) result.connector = connector;
|
|
915
|
+
const action = asString(taskConfig.action);
|
|
916
|
+
if (action) result.action = action;
|
|
917
|
+
const flowableType = asString(taskConfig.flowableType);
|
|
918
|
+
if (flowableType) result.flowableType = flowableType;
|
|
919
|
+
const flowableDelegateExpression = asString(taskConfig.flowableDelegateExpression);
|
|
920
|
+
if (flowableDelegateExpression) result.flowableDelegateExpression = flowableDelegateExpression;
|
|
921
|
+
const decisionRef = asString(taskConfig.decisionRef);
|
|
922
|
+
if (decisionRef) result.decisionRef = decisionRef;
|
|
923
|
+
const formKey = asString(taskConfig.formKey);
|
|
924
|
+
if (formKey) result.formKey = formKey;
|
|
925
|
+
return result;
|
|
926
|
+
}
|
|
927
|
+
function extractCompletionCondition(el) {
|
|
928
|
+
const cc = el.completionCondition;
|
|
929
|
+
if (!cc) return void 0;
|
|
930
|
+
if (typeof cc === "string") return cc.trim() || void 0;
|
|
931
|
+
return asString(cc.body);
|
|
932
|
+
}
|
|
863
933
|
function walkFlowElements(elements, parentId, ctx, nodes, edges) {
|
|
864
934
|
for (const el of elements) {
|
|
865
935
|
const { $type, id } = el;
|
|
@@ -896,6 +966,11 @@ function buildNode(el, elementType, parentId, ctx, nodes) {
|
|
|
896
966
|
const eventDefinition = extractEventDefinition(el);
|
|
897
967
|
const isNonInterrupting = el.cancelActivity === false;
|
|
898
968
|
const attachedToRef = el.attachedToRef?.id;
|
|
969
|
+
const calledElement = elementType === "CallActivity" ? asString(el.calledElement) : void 0;
|
|
970
|
+
const aranzaExt = extractAranzaExtensions(el);
|
|
971
|
+
const scriptFormat = elementType === "ScriptTask" ? asString(el.scriptFormat) : void 0;
|
|
972
|
+
const script = elementType === "ScriptTask" ? asString(el.script) : void 0;
|
|
973
|
+
const completionCondition = elementType === "AdHocSubProcess" ? extractCompletionCondition(el) : void 0;
|
|
899
974
|
const data = {
|
|
900
975
|
elementType,
|
|
901
976
|
...label ? { label } : {},
|
|
@@ -911,7 +986,12 @@ function buildNode(el, elementType, parentId, ctx, nodes) {
|
|
|
911
986
|
...eventDefinition?.errorRef ? { errorRef: eventDefinition.errorRef } : {},
|
|
912
987
|
...eventDefinition?.escalationRef ? { escalationRef: eventDefinition.escalationRef } : {},
|
|
913
988
|
...eventDefinition?.conditionExpression ? { conditionExpression: eventDefinition.conditionExpression } : {},
|
|
914
|
-
...eventDefinition?.linkName ? { linkName: eventDefinition.linkName } : {}
|
|
989
|
+
...eventDefinition?.linkName ? { linkName: eventDefinition.linkName } : {},
|
|
990
|
+
...calledElement ? { calledElement } : {},
|
|
991
|
+
...scriptFormat ? { scriptFormat } : {},
|
|
992
|
+
...script ? { script } : {},
|
|
993
|
+
...completionCondition ? { completionCondition } : {},
|
|
994
|
+
...aranzaExt
|
|
915
995
|
};
|
|
916
996
|
if (elementType === "SubProcess" || elementType === "Transaction" || elementType === "EventSubProcess" || elementType === "AdHocSubProcess") {
|
|
917
997
|
const variant = extractSubProcessVariant(el);
|
|
@@ -1011,7 +1091,8 @@ function addLaneNodes(laneSet, poolId, ctx, nodes) {
|
|
|
1011
1091
|
}
|
|
1012
1092
|
}
|
|
1013
1093
|
async function parseBpmnXml(xml) {
|
|
1014
|
-
const
|
|
1094
|
+
const { BpmnModdle } = await import('bpmn-moddle');
|
|
1095
|
+
const moddle = new BpmnModdle({ aranza: ARANZA_DESCRIPTOR });
|
|
1015
1096
|
const warnings = [];
|
|
1016
1097
|
let rootElement;
|
|
1017
1098
|
try {
|
|
@@ -1101,6 +1182,8 @@ function normalizeChildPositions(nodes, nodeIds) {
|
|
|
1101
1182
|
};
|
|
1102
1183
|
});
|
|
1103
1184
|
}
|
|
1185
|
+
|
|
1186
|
+
// src/xml/exporter.ts
|
|
1104
1187
|
function uid(prefix, id) {
|
|
1105
1188
|
return `${prefix}_${id}`;
|
|
1106
1189
|
}
|
|
@@ -1200,6 +1283,30 @@ function buildEventDefinitions(moddle, node, eventDefinition) {
|
|
|
1200
1283
|
}
|
|
1201
1284
|
return [moddle.create(defType, attrs)];
|
|
1202
1285
|
}
|
|
1286
|
+
function buildAranzaExtensionElements(moddle, node) {
|
|
1287
|
+
const { priority, owner, sla } = node.data;
|
|
1288
|
+
const connector = typeof node.data.connector === "string" ? node.data.connector : void 0;
|
|
1289
|
+
const action = typeof node.data.action === "string" ? node.data.action : void 0;
|
|
1290
|
+
const flowableType = typeof node.data.flowableType === "string" ? node.data.flowableType : void 0;
|
|
1291
|
+
const flowableDelegateExpression = typeof node.data.flowableDelegateExpression === "string" ? node.data.flowableDelegateExpression : void 0;
|
|
1292
|
+
const decisionRef = typeof node.data.decisionRef === "string" ? node.data.decisionRef : void 0;
|
|
1293
|
+
const formKey = typeof node.data.formKey === "string" ? node.data.formKey : void 0;
|
|
1294
|
+
if (!priority && !owner && !sla && !connector && !action && !flowableType && !flowableDelegateExpression && !decisionRef && !formKey) {
|
|
1295
|
+
return null;
|
|
1296
|
+
}
|
|
1297
|
+
const configAttrs = {};
|
|
1298
|
+
if (priority) configAttrs.priority = priority;
|
|
1299
|
+
if (owner) configAttrs.owner = owner;
|
|
1300
|
+
if (sla) configAttrs.sla = sla;
|
|
1301
|
+
if (connector) configAttrs.connector = connector;
|
|
1302
|
+
if (action) configAttrs.action = action;
|
|
1303
|
+
if (flowableType) configAttrs.flowableType = flowableType;
|
|
1304
|
+
if (flowableDelegateExpression) configAttrs.flowableDelegateExpression = flowableDelegateExpression;
|
|
1305
|
+
if (decisionRef) configAttrs.decisionRef = decisionRef;
|
|
1306
|
+
if (formKey) configAttrs.formKey = formKey;
|
|
1307
|
+
const taskConfig = moddle.create("aranza:TaskConfig", configAttrs);
|
|
1308
|
+
return moddle.create("bpmn:ExtensionElements", { values: [taskConfig] });
|
|
1309
|
+
}
|
|
1203
1310
|
function buildSemanticModel(moddle, nodes, edges, opts) {
|
|
1204
1311
|
const defId = opts.id ?? "Definitions_1";
|
|
1205
1312
|
const defName = opts.name;
|
|
@@ -1369,12 +1476,44 @@ function buildFlowElement(moddle, node, allNodes, allEdges) {
|
|
|
1369
1476
|
const interrupting = node.data.cancelActivity ?? !node.data.isNonInterrupting;
|
|
1370
1477
|
attrs.cancelActivity = interrupting;
|
|
1371
1478
|
}
|
|
1479
|
+
if (elementType === "CallActivity" && node.data.calledElement) {
|
|
1480
|
+
attrs.calledElement = node.data.calledElement;
|
|
1481
|
+
}
|
|
1482
|
+
if (elementType === "ScriptTask") {
|
|
1483
|
+
const scriptFormat = typeof node.data.scriptFormat === "string" ? node.data.scriptFormat : void 0;
|
|
1484
|
+
const script = typeof node.data.script === "string" ? node.data.script : void 0;
|
|
1485
|
+
if (scriptFormat) attrs.scriptFormat = scriptFormat;
|
|
1486
|
+
if (script) attrs.script = script;
|
|
1487
|
+
}
|
|
1488
|
+
if (elementType === "UserTask") {
|
|
1489
|
+
const fk = typeof node.data.formKey === "string" ? node.data.formKey : void 0;
|
|
1490
|
+
if (fk) attrs.$attrs = { "flowable:formKey": fk };
|
|
1491
|
+
}
|
|
1492
|
+
if (elementType === "ServiceTask") {
|
|
1493
|
+
const flowableAttrs = {};
|
|
1494
|
+
const flowableType = typeof node.data.flowableType === "string" ? node.data.flowableType : void 0;
|
|
1495
|
+
const flowableDelegateExpression = typeof node.data.flowableDelegateExpression === "string" ? node.data.flowableDelegateExpression : void 0;
|
|
1496
|
+
const connector = typeof node.data.connector === "string" ? node.data.connector : void 0;
|
|
1497
|
+
if (connector) flowableAttrs["flowable:type"] = "http";
|
|
1498
|
+
if (flowableType) flowableAttrs["flowable:type"] = flowableType;
|
|
1499
|
+
if (flowableDelegateExpression) {
|
|
1500
|
+
flowableAttrs["flowable:delegateExpression"] = flowableDelegateExpression;
|
|
1501
|
+
}
|
|
1502
|
+
if (Object.keys(flowableAttrs).length > 0) attrs.$attrs = flowableAttrs;
|
|
1503
|
+
}
|
|
1504
|
+
const aranzaConfig = buildAranzaExtensionElements(moddle, node);
|
|
1505
|
+
if (aranzaConfig) attrs.extensionElements = aranzaConfig;
|
|
1372
1506
|
const isSubProcess = elementType === "SubProcess" || elementType === "Transaction" || elementType === "EventSubProcess" || elementType === "AdHocSubProcess";
|
|
1373
1507
|
if (isSubProcess) {
|
|
1374
1508
|
attrs.flowElements = buildNestedFlowElements(moddle, node, allNodes, allEdges);
|
|
1375
1509
|
if (elementType === "EventSubProcess" || node.data.subProcessVariant === "event") {
|
|
1376
1510
|
attrs.triggeredByEvent = true;
|
|
1377
1511
|
}
|
|
1512
|
+
if (elementType === "AdHocSubProcess" && typeof node.data.completionCondition === "string" && node.data.completionCondition.trim()) {
|
|
1513
|
+
attrs.completionCondition = moddle.create("bpmn:FormalExpression", {
|
|
1514
|
+
body: node.data.completionCondition.trim()
|
|
1515
|
+
});
|
|
1516
|
+
}
|
|
1378
1517
|
}
|
|
1379
1518
|
const element = moddle.create(moddleType, attrs);
|
|
1380
1519
|
return element;
|
|
@@ -1506,7 +1645,8 @@ function buildAbsolutePositionMap(nodes) {
|
|
|
1506
1645
|
return absoluteById;
|
|
1507
1646
|
}
|
|
1508
1647
|
async function serializeBpmnXml(nodes, edges, opts = {}) {
|
|
1509
|
-
const
|
|
1648
|
+
const { BpmnModdle } = await import('bpmn-moddle');
|
|
1649
|
+
const moddle = new BpmnModdle({ aranza: ARANZA_DESCRIPTOR });
|
|
1510
1650
|
const definitions = buildSemanticModel(moddle, nodes, edges, opts);
|
|
1511
1651
|
buildBpmnDI(moddle, definitions, nodes, edges);
|
|
1512
1652
|
const { xml } = await moddle.toXML(definitions, {
|