@aranzatech/diagrams-bpmn 0.1.3 → 0.2.1
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 +20 -0
- package/README.md +121 -0
- package/dist/catalog-OVnBDD8R.d.ts +9 -0
- package/dist/catalog-OWfI_yHU.d.cts +9 -0
- package/dist/{chunk-W3ROOC6E.js → chunk-33AR3PXF.js} +177 -40
- package/dist/chunk-33AR3PXF.js.map +1 -0
- package/dist/{chunk-3AFZDIMQ.js → chunk-ECTJRD7Z.js} +3 -3
- package/dist/{chunk-3AFZDIMQ.js.map → chunk-ECTJRD7Z.js.map} +1 -1
- package/dist/{chunk-NXMUX67A.js → chunk-H3YMTGFG.js} +79 -38
- package/dist/chunk-H3YMTGFG.js.map +1 -0
- package/dist/chunk-KALSGH4D.js +36 -0
- package/dist/chunk-KALSGH4D.js.map +1 -0
- package/dist/{chunk-DNR5WBQH.js → chunk-L5Z22RLX.js} +81 -20
- package/dist/chunk-L5Z22RLX.js.map +1 -0
- package/dist/chunk-OZKTOILD.js +3 -0
- package/dist/chunk-OZKTOILD.js.map +1 -0
- package/dist/{chunk-4AX573IV.js → chunk-RLAJNRF2.js} +3 -3
- package/dist/{chunk-4AX573IV.js.map → chunk-RLAJNRF2.js.map} +1 -1
- package/dist/chunk-YQTIODXH.js +532 -0
- package/dist/chunk-YQTIODXH.js.map +1 -0
- package/dist/chunk-ZFGQVLHB.js +226 -0
- package/dist/chunk-ZFGQVLHB.js.map +1 -0
- package/dist/edges/index.cjs +1 -1
- package/dist/edges/index.cjs.map +1 -1
- package/dist/edges/index.js +2 -2
- package/dist/elements/index.cjs +81 -17
- package/dist/elements/index.cjs.map +1 -1
- package/dist/elements/index.d.cts +4 -6
- package/dist/elements/index.d.ts +4 -6
- package/dist/elements/index.js +3 -2
- package/dist/index.cjs +1120 -118
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -63
- package/dist/index.d.ts +10 -63
- package/dist/index.js +9 -42
- package/dist/index.js.map +1 -1
- package/dist/modeling/index.cjs +1241 -0
- package/dist/modeling/index.cjs.map +1 -0
- package/dist/modeling/index.d.cts +146 -0
- package/dist/modeling/index.d.ts +146 -0
- package/dist/modeling/index.js +5 -0
- package/dist/modeling/index.js.map +1 -0
- package/dist/nodes/index.cjs +91 -38
- package/dist/nodes/index.cjs.map +1 -1
- package/dist/nodes/index.js +2 -2
- package/dist/types-BxjCV2oX.d.ts +20 -0
- package/dist/{types-C78d_Kdh.d.cts → types-DznxZxpV.d.cts} +17 -19
- package/dist/{types-C78d_Kdh.d.ts → types-DznxZxpV.d.ts} +17 -19
- package/dist/types-vVi5T7qj.d.cts +20 -0
- package/dist/validation/index.cjs +848 -0
- package/dist/validation/index.cjs.map +1 -0
- package/dist/validation/index.d.cts +25 -0
- package/dist/validation/index.d.ts +25 -0
- package/dist/validation/index.js +5 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/xml/index.cjs +215 -54
- package/dist/xml/index.cjs.map +1 -1
- package/dist/xml/index.d.cts +4 -19
- package/dist/xml/index.d.ts +4 -19
- package/dist/xml/index.js +2 -2
- package/package.json +16 -4
- package/dist/chunk-23B2IGK5.js +0 -24
- package/dist/chunk-23B2IGK5.js.map +0 -1
- package/dist/chunk-DNR5WBQH.js.map +0 -1
- package/dist/chunk-NXMUX67A.js.map +0 -1
- package/dist/chunk-W3ROOC6E.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -4,6 +4,8 @@ var react = require('@xyflow/react');
|
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var routing = require('@aranzatech/diagrams-core/routing');
|
|
6
6
|
var bpmnModdle = require('bpmn-moddle');
|
|
7
|
+
var diagramsCore = require('@aranzatech/diagrams-core');
|
|
8
|
+
var serialization = require('@aranzatech/diagrams-core/serialization');
|
|
7
9
|
|
|
8
10
|
// src/elements/catalog.ts
|
|
9
11
|
var BPMN_ELEMENT_CATALOG = {
|
|
@@ -41,7 +43,7 @@ var BPMN_ELEMENT_CATALOG = {
|
|
|
41
43
|
},
|
|
42
44
|
IntermediateCatchEvent: {
|
|
43
45
|
label: "Intermediate Catch Event",
|
|
44
|
-
icon: "
|
|
46
|
+
icon: "Clock3",
|
|
45
47
|
category: "event",
|
|
46
48
|
defaultWidth: 36,
|
|
47
49
|
defaultHeight: 36,
|
|
@@ -55,7 +57,7 @@ var BPMN_ELEMENT_CATALOG = {
|
|
|
55
57
|
},
|
|
56
58
|
IntermediateThrowEvent: {
|
|
57
59
|
label: "Intermediate Throw Event",
|
|
58
|
-
icon: "
|
|
60
|
+
icon: "Send",
|
|
59
61
|
category: "event",
|
|
60
62
|
defaultWidth: 36,
|
|
61
63
|
defaultHeight: 36,
|
|
@@ -69,7 +71,7 @@ var BPMN_ELEMENT_CATALOG = {
|
|
|
69
71
|
},
|
|
70
72
|
BoundaryEvent: {
|
|
71
73
|
label: "Boundary Event",
|
|
72
|
-
icon: "
|
|
74
|
+
icon: "AlarmClock",
|
|
73
75
|
category: "event",
|
|
74
76
|
defaultWidth: 36,
|
|
75
77
|
defaultHeight: 36,
|
|
@@ -85,7 +87,7 @@ var BPMN_ELEMENT_CATALOG = {
|
|
|
85
87
|
// ─── Tasks ───────────────────────────────────────────────────────────────────
|
|
86
88
|
Task: {
|
|
87
89
|
label: "Task",
|
|
88
|
-
icon: "
|
|
90
|
+
icon: "CheckSquare",
|
|
89
91
|
category: "task",
|
|
90
92
|
defaultWidth: 120,
|
|
91
93
|
defaultHeight: 60,
|
|
@@ -99,7 +101,7 @@ var BPMN_ELEMENT_CATALOG = {
|
|
|
99
101
|
},
|
|
100
102
|
UserTask: {
|
|
101
103
|
label: "User Task",
|
|
102
|
-
icon: "
|
|
104
|
+
icon: "UserRound",
|
|
103
105
|
category: "task",
|
|
104
106
|
defaultWidth: 120,
|
|
105
107
|
defaultHeight: 60,
|
|
@@ -113,7 +115,7 @@ var BPMN_ELEMENT_CATALOG = {
|
|
|
113
115
|
},
|
|
114
116
|
ServiceTask: {
|
|
115
117
|
label: "Service Task",
|
|
116
|
-
icon: "
|
|
118
|
+
icon: "Cog",
|
|
117
119
|
category: "task",
|
|
118
120
|
defaultWidth: 120,
|
|
119
121
|
defaultHeight: 60,
|
|
@@ -155,7 +157,7 @@ var BPMN_ELEMENT_CATALOG = {
|
|
|
155
157
|
},
|
|
156
158
|
BusinessRuleTask: {
|
|
157
159
|
label: "Business Rule Task",
|
|
158
|
-
icon: "
|
|
160
|
+
icon: "Table2",
|
|
159
161
|
category: "task",
|
|
160
162
|
defaultWidth: 120,
|
|
161
163
|
defaultHeight: 60,
|
|
@@ -169,7 +171,7 @@ var BPMN_ELEMENT_CATALOG = {
|
|
|
169
171
|
},
|
|
170
172
|
ReceiveTask: {
|
|
171
173
|
label: "Receive Task",
|
|
172
|
-
icon: "
|
|
174
|
+
icon: "Inbox",
|
|
173
175
|
category: "task",
|
|
174
176
|
defaultWidth: 120,
|
|
175
177
|
defaultHeight: 60,
|
|
@@ -212,7 +214,7 @@ var BPMN_ELEMENT_CATALOG = {
|
|
|
212
214
|
// ─── Gateways ────────────────────────────────────────────────────────────────
|
|
213
215
|
ExclusiveGateway: {
|
|
214
216
|
label: "Exclusive Gateway",
|
|
215
|
-
icon: "
|
|
217
|
+
icon: "X",
|
|
216
218
|
category: "gateway",
|
|
217
219
|
defaultWidth: 50,
|
|
218
220
|
defaultHeight: 50,
|
|
@@ -225,7 +227,7 @@ var BPMN_ELEMENT_CATALOG = {
|
|
|
225
227
|
},
|
|
226
228
|
InclusiveGateway: {
|
|
227
229
|
label: "Inclusive Gateway",
|
|
228
|
-
icon: "
|
|
230
|
+
icon: "Circle",
|
|
229
231
|
category: "gateway",
|
|
230
232
|
defaultWidth: 50,
|
|
231
233
|
defaultHeight: 50,
|
|
@@ -238,7 +240,7 @@ var BPMN_ELEMENT_CATALOG = {
|
|
|
238
240
|
},
|
|
239
241
|
ParallelGateway: {
|
|
240
242
|
label: "Parallel Gateway",
|
|
241
|
-
icon: "
|
|
243
|
+
icon: "Plus",
|
|
242
244
|
category: "gateway",
|
|
243
245
|
defaultWidth: 50,
|
|
244
246
|
defaultHeight: 50,
|
|
@@ -279,7 +281,7 @@ var BPMN_ELEMENT_CATALOG = {
|
|
|
279
281
|
// ─── Containers ───────────────────────────────────────────────────────────────
|
|
280
282
|
SubProcess: {
|
|
281
283
|
label: "Sub-Process",
|
|
282
|
-
icon: "
|
|
284
|
+
icon: "PlusSquare",
|
|
283
285
|
category: "container",
|
|
284
286
|
defaultWidth: 350,
|
|
285
287
|
defaultHeight: 200,
|
|
@@ -294,7 +296,7 @@ var BPMN_ELEMENT_CATALOG = {
|
|
|
294
296
|
},
|
|
295
297
|
Transaction: {
|
|
296
298
|
label: "Transaction",
|
|
297
|
-
icon: "
|
|
299
|
+
icon: "Receipt",
|
|
298
300
|
category: "container",
|
|
299
301
|
defaultWidth: 350,
|
|
300
302
|
defaultHeight: 200,
|
|
@@ -309,7 +311,7 @@ var BPMN_ELEMENT_CATALOG = {
|
|
|
309
311
|
},
|
|
310
312
|
EventSubProcess: {
|
|
311
313
|
label: "Event Sub-Process",
|
|
312
|
-
icon: "
|
|
314
|
+
icon: "CircleDotDashed",
|
|
313
315
|
category: "container",
|
|
314
316
|
defaultWidth: 350,
|
|
315
317
|
defaultHeight: 200,
|
|
@@ -324,7 +326,7 @@ var BPMN_ELEMENT_CATALOG = {
|
|
|
324
326
|
},
|
|
325
327
|
AdHocSubProcess: {
|
|
326
328
|
label: "Ad-Hoc Sub-Process",
|
|
327
|
-
icon: "
|
|
329
|
+
icon: "Waves",
|
|
328
330
|
category: "container",
|
|
329
331
|
defaultWidth: 350,
|
|
330
332
|
defaultHeight: 200,
|
|
@@ -339,7 +341,7 @@ var BPMN_ELEMENT_CATALOG = {
|
|
|
339
341
|
},
|
|
340
342
|
Pool: {
|
|
341
343
|
label: "Pool",
|
|
342
|
-
icon: "
|
|
344
|
+
icon: "Rows3",
|
|
343
345
|
category: "container",
|
|
344
346
|
defaultWidth: 600,
|
|
345
347
|
defaultHeight: 200,
|
|
@@ -354,7 +356,7 @@ var BPMN_ELEMENT_CATALOG = {
|
|
|
354
356
|
},
|
|
355
357
|
Lane: {
|
|
356
358
|
label: "Lane",
|
|
357
|
-
icon: "
|
|
359
|
+
icon: "PanelTop",
|
|
358
360
|
category: "container",
|
|
359
361
|
defaultWidth: 600,
|
|
360
362
|
defaultHeight: 120,
|
|
@@ -573,6 +575,67 @@ var BPMN_ELEMENT_CATALOG = {
|
|
|
573
575
|
function getElementMeta(type) {
|
|
574
576
|
return BPMN_ELEMENT_CATALOG[type];
|
|
575
577
|
}
|
|
578
|
+
var BPMN_RESIZABLE_ELEMENT_TYPES = [
|
|
579
|
+
"Task",
|
|
580
|
+
"UserTask",
|
|
581
|
+
"ServiceTask",
|
|
582
|
+
"ScriptTask",
|
|
583
|
+
"ManualTask",
|
|
584
|
+
"BusinessRuleTask",
|
|
585
|
+
"ReceiveTask",
|
|
586
|
+
"SendTask",
|
|
587
|
+
"CallActivity",
|
|
588
|
+
"SubProcess",
|
|
589
|
+
"Transaction",
|
|
590
|
+
"EventSubProcess",
|
|
591
|
+
"AdHocSubProcess",
|
|
592
|
+
"Pool",
|
|
593
|
+
"Lane",
|
|
594
|
+
"Annotation",
|
|
595
|
+
"Group",
|
|
596
|
+
"SubConversation",
|
|
597
|
+
"ChoreographyTask",
|
|
598
|
+
"SubChoreography",
|
|
599
|
+
"CallChoreography"
|
|
600
|
+
];
|
|
601
|
+
var BPMN_MIN_SIZE_OVERRIDES = {
|
|
602
|
+
Task: { minWidth: 80, minHeight: 48 },
|
|
603
|
+
UserTask: { minWidth: 80, minHeight: 48 },
|
|
604
|
+
ServiceTask: { minWidth: 80, minHeight: 48 },
|
|
605
|
+
ScriptTask: { minWidth: 80, minHeight: 48 },
|
|
606
|
+
ManualTask: { minWidth: 80, minHeight: 48 },
|
|
607
|
+
BusinessRuleTask: { minWidth: 80, minHeight: 48 },
|
|
608
|
+
ReceiveTask: { minWidth: 80, minHeight: 48 },
|
|
609
|
+
SendTask: { minWidth: 80, minHeight: 48 },
|
|
610
|
+
CallActivity: { minWidth: 80, minHeight: 48 },
|
|
611
|
+
SubProcess: { minWidth: 160, minHeight: 100 },
|
|
612
|
+
Transaction: { minWidth: 160, minHeight: 100 },
|
|
613
|
+
EventSubProcess: { minWidth: 160, minHeight: 100 },
|
|
614
|
+
AdHocSubProcess: { minWidth: 160, minHeight: 100 },
|
|
615
|
+
Pool: { minWidth: 240, minHeight: 120 },
|
|
616
|
+
Lane: { minWidth: 240, minHeight: 80 },
|
|
617
|
+
Annotation: { minWidth: 80, minHeight: 40 },
|
|
618
|
+
Group: { minWidth: 120, minHeight: 80 },
|
|
619
|
+
SubConversation: { minWidth: 60, minHeight: 52 },
|
|
620
|
+
ChoreographyTask: { minWidth: 100, minHeight: 70 },
|
|
621
|
+
SubChoreography: { minWidth: 100, minHeight: 70 },
|
|
622
|
+
CallChoreography: { minWidth: 100, minHeight: 70 }
|
|
623
|
+
};
|
|
624
|
+
var resizableTypes = new Set(BPMN_RESIZABLE_ELEMENT_TYPES);
|
|
625
|
+
function isBpmnElementResizable(type) {
|
|
626
|
+
return resizableTypes.has(type);
|
|
627
|
+
}
|
|
628
|
+
function getBpmnElementSize(type) {
|
|
629
|
+
const meta = getElementMeta(type);
|
|
630
|
+
const min = BPMN_MIN_SIZE_OVERRIDES[type];
|
|
631
|
+
return {
|
|
632
|
+
width: meta.defaultWidth,
|
|
633
|
+
height: meta.defaultHeight,
|
|
634
|
+
minWidth: meta.minWidth ?? min?.minWidth ?? meta.defaultWidth,
|
|
635
|
+
minHeight: meta.minHeight ?? min?.minHeight ?? meta.defaultHeight,
|
|
636
|
+
resizable: meta.resizable ?? isBpmnElementResizable(type)
|
|
637
|
+
};
|
|
638
|
+
}
|
|
576
639
|
|
|
577
640
|
// src/elements/guards.ts
|
|
578
641
|
var TASK_TYPES = /* @__PURE__ */ new Set([
|
|
@@ -696,13 +759,19 @@ function BpmnHandles({ variant = "all" }) {
|
|
|
696
759
|
// src/nodes/shared/theme.ts
|
|
697
760
|
var BPMN_THEME = {
|
|
698
761
|
fill: "#ffffff",
|
|
699
|
-
|
|
700
|
-
|
|
762
|
+
fillSoft: "#f8fbff",
|
|
763
|
+
fillSubtle: "#eef6ff",
|
|
764
|
+
stroke: "#334155",
|
|
765
|
+
strokeSelected: "#2563eb",
|
|
701
766
|
strokeWidth: 1.5,
|
|
702
767
|
strokeWidthSelected: 2.5,
|
|
703
768
|
fontFamily: "Inter, system-ui, sans-serif",
|
|
704
769
|
fontSize: 11,
|
|
705
|
-
labelColor: "#
|
|
770
|
+
labelColor: "#0f172a",
|
|
771
|
+
shadow: "0 4px 12px rgba(15, 23, 42, 0.08)",
|
|
772
|
+
shadowSelected: "0 0 0 4px rgba(37, 99, 235, 0.14), 0 8px 18px rgba(15, 23, 42, 0.12)",
|
|
773
|
+
transition: "box-shadow 140ms ease, filter 140ms ease, transform 140ms ease"
|
|
774
|
+
};
|
|
706
775
|
function resolveStroke(selected, override) {
|
|
707
776
|
if (selected) return BPMN_THEME.strokeSelected;
|
|
708
777
|
return override ?? BPMN_THEME.stroke;
|
|
@@ -710,6 +779,12 @@ function resolveStroke(selected, override) {
|
|
|
710
779
|
function resolveStrokeWidth(selected) {
|
|
711
780
|
return selected ? BPMN_THEME.strokeWidthSelected : BPMN_THEME.strokeWidth;
|
|
712
781
|
}
|
|
782
|
+
function resolveShapeFilter(selected) {
|
|
783
|
+
return selected ? "drop-shadow(0 0 0 rgba(37,99,235,0.2)) drop-shadow(0 8px 14px rgba(15,23,42,0.12))" : "drop-shadow(0 4px 10px rgba(15,23,42,0.08))";
|
|
784
|
+
}
|
|
785
|
+
function resolveNodeShadow(selected) {
|
|
786
|
+
return selected ? BPMN_THEME.shadowSelected : BPMN_THEME.shadow;
|
|
787
|
+
}
|
|
713
788
|
var EXTERNAL_STYLE = {
|
|
714
789
|
position: "absolute",
|
|
715
790
|
top: "100%",
|
|
@@ -862,7 +937,7 @@ function StartEventNode({ data, selected }) {
|
|
|
862
937
|
const trigger = d.trigger ?? "none";
|
|
863
938
|
const dashArray = d.isNonInterrupting ? "4 2" : void 0;
|
|
864
939
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: SIZE, height: SIZE, position: "relative" }, children: [
|
|
865
|
-
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE, height: SIZE, style: { overflow: "visible", display: "block" }, children: [
|
|
940
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE, height: SIZE, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
|
|
866
941
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
867
942
|
"circle",
|
|
868
943
|
{
|
|
@@ -891,7 +966,7 @@ function EndEventNode({ data, selected }) {
|
|
|
891
966
|
const fill = d.color?.fill ?? BPMN_THEME.fill;
|
|
892
967
|
const trigger = d.trigger ?? "none";
|
|
893
968
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: SIZE2, height: SIZE2, position: "relative" }, children: [
|
|
894
|
-
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE2, height: SIZE2, style: { overflow: "visible", display: "block" }, children: [
|
|
969
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE2, height: SIZE2, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
|
|
895
970
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
896
971
|
"circle",
|
|
897
972
|
{
|
|
@@ -919,9 +994,9 @@ function IntermediateCatchEventNode({ data, selected }) {
|
|
|
919
994
|
const stroke = resolveStroke(selected, d.color?.stroke);
|
|
920
995
|
const sw = resolveStrokeWidth(selected);
|
|
921
996
|
const fill = d.color?.fill ?? BPMN_THEME.fill;
|
|
922
|
-
const trigger = d.trigger
|
|
997
|
+
const trigger = d.trigger && d.trigger !== "none" ? d.trigger : "timer";
|
|
923
998
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: SIZE3, height: SIZE3, position: "relative" }, children: [
|
|
924
|
-
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE3, height: SIZE3, style: { overflow: "visible", display: "block" }, children: [
|
|
999
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE3, height: SIZE3, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
|
|
925
1000
|
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: CX3, cy: CX3, r: R_OUTER, fill, stroke, strokeWidth: sw }),
|
|
926
1001
|
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: CX3, cy: CX3, r: R_INNER, fill: "none", stroke, strokeWidth: sw }),
|
|
927
1002
|
/* @__PURE__ */ jsxRuntime.jsx(EventMarker, { cx: CX3, cy: CX3, trigger, filled: false, stroke, bg: fill, r: ICON_R })
|
|
@@ -935,9 +1010,9 @@ function IntermediateThrowEventNode({ data, selected }) {
|
|
|
935
1010
|
const stroke = resolveStroke(selected, d.color?.stroke);
|
|
936
1011
|
const sw = resolveStrokeWidth(selected);
|
|
937
1012
|
const fill = d.color?.fill ?? BPMN_THEME.fill;
|
|
938
|
-
const trigger = d.trigger
|
|
1013
|
+
const trigger = d.trigger && d.trigger !== "none" ? d.trigger : "message";
|
|
939
1014
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: SIZE3, height: SIZE3, position: "relative" }, children: [
|
|
940
|
-
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE3, height: SIZE3, style: { overflow: "visible", display: "block" }, children: [
|
|
1015
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE3, height: SIZE3, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
|
|
941
1016
|
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: CX3, cy: CX3, r: R_OUTER, fill, stroke, strokeWidth: sw }),
|
|
942
1017
|
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: CX3, cy: CX3, r: R_INNER, fill: stroke, stroke, strokeWidth: sw }),
|
|
943
1018
|
/* @__PURE__ */ jsxRuntime.jsx(EventMarker, { cx: CX3, cy: CX3, trigger, filled: true, stroke: fill, bg: stroke, r: ICON_R })
|
|
@@ -951,10 +1026,10 @@ function BoundaryEventNode({ data, selected }) {
|
|
|
951
1026
|
const stroke = resolveStroke(selected, d.color?.stroke);
|
|
952
1027
|
const sw = resolveStrokeWidth(selected);
|
|
953
1028
|
const fill = d.color?.fill ?? BPMN_THEME.fill;
|
|
954
|
-
const trigger = d.trigger
|
|
1029
|
+
const trigger = d.trigger && d.trigger !== "none" ? d.trigger : "timer";
|
|
955
1030
|
const dashArray = d.isNonInterrupting ? "4 2" : void 0;
|
|
956
1031
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: SIZE3, height: SIZE3, position: "relative" }, children: [
|
|
957
|
-
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE3, height: SIZE3, style: { overflow: "visible", display: "block" }, children: [
|
|
1032
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE3, height: SIZE3, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
|
|
958
1033
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
959
1034
|
"circle",
|
|
960
1035
|
{
|
|
@@ -989,6 +1064,11 @@ function TaskIcon({ type, size = 14, color = "#404040" }) {
|
|
|
989
1064
|
const s = size;
|
|
990
1065
|
const c = color;
|
|
991
1066
|
switch (type) {
|
|
1067
|
+
case "Task":
|
|
1068
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: s, height: s, viewBox: "0 0 16 16", fill: "none", children: [
|
|
1069
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "3", y: "3", width: "10", height: "10", rx: "1.5", stroke: c, strokeWidth: "1.5" }),
|
|
1070
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5.5 8.2 7.2 10 10.8 6", stroke: c, strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
1071
|
+
] });
|
|
992
1072
|
case "UserTask":
|
|
993
1073
|
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: s, height: s, viewBox: "0 0 16 16", fill: "none", children: [
|
|
994
1074
|
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "8", cy: "5", r: "3", stroke: c, strokeWidth: "1.5" }),
|
|
@@ -1131,20 +1211,22 @@ function TaskNode({ data, selected }) {
|
|
|
1131
1211
|
style: {
|
|
1132
1212
|
width: "100%",
|
|
1133
1213
|
height: "100%",
|
|
1134
|
-
background: d.color?.fill ?? BPMN_THEME.fill
|
|
1214
|
+
background: d.color?.fill ?? `linear-gradient(180deg, ${BPMN_THEME.fill} 0%, ${BPMN_THEME.fillSoft} 100%)`,
|
|
1135
1215
|
border: `${borderWidth}px solid ${stroke}`,
|
|
1136
|
-
borderRadius:
|
|
1216
|
+
borderRadius: 7,
|
|
1137
1217
|
boxSizing: "border-box",
|
|
1218
|
+
boxShadow: resolveNodeShadow(selected),
|
|
1138
1219
|
display: "flex",
|
|
1139
1220
|
flexDirection: "column",
|
|
1140
1221
|
alignItems: "center",
|
|
1141
1222
|
justifyContent: "center",
|
|
1142
1223
|
padding: hasMarkers ? "4px 8px 22px" : "4px 8px",
|
|
1143
1224
|
position: "relative",
|
|
1144
|
-
fontFamily: BPMN_THEME.fontFamily
|
|
1225
|
+
fontFamily: BPMN_THEME.fontFamily,
|
|
1226
|
+
transition: BPMN_THEME.transition
|
|
1145
1227
|
},
|
|
1146
1228
|
children: [
|
|
1147
|
-
d.elementType &&
|
|
1229
|
+
d.elementType && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { position: "absolute", top: 5, left: 5 }, children: /* @__PURE__ */ jsxRuntime.jsx(TaskIcon, { type: d.elementType, size: 14, color: stroke }) }),
|
|
1148
1230
|
/* @__PURE__ */ jsxRuntime.jsx(BpmnLabel, { style: { width: "100%" }, children: d.label ?? d.elementType }),
|
|
1149
1231
|
d.priority && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1150
1232
|
"div",
|
|
@@ -1222,7 +1304,7 @@ function GatewayNode({ data, selected }) {
|
|
|
1222
1304
|
const stroke = resolveStroke(selected, d.color?.stroke);
|
|
1223
1305
|
const sw = resolveStrokeWidth(selected);
|
|
1224
1306
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: SIZE4, height: SIZE4, position: "relative" }, children: [
|
|
1225
|
-
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE4, height: SIZE4, style: { overflow: "visible", display: "block" }, children: [
|
|
1307
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: SIZE4, height: SIZE4, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
|
|
1226
1308
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1227
1309
|
"polygon",
|
|
1228
1310
|
{
|
|
@@ -1238,11 +1320,24 @@ function GatewayNode({ data, selected }) {
|
|
|
1238
1320
|
/* @__PURE__ */ jsxRuntime.jsx(BpmnLabel, { external: true, children: d.label })
|
|
1239
1321
|
] });
|
|
1240
1322
|
}
|
|
1323
|
+
function resolveVariant(d) {
|
|
1324
|
+
if (d.subProcessVariant) return d.subProcessVariant;
|
|
1325
|
+
switch (d.elementType) {
|
|
1326
|
+
case "Transaction":
|
|
1327
|
+
return "transaction";
|
|
1328
|
+
case "EventSubProcess":
|
|
1329
|
+
return "event";
|
|
1330
|
+
case "AdHocSubProcess":
|
|
1331
|
+
return "adhoc";
|
|
1332
|
+
default:
|
|
1333
|
+
return "embedded";
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1241
1336
|
function SubProcessNode({ data, selected }) {
|
|
1242
1337
|
const d = data;
|
|
1243
1338
|
const stroke = resolveStroke(selected, d.color?.stroke);
|
|
1244
1339
|
const sw = resolveStrokeWidth(selected);
|
|
1245
|
-
const variant = d
|
|
1340
|
+
const variant = resolveVariant(d);
|
|
1246
1341
|
const isExpanded = d.isExpanded ?? true;
|
|
1247
1342
|
const hasMarkers = d.markers && d.markers.length > 0;
|
|
1248
1343
|
const borderStyle = variant === "event" ? "dashed" : "solid";
|
|
@@ -1252,12 +1347,14 @@ function SubProcessNode({ data, selected }) {
|
|
|
1252
1347
|
style: {
|
|
1253
1348
|
width: "100%",
|
|
1254
1349
|
height: "100%",
|
|
1255
|
-
background: d.color?.fill ??
|
|
1350
|
+
background: d.color?.fill ?? `linear-gradient(180deg, ${BPMN_THEME.fill} 0%, ${BPMN_THEME.fillSubtle} 100%)`,
|
|
1256
1351
|
border: `${sw}px ${borderStyle} ${stroke}`,
|
|
1257
1352
|
borderRadius: 6,
|
|
1258
1353
|
boxSizing: "border-box",
|
|
1354
|
+
boxShadow: resolveNodeShadow(selected),
|
|
1259
1355
|
position: "relative",
|
|
1260
|
-
fontFamily: BPMN_THEME.fontFamily
|
|
1356
|
+
fontFamily: BPMN_THEME.fontFamily,
|
|
1357
|
+
transition: BPMN_THEME.transition
|
|
1261
1358
|
},
|
|
1262
1359
|
children: [
|
|
1263
1360
|
variant === "transaction" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1311,8 +1408,8 @@ function PoolNode({ data, selected }) {
|
|
|
1311
1408
|
const stroke = resolveStroke(selected, d.color?.stroke);
|
|
1312
1409
|
const sw = resolveStrokeWidth(selected);
|
|
1313
1410
|
const orientation = d.orientation ?? "horizontal";
|
|
1314
|
-
const fill = d.color?.fill ?? "#
|
|
1315
|
-
const headerFill = d.color?.fill ?? "#
|
|
1411
|
+
const fill = d.color?.fill ?? "#f8fbff";
|
|
1412
|
+
const headerFill = d.color?.fill ?? "#eaf2ff";
|
|
1316
1413
|
if (orientation === "vertical") {
|
|
1317
1414
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1318
1415
|
"div",
|
|
@@ -1326,14 +1423,17 @@ function PoolNode({ data, selected }) {
|
|
|
1326
1423
|
borderRadius: 4,
|
|
1327
1424
|
boxSizing: "border-box",
|
|
1328
1425
|
background: fill,
|
|
1426
|
+
boxShadow: resolveNodeShadow(selected),
|
|
1329
1427
|
overflow: "hidden",
|
|
1330
|
-
fontFamily: BPMN_THEME.fontFamily
|
|
1428
|
+
fontFamily: BPMN_THEME.fontFamily,
|
|
1429
|
+
transition: BPMN_THEME.transition
|
|
1331
1430
|
},
|
|
1332
1431
|
children: [
|
|
1333
1432
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1334
1433
|
"div",
|
|
1335
1434
|
{
|
|
1336
1435
|
"aria-label": "pool-header",
|
|
1436
|
+
className: "pool-drag-handle",
|
|
1337
1437
|
style: {
|
|
1338
1438
|
height: HEADER_HEIGHT,
|
|
1339
1439
|
minHeight: HEADER_HEIGHT,
|
|
@@ -1342,7 +1442,8 @@ function PoolNode({ data, selected }) {
|
|
|
1342
1442
|
alignItems: "center",
|
|
1343
1443
|
justifyContent: "center",
|
|
1344
1444
|
background: headerFill,
|
|
1345
|
-
padding: "0 8px"
|
|
1445
|
+
padding: "0 8px",
|
|
1446
|
+
cursor: "grab"
|
|
1346
1447
|
},
|
|
1347
1448
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1348
1449
|
"span",
|
|
@@ -1376,14 +1477,17 @@ function PoolNode({ data, selected }) {
|
|
|
1376
1477
|
borderRadius: 4,
|
|
1377
1478
|
boxSizing: "border-box",
|
|
1378
1479
|
background: fill,
|
|
1480
|
+
boxShadow: resolveNodeShadow(selected),
|
|
1379
1481
|
overflow: "hidden",
|
|
1380
|
-
fontFamily: BPMN_THEME.fontFamily
|
|
1482
|
+
fontFamily: BPMN_THEME.fontFamily,
|
|
1483
|
+
transition: BPMN_THEME.transition
|
|
1381
1484
|
},
|
|
1382
1485
|
children: [
|
|
1383
1486
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1384
1487
|
"div",
|
|
1385
1488
|
{
|
|
1386
1489
|
"aria-label": "pool-header",
|
|
1490
|
+
className: "pool-drag-handle",
|
|
1387
1491
|
style: {
|
|
1388
1492
|
width: HEADER_WIDTH,
|
|
1389
1493
|
minWidth: HEADER_WIDTH,
|
|
@@ -1391,7 +1495,8 @@ function PoolNode({ data, selected }) {
|
|
|
1391
1495
|
display: "flex",
|
|
1392
1496
|
alignItems: "center",
|
|
1393
1497
|
justifyContent: "center",
|
|
1394
|
-
background: headerFill
|
|
1498
|
+
background: headerFill,
|
|
1499
|
+
cursor: "grab"
|
|
1395
1500
|
},
|
|
1396
1501
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1397
1502
|
"span",
|
|
@@ -1424,8 +1529,8 @@ function LaneNode({ data, selected }) {
|
|
|
1424
1529
|
const stroke = resolveStroke(selected, d.color?.stroke);
|
|
1425
1530
|
const sw = resolveStrokeWidth(selected);
|
|
1426
1531
|
const orientation = d.orientation ?? "horizontal";
|
|
1427
|
-
const fill = d.color?.fill ?? "#
|
|
1428
|
-
const headerFill = d.color?.fill ?? "#
|
|
1532
|
+
const fill = d.color?.fill ?? "#fbfdff";
|
|
1533
|
+
const headerFill = d.color?.fill ?? "#eef6ff";
|
|
1429
1534
|
if (orientation === "vertical") {
|
|
1430
1535
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1431
1536
|
"div",
|
|
@@ -1438,14 +1543,17 @@ function LaneNode({ data, selected }) {
|
|
|
1438
1543
|
borderRadius: 2,
|
|
1439
1544
|
boxSizing: "border-box",
|
|
1440
1545
|
background: fill,
|
|
1546
|
+
boxShadow: resolveNodeShadow(selected),
|
|
1441
1547
|
overflow: "hidden",
|
|
1442
|
-
fontFamily: BPMN_THEME.fontFamily
|
|
1548
|
+
fontFamily: BPMN_THEME.fontFamily,
|
|
1549
|
+
transition: BPMN_THEME.transition
|
|
1443
1550
|
},
|
|
1444
1551
|
children: [
|
|
1445
1552
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1446
1553
|
"div",
|
|
1447
1554
|
{
|
|
1448
1555
|
"aria-label": "lane-header",
|
|
1556
|
+
className: "lane-drag-handle",
|
|
1449
1557
|
style: {
|
|
1450
1558
|
width: HEADER_WIDTH2,
|
|
1451
1559
|
minWidth: HEADER_WIDTH2,
|
|
@@ -1454,7 +1562,8 @@ function LaneNode({ data, selected }) {
|
|
|
1454
1562
|
alignItems: "center",
|
|
1455
1563
|
justifyContent: "center",
|
|
1456
1564
|
background: headerFill,
|
|
1457
|
-
padding: "6px 0"
|
|
1565
|
+
padding: "6px 0",
|
|
1566
|
+
cursor: "grab"
|
|
1458
1567
|
},
|
|
1459
1568
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1460
1569
|
"span",
|
|
@@ -1492,14 +1601,17 @@ function LaneNode({ data, selected }) {
|
|
|
1492
1601
|
borderRadius: 2,
|
|
1493
1602
|
boxSizing: "border-box",
|
|
1494
1603
|
background: fill,
|
|
1604
|
+
boxShadow: resolveNodeShadow(selected),
|
|
1495
1605
|
overflow: "hidden",
|
|
1496
|
-
fontFamily: BPMN_THEME.fontFamily
|
|
1606
|
+
fontFamily: BPMN_THEME.fontFamily,
|
|
1607
|
+
transition: BPMN_THEME.transition
|
|
1497
1608
|
},
|
|
1498
1609
|
children: [
|
|
1499
1610
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1500
1611
|
"div",
|
|
1501
1612
|
{
|
|
1502
1613
|
"aria-label": "lane-header",
|
|
1614
|
+
className: "lane-drag-handle",
|
|
1503
1615
|
style: {
|
|
1504
1616
|
height: HEADER_HEIGHT2,
|
|
1505
1617
|
minHeight: HEADER_HEIGHT2,
|
|
@@ -1510,7 +1622,8 @@ function LaneNode({ data, selected }) {
|
|
|
1510
1622
|
background: headerFill,
|
|
1511
1623
|
fontSize: BPMN_THEME.fontSize,
|
|
1512
1624
|
fontWeight: 500,
|
|
1513
|
-
color: BPMN_THEME.labelColor
|
|
1625
|
+
color: BPMN_THEME.labelColor,
|
|
1626
|
+
cursor: "grab"
|
|
1514
1627
|
},
|
|
1515
1628
|
children: d.label
|
|
1516
1629
|
}
|
|
@@ -1627,7 +1740,7 @@ function DataObjectNode({ data, selected }) {
|
|
|
1627
1740
|
`L ${W} ${FOLD}`
|
|
1628
1741
|
].join(" ");
|
|
1629
1742
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: W, height: H2, position: "relative" }, children: [
|
|
1630
|
-
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: W, height: H2, style: { overflow: "visible", display: "block" }, children: [
|
|
1743
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: W, height: H2, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
|
|
1631
1744
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: path, fill, stroke, strokeWidth: sw }),
|
|
1632
1745
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: foldPath2, fill: "none", stroke, strokeWidth: sw })
|
|
1633
1746
|
] }),
|
|
@@ -1645,7 +1758,7 @@ function DataStoreNode({ data, selected }) {
|
|
|
1645
1758
|
const sw = resolveStrokeWidth(selected);
|
|
1646
1759
|
const fill = d.color?.fill ?? BPMN_THEME.fill;
|
|
1647
1760
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: DS_W, height: DS_H, position: "relative" }, children: [
|
|
1648
|
-
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: DS_W, height: DS_H, style: { overflow: "visible", display: "block" }, children: [
|
|
1761
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: DS_W, height: DS_H, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
|
|
1649
1762
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1650
1763
|
"path",
|
|
1651
1764
|
{
|
|
@@ -1691,7 +1804,7 @@ function DataObjectReferenceNode({ data, selected }) {
|
|
|
1691
1804
|
const sw = resolveStrokeWidth(selected);
|
|
1692
1805
|
const fill = d.color?.fill ?? BPMN_THEME.fill;
|
|
1693
1806
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: W2, height: H3, position: "relative" }, children: [
|
|
1694
|
-
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: W2, height: H3, style: { overflow: "visible", display: "block" }, children: [
|
|
1807
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: W2, height: H3, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
|
|
1695
1808
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: documentPath(), fill, stroke, strokeWidth: sw }),
|
|
1696
1809
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: foldPath(), fill: "none", stroke, strokeWidth: sw }),
|
|
1697
1810
|
d.isCollection && collectionLines(stroke, sw)
|
|
@@ -1706,7 +1819,7 @@ function DataInputNode({ data, selected }) {
|
|
|
1706
1819
|
const sw = resolveStrokeWidth(selected);
|
|
1707
1820
|
const fill = d.color?.fill ?? BPMN_THEME.fill;
|
|
1708
1821
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: W2, height: H3, position: "relative" }, children: [
|
|
1709
|
-
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: W2, height: H3, style: { overflow: "visible", display: "block" }, children: [
|
|
1822
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: W2, height: H3, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
|
|
1710
1823
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: documentPath(), fill, stroke, strokeWidth: sw }),
|
|
1711
1824
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: foldPath(), fill: "none", stroke, strokeWidth: sw }),
|
|
1712
1825
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1730,7 +1843,7 @@ function DataOutputNode({ data, selected }) {
|
|
|
1730
1843
|
const sw = resolveStrokeWidth(selected);
|
|
1731
1844
|
const fill = d.color?.fill ?? BPMN_THEME.fill;
|
|
1732
1845
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: W2, height: H3, position: "relative" }, children: [
|
|
1733
|
-
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: W2, height: H3, style: { overflow: "visible", display: "block" }, children: [
|
|
1846
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: W2, height: H3, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
|
|
1734
1847
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: documentPath(), fill, stroke, strokeWidth: sw }),
|
|
1735
1848
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: foldPath(), fill: "none", stroke, strokeWidth: sw }),
|
|
1736
1849
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1758,7 +1871,7 @@ function DataStoreReferenceNode({ data, selected }) {
|
|
|
1758
1871
|
const sw = resolveStrokeWidth(selected);
|
|
1759
1872
|
const fill = d.color?.fill ?? BPMN_THEME.fill;
|
|
1760
1873
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: DS_W2, height: DS_H2, position: "relative" }, children: [
|
|
1761
|
-
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: DS_W2, height: DS_H2, style: { overflow: "visible", display: "block" }, children: [
|
|
1874
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: DS_W2, height: DS_H2, style: { overflow: "visible", display: "block", filter: resolveShapeFilter(selected) }, children: [
|
|
1762
1875
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1763
1876
|
"path",
|
|
1764
1877
|
{
|
|
@@ -2084,8 +2197,11 @@ var BPMN_NODE_TYPES = {
|
|
|
2084
2197
|
ParallelGateway: GatewayNode,
|
|
2085
2198
|
EventBasedGateway: GatewayNode,
|
|
2086
2199
|
ComplexGateway: GatewayNode,
|
|
2087
|
-
// Containers
|
|
2200
|
+
// Containers — Transaction, EventSubProcess, AdHocSubProcess derive their visual variant from elementType
|
|
2088
2201
|
SubProcess: SubProcessNode,
|
|
2202
|
+
Transaction: SubProcessNode,
|
|
2203
|
+
EventSubProcess: SubProcessNode,
|
|
2204
|
+
AdHocSubProcess: SubProcessNode,
|
|
2089
2205
|
Pool: PoolNode,
|
|
2090
2206
|
Lane: LaneNode,
|
|
2091
2207
|
// Artifacts
|
|
@@ -2408,8 +2524,8 @@ var MODDLE_TO_ELEMENT_TYPE = {
|
|
|
2408
2524
|
"bpmn:EventBasedGateway": "EventBasedGateway",
|
|
2409
2525
|
"bpmn:ComplexGateway": "ComplexGateway",
|
|
2410
2526
|
"bpmn:SubProcess": "SubProcess",
|
|
2411
|
-
"bpmn:AdHocSubProcess": "
|
|
2412
|
-
"bpmn:Transaction": "
|
|
2527
|
+
"bpmn:AdHocSubProcess": "AdHocSubProcess",
|
|
2528
|
+
"bpmn:Transaction": "Transaction",
|
|
2413
2529
|
"bpmn:TextAnnotation": "Annotation",
|
|
2414
2530
|
"bpmn:Group": "Group",
|
|
2415
2531
|
"bpmn:DataObject": "DataObject",
|
|
@@ -2447,6 +2563,9 @@ var ELEMENT_TYPE_TO_MODDLE = {
|
|
|
2447
2563
|
EventBasedGateway: "bpmn:EventBasedGateway",
|
|
2448
2564
|
ComplexGateway: "bpmn:ComplexGateway",
|
|
2449
2565
|
SubProcess: "bpmn:SubProcess",
|
|
2566
|
+
Transaction: "bpmn:Transaction",
|
|
2567
|
+
EventSubProcess: "bpmn:SubProcess",
|
|
2568
|
+
AdHocSubProcess: "bpmn:AdHocSubProcess",
|
|
2450
2569
|
Pool: "bpmn:Participant",
|
|
2451
2570
|
Lane: "bpmn:Lane",
|
|
2452
2571
|
Annotation: "bpmn:TextAnnotation",
|
|
@@ -2511,6 +2630,10 @@ function asElements(v) {
|
|
|
2511
2630
|
function asString(v) {
|
|
2512
2631
|
return typeof v === "string" && v.trim() ? v.trim() : void 0;
|
|
2513
2632
|
}
|
|
2633
|
+
function extractDocumentation(el) {
|
|
2634
|
+
const [doc] = asElements(el.documentation);
|
|
2635
|
+
return asString(doc?.text);
|
|
2636
|
+
}
|
|
2514
2637
|
function extractDiagramInfo(definitions) {
|
|
2515
2638
|
const shapes = /* @__PURE__ */ new Map();
|
|
2516
2639
|
const waypoints = /* @__PURE__ */ new Map();
|
|
@@ -2566,6 +2689,7 @@ function extractTrigger(el) {
|
|
|
2566
2689
|
function extractSubProcessVariant(el) {
|
|
2567
2690
|
if (el.$type === "bpmn:Transaction") return "transaction";
|
|
2568
2691
|
if (el.$type === "bpmn:AdHocSubProcess") return "adhoc";
|
|
2692
|
+
if (el.$type === "bpmn:SubProcess" && el.triggeredByEvent === true) return "event";
|
|
2569
2693
|
if (el.triggeredByEvent === true) return "event";
|
|
2570
2694
|
return "embedded";
|
|
2571
2695
|
}
|
|
@@ -2579,7 +2703,7 @@ function walkFlowElements(elements, parentId, ctx, nodes, edges) {
|
|
|
2579
2703
|
continue;
|
|
2580
2704
|
}
|
|
2581
2705
|
if ($type === "bpmn:LaneSet") continue;
|
|
2582
|
-
const elementType = MODDLE_TO_ELEMENT_TYPE[$type];
|
|
2706
|
+
const elementType = $type === "bpmn:SubProcess" && el.triggeredByEvent === true ? "EventSubProcess" : MODDLE_TO_ELEMENT_TYPE[$type];
|
|
2583
2707
|
if (!elementType) {
|
|
2584
2708
|
ctx.warnings.push(`Unknown element type "${$type}" (id=${id}) \u2014 skipped.`);
|
|
2585
2709
|
continue;
|
|
@@ -2600,22 +2724,26 @@ function buildNode(el, elementType, parentId, ctx, nodes) {
|
|
|
2600
2724
|
const y = shape?.y ?? 100;
|
|
2601
2725
|
if (!shape) ctx.autoX.value += (meta?.defaultWidth ?? 120) + 20;
|
|
2602
2726
|
const label = asString(el.name);
|
|
2727
|
+
const documentation = extractDocumentation(el);
|
|
2603
2728
|
const trigger = extractTrigger(el);
|
|
2604
2729
|
const isNonInterrupting = el.cancelActivity === false;
|
|
2730
|
+
const attachedToRef = el.attachedToRef?.id;
|
|
2605
2731
|
const data = {
|
|
2606
2732
|
elementType,
|
|
2607
2733
|
...label ? { label } : {},
|
|
2734
|
+
...documentation ? { documentation } : {},
|
|
2608
2735
|
...trigger ? { trigger } : {},
|
|
2609
|
-
...isNonInterrupting ? { isNonInterrupting: true } : {}
|
|
2736
|
+
...isNonInterrupting ? { isNonInterrupting: true } : {},
|
|
2737
|
+
...attachedToRef ? { attachedToRef } : {}
|
|
2610
2738
|
};
|
|
2611
|
-
if (elementType === "SubProcess") {
|
|
2739
|
+
if (elementType === "SubProcess" || elementType === "Transaction" || elementType === "EventSubProcess" || elementType === "AdHocSubProcess") {
|
|
2612
2740
|
const variant = extractSubProcessVariant(el);
|
|
2613
2741
|
if (variant) data.subProcessVariant = variant;
|
|
2614
2742
|
const isExpanded = shape?.isExpanded ?? true;
|
|
2615
2743
|
data.isExpanded = isExpanded;
|
|
2616
2744
|
}
|
|
2617
2745
|
const laneId = ctx.laneMembership.get(id);
|
|
2618
|
-
const effectiveParentId = laneId ?? parentId;
|
|
2746
|
+
const effectiveParentId = attachedToRef ?? laneId ?? parentId;
|
|
2619
2747
|
const node = {
|
|
2620
2748
|
id,
|
|
2621
2749
|
type: elementType,
|
|
@@ -2636,10 +2764,12 @@ function buildEdge(el, edgeType, ctx, edges) {
|
|
|
2636
2764
|
return;
|
|
2637
2765
|
}
|
|
2638
2766
|
const label = asString(el.name);
|
|
2767
|
+
const documentation = extractDocumentation(el);
|
|
2639
2768
|
const condExpr = el.conditionExpression;
|
|
2640
2769
|
const data = {
|
|
2641
2770
|
edgeType,
|
|
2642
2771
|
...label ? { label } : {},
|
|
2772
|
+
...documentation ? { documentation } : {},
|
|
2643
2773
|
...condExpr?.body ? { conditionExpression: condExpr.body } : {}
|
|
2644
2774
|
};
|
|
2645
2775
|
const waypoints = ctx.waypoints.get(id);
|
|
@@ -2740,7 +2870,46 @@ async function parseBpmnXml(xml) {
|
|
|
2740
2870
|
);
|
|
2741
2871
|
}
|
|
2742
2872
|
}
|
|
2743
|
-
|
|
2873
|
+
const defaultFlowById = /* @__PURE__ */ new Set();
|
|
2874
|
+
const nodeIds = new Set(nodes.map((node) => node.id));
|
|
2875
|
+
for (const rootEl of asElements(rootElement.rootElements)) {
|
|
2876
|
+
collectDefaultFlows(rootEl, defaultFlowById);
|
|
2877
|
+
}
|
|
2878
|
+
const normalizedEdges = edges.map((edge) => {
|
|
2879
|
+
if (!defaultFlowById.has(edge.id)) return edge;
|
|
2880
|
+
const data = {
|
|
2881
|
+
edgeType: edge.data?.edgeType ?? edge.type,
|
|
2882
|
+
...edge.data ?? {},
|
|
2883
|
+
isDefault: true
|
|
2884
|
+
};
|
|
2885
|
+
return { ...edge, data };
|
|
2886
|
+
});
|
|
2887
|
+
return {
|
|
2888
|
+
nodes: normalizeChildPositions(nodes, nodeIds),
|
|
2889
|
+
edges: normalizedEdges,
|
|
2890
|
+
warnings
|
|
2891
|
+
};
|
|
2892
|
+
}
|
|
2893
|
+
function collectDefaultFlows(el, defaultFlowById) {
|
|
2894
|
+
const defaultRef = el.default;
|
|
2895
|
+
if (defaultRef?.id) defaultFlowById.add(defaultRef.id);
|
|
2896
|
+
for (const child of asElements(el.rootElements)) collectDefaultFlows(child, defaultFlowById);
|
|
2897
|
+
for (const child of asElements(el.flowElements)) collectDefaultFlows(child, defaultFlowById);
|
|
2898
|
+
}
|
|
2899
|
+
function normalizeChildPositions(nodes, nodeIds) {
|
|
2900
|
+
const absoluteById = new Map(nodes.map((node) => [node.id, node.position]));
|
|
2901
|
+
return nodes.map((node) => {
|
|
2902
|
+
if (!node.parentId || !nodeIds.has(node.parentId)) return node;
|
|
2903
|
+
const parentPosition = absoluteById.get(node.parentId);
|
|
2904
|
+
if (!parentPosition) return node;
|
|
2905
|
+
return {
|
|
2906
|
+
...node,
|
|
2907
|
+
position: {
|
|
2908
|
+
x: node.position.x - parentPosition.x,
|
|
2909
|
+
y: node.position.y - parentPosition.y
|
|
2910
|
+
}
|
|
2911
|
+
};
|
|
2912
|
+
});
|
|
2744
2913
|
}
|
|
2745
2914
|
function uid(prefix, id) {
|
|
2746
2915
|
return `${prefix}_${id}`;
|
|
@@ -2748,19 +2917,6 @@ function uid(prefix, id) {
|
|
|
2748
2917
|
function asNodes(nodes, types) {
|
|
2749
2918
|
return nodes.filter((n) => types.includes(n.data.elementType));
|
|
2750
2919
|
}
|
|
2751
|
-
function buildFlowableAttrs(data) {
|
|
2752
|
-
const attrs = {};
|
|
2753
|
-
if (data.flowableAssignee) attrs["flowable:assignee"] = data.flowableAssignee;
|
|
2754
|
-
if (data.flowableCandidateGroups) attrs["flowable:candidateGroups"] = data.flowableCandidateGroups;
|
|
2755
|
-
if (data.flowableCandidateUsers) attrs["flowable:candidateUsers"] = data.flowableCandidateUsers;
|
|
2756
|
-
if (data.flowableFormKey) attrs["flowable:formKey"] = data.flowableFormKey;
|
|
2757
|
-
if (data.flowableDueDate) attrs["flowable:dueDate"] = data.flowableDueDate;
|
|
2758
|
-
if (data.flowableType) attrs["flowable:type"] = data.flowableType;
|
|
2759
|
-
if (data.flowableExpression) attrs["flowable:expression"] = data.flowableExpression;
|
|
2760
|
-
if (data.flowableClass) attrs["flowable:class"] = data.flowableClass;
|
|
2761
|
-
if (data.flowableDelegateExpression) attrs["flowable:delegateExpression"] = data.flowableDelegateExpression;
|
|
2762
|
-
return attrs;
|
|
2763
|
-
}
|
|
2764
2920
|
function buildSemanticModel(moddle, nodes, edges, opts) {
|
|
2765
2921
|
const defId = opts.id ?? "Definitions_1";
|
|
2766
2922
|
const defName = opts.name;
|
|
@@ -2819,13 +2975,32 @@ function buildSemanticModel(moddle, nodes, edges, opts) {
|
|
|
2819
2975
|
return definitions;
|
|
2820
2976
|
}
|
|
2821
2977
|
function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId) {
|
|
2822
|
-
const
|
|
2823
|
-
|
|
2824
|
-
|
|
2978
|
+
const subProcessIds = new Set(
|
|
2979
|
+
allNodes.filter(
|
|
2980
|
+
(n) => n.data.elementType === "SubProcess" || n.data.elementType === "Transaction" || n.data.elementType === "EventSubProcess" || n.data.elementType === "AdHocSubProcess"
|
|
2981
|
+
).map((n) => n.id)
|
|
2982
|
+
);
|
|
2983
|
+
const isInsideSubProcess = (node) => {
|
|
2984
|
+
let parentId = node.parentId;
|
|
2985
|
+
while (parentId) {
|
|
2986
|
+
if (subProcessIds.has(parentId)) return true;
|
|
2987
|
+
parentId = allNodes.find((candidate) => candidate.id === parentId)?.parentId;
|
|
2988
|
+
}
|
|
2989
|
+
return false;
|
|
2990
|
+
};
|
|
2991
|
+
const belongsToPool = (node) => {
|
|
2992
|
+
let parentId = node.parentId;
|
|
2993
|
+
while (parentId) {
|
|
2994
|
+
if (parentId === poolId) return true;
|
|
2995
|
+
parentId = allNodes.find((candidate) => candidate.id === parentId)?.parentId;
|
|
2996
|
+
}
|
|
2997
|
+
return false;
|
|
2998
|
+
};
|
|
2999
|
+
const myNodes = (poolId ? allNodes.filter((n) => belongsToPool(n)) : allNodes.filter((n) => n.data.elementType !== "Pool" && n.data.elementType !== "Lane")).filter((n) => !isInsideSubProcess(n));
|
|
2825
3000
|
const myLanes = laneNodes.filter((l) => poolId ? l.parentId === poolId : true);
|
|
2826
3001
|
const flowElements = [];
|
|
2827
3002
|
for (const node of myNodes) {
|
|
2828
|
-
const el = buildFlowElement(moddle, node);
|
|
3003
|
+
const el = buildFlowElement(moddle, node, allNodes, allEdges);
|
|
2829
3004
|
if (el) flowElements.push(el);
|
|
2830
3005
|
}
|
|
2831
3006
|
const myNodeIds = new Set(myNodes.map((n) => n.id));
|
|
@@ -2836,6 +3011,17 @@ function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId)
|
|
|
2836
3011
|
const edgeMeta = buildEdgeElement(moddle, edge);
|
|
2837
3012
|
if (edgeMeta) flowElements.push(edgeMeta);
|
|
2838
3013
|
}
|
|
3014
|
+
const elementById = new Map(
|
|
3015
|
+
flowElements.filter((element) => typeof element.id === "string").map((element) => [element.id, element])
|
|
3016
|
+
);
|
|
3017
|
+
for (const edge of myEdges) {
|
|
3018
|
+
if (!edge.data?.isDefault) continue;
|
|
3019
|
+
const sourceElement = elementById.get(edge.source);
|
|
3020
|
+
const edgeElement = elementById.get(edge.id);
|
|
3021
|
+
if (sourceElement && edgeElement) {
|
|
3022
|
+
sourceElement.default = edgeElement;
|
|
3023
|
+
}
|
|
3024
|
+
}
|
|
2839
3025
|
const process = moddle.create("bpmn:Process", {
|
|
2840
3026
|
id: processId,
|
|
2841
3027
|
isExecutable: true,
|
|
@@ -2856,7 +3042,7 @@ function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId)
|
|
|
2856
3042
|
}
|
|
2857
3043
|
return process;
|
|
2858
3044
|
}
|
|
2859
|
-
function buildFlowElement(moddle, node,
|
|
3045
|
+
function buildFlowElement(moddle, node, allNodes, allEdges) {
|
|
2860
3046
|
const { elementType, label, trigger } = node.data;
|
|
2861
3047
|
if (elementType === "Pool" || elementType === "Lane") return null;
|
|
2862
3048
|
const moddleType = ELEMENT_TYPE_TO_MODDLE[elementType];
|
|
@@ -2865,25 +3051,46 @@ function buildFlowElement(moddle, node, _allNodes, _allEdges) {
|
|
|
2865
3051
|
id: node.id,
|
|
2866
3052
|
name: label ?? ""
|
|
2867
3053
|
};
|
|
3054
|
+
if (node.data.documentation) {
|
|
3055
|
+
attrs.documentation = [
|
|
3056
|
+
moddle.create("bpmn:Documentation", { text: node.data.documentation })
|
|
3057
|
+
];
|
|
3058
|
+
}
|
|
2868
3059
|
if (trigger && trigger !== "none") {
|
|
2869
3060
|
const defType = TRIGGER_TO_EVENT_DEF[trigger];
|
|
2870
3061
|
if (defType) {
|
|
2871
3062
|
attrs.eventDefinitions = [moddle.create(defType, { id: uid("EventDef", node.id) })];
|
|
2872
3063
|
}
|
|
2873
3064
|
}
|
|
2874
|
-
if (elementType === "
|
|
2875
|
-
|
|
3065
|
+
if (elementType === "BoundaryEvent") {
|
|
3066
|
+
attrs.attachedToRef = { id: node.data.attachedToRef ?? node.parentId };
|
|
3067
|
+
attrs.cancelActivity = node.data.isNonInterrupting ? false : true;
|
|
2876
3068
|
}
|
|
2877
|
-
|
|
2878
|
-
|
|
3069
|
+
const isSubProcess3 = elementType === "SubProcess" || elementType === "Transaction" || elementType === "EventSubProcess" || elementType === "AdHocSubProcess";
|
|
3070
|
+
if (isSubProcess3) {
|
|
3071
|
+
attrs.flowElements = buildNestedFlowElements(moddle, node, allNodes, allEdges);
|
|
3072
|
+
if (elementType === "EventSubProcess" || node.data.subProcessVariant === "event") {
|
|
3073
|
+
attrs.triggeredByEvent = true;
|
|
3074
|
+
}
|
|
2879
3075
|
}
|
|
2880
3076
|
const element = moddle.create(moddleType, attrs);
|
|
2881
|
-
const flowableAttrs = buildFlowableAttrs(node.data);
|
|
2882
|
-
if (Object.keys(flowableAttrs).length > 0) {
|
|
2883
|
-
element.$attrs = flowableAttrs;
|
|
2884
|
-
}
|
|
2885
3077
|
return element;
|
|
2886
3078
|
}
|
|
3079
|
+
function buildNestedFlowElements(moddle, parent, allNodes, allEdges) {
|
|
3080
|
+
const childNodes = allNodes.filter((node) => node.parentId === parent.id);
|
|
3081
|
+
const childNodeIds = new Set(childNodes.map((node) => node.id));
|
|
3082
|
+
const flowElements = [];
|
|
3083
|
+
for (const child of childNodes) {
|
|
3084
|
+
const element = buildFlowElement(moddle, child, allNodes, allEdges);
|
|
3085
|
+
if (element) flowElements.push(element);
|
|
3086
|
+
}
|
|
3087
|
+
for (const edge of allEdges) {
|
|
3088
|
+
if (!childNodeIds.has(edge.source) || !childNodeIds.has(edge.target)) continue;
|
|
3089
|
+
const element = buildEdgeElement(moddle, edge);
|
|
3090
|
+
if (element) flowElements.push(element);
|
|
3091
|
+
}
|
|
3092
|
+
return flowElements;
|
|
3093
|
+
}
|
|
2887
3094
|
function buildEdgeElement(moddle, edge) {
|
|
2888
3095
|
if (!edge.data) return null;
|
|
2889
3096
|
const moddleType = EDGE_TYPE_TO_MODDLE[edge.data.edgeType];
|
|
@@ -2894,6 +3101,11 @@ function buildEdgeElement(moddle, edge) {
|
|
|
2894
3101
|
sourceRef: { id: edge.source },
|
|
2895
3102
|
targetRef: { id: edge.target }
|
|
2896
3103
|
};
|
|
3104
|
+
if (edge.data.documentation) {
|
|
3105
|
+
attrs.documentation = [
|
|
3106
|
+
moddle.create("bpmn:Documentation", { text: edge.data.documentation })
|
|
3107
|
+
];
|
|
3108
|
+
}
|
|
2897
3109
|
if (edge.data.conditionExpression) {
|
|
2898
3110
|
attrs.conditionExpression = moddle.create("bpmn:FormalExpression", {
|
|
2899
3111
|
body: edge.data.conditionExpression
|
|
@@ -2904,13 +3116,14 @@ function buildEdgeElement(moddle, edge) {
|
|
|
2904
3116
|
function buildBpmnDI(moddle, definitions, nodes, edges) {
|
|
2905
3117
|
const shapes = [];
|
|
2906
3118
|
const edgeShapes = [];
|
|
3119
|
+
const absolutePositionById = buildAbsolutePositionMap(nodes);
|
|
2907
3120
|
for (const node of nodes) {
|
|
2908
3121
|
const meta = BPMN_ELEMENT_CATALOG[node.data.elementType];
|
|
2909
3122
|
const w = node.width ?? meta?.defaultWidth ?? 120;
|
|
2910
3123
|
const h = node.height ?? meta?.defaultHeight ?? 60;
|
|
2911
3124
|
const bounds = moddle.create("dc:Bounds", {
|
|
2912
|
-
x: node.position.x,
|
|
2913
|
-
y: node.position.y,
|
|
3125
|
+
x: absolutePositionById.get(node.id)?.x ?? node.position.x,
|
|
3126
|
+
y: absolutePositionById.get(node.id)?.y ?? node.position.y,
|
|
2914
3127
|
width: w,
|
|
2915
3128
|
height: h
|
|
2916
3129
|
});
|
|
@@ -2925,9 +3138,9 @@ function buildBpmnDI(moddle, definitions, nodes, edges) {
|
|
|
2925
3138
|
shapes.push(shape);
|
|
2926
3139
|
}
|
|
2927
3140
|
for (const edge of edges) {
|
|
2928
|
-
const waypoints = edge.
|
|
3141
|
+
const waypoints = resolveEdgeWaypoints(edge, nodes, absolutePositionById).map(
|
|
2929
3142
|
(p) => moddle.create("dc:Point", { x: p.x, y: p.y })
|
|
2930
|
-
)
|
|
3143
|
+
);
|
|
2931
3144
|
edgeShapes.push(
|
|
2932
3145
|
moddle.create("bpmndi:BPMNEdge", {
|
|
2933
3146
|
id: uid("BPMNEdge", edge.id),
|
|
@@ -2949,6 +3162,46 @@ function buildBpmnDI(moddle, definitions, nodes, edges) {
|
|
|
2949
3162
|
});
|
|
2950
3163
|
definitions.diagrams = [diagram];
|
|
2951
3164
|
}
|
|
3165
|
+
function resolveEdgeWaypoints(edge, nodes, absolutePositionById) {
|
|
3166
|
+
if (edge.data?.routingPoints && edge.data.routingPoints.length >= 2) {
|
|
3167
|
+
return edge.data.routingPoints;
|
|
3168
|
+
}
|
|
3169
|
+
const source = nodes.find((node) => node.id === edge.source);
|
|
3170
|
+
const target = nodes.find((node) => node.id === edge.target);
|
|
3171
|
+
if (!source || !target) return [];
|
|
3172
|
+
const sourceMeta = BPMN_ELEMENT_CATALOG[source.data.elementType];
|
|
3173
|
+
const targetMeta = BPMN_ELEMENT_CATALOG[target.data.elementType];
|
|
3174
|
+
const sourcePosition = absolutePositionById.get(source.id) ?? source.position;
|
|
3175
|
+
const targetPosition = absolutePositionById.get(target.id) ?? target.position;
|
|
3176
|
+
return [
|
|
3177
|
+
{
|
|
3178
|
+
x: sourcePosition.x + (source.width ?? sourceMeta.defaultWidth) / 2,
|
|
3179
|
+
y: sourcePosition.y + (source.height ?? sourceMeta.defaultHeight) / 2
|
|
3180
|
+
},
|
|
3181
|
+
{
|
|
3182
|
+
x: targetPosition.x + (target.width ?? targetMeta.defaultWidth) / 2,
|
|
3183
|
+
y: targetPosition.y + (target.height ?? targetMeta.defaultHeight) / 2
|
|
3184
|
+
}
|
|
3185
|
+
];
|
|
3186
|
+
}
|
|
3187
|
+
function buildAbsolutePositionMap(nodes) {
|
|
3188
|
+
const nodeById2 = new Map(nodes.map((node) => [node.id, node]));
|
|
3189
|
+
const absoluteById = /* @__PURE__ */ new Map();
|
|
3190
|
+
function resolve(node) {
|
|
3191
|
+
const cached = absoluteById.get(node.id);
|
|
3192
|
+
if (cached) return cached;
|
|
3193
|
+
const parent = node.parentId ? nodeById2.get(node.parentId) : void 0;
|
|
3194
|
+
const parentPosition = parent ? resolve(parent) : { x: 0, y: 0 };
|
|
3195
|
+
const absolute = {
|
|
3196
|
+
x: parentPosition.x + node.position.x,
|
|
3197
|
+
y: parentPosition.y + node.position.y
|
|
3198
|
+
};
|
|
3199
|
+
absoluteById.set(node.id, absolute);
|
|
3200
|
+
return absolute;
|
|
3201
|
+
}
|
|
3202
|
+
for (const node of nodes) resolve(node);
|
|
3203
|
+
return absoluteById;
|
|
3204
|
+
}
|
|
2952
3205
|
async function serializeBpmnXml(nodes, edges, opts = {}) {
|
|
2953
3206
|
const moddle = new bpmnModdle.BpmnModdle();
|
|
2954
3207
|
const definitions = buildSemanticModel(moddle, nodes, edges, opts);
|
|
@@ -3431,45 +3684,761 @@ function isCompleted(state) {
|
|
|
3431
3684
|
function setVariable(state, key, value) {
|
|
3432
3685
|
return { ...state, variables: { ...state.variables, [key]: value } };
|
|
3433
3686
|
}
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3687
|
+
function createBpmnNode(options) {
|
|
3688
|
+
const size = getBpmnElementSize(options.elementType);
|
|
3689
|
+
const meta = BPMN_ELEMENT_CATALOG[options.elementType];
|
|
3690
|
+
const orientation = options.data?.orientation ?? meta.orientation;
|
|
3691
|
+
const dragHandle = getBpmnDragHandleSelector(options.elementType);
|
|
3692
|
+
return {
|
|
3693
|
+
id: options.id,
|
|
3694
|
+
type: options.elementType,
|
|
3695
|
+
position: options.position,
|
|
3696
|
+
data: {
|
|
3697
|
+
elementType: options.elementType,
|
|
3698
|
+
orientation,
|
|
3699
|
+
...options.label ? { label: options.label } : {},
|
|
3700
|
+
...options.data ?? {}
|
|
3701
|
+
},
|
|
3702
|
+
width: options.width ?? size.width,
|
|
3703
|
+
height: options.height ?? size.height,
|
|
3704
|
+
...options.parentId ? { parentId: options.parentId } : {},
|
|
3705
|
+
...dragHandle ? { dragHandle } : {}
|
|
3706
|
+
};
|
|
3707
|
+
}
|
|
3708
|
+
var BPMN_POOL_LANE_LAYOUT = {
|
|
3709
|
+
poolHeaderSize: 30,
|
|
3710
|
+
laneHeaderSize: 24,
|
|
3711
|
+
laneGap: 0
|
|
3712
|
+
};
|
|
3713
|
+
function getBpmnDragHandleSelector(elementType) {
|
|
3714
|
+
if (elementType === "Pool") return ".pool-drag-handle";
|
|
3715
|
+
if (elementType === "Lane") return ".lane-drag-handle";
|
|
3716
|
+
return void 0;
|
|
3717
|
+
}
|
|
3718
|
+
var BPMN_SELECTION_STYLE = {
|
|
3719
|
+
nodeOutline: "#2563eb",
|
|
3720
|
+
edgeStroke: "#2563eb",
|
|
3721
|
+
handleFill: "#ffffff",
|
|
3722
|
+
handleStroke: "#2563eb",
|
|
3723
|
+
resizeHandleSize: 8,
|
|
3724
|
+
routingPointRadius: 5
|
|
3725
|
+
};
|
|
3726
|
+
var BPMN_ROUTABLE_EDGE_TYPES = [
|
|
3727
|
+
"sequenceFlow",
|
|
3728
|
+
"messageFlow",
|
|
3729
|
+
"association",
|
|
3730
|
+
"dataAssociation",
|
|
3731
|
+
"conversationLink"
|
|
3732
|
+
];
|
|
3733
|
+
var BPMN_EDGE_CONNECTION_RULES = {
|
|
3734
|
+
sequenceFlow: {
|
|
3735
|
+
edgeType: "sequenceFlow",
|
|
3736
|
+
sourceCategories: ["flowNode"],
|
|
3737
|
+
targetCategories: ["flowNode"],
|
|
3738
|
+
allowSameParent: true,
|
|
3739
|
+
allowDifferentParent: false
|
|
3740
|
+
},
|
|
3741
|
+
messageFlow: {
|
|
3742
|
+
edgeType: "messageFlow",
|
|
3743
|
+
sourceCategories: ["flowNode"],
|
|
3744
|
+
targetCategories: ["flowNode"],
|
|
3745
|
+
allowSameParent: false,
|
|
3746
|
+
allowDifferentParent: true
|
|
3747
|
+
},
|
|
3748
|
+
association: {
|
|
3749
|
+
edgeType: "association",
|
|
3750
|
+
sourceCategories: ["flowNode", "artifact", "data"],
|
|
3751
|
+
targetCategories: ["flowNode", "artifact", "data"],
|
|
3752
|
+
allowSameParent: true,
|
|
3753
|
+
allowDifferentParent: true
|
|
3754
|
+
},
|
|
3755
|
+
dataAssociation: {
|
|
3756
|
+
edgeType: "dataAssociation",
|
|
3757
|
+
sourceCategories: ["flowNode", "data"],
|
|
3758
|
+
targetCategories: ["flowNode", "data"],
|
|
3759
|
+
allowSameParent: true,
|
|
3760
|
+
allowDifferentParent: true
|
|
3761
|
+
},
|
|
3762
|
+
conversationLink: {
|
|
3763
|
+
edgeType: "conversationLink",
|
|
3764
|
+
sourceCategories: ["conversation", "flowNode"],
|
|
3765
|
+
targetCategories: ["conversation", "flowNode"],
|
|
3766
|
+
allowSameParent: true,
|
|
3767
|
+
allowDifferentParent: true
|
|
3441
3768
|
}
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3769
|
+
};
|
|
3770
|
+
function inferBpmnEdgeType(state, sourceId, targetId) {
|
|
3771
|
+
const source = diagramsCore.getNode(state, sourceId);
|
|
3772
|
+
const target = diagramsCore.getNode(state, targetId);
|
|
3773
|
+
if (!source || !target) return "sequenceFlow";
|
|
3774
|
+
if (isDataType(source.data.elementType) || isDataType(target.data.elementType)) {
|
|
3775
|
+
return "dataAssociation";
|
|
3445
3776
|
}
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
return this.state;
|
|
3777
|
+
if (source.data.elementType === "Annotation" || target.data.elementType === "Annotation" || source.data.elementType === "Group" || target.data.elementType === "Group") {
|
|
3778
|
+
return "association";
|
|
3449
3779
|
}
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
return this.state;
|
|
3780
|
+
if (source.data.elementType === "Conversation" || source.data.elementType === "SubConversation" || source.data.elementType === "CallConversation" || target.data.elementType === "Conversation" || target.data.elementType === "SubConversation" || target.data.elementType === "CallConversation") {
|
|
3781
|
+
return "conversationLink";
|
|
3453
3782
|
}
|
|
3454
|
-
|
|
3455
|
-
return
|
|
3783
|
+
if (source.parentId && target.parentId && source.parentId !== target.parentId) {
|
|
3784
|
+
return "messageFlow";
|
|
3456
3785
|
}
|
|
3457
|
-
|
|
3458
|
-
|
|
3786
|
+
return "sequenceFlow";
|
|
3787
|
+
}
|
|
3788
|
+
function canUseSequenceFlow(type) {
|
|
3789
|
+
const meta = BPMN_ELEMENT_CATALOG[type];
|
|
3790
|
+
return meta.handlePolicy !== "none" && !isDataType(type) && type !== "Annotation" && type !== "Group" && meta.category !== "conversation";
|
|
3791
|
+
}
|
|
3792
|
+
function matchesConnectionCategory(type, categories) {
|
|
3793
|
+
return categories.some((category) => {
|
|
3794
|
+
if (category === type) return true;
|
|
3795
|
+
if (category === "flowNode") return canUseSequenceFlow(type);
|
|
3796
|
+
if (category === "data") return isDataType(type);
|
|
3797
|
+
if (category === "artifact") return type === "Annotation" || type === "Group";
|
|
3798
|
+
if (category === "conversation") return BPMN_ELEMENT_CATALOG[type].category === "conversation";
|
|
3799
|
+
return false;
|
|
3800
|
+
});
|
|
3801
|
+
}
|
|
3802
|
+
function isBpmnEdgeRoutingEditable(edgeType) {
|
|
3803
|
+
return BPMN_ROUTABLE_EDGE_TYPES.includes(edgeType);
|
|
3804
|
+
}
|
|
3805
|
+
function isBpmnProcessNode(type) {
|
|
3806
|
+
return isEventType(type) || isGatewayType(type) || type.includes("Task") || type === "CallActivity" || type === "SubProcess" || type === "Transaction" || type === "EventSubProcess" || type === "AdHocSubProcess";
|
|
3807
|
+
}
|
|
3808
|
+
function canContainBpmnElement(parentType, childType) {
|
|
3809
|
+
if (!parentType) return true;
|
|
3810
|
+
if (parentType === "Pool") {
|
|
3811
|
+
return childType === "Lane" || isBpmnProcessNode(childType) ? true : "Pools can contain lanes or BPMN process nodes.";
|
|
3459
3812
|
}
|
|
3460
|
-
|
|
3461
|
-
return
|
|
3813
|
+
if (parentType === "Lane") {
|
|
3814
|
+
return isBpmnProcessNode(childType) ? true : "Lanes can only contain BPMN process nodes.";
|
|
3462
3815
|
}
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3816
|
+
if (parentType === "SubProcess" || parentType === "Transaction" || parentType === "EventSubProcess" || parentType === "AdHocSubProcess") {
|
|
3817
|
+
return isBpmnProcessNode(childType) ? true : "Subprocesses can only contain BPMN process nodes.";
|
|
3818
|
+
}
|
|
3819
|
+
return `${parentType} cannot contain BPMN child elements.`;
|
|
3820
|
+
}
|
|
3821
|
+
function getDirectBpmnChildren(state, parentId) {
|
|
3822
|
+
return state.nodes.filter((node) => node.parentId === parentId);
|
|
3823
|
+
}
|
|
3824
|
+
function getBpmnPoolLanes(state, poolId) {
|
|
3825
|
+
return getDirectBpmnChildren(state, poolId).filter(
|
|
3826
|
+
(node) => node.data.elementType === "Lane"
|
|
3827
|
+
);
|
|
3828
|
+
}
|
|
3829
|
+
function getNodeDimension(node, axis) {
|
|
3830
|
+
return node[axis] ?? node.measured?.[axis] ?? getBpmnElementSize(node.data.elementType)[axis];
|
|
3831
|
+
}
|
|
3832
|
+
function resolvePoolLaneDirection(pool) {
|
|
3833
|
+
return pool.data.orientation === "vertical" ? "horizontal" : "vertical";
|
|
3834
|
+
}
|
|
3835
|
+
function getBpmnLaneIndexAtPosition(state, poolId, position) {
|
|
3836
|
+
const pool = diagramsCore.getNode(state, poolId);
|
|
3837
|
+
if (!pool) return 0;
|
|
3838
|
+
const lanes = getBpmnPoolLanes(state, poolId);
|
|
3839
|
+
const direction = resolvePoolLaneDirection(pool);
|
|
3840
|
+
const axis = direction === "vertical" ? "y" : "x";
|
|
3841
|
+
const sizeKey = direction === "vertical" ? "height" : "width";
|
|
3842
|
+
for (let index = 0; index < lanes.length; index += 1) {
|
|
3843
|
+
const lane = lanes[index];
|
|
3844
|
+
const midpoint = lane.position[axis] + getNodeDimension(lane, sizeKey) / 2;
|
|
3845
|
+
if (position[axis] < midpoint) return index;
|
|
3846
|
+
}
|
|
3847
|
+
return lanes.length;
|
|
3848
|
+
}
|
|
3849
|
+
function sortBpmnLanes(state, poolId, laneId, index) {
|
|
3850
|
+
const lanes = getBpmnPoolLanes(state, poolId);
|
|
3851
|
+
const currentIndex = lanes.findIndex((lane) => lane.id === laneId);
|
|
3852
|
+
if (currentIndex < 0) return state;
|
|
3853
|
+
const orderedIds = lanes.map((lane) => lane.id);
|
|
3854
|
+
const [moved] = orderedIds.splice(currentIndex, 1);
|
|
3855
|
+
orderedIds.splice(Math.max(0, Math.min(index, orderedIds.length)), 0, moved);
|
|
3856
|
+
const order = new Map(orderedIds.map((id, laneIndex) => [id, laneIndex]));
|
|
3857
|
+
return {
|
|
3858
|
+
...state,
|
|
3859
|
+
nodes: [...state.nodes].sort((a, b) => {
|
|
3860
|
+
const aOrder = order.get(a.id);
|
|
3861
|
+
const bOrder = order.get(b.id);
|
|
3862
|
+
if (aOrder === void 0 && bOrder === void 0) return 0;
|
|
3863
|
+
if (aOrder === void 0) return -1;
|
|
3864
|
+
if (bOrder === void 0) return 1;
|
|
3865
|
+
return aOrder - bOrder;
|
|
3866
|
+
})
|
|
3867
|
+
};
|
|
3868
|
+
}
|
|
3869
|
+
function layoutBpmnPoolLanes(state, poolId) {
|
|
3870
|
+
const pool = diagramsCore.getNode(state, poolId);
|
|
3871
|
+
if (!pool) return state;
|
|
3872
|
+
const poolSize = getBpmnElementSize("Pool");
|
|
3873
|
+
const direction = resolvePoolLaneDirection(pool);
|
|
3874
|
+
const lanes = getBpmnPoolLanes(state, poolId);
|
|
3875
|
+
let cursor = direction === "vertical" ? BPMN_POOL_LANE_LAYOUT.poolHeaderSize : 0;
|
|
3876
|
+
let next = state;
|
|
3877
|
+
for (const lane of lanes) {
|
|
3878
|
+
const laneSize = getBpmnElementSize("Lane");
|
|
3879
|
+
const width = direction === "vertical" ? Math.max(poolSize.minWidth - BPMN_POOL_LANE_LAYOUT.poolHeaderSize, lane.width ?? laneSize.width) : lane.width ?? laneSize.width;
|
|
3880
|
+
const height = direction === "vertical" ? lane.height ?? laneSize.height : Math.max(poolSize.minHeight - BPMN_POOL_LANE_LAYOUT.poolHeaderSize, lane.height ?? laneSize.height);
|
|
3881
|
+
next = diagramsCore.patchNode(next, lane.id, {
|
|
3882
|
+
position: direction === "vertical" ? { x: BPMN_POOL_LANE_LAYOUT.poolHeaderSize, y: cursor } : { x: cursor, y: BPMN_POOL_LANE_LAYOUT.poolHeaderSize },
|
|
3883
|
+
width,
|
|
3884
|
+
height,
|
|
3885
|
+
data: { orientation: pool.data.orientation ?? "horizontal" }
|
|
3886
|
+
});
|
|
3887
|
+
cursor += (direction === "vertical" ? height : width) + BPMN_POOL_LANE_LAYOUT.laneGap;
|
|
3888
|
+
}
|
|
3889
|
+
const minWidth = direction === "vertical" ? poolSize.minWidth : Math.max(poolSize.minWidth, cursor);
|
|
3890
|
+
const minHeight = direction === "vertical" ? Math.max(poolSize.minHeight, cursor) : poolSize.minHeight;
|
|
3891
|
+
return diagramsCore.resizeNode(next, poolId, { width: minWidth, height: minHeight });
|
|
3892
|
+
}
|
|
3893
|
+
function reorderBpmnLane(state, options) {
|
|
3894
|
+
return layoutBpmnPoolLanes(
|
|
3895
|
+
sortBpmnLanes(state, options.poolId, options.laneId, options.index),
|
|
3896
|
+
options.poolId
|
|
3897
|
+
);
|
|
3898
|
+
}
|
|
3899
|
+
function validateBpmnConnectionForEdgeType(state, edgeType, source, target) {
|
|
3900
|
+
const rule = BPMN_EDGE_CONNECTION_RULES[edgeType];
|
|
3901
|
+
if (!matchesConnectionCategory(source.data.elementType, rule.sourceCategories)) {
|
|
3902
|
+
return `${edgeType} cannot start from ${source.data.elementType}.`;
|
|
3903
|
+
}
|
|
3904
|
+
if (!matchesConnectionCategory(target.data.elementType, rule.targetCategories)) {
|
|
3905
|
+
return `${edgeType} cannot target ${target.data.elementType}.`;
|
|
3906
|
+
}
|
|
3907
|
+
const sameParent = (source.parentId ?? null) === (target.parentId ?? null);
|
|
3908
|
+
if (sameParent && rule.allowSameParent === false) {
|
|
3909
|
+
return `${edgeType} must connect BPMN elements in different participants/scopes.`;
|
|
3910
|
+
}
|
|
3911
|
+
if (!sameParent && rule.allowDifferentParent === false) {
|
|
3912
|
+
return `${edgeType} must stay inside the same BPMN participant/scope.`;
|
|
3913
|
+
}
|
|
3914
|
+
if (edgeType === "sequenceFlow") {
|
|
3915
|
+
if (source.data.elementType === "EndEvent") return "End events cannot have outgoing sequence flows.";
|
|
3916
|
+
if (target.data.elementType === "StartEvent") return "Start events cannot have incoming sequence flows.";
|
|
3917
|
+
return validateEdgeCardinality(state, edgeType, source, target);
|
|
3918
|
+
}
|
|
3919
|
+
return true;
|
|
3920
|
+
}
|
|
3921
|
+
function validateEdgeCardinality(state, edgeType, source, target) {
|
|
3922
|
+
if (edgeType !== "sequenceFlow") return true;
|
|
3923
|
+
const sourceMax = BPMN_ELEMENT_CATALOG[source.data.elementType].maxOutgoing;
|
|
3924
|
+
const targetMax = BPMN_ELEMENT_CATALOG[target.data.elementType].maxIncoming;
|
|
3925
|
+
const outgoing = diagramsCore.getOutgoingEdges(state, source.id).filter(
|
|
3926
|
+
(edge) => edge.data?.edgeType === "sequenceFlow"
|
|
3927
|
+
);
|
|
3928
|
+
const incoming = diagramsCore.getIncomingEdges(state, target.id).filter(
|
|
3929
|
+
(edge) => edge.data?.edgeType === "sequenceFlow"
|
|
3930
|
+
);
|
|
3931
|
+
if (sourceMax !== void 0 && outgoing.length >= sourceMax) {
|
|
3932
|
+
return `${source.data.elementType} cannot have more than ${sourceMax} outgoing sequence flow(s).`;
|
|
3933
|
+
}
|
|
3934
|
+
if (targetMax !== void 0 && incoming.length >= targetMax) {
|
|
3935
|
+
return `${target.data.elementType} cannot have more than ${targetMax} incoming sequence flow(s).`;
|
|
3936
|
+
}
|
|
3937
|
+
return true;
|
|
3938
|
+
}
|
|
3939
|
+
var bpmnConnectionValidators = [
|
|
3940
|
+
({ state, source, target }) => {
|
|
3941
|
+
if (source.id === target.id) return "BPMN self-connections are not allowed.";
|
|
3942
|
+
const edgeType = inferBpmnEdgeType(state, source.id, target.id);
|
|
3943
|
+
if (getHandlePolicy(source.data.elementType) === "none" || getHandlePolicy(target.data.elementType) === "none") {
|
|
3944
|
+
return "Elements without BPMN connection handles cannot be directly connected.";
|
|
3945
|
+
}
|
|
3946
|
+
if (edgeType === "sequenceFlow") {
|
|
3947
|
+
return validateBpmnConnectionForEdgeType(state, edgeType, source, target);
|
|
3948
|
+
}
|
|
3949
|
+
return validateBpmnConnectionForEdgeType(state, edgeType, source, target);
|
|
3950
|
+
}
|
|
3951
|
+
];
|
|
3952
|
+
var BPMN_MODELING_RULES = diagramsCore.createModelingRules({
|
|
3953
|
+
connect: [
|
|
3954
|
+
({ state, source, target }) => {
|
|
3955
|
+
if (!source || !target) return false;
|
|
3956
|
+
for (const validator of bpmnConnectionValidators) {
|
|
3957
|
+
const result = validator({
|
|
3958
|
+
state,
|
|
3959
|
+
source,
|
|
3960
|
+
target,
|
|
3961
|
+
existingEdges: state.edges
|
|
3962
|
+
});
|
|
3963
|
+
if (result !== true) return result;
|
|
3964
|
+
}
|
|
3965
|
+
return true;
|
|
3966
|
+
}
|
|
3967
|
+
],
|
|
3968
|
+
drop: [
|
|
3969
|
+
({ node, parent }) => {
|
|
3970
|
+
if (!node || !parent) return true;
|
|
3971
|
+
if (node.data.elementType === "BoundaryEvent") {
|
|
3972
|
+
return acceptsBoundaryEvents(parent.data.elementType) ? true : "Boundary events can only be attached to tasks or subprocesses.";
|
|
3973
|
+
}
|
|
3974
|
+
return canContainBpmnElement(parent.data.elementType, node.data.elementType);
|
|
3975
|
+
}
|
|
3976
|
+
],
|
|
3977
|
+
reparent: [
|
|
3978
|
+
({ node, parent }) => {
|
|
3979
|
+
if (!node || !parent) return true;
|
|
3980
|
+
if (node.data.elementType === "BoundaryEvent") {
|
|
3981
|
+
return acceptsBoundaryEvents(parent.data.elementType) ? true : "Boundary events can only be reparented to tasks or subprocesses.";
|
|
3982
|
+
}
|
|
3983
|
+
return canContainBpmnElement(parent?.data.elementType, node.data.elementType);
|
|
3984
|
+
}
|
|
3985
|
+
],
|
|
3986
|
+
delete: [() => true],
|
|
3987
|
+
resize: [
|
|
3988
|
+
({ node }) => !node || isBpmnElementResizable(node.data.elementType) ? true : `${node.data.elementType} is not resizable in BPMN.`
|
|
3989
|
+
]
|
|
3990
|
+
});
|
|
3991
|
+
function createBpmnNodeCommand(options) {
|
|
3992
|
+
return {
|
|
3993
|
+
id: `bpmn.createNode.${options.id}`,
|
|
3994
|
+
label: `Create ${options.elementType}`,
|
|
3995
|
+
execute: (state) => diagramsCore.addNode(state, createBpmnNode(options))
|
|
3996
|
+
};
|
|
3997
|
+
}
|
|
3998
|
+
function connectBpmnCommand(options) {
|
|
3999
|
+
return {
|
|
4000
|
+
id: `bpmn.connect.${options.id ?? `${options.source}-${options.target}`}`,
|
|
4001
|
+
label: "Connect BPMN elements",
|
|
4002
|
+
execute: (state) => {
|
|
4003
|
+
const edgeType = options.edgeType ?? inferBpmnEdgeType(state, options.source, options.target);
|
|
4004
|
+
const source = diagramsCore.getNode(state, options.source);
|
|
4005
|
+
const target = diagramsCore.getNode(state, options.target);
|
|
4006
|
+
if (!source) throw new Error(`Source node "${options.source}" does not exist.`);
|
|
4007
|
+
if (!target) throw new Error(`Target node "${options.target}" does not exist.`);
|
|
4008
|
+
const validation = validateBpmnConnectionForEdgeType(state, edgeType, source, target);
|
|
4009
|
+
if (validation !== true) throw new Error(validation);
|
|
4010
|
+
return diagramsCore.connectNodes(
|
|
4011
|
+
state,
|
|
4012
|
+
{
|
|
4013
|
+
source: options.source,
|
|
4014
|
+
target: options.target,
|
|
4015
|
+
type: edgeType,
|
|
4016
|
+
...options.sourceHandle !== void 0 ? { sourceHandle: options.sourceHandle } : {},
|
|
4017
|
+
...options.targetHandle !== void 0 ? { targetHandle: options.targetHandle } : {},
|
|
4018
|
+
...options.id ? { id: options.id } : {},
|
|
4019
|
+
data: {
|
|
4020
|
+
edgeType,
|
|
4021
|
+
...options.label ? { label: options.label } : {},
|
|
4022
|
+
...options.data ?? {}
|
|
4023
|
+
}
|
|
4024
|
+
},
|
|
4025
|
+
[]
|
|
4026
|
+
);
|
|
4027
|
+
}
|
|
4028
|
+
};
|
|
4029
|
+
}
|
|
4030
|
+
function attachBoundaryEventCommand(boundaryId, hostId) {
|
|
4031
|
+
return {
|
|
4032
|
+
id: `bpmn.attachBoundary.${boundaryId}.${hostId}`,
|
|
4033
|
+
label: "Attach boundary event",
|
|
4034
|
+
execute: (state) => {
|
|
4035
|
+
const host = diagramsCore.getNode(state, hostId);
|
|
4036
|
+
if (!host || !acceptsBoundaryEvents(host.data.elementType)) {
|
|
4037
|
+
throw new Error(`Element "${hostId}" cannot host boundary events.`);
|
|
4038
|
+
}
|
|
4039
|
+
const boundary = diagramsCore.getNode(state, boundaryId);
|
|
4040
|
+
if (!boundary || boundary.data.elementType !== "BoundaryEvent") {
|
|
4041
|
+
throw new Error(`Element "${boundaryId}" is not a boundary event.`);
|
|
4042
|
+
}
|
|
4043
|
+
const reparented = diagramsCore.reparentNode(state, boundaryId, { parentId: hostId });
|
|
4044
|
+
return diagramsCore.patchNode(reparented, boundaryId, {
|
|
4045
|
+
data: { attachedToRef: hostId }
|
|
4046
|
+
});
|
|
4047
|
+
}
|
|
4048
|
+
};
|
|
4049
|
+
}
|
|
4050
|
+
function replaceBpmnNodeCommand(options) {
|
|
4051
|
+
return {
|
|
4052
|
+
id: `bpmn.replaceNode.${options.id}.${options.elementType}`,
|
|
4053
|
+
label: `Replace with ${options.elementType}`,
|
|
4054
|
+
execute: (state) => {
|
|
4055
|
+
const current = diagramsCore.getNode(state, options.id);
|
|
4056
|
+
if (!current) throw new Error(`Element "${options.id}" does not exist.`);
|
|
4057
|
+
const meta = BPMN_ELEMENT_CATALOG[options.elementType];
|
|
4058
|
+
return diagramsCore.replaceNode(state, options.id, {
|
|
4059
|
+
...current,
|
|
4060
|
+
type: options.elementType,
|
|
4061
|
+
width: options.width ?? current.width ?? meta.defaultWidth,
|
|
4062
|
+
height: options.height ?? current.height ?? meta.defaultHeight,
|
|
4063
|
+
data: {
|
|
4064
|
+
...current.data,
|
|
4065
|
+
elementType: options.elementType,
|
|
4066
|
+
...options.label ? { label: options.label } : {},
|
|
4067
|
+
...options.data ?? {}
|
|
4068
|
+
}
|
|
4069
|
+
});
|
|
4070
|
+
}
|
|
4071
|
+
};
|
|
4072
|
+
}
|
|
4073
|
+
function reparentBpmnNodeCommand(options) {
|
|
4074
|
+
return {
|
|
4075
|
+
id: `bpmn.reparent.${options.id}.${options.parentId ?? "root"}`,
|
|
4076
|
+
label: "Reparent BPMN element",
|
|
4077
|
+
execute: (state) => {
|
|
4078
|
+
const node = diagramsCore.getNode(state, options.id);
|
|
4079
|
+
const parent = options.parentId ? diagramsCore.getNode(state, options.parentId) : void 0;
|
|
4080
|
+
if (!node) throw new Error(`Element "${options.id}" does not exist.`);
|
|
4081
|
+
if (parent && node.data.elementType === "BoundaryEvent" && !acceptsBoundaryEvents(parent.data.elementType)) {
|
|
4082
|
+
throw new Error("Boundary events can only be reparented to tasks or subprocesses.");
|
|
4083
|
+
}
|
|
4084
|
+
const containment = canContainBpmnElement(parent?.data.elementType, node.data.elementType);
|
|
4085
|
+
if (containment !== true) throw new Error(containment);
|
|
4086
|
+
const reparented = diagramsCore.reparentNode(state, options.id, {
|
|
4087
|
+
...options.parentId !== void 0 ? { parentId: options.parentId } : {},
|
|
4088
|
+
...options.position ? { position: options.position } : {}
|
|
4089
|
+
});
|
|
4090
|
+
return parent?.data.elementType === "Pool" && node.data.elementType === "Lane" ? layoutBpmnPoolLanes(reparented, parent.id) : reparented;
|
|
4091
|
+
}
|
|
4092
|
+
};
|
|
4093
|
+
}
|
|
4094
|
+
function resizeBpmnNodeCommand(options) {
|
|
4095
|
+
return {
|
|
4096
|
+
id: `bpmn.resize.${options.id}`,
|
|
4097
|
+
label: "Resize BPMN element",
|
|
4098
|
+
execute: (state) => {
|
|
4099
|
+
const node = diagramsCore.getNode(state, options.id);
|
|
4100
|
+
if (!node) throw new Error(`Element "${options.id}" does not exist.`);
|
|
4101
|
+
const size = getBpmnElementSize(node.data.elementType);
|
|
4102
|
+
if (!size.resizable) {
|
|
4103
|
+
throw new Error(`${node.data.elementType} is not resizable in BPMN.`);
|
|
4104
|
+
}
|
|
4105
|
+
return diagramsCore.resizeNode(state, options.id, {
|
|
4106
|
+
width: options.width === void 0 ? void 0 : Math.max(size.minWidth, options.width),
|
|
4107
|
+
height: options.height === void 0 ? void 0 : Math.max(size.minHeight, options.height)
|
|
4108
|
+
});
|
|
4109
|
+
}
|
|
4110
|
+
};
|
|
4111
|
+
}
|
|
4112
|
+
function reorderBpmnLaneCommand(options) {
|
|
4113
|
+
return {
|
|
4114
|
+
id: `bpmn.reorderLane.${options.poolId}.${options.laneId}`,
|
|
4115
|
+
label: "Reorder BPMN lane",
|
|
4116
|
+
execute: (state) => {
|
|
4117
|
+
const pool = diagramsCore.getNode(state, options.poolId);
|
|
4118
|
+
const lane = diagramsCore.getNode(state, options.laneId);
|
|
4119
|
+
if (!pool || pool.data.elementType !== "Pool") {
|
|
4120
|
+
throw new Error(`Element "${options.poolId}" is not a pool.`);
|
|
4121
|
+
}
|
|
4122
|
+
if (!lane || lane.data.elementType !== "Lane" || lane.parentId !== options.poolId) {
|
|
4123
|
+
throw new Error(`Element "${options.laneId}" is not a lane in pool "${options.poolId}".`);
|
|
4124
|
+
}
|
|
4125
|
+
return reorderBpmnLane(state, options);
|
|
4126
|
+
}
|
|
4127
|
+
};
|
|
4128
|
+
}
|
|
4129
|
+
function moveBpmnLaneCommand(options) {
|
|
4130
|
+
return {
|
|
4131
|
+
id: `bpmn.moveLane.${options.poolId}.${options.laneId}`,
|
|
4132
|
+
label: "Move BPMN lane",
|
|
4133
|
+
execute: (state) => reorderBpmnLane(state, {
|
|
4134
|
+
poolId: options.poolId,
|
|
4135
|
+
laneId: options.laneId,
|
|
4136
|
+
index: getBpmnLaneIndexAtPosition(state, options.poolId, options.position)
|
|
4137
|
+
})
|
|
4138
|
+
};
|
|
4139
|
+
}
|
|
4140
|
+
function routeBpmnEdgeCommand(options) {
|
|
4141
|
+
return {
|
|
4142
|
+
id: `bpmn.routeEdge.${options.id}`,
|
|
4143
|
+
label: "Route BPMN edge",
|
|
4144
|
+
execute: (state) => {
|
|
4145
|
+
const edge = state.edges.find((item) => item.id === options.id);
|
|
4146
|
+
if (!edge) throw new Error(`Edge "${options.id}" does not exist.`);
|
|
4147
|
+
const edgeType = edge.data?.edgeType;
|
|
4148
|
+
if (!edgeType || !isBpmnEdgeRoutingEditable(edgeType)) {
|
|
4149
|
+
throw new Error(`${edgeType ?? "edge"} routing points cannot be edited.`);
|
|
4150
|
+
}
|
|
4151
|
+
return diagramsCore.patchEdge(state, options.id, {
|
|
4152
|
+
data: { routingPoints: options.routingPoints }
|
|
4153
|
+
});
|
|
4154
|
+
}
|
|
4155
|
+
};
|
|
4156
|
+
}
|
|
4157
|
+
function deleteBpmnElementsCommand(ids) {
|
|
4158
|
+
return {
|
|
4159
|
+
id: `bpmn.delete.${ids.join(".")}`,
|
|
4160
|
+
label: "Delete BPMN elements",
|
|
4161
|
+
execute: (state) => diagramsCore.removeElements(state, ids)
|
|
4162
|
+
};
|
|
4163
|
+
}
|
|
4164
|
+
function copyBpmnElements(state, selection) {
|
|
4165
|
+
return diagramsCore.copyElements(state, selection);
|
|
4166
|
+
}
|
|
4167
|
+
function pasteBpmnElementsCommand(clipboard, options = {}) {
|
|
4168
|
+
return {
|
|
4169
|
+
id: "bpmn.paste",
|
|
4170
|
+
label: "Paste BPMN elements",
|
|
4171
|
+
execute: (state) => diagramsCore.pasteElements(state, clipboard, options)
|
|
4172
|
+
};
|
|
4173
|
+
}
|
|
4174
|
+
function selectBpmnElementsCommand(selection) {
|
|
4175
|
+
return {
|
|
4176
|
+
id: "bpmn.select",
|
|
4177
|
+
label: "Select BPMN elements",
|
|
4178
|
+
execute: (state) => diagramsCore.setSelection(state, diagramsCore.createSelectionState(selection.nodeIds, selection.edgeIds))
|
|
4179
|
+
};
|
|
4180
|
+
}
|
|
4181
|
+
function createBpmnDiagramDocument(state, options = {}) {
|
|
4182
|
+
return serialization.createDiagramDocument(diagramsCore.normalizeDiagramState(state), {
|
|
4183
|
+
...options,
|
|
4184
|
+
diagramType: "bpmn"
|
|
4185
|
+
});
|
|
4186
|
+
}
|
|
4187
|
+
function serializeBpmnDiagram(state, options = {}) {
|
|
4188
|
+
return serialization.serializeDiagram(diagramsCore.normalizeDiagramState(state), {
|
|
4189
|
+
...options,
|
|
4190
|
+
diagramType: "bpmn"
|
|
4191
|
+
});
|
|
4192
|
+
}
|
|
4193
|
+
function parseBpmnDiagramDocument(json) {
|
|
4194
|
+
const document = serialization.parseDiagramDocument(json);
|
|
4195
|
+
if (document.diagramType && document.diagramType !== "bpmn") {
|
|
4196
|
+
throw new Error(`Expected a BPMN diagram document, received "${document.diagramType}".`);
|
|
4197
|
+
}
|
|
4198
|
+
return document;
|
|
4199
|
+
}
|
|
4200
|
+
function deserializeBpmnDiagram(json) {
|
|
4201
|
+
const document = parseBpmnDiagramDocument(json);
|
|
4202
|
+
return serialization.deserializeDiagram(JSON.stringify(document));
|
|
4203
|
+
}
|
|
4204
|
+
function runBpmnCommand(stack, command) {
|
|
4205
|
+
return diagramsCore.executeCommand(stack, command);
|
|
4206
|
+
}
|
|
4207
|
+
function runBpmnCommands(stack, commands, options = {}) {
|
|
4208
|
+
return diagramsCore.executeCommands(stack, commands, options);
|
|
4209
|
+
}
|
|
4210
|
+
|
|
4211
|
+
// src/validation/index.ts
|
|
4212
|
+
function isFlowNode(type) {
|
|
4213
|
+
return isEventType(type) || isGatewayType(type) || type.includes("Task") || type === "CallActivity" || type === "SubProcess" || type === "Transaction" || type === "EventSubProcess" || type === "AdHocSubProcess" || type === "ChoreographyTask" || type === "SubChoreography" || type === "CallChoreography";
|
|
4214
|
+
}
|
|
4215
|
+
function isProcessNode(type) {
|
|
4216
|
+
return isFlowNode(type) && type !== "BoundaryEvent";
|
|
4217
|
+
}
|
|
4218
|
+
function isSubProcess2(type) {
|
|
4219
|
+
return type === "SubProcess" || type === "Transaction" || type === "EventSubProcess" || type === "AdHocSubProcess";
|
|
4220
|
+
}
|
|
4221
|
+
function isCatchTarget(type) {
|
|
4222
|
+
return type === "IntermediateCatchEvent" || type === "ReceiveTask";
|
|
4223
|
+
}
|
|
4224
|
+
function poolAncestor(node, nodeById2) {
|
|
4225
|
+
let current = node;
|
|
4226
|
+
const visited = /* @__PURE__ */ new Set();
|
|
4227
|
+
while (current?.parentId && !visited.has(current.id)) {
|
|
4228
|
+
visited.add(current.id);
|
|
4229
|
+
const parent = nodeById2.get(current.parentId);
|
|
4230
|
+
if (parent?.data.elementType === "Pool") return parent.id;
|
|
4231
|
+
current = parent;
|
|
4232
|
+
}
|
|
4233
|
+
return void 0;
|
|
4234
|
+
}
|
|
4235
|
+
function countSequenceEdges(edges, nodeId, direction) {
|
|
4236
|
+
return edges.filter((edge) => {
|
|
4237
|
+
if (edge.data?.edgeType !== "sequenceFlow") return false;
|
|
4238
|
+
return direction === "in" ? edge.target === nodeId : edge.source === nodeId;
|
|
4239
|
+
}).length;
|
|
4240
|
+
}
|
|
4241
|
+
function sequenceEdges(edges) {
|
|
4242
|
+
return edges.filter((edge) => (edge.data?.edgeType ?? edge.type) === "sequenceFlow");
|
|
4243
|
+
}
|
|
4244
|
+
function sequenceOut(edges, nodeId) {
|
|
4245
|
+
return sequenceEdges(edges).filter((edge) => edge.source === nodeId);
|
|
4246
|
+
}
|
|
4247
|
+
function sequenceIn(edges, nodeId) {
|
|
4248
|
+
return sequenceEdges(edges).filter((edge) => edge.target === nodeId);
|
|
4249
|
+
}
|
|
4250
|
+
function issue(code, severity, message, elementId, relatedElementIds) {
|
|
4251
|
+
return {
|
|
4252
|
+
id: `${code}:${elementId ?? relatedElementIds?.join(",") ?? "diagram"}`,
|
|
4253
|
+
code,
|
|
4254
|
+
severity,
|
|
4255
|
+
message,
|
|
4256
|
+
...elementId ? { elementId } : {},
|
|
4257
|
+
...relatedElementIds ? { relatedElementIds } : {}
|
|
4258
|
+
};
|
|
4259
|
+
}
|
|
4260
|
+
function validateBpmnDiagram(nodes, edges, options = {}) {
|
|
4261
|
+
const opts = {
|
|
4262
|
+
requireStartEvent: true,
|
|
4263
|
+
requireEndEvent: true,
|
|
4264
|
+
strictNames: false,
|
|
4265
|
+
...options
|
|
4266
|
+
};
|
|
4267
|
+
const issues = [];
|
|
4268
|
+
const nodeById2 = new Map(nodes.map((node) => [node.id, node]));
|
|
4269
|
+
const seqEdges = sequenceEdges(edges);
|
|
4270
|
+
const processNodes = nodes.filter((node) => isProcessNode(node.data.elementType));
|
|
4271
|
+
if (opts.requireStartEvent && !processNodes.some((node) => node.data.elementType === "StartEvent")) {
|
|
4272
|
+
issues.push(issue("bpmn/start-event-required", "error", "The diagram must contain at least one start event."));
|
|
4273
|
+
}
|
|
4274
|
+
if (opts.requireEndEvent && !processNodes.some((node) => node.data.elementType === "EndEvent")) {
|
|
4275
|
+
issues.push(issue("bpmn/end-event-required", "error", "The diagram must contain at least one end event."));
|
|
4276
|
+
}
|
|
4277
|
+
for (const edge of edges) {
|
|
4278
|
+
const edgeType = edge.data?.edgeType ?? edge.type;
|
|
4279
|
+
const source = nodeById2.get(edge.source);
|
|
4280
|
+
const target = nodeById2.get(edge.target);
|
|
4281
|
+
if (!source || !target) {
|
|
4282
|
+
issues.push(issue(
|
|
4283
|
+
"bpmn/no-orphan-edges",
|
|
4284
|
+
"error",
|
|
4285
|
+
`Edge "${edge.id}" references a missing ${!source ? "source" : "target"} node.`,
|
|
4286
|
+
edge.id,
|
|
4287
|
+
[edge.source, edge.target]
|
|
4288
|
+
));
|
|
4289
|
+
continue;
|
|
4290
|
+
}
|
|
4291
|
+
if (edge.source === edge.target) {
|
|
4292
|
+
issues.push(issue("bpmn/no-self-loop", "error", "BPMN edges cannot connect an element to itself.", edge.id, [edge.source]));
|
|
4293
|
+
}
|
|
4294
|
+
if (edgeType === "sequenceFlow") {
|
|
4295
|
+
if (!isFlowNode(source.data.elementType) || !isFlowNode(target.data.elementType) || isDataType(source.data.elementType) || isDataType(target.data.elementType)) {
|
|
4296
|
+
issues.push(issue("bpmn/sequence-flow-valid-endpoints", "error", "Sequence flows must connect BPMN flow nodes.", edge.id, [source.id, target.id]));
|
|
4297
|
+
}
|
|
4298
|
+
const sourcePool = poolAncestor(source, nodeById2);
|
|
4299
|
+
const targetPool = poolAncestor(target, nodeById2);
|
|
4300
|
+
if (sourcePool && targetPool && sourcePool !== targetPool) {
|
|
4301
|
+
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]));
|
|
4302
|
+
}
|
|
4303
|
+
}
|
|
4304
|
+
if (edgeType === "messageFlow") {
|
|
4305
|
+
const sourcePool = poolAncestor(source, nodeById2);
|
|
4306
|
+
const targetPool = poolAncestor(target, nodeById2);
|
|
4307
|
+
if (!sourcePool || !targetPool || sourcePool === targetPool) {
|
|
4308
|
+
issues.push(issue("bpmn/message-flow-valid-endpoints", "error", "Message flows must connect flow nodes in different pools.", edge.id, [source.id, target.id]));
|
|
4309
|
+
}
|
|
4310
|
+
if (!isFlowNode(source.data.elementType) || !isFlowNode(target.data.elementType)) {
|
|
4311
|
+
issues.push(issue("bpmn/message-flow-valid-endpoints", "error", "Message flows must connect BPMN flow nodes, not containers.", edge.id, [source.id, target.id]));
|
|
4312
|
+
}
|
|
4313
|
+
}
|
|
4314
|
+
if (edgeType === "dataAssociation") {
|
|
4315
|
+
const hasDataEndpoint = isDataType(source.data.elementType) || isDataType(target.data.elementType);
|
|
4316
|
+
const hasFlowEndpoint = isFlowNode(source.data.elementType) || isFlowNode(target.data.elementType);
|
|
4317
|
+
if (!hasDataEndpoint || !hasFlowEndpoint) {
|
|
4318
|
+
issues.push(issue("bpmn/data-association-valid-endpoints", "error", "Data associations must connect data elements with flow nodes.", edge.id, [source.id, target.id]));
|
|
4319
|
+
}
|
|
4320
|
+
}
|
|
4321
|
+
}
|
|
4322
|
+
const duplicateSequenceKeys = /* @__PURE__ */ new Set();
|
|
4323
|
+
const reportedDuplicateKeys = /* @__PURE__ */ new Set();
|
|
4324
|
+
for (const edge of seqEdges) {
|
|
4325
|
+
const key = `${edge.source}->${edge.target}`;
|
|
4326
|
+
if (duplicateSequenceKeys.has(key) && !reportedDuplicateKeys.has(key)) {
|
|
4327
|
+
reportedDuplicateKeys.add(key);
|
|
4328
|
+
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]));
|
|
4329
|
+
}
|
|
4330
|
+
duplicateSequenceKeys.add(key);
|
|
4331
|
+
}
|
|
4332
|
+
for (const node of nodes) {
|
|
4333
|
+
const type = node.data.elementType;
|
|
4334
|
+
const incoming = countSequenceEdges(edges, node.id, "in");
|
|
4335
|
+
const outgoing = countSequenceEdges(edges, node.id, "out");
|
|
4336
|
+
const meta = BPMN_ELEMENT_CATALOG[type];
|
|
4337
|
+
if (type === "StartEvent" && incoming > 0) {
|
|
4338
|
+
issues.push(issue("bpmn/start-event-no-incoming", "error", "Start events cannot have incoming sequence flows.", node.id));
|
|
4339
|
+
}
|
|
4340
|
+
if (type === "EndEvent") {
|
|
4341
|
+
if (outgoing > 0) issues.push(issue("bpmn/no-outgoing-from-end-event", "error", "End events cannot have outgoing sequence flows.", node.id));
|
|
4342
|
+
if (incoming === 0) issues.push(issue("bpmn/end-event-has-incoming", "error", "End events should have at least one incoming sequence flow.", node.id));
|
|
4343
|
+
}
|
|
4344
|
+
if ((type === "IntermediateCatchEvent" || type === "IntermediateThrowEvent") && (incoming === 0 || outgoing === 0)) {
|
|
4345
|
+
issues.push(issue("bpmn/intermediate-event-both-flows", "error", "Intermediate events should have both incoming and outgoing sequence flows.", node.id));
|
|
4346
|
+
}
|
|
4347
|
+
if (type === "BoundaryEvent") {
|
|
4348
|
+
const hostId = node.data.attachedToRef ?? node.parentId;
|
|
4349
|
+
const host = hostId ? nodeById2.get(hostId) : void 0;
|
|
4350
|
+
if (!host || !BPMN_ELEMENT_CATALOG[host.data.elementType]?.acceptsBoundaryEvents) {
|
|
4351
|
+
issues.push(issue("bpmn/boundary-event-attached", "error", "Boundary events must be attached to an activity or subprocess.", node.id, hostId ? [hostId] : void 0));
|
|
4352
|
+
}
|
|
4353
|
+
if (sequenceIn(edges, node.id).length > 0) {
|
|
4354
|
+
issues.push(issue("bpmn/boundary-no-incoming", "error", "Boundary events cannot have incoming sequence flows.", node.id));
|
|
4355
|
+
}
|
|
4356
|
+
if (sequenceOut(edges, node.id).length === 0) {
|
|
4357
|
+
issues.push(issue("bpmn/boundary-has-outgoing", "warning", "Boundary events should define an outgoing exception path.", node.id));
|
|
4358
|
+
}
|
|
4359
|
+
}
|
|
4360
|
+
if (isGatewayType(type)) {
|
|
4361
|
+
if (incoming === 0) issues.push(issue("bpmn/gateway-has-incoming", "error", "Gateways should have at least one incoming sequence flow.", node.id));
|
|
4362
|
+
if (outgoing === 0) issues.push(issue("bpmn/gateway-has-outgoing", "error", "Gateways should have at least one outgoing sequence flow.", node.id));
|
|
4363
|
+
}
|
|
4364
|
+
if (type === "ExclusiveGateway" || type === "InclusiveGateway" || type === "ComplexGateway") {
|
|
4365
|
+
const outgoingEdges = sequenceOut(edges, node.id);
|
|
4366
|
+
const defaults = outgoingEdges.filter((edge) => edge.data?.isDefault);
|
|
4367
|
+
if (defaults.length > 1) {
|
|
4368
|
+
issues.push(issue("bpmn/gateway-single-default", "error", "Gateways can have at most one default sequence flow.", node.id, defaults.map((edge) => edge.id)));
|
|
4369
|
+
}
|
|
4370
|
+
if (outgoingEdges.length >= 2) {
|
|
4371
|
+
for (const edge of outgoingEdges) {
|
|
4372
|
+
if (!edge.data?.isDefault && !edge.data?.conditionExpression) {
|
|
4373
|
+
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]));
|
|
4374
|
+
}
|
|
4375
|
+
}
|
|
4376
|
+
}
|
|
4377
|
+
}
|
|
4378
|
+
if (type === "EventBasedGateway") {
|
|
4379
|
+
const outgoingEdges = edges.filter((edge) => edge.data?.edgeType === "sequenceFlow" && edge.source === node.id);
|
|
4380
|
+
if (outgoingEdges.length < 2) {
|
|
4381
|
+
issues.push(issue("bpmn/event-based-gateway-min-outgoing", "error", "Event-based gateways should have at least two outgoing sequence flows.", node.id));
|
|
4382
|
+
}
|
|
4383
|
+
for (const edge of outgoingEdges) {
|
|
4384
|
+
const target = nodeById2.get(edge.target);
|
|
4385
|
+
if (target && !isCatchTarget(target.data.elementType)) {
|
|
4386
|
+
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]));
|
|
4387
|
+
}
|
|
4388
|
+
}
|
|
4389
|
+
}
|
|
4390
|
+
if (meta.maxIncoming !== void 0 && incoming > meta.maxIncoming) {
|
|
4391
|
+
issues.push(issue("bpmn/max-incoming", "error", `${type} cannot have more than ${meta.maxIncoming} incoming sequence flow(s).`, node.id));
|
|
4392
|
+
}
|
|
4393
|
+
if (meta.maxOutgoing !== void 0 && outgoing > meta.maxOutgoing) {
|
|
4394
|
+
issues.push(issue("bpmn/max-outgoing", "error", `${type} cannot have more than ${meta.maxOutgoing} outgoing sequence flow(s).`, node.id));
|
|
4395
|
+
}
|
|
4396
|
+
if (opts.strictNames && (type.includes("Task") || isGatewayType(type)) && !node.data.label) {
|
|
4397
|
+
issues.push(issue("bpmn/name-required", "warning", `${type} should have a label.`, node.id));
|
|
4398
|
+
}
|
|
4399
|
+
if (isSubProcess2(type)) {
|
|
4400
|
+
const childNodes = nodes.filter((child) => child.parentId === node.id);
|
|
4401
|
+
if (childNodes.length > 0) {
|
|
4402
|
+
if (!childNodes.some((child) => child.data.elementType === "StartEvent")) {
|
|
4403
|
+
issues.push(issue("bpmn/subprocess-has-start-end", "error", "Expanded subprocesses should contain a start event.", node.id));
|
|
4404
|
+
}
|
|
4405
|
+
if (!childNodes.some((child) => child.data.elementType === "EndEvent")) {
|
|
4406
|
+
issues.push(issue("bpmn/subprocess-has-start-end", "error", "Expanded subprocesses should contain an end event.", node.id));
|
|
4407
|
+
}
|
|
4408
|
+
}
|
|
4409
|
+
if (type === "EventSubProcess") {
|
|
4410
|
+
const starts = childNodes.filter((child) => child.data.elementType === "StartEvent");
|
|
4411
|
+
for (const start of starts) {
|
|
4412
|
+
if (!start.data.trigger || start.data.trigger === "none") {
|
|
4413
|
+
issues.push(issue("bpmn/event-subprocess-triggered-start", "error", "Event subprocess start events must define an event trigger.", start.id, [node.id]));
|
|
4414
|
+
}
|
|
4415
|
+
}
|
|
4416
|
+
}
|
|
4417
|
+
}
|
|
4418
|
+
if (type === "Lane") {
|
|
4419
|
+
const parent = node.parentId ? nodeById2.get(node.parentId) : void 0;
|
|
4420
|
+
if (parent?.data.elementType !== "Pool") {
|
|
4421
|
+
issues.push(issue("bpmn/lane-parent-pool", "error", "Lanes must be contained by a pool.", node.id));
|
|
4422
|
+
}
|
|
4423
|
+
}
|
|
4424
|
+
}
|
|
4425
|
+
return {
|
|
4426
|
+
valid: issues.every((item) => item.severity !== "error"),
|
|
4427
|
+
issues
|
|
4428
|
+
};
|
|
3466
4429
|
}
|
|
3467
4430
|
|
|
3468
4431
|
exports.AnnotationNode = AnnotationNode;
|
|
3469
4432
|
exports.AssociationEdge = AssociationEdge;
|
|
4433
|
+
exports.BPMN_EDGE_CONNECTION_RULES = BPMN_EDGE_CONNECTION_RULES;
|
|
3470
4434
|
exports.BPMN_EDGE_TYPES = BPMN_EDGE_TYPES;
|
|
3471
4435
|
exports.BPMN_ELEMENT_CATALOG = BPMN_ELEMENT_CATALOG;
|
|
4436
|
+
exports.BPMN_MODELING_RULES = BPMN_MODELING_RULES;
|
|
3472
4437
|
exports.BPMN_NODE_TYPES = BPMN_NODE_TYPES;
|
|
4438
|
+
exports.BPMN_POOL_LANE_LAYOUT = BPMN_POOL_LANE_LAYOUT;
|
|
4439
|
+
exports.BPMN_RESIZABLE_ELEMENT_TYPES = BPMN_RESIZABLE_ELEMENT_TYPES;
|
|
4440
|
+
exports.BPMN_ROUTABLE_EDGE_TYPES = BPMN_ROUTABLE_EDGE_TYPES;
|
|
4441
|
+
exports.BPMN_SELECTION_STYLE = BPMN_SELECTION_STYLE;
|
|
3473
4442
|
exports.BoundaryEventNode = BoundaryEventNode;
|
|
3474
4443
|
exports.CallChoreographyNode = CallChoreographyNode;
|
|
3475
4444
|
exports.CallConversationNode = CallConversationNode;
|
|
@@ -3498,13 +4467,30 @@ exports.SubConversationNode = SubConversationNode;
|
|
|
3498
4467
|
exports.SubProcessNode = SubProcessNode;
|
|
3499
4468
|
exports.TaskNode = TaskNode;
|
|
3500
4469
|
exports.acceptsBoundaryEvents = acceptsBoundaryEvents;
|
|
3501
|
-
exports.
|
|
4470
|
+
exports.attachBoundaryEventCommand = attachBoundaryEventCommand;
|
|
4471
|
+
exports.bpmnConnectionValidators = bpmnConnectionValidators;
|
|
4472
|
+
exports.canContainBpmnElement = canContainBpmnElement;
|
|
4473
|
+
exports.connectBpmnCommand = connectBpmnCommand;
|
|
4474
|
+
exports.copyBpmnElements = copyBpmnElements;
|
|
4475
|
+
exports.createBpmnDiagramDocument = createBpmnDiagramDocument;
|
|
4476
|
+
exports.createBpmnNode = createBpmnNode;
|
|
4477
|
+
exports.createBpmnNodeCommand = createBpmnNodeCommand;
|
|
3502
4478
|
exports.createSimulation = createSimulation;
|
|
4479
|
+
exports.deleteBpmnElementsCommand = deleteBpmnElementsCommand;
|
|
4480
|
+
exports.deserializeBpmnDiagram = deserializeBpmnDiagram;
|
|
3503
4481
|
exports.fire = fire;
|
|
4482
|
+
exports.getBpmnDragHandleSelector = getBpmnDragHandleSelector;
|
|
4483
|
+
exports.getBpmnElementSize = getBpmnElementSize;
|
|
4484
|
+
exports.getBpmnLaneIndexAtPosition = getBpmnLaneIndexAtPosition;
|
|
4485
|
+
exports.getBpmnPoolLanes = getBpmnPoolLanes;
|
|
3504
4486
|
exports.getElementMeta = getElementMeta;
|
|
3505
4487
|
exports.getFireable = getFireable;
|
|
3506
4488
|
exports.getHandlePolicy = getHandlePolicy;
|
|
3507
4489
|
exports.getOrientation = getOrientation;
|
|
4490
|
+
exports.inferBpmnEdgeType = inferBpmnEdgeType;
|
|
4491
|
+
exports.isBpmnEdgeRoutingEditable = isBpmnEdgeRoutingEditable;
|
|
4492
|
+
exports.isBpmnElementResizable = isBpmnElementResizable;
|
|
4493
|
+
exports.isBpmnProcessNode = isBpmnProcessNode;
|
|
3508
4494
|
exports.isChoreographyType = isChoreographyType;
|
|
3509
4495
|
exports.isCompleted = isCompleted;
|
|
3510
4496
|
exports.isContainerType = isContainerType;
|
|
@@ -3513,11 +4499,27 @@ exports.isDataType = isDataType;
|
|
|
3513
4499
|
exports.isEventType = isEventType;
|
|
3514
4500
|
exports.isGatewayType = isGatewayType;
|
|
3515
4501
|
exports.isTaskType = isTaskType;
|
|
4502
|
+
exports.layoutBpmnPoolLanes = layoutBpmnPoolLanes;
|
|
4503
|
+
exports.moveBpmnLaneCommand = moveBpmnLaneCommand;
|
|
4504
|
+
exports.parseBpmnDiagramDocument = parseBpmnDiagramDocument;
|
|
3516
4505
|
exports.parseBpmnXml = parseBpmnXml;
|
|
4506
|
+
exports.pasteBpmnElementsCommand = pasteBpmnElementsCommand;
|
|
4507
|
+
exports.reorderBpmnLane = reorderBpmnLane;
|
|
4508
|
+
exports.reorderBpmnLaneCommand = reorderBpmnLaneCommand;
|
|
4509
|
+
exports.reparentBpmnNodeCommand = reparentBpmnNodeCommand;
|
|
4510
|
+
exports.replaceBpmnNodeCommand = replaceBpmnNodeCommand;
|
|
4511
|
+
exports.resizeBpmnNodeCommand = resizeBpmnNodeCommand;
|
|
4512
|
+
exports.routeBpmnEdgeCommand = routeBpmnEdgeCommand;
|
|
4513
|
+
exports.runBpmnCommand = runBpmnCommand;
|
|
4514
|
+
exports.runBpmnCommands = runBpmnCommands;
|
|
4515
|
+
exports.selectBpmnElementsCommand = selectBpmnElementsCommand;
|
|
4516
|
+
exports.serializeBpmnDiagram = serializeBpmnDiagram;
|
|
3517
4517
|
exports.serializeBpmnXml = serializeBpmnXml;
|
|
3518
4518
|
exports.setVariable = setVariable;
|
|
3519
4519
|
exports.supportsCollapse = supportsCollapse;
|
|
3520
4520
|
exports.supportsMarkers = supportsMarkers;
|
|
3521
4521
|
exports.tick = tick;
|
|
4522
|
+
exports.validateBpmnConnectionForEdgeType = validateBpmnConnectionForEdgeType;
|
|
4523
|
+
exports.validateBpmnDiagram = validateBpmnDiagram;
|
|
3522
4524
|
//# sourceMappingURL=index.cjs.map
|
|
3523
4525
|
//# sourceMappingURL=index.cjs.map
|