@aranzatech/diagrams-bpmn 0.2.10 → 0.2.12
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 +25 -0
- package/dist/{catalog-BOwJOaXV.d.ts → catalog-BKdtbOQT.d.ts} +1 -1
- package/dist/{catalog-Ch3YT0-0.d.cts → catalog-DUfPajtM.d.cts} +1 -1
- package/dist/{chunk-HLCUGTEK.js → chunk-MZVDC6FU.js} +150 -28
- package/dist/chunk-MZVDC6FU.js.map +1 -0
- package/dist/elements/index.d.cts +3 -3
- package/dist/elements/index.d.ts +3 -3
- package/dist/index.cjs +273 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +102 -4
- package/dist/index.d.ts +102 -4
- package/dist/index.js +128 -1
- package/dist/index.js.map +1 -1
- package/dist/layout/index.cjs +87 -0
- package/dist/layout/index.cjs.map +1 -1
- package/dist/layout/index.d.cts +22 -4
- package/dist/layout/index.d.ts +22 -4
- package/dist/layout/index.js +90 -2
- package/dist/layout/index.js.map +1 -1
- package/dist/modeling/index.d.cts +3 -3
- package/dist/modeling/index.d.ts +3 -3
- package/dist/{types-C7tONwP5.d.cts → types-44yNtMtO.d.cts} +1 -1
- package/dist/{types-BTuiBv7p.d.cts → types-hgmLfRA9.d.cts} +16 -0
- package/dist/{types-BTuiBv7p.d.ts → types-hgmLfRA9.d.ts} +16 -0
- package/dist/{types-DSDMCAre.d.ts → types-kI1SiQB4.d.ts} +1 -1
- package/dist/validation/index.d.cts +2 -2
- package/dist/validation/index.d.ts +2 -2
- package/dist/xml/index.cjs +148 -26
- package/dist/xml/index.cjs.map +1 -1
- package/dist/xml/index.d.cts +3 -3
- package/dist/xml/index.d.ts +3 -3
- package/dist/xml/index.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-HLCUGTEK.js.map +0 -1
package/dist/layout/index.js
CHANGED
|
@@ -1,9 +1,97 @@
|
|
|
1
1
|
import { getBpmnNodeSize } from '../chunk-UAWLUDKC.js';
|
|
2
2
|
import '../chunk-RLAJNRF2.js';
|
|
3
3
|
import '../chunk-L5Z22RLX.js';
|
|
4
|
-
import { dagreLayout, applyLayoutResultToDiagram } from '@aranzatech/diagrams-core/layout';
|
|
4
|
+
import { elkLayout, dagreLayout, applyLayoutResultToDiagram } from '@aranzatech/diagrams-core/layout';
|
|
5
5
|
export { applyLayoutResultToDiagram } from '@aranzatech/diagrams-core/layout';
|
|
6
6
|
|
|
7
|
+
var BPMN_CONTAINER_TYPES = /* @__PURE__ */ new Set([
|
|
8
|
+
"Pool",
|
|
9
|
+
"Lane",
|
|
10
|
+
"SubProcess",
|
|
11
|
+
"Transaction",
|
|
12
|
+
"EventSubProcess",
|
|
13
|
+
"AdHocSubProcess"
|
|
14
|
+
]);
|
|
15
|
+
var CONTAINER_MIN_SIZE = {
|
|
16
|
+
Pool: { w: 560, h: 160 },
|
|
17
|
+
Lane: { w: 480, h: 100 },
|
|
18
|
+
SubProcess: { w: 200, h: 120 },
|
|
19
|
+
Transaction: { w: 200, h: 120 },
|
|
20
|
+
EventSubProcess: { w: 200, h: 120 },
|
|
21
|
+
AdHocSubProcess: { w: 200, h: 120 }
|
|
22
|
+
};
|
|
23
|
+
var CONTAINER_PADDING = {
|
|
24
|
+
Pool: "[top=20,left=30,bottom=20,right=20]",
|
|
25
|
+
Lane: "[top=20,left=50,bottom=20,right=50]",
|
|
26
|
+
SubProcess: "[top=20,left=30,bottom=20,right=30]",
|
|
27
|
+
Transaction: "[top=20,left=30,bottom=20,right=30]",
|
|
28
|
+
EventSubProcess: "[top=20,left=30,bottom=20,right=30]",
|
|
29
|
+
AdHocSubProcess: "[top=20,left=30,bottom=20,right=30]"
|
|
30
|
+
};
|
|
31
|
+
async function bpmnElkLayout(nodes, edges) {
|
|
32
|
+
const poolsWithLanes = /* @__PURE__ */ new Set();
|
|
33
|
+
for (const node of nodes) {
|
|
34
|
+
if (node.data.elementType === "Lane" && node.parentId) {
|
|
35
|
+
poolsWithLanes.add(node.parentId);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const result = await elkLayout(
|
|
39
|
+
nodes,
|
|
40
|
+
edges,
|
|
41
|
+
{
|
|
42
|
+
direction: "LR",
|
|
43
|
+
getNodeSize: (node) => {
|
|
44
|
+
const bNode = node;
|
|
45
|
+
if (BPMN_CONTAINER_TYPES.has(bNode.data.elementType)) return void 0;
|
|
46
|
+
return getBpmnNodeSize(bNode);
|
|
47
|
+
},
|
|
48
|
+
isContainerNode: (node) => BPMN_CONTAINER_TYPES.has(node.data.elementType),
|
|
49
|
+
getNodeLayoutOptions: (node) => {
|
|
50
|
+
const type = node.data.elementType;
|
|
51
|
+
if (!BPMN_CONTAINER_TYPES.has(type)) return void 0;
|
|
52
|
+
const min = CONTAINER_MIN_SIZE[type];
|
|
53
|
+
const dir = type === "Pool" && poolsWithLanes.has(node.id) ? "DOWN" : "RIGHT";
|
|
54
|
+
return {
|
|
55
|
+
"elk.direction": dir,
|
|
56
|
+
"elk.nodeSize.constraints": "MINIMUM_SIZE",
|
|
57
|
+
...min ? { "elk.nodeSize.minimum": `[w=${min.w},h=${min.h}]` } : {},
|
|
58
|
+
...CONTAINER_PADDING[type] ? { "elk.padding": CONTAINER_PADDING[type] } : {}
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
elk: {
|
|
62
|
+
"elk.algorithm": "layered",
|
|
63
|
+
"elk.direction": "RIGHT",
|
|
64
|
+
"elk.hierarchyHandling": "INCLUDE_CHILDREN",
|
|
65
|
+
"elk.edgeRouting": "ORTHOGONAL",
|
|
66
|
+
"elk.layered.spacing.nodeNodeBetweenLayers": "80",
|
|
67
|
+
"elk.layered.spacing.edgeNodeBetweenLayers": "20",
|
|
68
|
+
"elk.spacing.nodeNode": "40",
|
|
69
|
+
"elk.spacing.componentComponent": "60"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
const nodeMap = new Map(result.nodes.map((n) => [n.id, n]));
|
|
74
|
+
const edgeMap = new Map(result.edges.map((e) => [e.id, e]));
|
|
75
|
+
const updatedNodes = nodes.map((node) => {
|
|
76
|
+
const laid = nodeMap.get(node.id);
|
|
77
|
+
if (!laid) return node;
|
|
78
|
+
return { ...node, position: laid.position, width: laid.width, height: laid.height };
|
|
79
|
+
});
|
|
80
|
+
const updatedEdges = edges.map((edge) => {
|
|
81
|
+
const laid = edgeMap.get(edge.id);
|
|
82
|
+
if (!laid) return edge;
|
|
83
|
+
const nextData = { ...edge.data };
|
|
84
|
+
if (laid.points && laid.points.length > 0) {
|
|
85
|
+
nextData.routingPoints = laid.points;
|
|
86
|
+
} else {
|
|
87
|
+
delete nextData.routingPoints;
|
|
88
|
+
}
|
|
89
|
+
return { ...edge, data: nextData };
|
|
90
|
+
});
|
|
91
|
+
return { nodes: updatedNodes, edges: updatedEdges };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// src/layout/index.ts
|
|
7
95
|
async function bpmnDagreLayout(nodes, edges, options = {}) {
|
|
8
96
|
return dagreLayout(nodes, edges, {
|
|
9
97
|
...options,
|
|
@@ -14,6 +102,6 @@ function applyBpmnLayoutResult(state, result) {
|
|
|
14
102
|
return applyLayoutResultToDiagram(state, result);
|
|
15
103
|
}
|
|
16
104
|
|
|
17
|
-
export { applyBpmnLayoutResult, bpmnDagreLayout };
|
|
105
|
+
export { applyBpmnLayoutResult, bpmnDagreLayout, bpmnElkLayout };
|
|
18
106
|
//# sourceMappingURL=index.js.map
|
|
19
107
|
//# sourceMappingURL=index.js.map
|
package/dist/layout/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/layout/index.ts"],"names":[],"mappings":";;;;;;AAcA,eAAsB,eAAA,CACpB,KAAA,EACA,KAAA,EACA,OAAA,GAAyB,EAAC,EACH;AACvB,EAAA,OAAO,WAAA,CAAY,OAAwB,KAAA,EAAwB;AAAA,IACjE,GAAG,OAAA;AAAA,IACH,WAAA,EAAa,CAAC,IAAA,KAAS,eAAA,CAAgB,IAAkB;AAAA,GAC1D,CAAA;AACH;AAMO,SAAS,qBAAA,CACd,OACA,MAAA,EACkB;AAClB,EAAA,OAAO,0BAAA,CAA2B,OAAO,MAAM,CAAA;AACjD","file":"index.js","sourcesContent":["import type { DiagramEdge, LayoutOptions, LayoutResult } from \"@aranzatech/diagrams-core/types\";\nimport { dagreLayout, applyLayoutResultToDiagram } from \"@aranzatech/diagrams-core/layout\";\nimport type { DiagramNode } from \"@aranzatech/diagrams-core/types\";\nimport type { BpmnRFNode, BpmnRFEdge } from \"../xml/types\";\nimport { getBpmnNodeSize } from \"../modeling\";\nimport type { BpmnDiagramState } from \"../modeling\";\n\nexport { applyLayoutResultToDiagram };\n\n/**\n * Dagre layout pre-configured for BPMN diagrams.\n * Uses BPMN-specific node sizes (events 52×52, gateways 64×64, tasks 192×64, etc.)\n * instead of the generic fallback, which prevents overlaps and poor spacing.\n */\nexport async function bpmnDagreLayout(\n nodes: BpmnRFNode[],\n edges: BpmnRFEdge[],\n options: LayoutOptions = {},\n): Promise<LayoutResult> {\n return dagreLayout(nodes as DiagramNode[], edges as DiagramEdge[], {\n ...options,\n getNodeSize: (node) => getBpmnNodeSize(node as BpmnRFNode),\n });\n}\n\n/**\n * Applies a bpmn dagre layout result back to the diagram state.\n * Convenience wrapper so callers only need one import.\n */\nexport function applyBpmnLayoutResult(\n state: BpmnDiagramState,\n result: LayoutResult,\n): BpmnDiagramState {\n return applyLayoutResultToDiagram(state, result) as BpmnDiagramState;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/layout/elk.ts","../../src/layout/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { elkLayout } from \"@aranzatech/diagrams-core/layout\";\nimport type { DiagramNode, DiagramEdge } from \"@aranzatech/diagrams-core/types\";\nimport type { BpmnRFNode, BpmnRFEdge } from \"../xml/types\";\nimport type { BpmnElementType } from \"../elements/types\";\nimport { getBpmnNodeSize } from \"../modeling\";\n\n// Container types that ELK auto-sizes based on their children.\nconst BPMN_CONTAINER_TYPES = new Set<BpmnElementType>([\n \"Pool\",\n \"Lane\",\n \"SubProcess\",\n \"Transaction\",\n \"EventSubProcess\",\n \"AdHocSubProcess\",\n]);\n\nconst CONTAINER_MIN_SIZE: Partial<Record<BpmnElementType, { w: number; h: number }>> = {\n Pool: { w: 560, h: 160 },\n Lane: { w: 480, h: 100 },\n SubProcess: { w: 200, h: 120 },\n Transaction: { w: 200, h: 120 },\n EventSubProcess: { w: 200, h: 120 },\n AdHocSubProcess: { w: 200, h: 120 },\n};\n\n// Left padding includes the pool label strip (≈30 px).\nconst CONTAINER_PADDING: Partial<Record<BpmnElementType, string>> = {\n Pool: \"[top=20,left=30,bottom=20,right=20]\",\n Lane: \"[top=20,left=50,bottom=20,right=50]\",\n SubProcess: \"[top=20,left=30,bottom=20,right=30]\",\n Transaction: \"[top=20,left=30,bottom=20,right=30]\",\n EventSubProcess: \"[top=20,left=30,bottom=20,right=30]\",\n AdHocSubProcess: \"[top=20,left=30,bottom=20,right=30]\",\n};\n\n/**\n * ELK-based auto-layout for BPMN diagrams.\n *\n * Direction policy — always LEFT-TO-RIGHT to match screen anatomy:\n * - Root: RIGHT — free nodes and pools flow LR on the canvas.\n * - Pool that contains Lanes: DOWN internally so lanes stack top-to-bottom\n * (standard horizontal-pool anatomy); the pool itself is still placed LR.\n * - Pool without lanes, Lane, SubProcess, Transaction, AdHoc: RIGHT — content\n * flows left-to-right inside the container.\n * - All edges get ORTHOGONAL routing in a single INCLUDE_CHILDREN pass so\n * cross-pool and cross-lane edges are routed correctly.\n * - Containers auto-resize to fit their children.\n */\nexport async function bpmnElkLayout(\n nodes: BpmnRFNode[],\n edges: BpmnRFEdge[],\n): Promise<{ nodes: BpmnRFNode[]; edges: BpmnRFEdge[] }> {\n // Pools that contain at least one Lane child need DOWN internal direction so\n // the lanes stack vertically (standard horizontal BPMN pool).\n const poolsWithLanes = new Set<string>();\n for (const node of nodes) {\n if (node.data.elementType === \"Lane\" && node.parentId) {\n poolsWithLanes.add(node.parentId);\n }\n }\n\n const result = await elkLayout(\n nodes as unknown as DiagramNode[],\n edges as unknown as DiagramEdge[],\n {\n direction: \"LR\",\n getNodeSize: (node) => {\n const bNode = node as unknown as BpmnRFNode;\n if (BPMN_CONTAINER_TYPES.has(bNode.data.elementType)) return undefined;\n return getBpmnNodeSize(bNode);\n },\n isContainerNode: (node) =>\n BPMN_CONTAINER_TYPES.has((node as unknown as BpmnRFNode).data.elementType),\n getNodeLayoutOptions: (node) => {\n const type = (node as unknown as BpmnRFNode).data.elementType;\n if (!BPMN_CONTAINER_TYPES.has(type)) return undefined;\n const min = CONTAINER_MIN_SIZE[type];\n // Pool with Lanes: DOWN so lanes stack top-to-bottom inside the pool.\n // Everything else (Lane content, SubProcess, free tasks): RIGHT (LR).\n const dir = type === \"Pool\" && poolsWithLanes.has(node.id) ? \"DOWN\" : \"RIGHT\";\n return {\n \"elk.direction\": dir,\n \"elk.nodeSize.constraints\": \"MINIMUM_SIZE\",\n ...(min ? { \"elk.nodeSize.minimum\": `[w=${min.w},h=${min.h}]` } : {}),\n ...(CONTAINER_PADDING[type] ? { \"elk.padding\": CONTAINER_PADDING[type] } : {}),\n };\n },\n elk: {\n \"elk.algorithm\": \"layered\",\n \"elk.direction\": \"RIGHT\",\n \"elk.hierarchyHandling\": \"INCLUDE_CHILDREN\",\n \"elk.edgeRouting\": \"ORTHOGONAL\",\n \"elk.layered.spacing.nodeNodeBetweenLayers\": \"80\",\n \"elk.layered.spacing.edgeNodeBetweenLayers\": \"20\",\n \"elk.spacing.nodeNode\": \"40\",\n \"elk.spacing.componentComponent\": \"60\",\n },\n },\n );\n\n const nodeMap = new Map(result.nodes.map((n) => [n.id, n]));\n const edgeMap = new Map(result.edges.map((e) => [e.id, e]));\n\n const updatedNodes = nodes.map((node) => {\n const laid = nodeMap.get(node.id);\n if (!laid) return node;\n return { ...node, position: laid.position, width: laid.width, height: laid.height };\n });\n\n const updatedEdges = edges.map((edge) => {\n const laid = edgeMap.get(edge.id);\n if (!laid) return edge;\n const nextData = { ...edge.data };\n if (laid.points && laid.points.length > 0) {\n nextData.routingPoints = laid.points;\n } else {\n delete nextData.routingPoints;\n }\n return { ...edge, data: nextData };\n });\n\n return { nodes: updatedNodes, edges: updatedEdges as BpmnRFEdge[] };\n}\n","import type { DiagramEdge, LayoutOptions, LayoutResult } from \"@aranzatech/diagrams-core/types\";\nimport { dagreLayout, applyLayoutResultToDiagram } from \"@aranzatech/diagrams-core/layout\";\nimport type { DiagramNode } from \"@aranzatech/diagrams-core/types\";\nimport type { BpmnRFNode, BpmnRFEdge } from \"../xml/types\";\nimport { getBpmnNodeSize } from \"../modeling\";\nimport type { BpmnDiagramState } from \"../modeling\";\n\nexport { applyLayoutResultToDiagram };\nexport { bpmnElkLayout } from \"./elk\";\n\n/**\n * Dagre layout pre-configured for BPMN diagrams.\n * Uses BPMN-specific node sizes (events 52×52, gateways 64×64, tasks 192×64, etc.)\n * instead of the generic fallback, which prevents overlaps and poor spacing.\n */\nexport async function bpmnDagreLayout(\n nodes: BpmnRFNode[],\n edges: BpmnRFEdge[],\n options: LayoutOptions = {},\n): Promise<LayoutResult> {\n return dagreLayout(nodes as DiagramNode[], edges as DiagramEdge[], {\n ...options,\n getNodeSize: (node) => getBpmnNodeSize(node as BpmnRFNode),\n });\n}\n\n/**\n * Applies a bpmn dagre layout result back to the diagram state.\n * Convenience wrapper so callers only need one import.\n */\nexport function applyBpmnLayoutResult(\n state: BpmnDiagramState,\n result: LayoutResult,\n): BpmnDiagramState {\n return applyLayoutResultToDiagram(state, result) as BpmnDiagramState;\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ModelingRules, ClipboardState, DiagramSnapshot, DiagramState, DiagramEventBus, ResizeHandlePosition, DiagramCommand, ConnectionValidator, SmartGuideResult, SelectionState, LayoutCacheOptions, LayoutCache, EdgeLabelOffsetOptions, EdgeLabelLayout, CommandStackState, Viewport, LayoutFn } from '@aranzatech/diagrams-core';
|
|
2
2
|
import { DiagramDocument, CreateDiagramDocumentOptions } from '@aranzatech/diagrams-core/serialization';
|
|
3
|
-
import { c as BpmnEdgeType, b as BpmnEdgeData, f as BpmnElementType, m as BpmnNodeData } from '../types-
|
|
4
|
-
import { d as BpmnRFNode, c as BpmnRFEdge } from '../types-
|
|
5
|
-
export { g as getBpmnElementSize, i as isBpmnElementResizable } from '../catalog-
|
|
3
|
+
import { c as BpmnEdgeType, b as BpmnEdgeData, f as BpmnElementType, m as BpmnNodeData } from '../types-hgmLfRA9.cjs';
|
|
4
|
+
import { d as BpmnRFNode, c as BpmnRFEdge } from '../types-44yNtMtO.cjs';
|
|
5
|
+
export { g as getBpmnElementSize, i as isBpmnElementResizable } from '../catalog-DUfPajtM.cjs';
|
|
6
6
|
import '@xyflow/react';
|
|
7
7
|
|
|
8
8
|
type BpmnDiagramState = DiagramState<BpmnRFNode, BpmnRFEdge>;
|
package/dist/modeling/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ModelingRules, ClipboardState, DiagramSnapshot, DiagramState, DiagramEventBus, ResizeHandlePosition, DiagramCommand, ConnectionValidator, SmartGuideResult, SelectionState, LayoutCacheOptions, LayoutCache, EdgeLabelOffsetOptions, EdgeLabelLayout, CommandStackState, Viewport, LayoutFn } from '@aranzatech/diagrams-core';
|
|
2
2
|
import { DiagramDocument, CreateDiagramDocumentOptions } from '@aranzatech/diagrams-core/serialization';
|
|
3
|
-
import { c as BpmnEdgeType, b as BpmnEdgeData, f as BpmnElementType, m as BpmnNodeData } from '../types-
|
|
4
|
-
import { d as BpmnRFNode, c as BpmnRFEdge } from '../types-
|
|
5
|
-
export { g as getBpmnElementSize, i as isBpmnElementResizable } from '../catalog-
|
|
3
|
+
import { c as BpmnEdgeType, b as BpmnEdgeData, f as BpmnElementType, m as BpmnNodeData } from '../types-hgmLfRA9.js';
|
|
4
|
+
import { d as BpmnRFNode, c as BpmnRFEdge } from '../types-kI1SiQB4.js';
|
|
5
|
+
export { g as getBpmnElementSize, i as isBpmnElementResizable } from '../catalog-BKdtbOQT.js';
|
|
6
6
|
import '@xyflow/react';
|
|
7
7
|
|
|
8
8
|
type BpmnDiagramState = DiagramState<BpmnRFNode, BpmnRFEdge>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Node, Edge } from '@xyflow/react';
|
|
2
|
-
import { m as BpmnNodeData, b as BpmnEdgeData, a as BpmnDefinitionsSet } from './types-
|
|
2
|
+
import { m as BpmnNodeData, b as BpmnEdgeData, a as BpmnDefinitionsSet } from './types-hgmLfRA9.cjs';
|
|
3
3
|
|
|
4
4
|
type BpmnRFNode = Node<BpmnNodeData>;
|
|
5
5
|
type BpmnRFEdge = Edge<BpmnEdgeData>;
|
|
@@ -172,8 +172,24 @@ interface BpmnNodeData extends Record<string, unknown> {
|
|
|
172
172
|
candidateUsers?: string;
|
|
173
173
|
/** UserTask: comma-separated Flowable group ids that can claim this task. */
|
|
174
174
|
candidateGroups?: string;
|
|
175
|
+
/** UserTask: ISO-8601 due date or FEEL expression evaluated at task creation. */
|
|
176
|
+
dueDate?: string;
|
|
177
|
+
/** UserTask: FEEL expression; when truthy the task is skipped. */
|
|
178
|
+
skipExpression?: string;
|
|
179
|
+
/** UserTask: name of the business calendar used to compute the due date. */
|
|
180
|
+
businessCalendarName?: string;
|
|
181
|
+
/** DataObjectReference: id of the backing bpmn:DataObject element. */
|
|
182
|
+
dataObjectRef?: string;
|
|
175
183
|
/** AdHocSubProcess: FEEL expression that determines when the sub-process completes. */
|
|
176
184
|
completionCondition?: string;
|
|
185
|
+
/** Loop / multi-instance type: none | loop | sequentialMultiple | parallelMultiple. */
|
|
186
|
+
loopType?: string;
|
|
187
|
+
/** StandardLoopCharacteristics: FEEL condition evaluated before each iteration. */
|
|
188
|
+
loopCondition?: string;
|
|
189
|
+
/** MultiInstanceLoopCharacteristics: number of instances as a FEEL expression. */
|
|
190
|
+
loopCardinality?: string;
|
|
191
|
+
/** MultiInstanceLoopCharacteristics: FEEL condition to stop before all instances finish. */
|
|
192
|
+
loopCompletionCondition?: string;
|
|
177
193
|
}
|
|
178
194
|
interface BpmnEdgeData extends Record<string, unknown> {
|
|
179
195
|
label?: string;
|
|
@@ -172,8 +172,24 @@ interface BpmnNodeData extends Record<string, unknown> {
|
|
|
172
172
|
candidateUsers?: string;
|
|
173
173
|
/** UserTask: comma-separated Flowable group ids that can claim this task. */
|
|
174
174
|
candidateGroups?: string;
|
|
175
|
+
/** UserTask: ISO-8601 due date or FEEL expression evaluated at task creation. */
|
|
176
|
+
dueDate?: string;
|
|
177
|
+
/** UserTask: FEEL expression; when truthy the task is skipped. */
|
|
178
|
+
skipExpression?: string;
|
|
179
|
+
/** UserTask: name of the business calendar used to compute the due date. */
|
|
180
|
+
businessCalendarName?: string;
|
|
181
|
+
/** DataObjectReference: id of the backing bpmn:DataObject element. */
|
|
182
|
+
dataObjectRef?: string;
|
|
175
183
|
/** AdHocSubProcess: FEEL expression that determines when the sub-process completes. */
|
|
176
184
|
completionCondition?: string;
|
|
185
|
+
/** Loop / multi-instance type: none | loop | sequentialMultiple | parallelMultiple. */
|
|
186
|
+
loopType?: string;
|
|
187
|
+
/** StandardLoopCharacteristics: FEEL condition evaluated before each iteration. */
|
|
188
|
+
loopCondition?: string;
|
|
189
|
+
/** MultiInstanceLoopCharacteristics: number of instances as a FEEL expression. */
|
|
190
|
+
loopCardinality?: string;
|
|
191
|
+
/** MultiInstanceLoopCharacteristics: FEEL condition to stop before all instances finish. */
|
|
192
|
+
loopCompletionCondition?: string;
|
|
177
193
|
}
|
|
178
194
|
interface BpmnEdgeData extends Record<string, unknown> {
|
|
179
195
|
label?: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Node, Edge } from '@xyflow/react';
|
|
2
|
-
import { m as BpmnNodeData, b as BpmnEdgeData, a as BpmnDefinitionsSet } from './types-
|
|
2
|
+
import { m as BpmnNodeData, b as BpmnEdgeData, a as BpmnDefinitionsSet } from './types-hgmLfRA9.js';
|
|
3
3
|
|
|
4
4
|
type BpmnRFNode = Node<BpmnNodeData>;
|
|
5
5
|
type BpmnRFEdge = Edge<BpmnEdgeData>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { d as BpmnRFNode, c as BpmnRFEdge } from '../types-
|
|
1
|
+
import { d as BpmnRFNode, c as BpmnRFEdge } from '../types-44yNtMtO.cjs';
|
|
2
2
|
import '@xyflow/react';
|
|
3
|
-
import '../types-
|
|
3
|
+
import '../types-hgmLfRA9.cjs';
|
|
4
4
|
|
|
5
5
|
type BpmnValidationSeverity = "error" | "warning" | "info";
|
|
6
6
|
interface BpmnValidationIssue {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { d as BpmnRFNode, c as BpmnRFEdge } from '../types-
|
|
1
|
+
import { d as BpmnRFNode, c as BpmnRFEdge } from '../types-kI1SiQB4.js';
|
|
2
2
|
import '@xyflow/react';
|
|
3
|
-
import '../types-
|
|
3
|
+
import '../types-hgmLfRA9.js';
|
|
4
4
|
|
|
5
5
|
type BpmnValidationSeverity = "error" | "warning" | "info";
|
|
6
6
|
interface BpmnValidationIssue {
|
package/dist/xml/index.cjs
CHANGED
|
@@ -26,7 +26,11 @@ var ARANZA_DESCRIPTOR = {
|
|
|
26
26
|
{ name: "formKey", isAttr: true, type: "String" },
|
|
27
27
|
// UserTask: Flowable task assignment — comma-separated ids
|
|
28
28
|
{ name: "candidateUsers", isAttr: true, type: "String" },
|
|
29
|
-
{ name: "candidateGroups", isAttr: true, type: "String" }
|
|
29
|
+
{ name: "candidateGroups", isAttr: true, type: "String" },
|
|
30
|
+
// UserTask: scheduling + skip expression
|
|
31
|
+
{ name: "dueDate", isAttr: true, type: "String" },
|
|
32
|
+
{ name: "skipExpression", isAttr: true, type: "String" },
|
|
33
|
+
{ name: "businessCalendarName", isAttr: true, type: "String" }
|
|
30
34
|
]
|
|
31
35
|
}
|
|
32
36
|
],
|
|
@@ -933,6 +937,12 @@ function extractAranzaExtensions(el) {
|
|
|
933
937
|
if (candidateUsers) result.candidateUsers = candidateUsers;
|
|
934
938
|
const candidateGroups = asString(taskConfig.candidateGroups);
|
|
935
939
|
if (candidateGroups) result.candidateGroups = candidateGroups;
|
|
940
|
+
const dueDate = asString(taskConfig.dueDate);
|
|
941
|
+
if (dueDate) result.dueDate = dueDate;
|
|
942
|
+
const skipExpression = asString(taskConfig.skipExpression);
|
|
943
|
+
if (skipExpression) result.skipExpression = skipExpression;
|
|
944
|
+
const businessCalendarName = asString(taskConfig.businessCalendarName);
|
|
945
|
+
if (businessCalendarName) result.businessCalendarName = businessCalendarName;
|
|
936
946
|
return result;
|
|
937
947
|
}
|
|
938
948
|
function extractCompletionCondition(el) {
|
|
@@ -941,6 +951,25 @@ function extractCompletionCondition(el) {
|
|
|
941
951
|
if (typeof cc === "string") return cc.trim() || void 0;
|
|
942
952
|
return asString(cc.body);
|
|
943
953
|
}
|
|
954
|
+
function extractLoopCharacteristics(el) {
|
|
955
|
+
const lc = el.loopCharacteristics;
|
|
956
|
+
if (!lc) return {};
|
|
957
|
+
if (lc.$type === "bpmn:StandardLoopCharacteristics") {
|
|
958
|
+
const loopCondition = asString(lc.loopCondition?.body);
|
|
959
|
+
return { loopType: "loop", ...loopCondition ? { loopCondition } : {} };
|
|
960
|
+
}
|
|
961
|
+
if (lc.$type === "bpmn:MultiInstanceLoopCharacteristics") {
|
|
962
|
+
const loopType = lc.isSequential === true ? "sequentialMultiple" : "parallelMultiple";
|
|
963
|
+
const loopCardinality = asString(lc.loopCardinality?.body);
|
|
964
|
+
const loopCompletionCondition = asString(lc.completionCondition?.body);
|
|
965
|
+
return {
|
|
966
|
+
loopType,
|
|
967
|
+
...loopCardinality ? { loopCardinality } : {},
|
|
968
|
+
...loopCompletionCondition ? { loopCompletionCondition } : {}
|
|
969
|
+
};
|
|
970
|
+
}
|
|
971
|
+
return {};
|
|
972
|
+
}
|
|
944
973
|
function walkFlowElements(elements, parentId, ctx, nodes, edges) {
|
|
945
974
|
for (const el of elements) {
|
|
946
975
|
const { $type, id } = el;
|
|
@@ -958,7 +987,7 @@ function walkFlowElements(elements, parentId, ctx, nodes, edges) {
|
|
|
958
987
|
}
|
|
959
988
|
buildNode(el, elementType, parentId, ctx, nodes);
|
|
960
989
|
if ($type === "bpmn:SubProcess" || $type === "bpmn:Transaction" || $type === "bpmn:AdHocSubProcess") {
|
|
961
|
-
const children = asElements(el.flowElements);
|
|
990
|
+
const children = [...asElements(el.flowElements), ...asElements(el.artifacts)];
|
|
962
991
|
const laneMembership = extractLaneMembership(el);
|
|
963
992
|
walkFlowElements(children, id, { ...ctx, laneMembership }, nodes, edges);
|
|
964
993
|
}
|
|
@@ -971,7 +1000,7 @@ function buildNode(el, elementType, parentId, ctx, nodes) {
|
|
|
971
1000
|
const x = shape?.x ?? ctx.autoX.value;
|
|
972
1001
|
const y = shape?.y ?? 100;
|
|
973
1002
|
if (!shape) ctx.autoX.value += (meta?.defaultWidth ?? 120) + 20;
|
|
974
|
-
const label = asString(el.name);
|
|
1003
|
+
const label = elementType === "Annotation" ? asString(el.text) ?? asString(el.name) : asString(el.name);
|
|
975
1004
|
const documentation = extractDocumentation(el);
|
|
976
1005
|
const trigger = extractTrigger(el);
|
|
977
1006
|
const eventDefinition = extractEventDefinition(el);
|
|
@@ -982,6 +1011,8 @@ function buildNode(el, elementType, parentId, ctx, nodes) {
|
|
|
982
1011
|
const scriptFormat = elementType === "ScriptTask" ? asString(el.scriptFormat) : void 0;
|
|
983
1012
|
const script = elementType === "ScriptTask" ? asString(el.script) : void 0;
|
|
984
1013
|
const completionCondition = elementType === "AdHocSubProcess" ? extractCompletionCondition(el) : void 0;
|
|
1014
|
+
const loopChars = extractLoopCharacteristics(el);
|
|
1015
|
+
const dataObjectRef = elementType === "DataObjectReference" ? asString(el.dataObjectRef?.id) : void 0;
|
|
985
1016
|
const data = {
|
|
986
1017
|
elementType,
|
|
987
1018
|
...label ? { label } : {},
|
|
@@ -1002,6 +1033,8 @@ function buildNode(el, elementType, parentId, ctx, nodes) {
|
|
|
1002
1033
|
...scriptFormat ? { scriptFormat } : {},
|
|
1003
1034
|
...script ? { script } : {},
|
|
1004
1035
|
...completionCondition ? { completionCondition } : {},
|
|
1036
|
+
...dataObjectRef ? { dataObjectRef } : {},
|
|
1037
|
+
...loopChars,
|
|
1005
1038
|
...aranzaExt
|
|
1006
1039
|
};
|
|
1007
1040
|
if (elementType === "SubProcess" || elementType === "Transaction" || elementType === "EventSubProcess" || elementType === "AdHocSubProcess") {
|
|
@@ -1034,11 +1067,14 @@ function buildEdge(el, edgeType, ctx, edges) {
|
|
|
1034
1067
|
const label = asString(el.name);
|
|
1035
1068
|
const documentation = extractDocumentation(el);
|
|
1036
1069
|
const condExpr = el.conditionExpression;
|
|
1070
|
+
const rawDir = asString(el.associationDirection);
|
|
1071
|
+
const associationDirection = edgeType === "association" && rawDir ? rawDir.toLowerCase() : void 0;
|
|
1037
1072
|
const data = {
|
|
1038
1073
|
edgeType,
|
|
1039
1074
|
...label ? { label } : {},
|
|
1040
1075
|
...documentation ? { documentation } : {},
|
|
1041
|
-
...condExpr?.body ? { conditionExpression: condExpr.body } : {}
|
|
1076
|
+
...condExpr?.body ? { conditionExpression: condExpr.body } : {},
|
|
1077
|
+
...associationDirection ? { associationDirection } : {}
|
|
1042
1078
|
};
|
|
1043
1079
|
const waypoints = ctx.waypoints.get(id);
|
|
1044
1080
|
if (waypoints?.length) data.routingPoints = waypoints;
|
|
@@ -1063,7 +1099,7 @@ function handleCollaboration(collaboration, ctx, nodes, edges) {
|
|
|
1063
1099
|
if (processRef) {
|
|
1064
1100
|
const laneMembership = extractLaneMembership(processRef);
|
|
1065
1101
|
walkFlowElements(
|
|
1066
|
-
asElements(processRef.flowElements),
|
|
1102
|
+
[...asElements(processRef.flowElements), ...asElements(processRef.artifacts)],
|
|
1067
1103
|
id,
|
|
1068
1104
|
{ ...ctx, laneMembership },
|
|
1069
1105
|
nodes,
|
|
@@ -1095,7 +1131,7 @@ function addLaneNodes(laneSet, poolId, ctx, nodes) {
|
|
|
1095
1131
|
data: { elementType: "Lane", ...label ? { label } : {} },
|
|
1096
1132
|
width: shape?.width ?? 570,
|
|
1097
1133
|
height: shape?.height ?? 120,
|
|
1098
|
-
parentId: poolId
|
|
1134
|
+
...poolId ? { parentId: poolId } : {}
|
|
1099
1135
|
});
|
|
1100
1136
|
const child = lane.childLaneSet;
|
|
1101
1137
|
if (child) addLaneNodes(child, poolId, ctx, nodes);
|
|
@@ -1129,9 +1165,9 @@ async function parseBpmnXml(xml) {
|
|
|
1129
1165
|
} else if (rootEl.$type === "bpmn:Process") {
|
|
1130
1166
|
const laneMembership = extractLaneMembership(rootEl);
|
|
1131
1167
|
const laneSet = rootEl.laneSet;
|
|
1132
|
-
if (laneSet) addLaneNodes(laneSet,
|
|
1168
|
+
if (laneSet) addLaneNodes(laneSet, void 0, ctx, nodes);
|
|
1133
1169
|
walkFlowElements(
|
|
1134
|
-
asElements(rootEl.flowElements),
|
|
1170
|
+
[...asElements(rootEl.flowElements), ...asElements(rootEl.artifacts)],
|
|
1135
1171
|
void 0,
|
|
1136
1172
|
{ ...ctx, laneMembership },
|
|
1137
1173
|
nodes,
|
|
@@ -1304,7 +1340,10 @@ function buildAranzaExtensionElements(moddle, node) {
|
|
|
1304
1340
|
const formKey = typeof node.data.formKey === "string" ? node.data.formKey : void 0;
|
|
1305
1341
|
const candidateUsers = typeof node.data.candidateUsers === "string" ? node.data.candidateUsers : void 0;
|
|
1306
1342
|
const candidateGroups = typeof node.data.candidateGroups === "string" ? node.data.candidateGroups : void 0;
|
|
1307
|
-
|
|
1343
|
+
const dueDate = typeof node.data.dueDate === "string" ? node.data.dueDate : void 0;
|
|
1344
|
+
const skipExpression = typeof node.data.skipExpression === "string" ? node.data.skipExpression : void 0;
|
|
1345
|
+
const businessCalendarName = typeof node.data.businessCalendarName === "string" ? node.data.businessCalendarName : void 0;
|
|
1346
|
+
if (!priority && !owner && !sla && !connector && !action && !flowableType && !flowableDelegateExpression && !decisionRef && !formKey && !candidateUsers && !candidateGroups && !dueDate && !skipExpression && !businessCalendarName) {
|
|
1308
1347
|
return null;
|
|
1309
1348
|
}
|
|
1310
1349
|
const configAttrs = {};
|
|
@@ -1319,9 +1358,13 @@ function buildAranzaExtensionElements(moddle, node) {
|
|
|
1319
1358
|
if (formKey) configAttrs.formKey = formKey;
|
|
1320
1359
|
if (candidateUsers) configAttrs.candidateUsers = candidateUsers;
|
|
1321
1360
|
if (candidateGroups) configAttrs.candidateGroups = candidateGroups;
|
|
1361
|
+
if (dueDate) configAttrs.dueDate = dueDate;
|
|
1362
|
+
if (skipExpression) configAttrs.skipExpression = skipExpression;
|
|
1363
|
+
if (businessCalendarName) configAttrs.businessCalendarName = businessCalendarName;
|
|
1322
1364
|
const taskConfig = moddle.create("aranza:TaskConfig", configAttrs);
|
|
1323
1365
|
return moddle.create("bpmn:ExtensionElements", { values: [taskConfig] });
|
|
1324
1366
|
}
|
|
1367
|
+
var ARTIFACT_ELEMENT_TYPES = /* @__PURE__ */ new Set(["Annotation", "Group"]);
|
|
1325
1368
|
function buildSemanticModel(moddle, nodes, edges, opts) {
|
|
1326
1369
|
const defId = opts.id ?? "Definitions_1";
|
|
1327
1370
|
const defName = opts.name;
|
|
@@ -1417,10 +1460,31 @@ function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId,
|
|
|
1417
1460
|
};
|
|
1418
1461
|
const myNodes = (poolId ? allNodes.filter((n) => belongsToPool(n)) : allNodes.filter((n) => n.data.elementType !== "Pool" && n.data.elementType !== "Lane")).filter((n) => !isInsideSubProcess(n));
|
|
1419
1462
|
const myLanes = laneNodes.filter((l) => poolId ? l.parentId === poolId : true);
|
|
1463
|
+
const presentDataObjectIds = new Set(
|
|
1464
|
+
myNodes.filter((n) => n.data.elementType === "DataObject").map((n) => n.id)
|
|
1465
|
+
);
|
|
1420
1466
|
const flowElements = [];
|
|
1467
|
+
const artifacts = [];
|
|
1468
|
+
for (const node of myNodes) {
|
|
1469
|
+
if (node.data.elementType === "DataObjectReference") {
|
|
1470
|
+
const explicitRef = typeof node.data.dataObjectRef === "string" ? node.data.dataObjectRef : null;
|
|
1471
|
+
if (!explicitRef || !presentDataObjectIds.has(explicitRef)) {
|
|
1472
|
+
const syntheticId = `DataObject_${node.id}`;
|
|
1473
|
+
if (!presentDataObjectIds.has(syntheticId)) {
|
|
1474
|
+
flowElements.push(moddle.create("bpmn:DataObject", { id: syntheticId }));
|
|
1475
|
+
presentDataObjectIds.add(syntheticId);
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1421
1480
|
for (const node of myNodes) {
|
|
1422
1481
|
const el = buildFlowElement(moddle, node, allNodes, allEdges);
|
|
1423
|
-
if (el)
|
|
1482
|
+
if (!el) continue;
|
|
1483
|
+
if (ARTIFACT_ELEMENT_TYPES.has(node.data.elementType)) {
|
|
1484
|
+
artifacts.push(el);
|
|
1485
|
+
} else {
|
|
1486
|
+
flowElements.push(el);
|
|
1487
|
+
}
|
|
1424
1488
|
}
|
|
1425
1489
|
const myNodeIds = new Set(myNodes.map((n) => n.id));
|
|
1426
1490
|
const myEdges = allEdges.filter(
|
|
@@ -1428,7 +1492,12 @@ function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId,
|
|
|
1428
1492
|
);
|
|
1429
1493
|
for (const edge of myEdges) {
|
|
1430
1494
|
const edgeMeta = buildEdgeElement(moddle, edge);
|
|
1431
|
-
if (edgeMeta)
|
|
1495
|
+
if (!edgeMeta) continue;
|
|
1496
|
+
if (edge.data?.edgeType === "association") {
|
|
1497
|
+
artifacts.push(edgeMeta);
|
|
1498
|
+
} else {
|
|
1499
|
+
flowElements.push(edgeMeta);
|
|
1500
|
+
}
|
|
1432
1501
|
}
|
|
1433
1502
|
const elementById = new Map(
|
|
1434
1503
|
flowElements.filter((element) => typeof element.id === "string").map((element) => [element.id, element])
|
|
@@ -1444,7 +1513,8 @@ function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId,
|
|
|
1444
1513
|
const process = moddle.create("bpmn:Process", {
|
|
1445
1514
|
id: processId,
|
|
1446
1515
|
isExecutable: opts.process?.executable ?? true,
|
|
1447
|
-
flowElements
|
|
1516
|
+
flowElements,
|
|
1517
|
+
...artifacts.length > 0 ? { artifacts } : {}
|
|
1448
1518
|
});
|
|
1449
1519
|
if (opts.process?.documentation) {
|
|
1450
1520
|
process.documentation = [
|
|
@@ -1476,6 +1546,10 @@ function buildFlowElement(moddle, node, allNodes, allEdges) {
|
|
|
1476
1546
|
id: node.id,
|
|
1477
1547
|
name: label ?? ""
|
|
1478
1548
|
};
|
|
1549
|
+
if (elementType === "Annotation") {
|
|
1550
|
+
delete attrs.name;
|
|
1551
|
+
attrs.text = label ?? "";
|
|
1552
|
+
}
|
|
1479
1553
|
if (node.data.documentation) {
|
|
1480
1554
|
attrs.documentation = [
|
|
1481
1555
|
moddle.create("bpmn:Documentation", { text: node.data.documentation })
|
|
@@ -1494,22 +1568,16 @@ function buildFlowElement(moddle, node, allNodes, allEdges) {
|
|
|
1494
1568
|
if (elementType === "CallActivity" && node.data.calledElement) {
|
|
1495
1569
|
attrs.calledElement = node.data.calledElement;
|
|
1496
1570
|
}
|
|
1571
|
+
if (elementType === "DataObjectReference") {
|
|
1572
|
+
const refId = typeof node.data.dataObjectRef === "string" ? node.data.dataObjectRef : `DataObject_${node.id}`;
|
|
1573
|
+
attrs.dataObjectRef = { id: refId };
|
|
1574
|
+
}
|
|
1497
1575
|
if (elementType === "ScriptTask") {
|
|
1498
1576
|
const scriptFormat = typeof node.data.scriptFormat === "string" ? node.data.scriptFormat : void 0;
|
|
1499
1577
|
const script = typeof node.data.script === "string" ? node.data.script : void 0;
|
|
1500
1578
|
if (scriptFormat) attrs.scriptFormat = scriptFormat;
|
|
1501
1579
|
if (script) attrs.script = script;
|
|
1502
1580
|
}
|
|
1503
|
-
if (elementType === "UserTask") {
|
|
1504
|
-
const flowableAttrs = {};
|
|
1505
|
-
const fk = typeof node.data.formKey === "string" ? node.data.formKey : void 0;
|
|
1506
|
-
const cu = typeof node.data.candidateUsers === "string" ? node.data.candidateUsers : void 0;
|
|
1507
|
-
const cg = typeof node.data.candidateGroups === "string" ? node.data.candidateGroups : void 0;
|
|
1508
|
-
if (fk) flowableAttrs["flowable:formKey"] = fk;
|
|
1509
|
-
if (cu) flowableAttrs["flowable:candidateUsers"] = cu;
|
|
1510
|
-
if (cg) flowableAttrs["flowable:candidateGroups"] = cg;
|
|
1511
|
-
if (Object.keys(flowableAttrs).length > 0) attrs.$attrs = flowableAttrs;
|
|
1512
|
-
}
|
|
1513
1581
|
if (elementType === "ServiceTask") {
|
|
1514
1582
|
const flowableAttrs = {};
|
|
1515
1583
|
const flowableType = typeof node.data.flowableType === "string" ? node.data.flowableType : void 0;
|
|
@@ -1526,7 +1594,9 @@ function buildFlowElement(moddle, node, allNodes, allEdges) {
|
|
|
1526
1594
|
if (aranzaConfig) attrs.extensionElements = aranzaConfig;
|
|
1527
1595
|
const isSubProcess = elementType === "SubProcess" || elementType === "Transaction" || elementType === "EventSubProcess" || elementType === "AdHocSubProcess";
|
|
1528
1596
|
if (isSubProcess) {
|
|
1529
|
-
|
|
1597
|
+
const nested = buildNestedFlowElements(moddle, node, allNodes, allEdges);
|
|
1598
|
+
attrs.flowElements = nested.flowElements;
|
|
1599
|
+
if (nested.artifacts.length > 0) attrs.artifacts = nested.artifacts;
|
|
1530
1600
|
if (elementType === "EventSubProcess" || node.data.subProcessVariant === "event") {
|
|
1531
1601
|
attrs.triggeredByEvent = true;
|
|
1532
1602
|
}
|
|
@@ -1536,6 +1606,29 @@ function buildFlowElement(moddle, node, allNodes, allEdges) {
|
|
|
1536
1606
|
});
|
|
1537
1607
|
}
|
|
1538
1608
|
}
|
|
1609
|
+
const loopType = typeof node.data.loopType === "string" ? node.data.loopType : "none";
|
|
1610
|
+
if (loopType && loopType !== "none") {
|
|
1611
|
+
if (loopType === "loop") {
|
|
1612
|
+
const lcAttrs = { id: uid("LoopChar", node.id) };
|
|
1613
|
+
const loopCondition = typeof node.data.loopCondition === "string" ? node.data.loopCondition : void 0;
|
|
1614
|
+
if (loopCondition) {
|
|
1615
|
+
lcAttrs.loopCondition = moddle.create("bpmn:FormalExpression", { body: loopCondition });
|
|
1616
|
+
}
|
|
1617
|
+
attrs.loopCharacteristics = moddle.create("bpmn:StandardLoopCharacteristics", lcAttrs);
|
|
1618
|
+
} else {
|
|
1619
|
+
const isSequential = loopType === "sequentialMultiple";
|
|
1620
|
+
const lcAttrs = { id: uid("LoopChar", node.id), isSequential };
|
|
1621
|
+
const loopCardinality = typeof node.data.loopCardinality === "string" ? node.data.loopCardinality : void 0;
|
|
1622
|
+
const loopCompletionCondition = typeof node.data.loopCompletionCondition === "string" ? node.data.loopCompletionCondition : void 0;
|
|
1623
|
+
if (loopCardinality) {
|
|
1624
|
+
lcAttrs.loopCardinality = moddle.create("bpmn:FormalExpression", { body: loopCardinality });
|
|
1625
|
+
}
|
|
1626
|
+
if (loopCompletionCondition) {
|
|
1627
|
+
lcAttrs.completionCondition = moddle.create("bpmn:FormalExpression", { body: loopCompletionCondition });
|
|
1628
|
+
}
|
|
1629
|
+
attrs.loopCharacteristics = moddle.create("bpmn:MultiInstanceLoopCharacteristics", lcAttrs);
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1539
1632
|
const element = moddle.create(moddleType, attrs);
|
|
1540
1633
|
return element;
|
|
1541
1634
|
}
|
|
@@ -1543,16 +1636,42 @@ function buildNestedFlowElements(moddle, parent, allNodes, allEdges) {
|
|
|
1543
1636
|
const childNodes = allNodes.filter((node) => node.parentId === parent.id);
|
|
1544
1637
|
const childNodeIds = new Set(childNodes.map((node) => node.id));
|
|
1545
1638
|
const flowElements = [];
|
|
1639
|
+
const artifacts = [];
|
|
1640
|
+
const presentDataObjectIds = new Set(
|
|
1641
|
+
childNodes.filter((n) => n.data.elementType === "DataObject").map((n) => n.id)
|
|
1642
|
+
);
|
|
1643
|
+
for (const node of childNodes) {
|
|
1644
|
+
if (node.data.elementType === "DataObjectReference") {
|
|
1645
|
+
const explicitRef = typeof node.data.dataObjectRef === "string" ? node.data.dataObjectRef : null;
|
|
1646
|
+
if (!explicitRef || !presentDataObjectIds.has(explicitRef)) {
|
|
1647
|
+
const syntheticId = `DataObject_${node.id}`;
|
|
1648
|
+
if (!presentDataObjectIds.has(syntheticId)) {
|
|
1649
|
+
flowElements.push(moddle.create("bpmn:DataObject", { id: syntheticId }));
|
|
1650
|
+
presentDataObjectIds.add(syntheticId);
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
}
|
|
1546
1655
|
for (const child of childNodes) {
|
|
1547
1656
|
const element = buildFlowElement(moddle, child, allNodes, allEdges);
|
|
1548
|
-
if (element)
|
|
1657
|
+
if (!element) continue;
|
|
1658
|
+
if (ARTIFACT_ELEMENT_TYPES.has(child.data.elementType)) {
|
|
1659
|
+
artifacts.push(element);
|
|
1660
|
+
} else {
|
|
1661
|
+
flowElements.push(element);
|
|
1662
|
+
}
|
|
1549
1663
|
}
|
|
1550
1664
|
for (const edge of allEdges) {
|
|
1551
1665
|
if (!childNodeIds.has(edge.source) || !childNodeIds.has(edge.target)) continue;
|
|
1552
1666
|
const element = buildEdgeElement(moddle, edge);
|
|
1553
|
-
if (element)
|
|
1667
|
+
if (!element) continue;
|
|
1668
|
+
if (edge.data?.edgeType === "association") {
|
|
1669
|
+
artifacts.push(element);
|
|
1670
|
+
} else {
|
|
1671
|
+
flowElements.push(element);
|
|
1672
|
+
}
|
|
1554
1673
|
}
|
|
1555
|
-
return flowElements;
|
|
1674
|
+
return { flowElements, artifacts };
|
|
1556
1675
|
}
|
|
1557
1676
|
function buildEdgeElement(moddle, edge) {
|
|
1558
1677
|
if (!edge.data) return null;
|
|
@@ -1574,6 +1693,9 @@ function buildEdgeElement(moddle, edge) {
|
|
|
1574
1693
|
body: edge.data.conditionExpression
|
|
1575
1694
|
});
|
|
1576
1695
|
}
|
|
1696
|
+
if (edge.data.edgeType === "association" && edge.data.associationDirection && edge.data.associationDirection !== "none") {
|
|
1697
|
+
attrs.associationDirection = edge.data.associationDirection === "both" ? "Both" : "One";
|
|
1698
|
+
}
|
|
1577
1699
|
return moddle.create(moddleType, attrs);
|
|
1578
1700
|
}
|
|
1579
1701
|
function buildBpmnDI(moddle, definitions, nodes, edges) {
|