@aranzatech/diagrams-bpmn 0.2.11 → 0.2.13

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.
Files changed (41) hide show
  1. package/dist/{catalog-Ch3YT0-0.d.cts → catalog-BiLXVn-2.d.cts} +1 -1
  2. package/dist/{catalog-BOwJOaXV.d.ts → catalog-Di2nzGs9.d.ts} +1 -1
  3. package/dist/chunk-FBTGIYZS.js +218 -0
  4. package/dist/chunk-FBTGIYZS.js.map +1 -0
  5. package/dist/{chunk-HLCUGTEK.js → chunk-YUE5EM3W.js} +223 -35
  6. package/dist/chunk-YUE5EM3W.js.map +1 -0
  7. package/dist/elements/index.cjs +217 -0
  8. package/dist/elements/index.cjs.map +1 -1
  9. package/dist/elements/index.d.cts +15 -16
  10. package/dist/elements/index.d.ts +15 -16
  11. package/dist/elements/index.js +1 -1
  12. package/dist/guards-DPHXfpY8.d.cts +16 -0
  13. package/dist/guards-qgSeZEU4.d.ts +16 -0
  14. package/dist/index.cjs +221 -33
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +4 -4
  17. package/dist/index.d.ts +4 -4
  18. package/dist/index.js +2 -2
  19. package/dist/layout/index.cjs +87 -0
  20. package/dist/layout/index.cjs.map +1 -1
  21. package/dist/layout/index.d.cts +22 -4
  22. package/dist/layout/index.d.ts +22 -4
  23. package/dist/layout/index.js +90 -2
  24. package/dist/layout/index.js.map +1 -1
  25. package/dist/modeling/index.d.cts +3 -3
  26. package/dist/modeling/index.d.ts +3 -3
  27. package/dist/{types-BTuiBv7p.d.cts → types-Dfrt0wVs.d.cts} +45 -1
  28. package/dist/{types-BTuiBv7p.d.ts → types-Dfrt0wVs.d.ts} +45 -1
  29. package/dist/{types-DSDMCAre.d.ts → types-rEfHsPr5.d.ts} +1 -1
  30. package/dist/{types-C7tONwP5.d.cts → types-s2_VvPGf.d.cts} +1 -1
  31. package/dist/validation/index.d.cts +2 -2
  32. package/dist/validation/index.d.ts +2 -2
  33. package/dist/xml/index.cjs +221 -33
  34. package/dist/xml/index.cjs.map +1 -1
  35. package/dist/xml/index.d.cts +3 -3
  36. package/dist/xml/index.d.ts +3 -3
  37. package/dist/xml/index.js +1 -1
  38. package/package.json +2 -2
  39. package/dist/chunk-HLCUGTEK.js.map +0 -1
  40. package/dist/chunk-OZKTOILD.js +0 -3
  41. package/dist/chunk-OZKTOILD.js.map +0 -1
@@ -26,7 +26,29 @@ var ARANZA_DESCRIPTOR = {
26
26
  { name: "formKey", isAttr: true, type: "String" },
27
27
  // UserTask: Flowable task assignment — comma-separated ids
28
28
  { name: "candidateUsers", isAttr: true, type: "String" },
29
- { name: "candidateGroups", isAttr: true, type: "String" }
29
+ { name: "candidateGroups", isAttr: true, type: "String" },
30
+ // UserTask: scheduling + skip expression
31
+ { name: "dueDate", isAttr: true, type: "String" },
32
+ { name: "skipExpression", isAttr: true, type: "String" },
33
+ { name: "businessCalendarName", isAttr: true, type: "String" }
34
+ ]
35
+ },
36
+ {
37
+ // BusinessRuleTask: simplified inline decision table (JSON-serialized)
38
+ name: "InlineDecision",
39
+ superClass: ["Element"],
40
+ properties: [
41
+ { name: "hitPolicy", isAttr: true, type: "String" },
42
+ { name: "tableJson", isAttr: true, type: "String" }
43
+ ]
44
+ },
45
+ {
46
+ // MessageFlow: payload schema + correlation key for executable BPMN
47
+ name: "MessageFlowConfig",
48
+ superClass: ["Element"],
49
+ properties: [
50
+ { name: "payloadSchema", isAttr: true, type: "String" },
51
+ { name: "correlationKey", isAttr: true, type: "String" }
30
52
  ]
31
53
  }
32
54
  ],
@@ -317,7 +339,20 @@ function extractAranzaExtensions(el) {
317
339
  }
318
340
  const ext = el.extensionElements;
319
341
  if (!ext) return result;
320
- const taskConfig = asElements(ext.values).find((v) => v.$type === "aranza:TaskConfig");
342
+ const extValues = asElements(ext.values);
343
+ const inlineDecision = extValues.find((v) => v.$type === "aranza:InlineDecision");
344
+ if (inlineDecision) {
345
+ const hitPolicy = asString(inlineDecision.hitPolicy) ?? "UNIQUE";
346
+ const tableJson = asString(inlineDecision.tableJson);
347
+ if (tableJson) {
348
+ try {
349
+ const parsed = JSON.parse(tableJson);
350
+ result.inlineDecisionTable = { hitPolicy, ...parsed };
351
+ } catch {
352
+ }
353
+ }
354
+ }
355
+ const taskConfig = extValues.find((v) => v.$type === "aranza:TaskConfig");
321
356
  if (!taskConfig) return result;
322
357
  const priority = asString(taskConfig.priority);
323
358
  if (priority === "critical" || priority === "high" || priority === "medium" || priority === "low") {
@@ -343,6 +378,12 @@ function extractAranzaExtensions(el) {
343
378
  if (candidateUsers) result.candidateUsers = candidateUsers;
344
379
  const candidateGroups = asString(taskConfig.candidateGroups);
345
380
  if (candidateGroups) result.candidateGroups = candidateGroups;
381
+ const dueDate = asString(taskConfig.dueDate);
382
+ if (dueDate) result.dueDate = dueDate;
383
+ const skipExpression = asString(taskConfig.skipExpression);
384
+ if (skipExpression) result.skipExpression = skipExpression;
385
+ const businessCalendarName = asString(taskConfig.businessCalendarName);
386
+ if (businessCalendarName) result.businessCalendarName = businessCalendarName;
346
387
  return result;
347
388
  }
348
389
  function extractCompletionCondition(el) {
@@ -351,6 +392,25 @@ function extractCompletionCondition(el) {
351
392
  if (typeof cc === "string") return cc.trim() || void 0;
352
393
  return asString(cc.body);
353
394
  }
395
+ function extractLoopCharacteristics(el) {
396
+ const lc = el.loopCharacteristics;
397
+ if (!lc) return {};
398
+ if (lc.$type === "bpmn:StandardLoopCharacteristics") {
399
+ const loopCondition = asString(lc.loopCondition?.body);
400
+ return { loopType: "loop", ...loopCondition ? { loopCondition } : {} };
401
+ }
402
+ if (lc.$type === "bpmn:MultiInstanceLoopCharacteristics") {
403
+ const loopType = lc.isSequential === true ? "sequentialMultiple" : "parallelMultiple";
404
+ const loopCardinality = asString(lc.loopCardinality?.body);
405
+ const loopCompletionCondition = asString(lc.completionCondition?.body);
406
+ return {
407
+ loopType,
408
+ ...loopCardinality ? { loopCardinality } : {},
409
+ ...loopCompletionCondition ? { loopCompletionCondition } : {}
410
+ };
411
+ }
412
+ return {};
413
+ }
354
414
  function walkFlowElements(elements, parentId, ctx, nodes, edges) {
355
415
  for (const el of elements) {
356
416
  const { $type, id } = el;
@@ -368,7 +428,7 @@ function walkFlowElements(elements, parentId, ctx, nodes, edges) {
368
428
  }
369
429
  buildNode(el, elementType, parentId, ctx, nodes);
370
430
  if ($type === "bpmn:SubProcess" || $type === "bpmn:Transaction" || $type === "bpmn:AdHocSubProcess") {
371
- const children = asElements(el.flowElements);
431
+ const children = [...asElements(el.flowElements), ...asElements(el.artifacts)];
372
432
  const laneMembership = extractLaneMembership(el);
373
433
  walkFlowElements(children, id, { ...ctx, laneMembership }, nodes, edges);
374
434
  }
@@ -381,7 +441,7 @@ function buildNode(el, elementType, parentId, ctx, nodes) {
381
441
  const x = shape?.x ?? ctx.autoX.value;
382
442
  const y = shape?.y ?? 100;
383
443
  if (!shape) ctx.autoX.value += (meta?.defaultWidth ?? 120) + 20;
384
- const label = asString(el.name);
444
+ const label = elementType === "Annotation" ? asString(el.text) ?? asString(el.name) : asString(el.name);
385
445
  const documentation = extractDocumentation(el);
386
446
  const trigger = extractTrigger(el);
387
447
  const eventDefinition = extractEventDefinition(el);
@@ -392,6 +452,8 @@ function buildNode(el, elementType, parentId, ctx, nodes) {
392
452
  const scriptFormat = elementType === "ScriptTask" ? asString(el.scriptFormat) : void 0;
393
453
  const script = elementType === "ScriptTask" ? asString(el.script) : void 0;
394
454
  const completionCondition = elementType === "AdHocSubProcess" ? extractCompletionCondition(el) : void 0;
455
+ const loopChars = extractLoopCharacteristics(el);
456
+ const dataObjectRef = elementType === "DataObjectReference" ? asString(el.dataObjectRef?.id) : void 0;
395
457
  const data = {
396
458
  elementType,
397
459
  ...label ? { label } : {},
@@ -412,6 +474,8 @@ function buildNode(el, elementType, parentId, ctx, nodes) {
412
474
  ...scriptFormat ? { scriptFormat } : {},
413
475
  ...script ? { script } : {},
414
476
  ...completionCondition ? { completionCondition } : {},
477
+ ...dataObjectRef ? { dataObjectRef } : {},
478
+ ...loopChars,
415
479
  ...aranzaExt
416
480
  };
417
481
  if (elementType === "SubProcess" || elementType === "Transaction" || elementType === "EventSubProcess" || elementType === "AdHocSubProcess") {
@@ -444,11 +508,28 @@ function buildEdge(el, edgeType, ctx, edges) {
444
508
  const label = asString(el.name);
445
509
  const documentation = extractDocumentation(el);
446
510
  const condExpr = el.conditionExpression;
511
+ const rawDir = asString(el.associationDirection);
512
+ const associationDirection = edgeType === "association" && rawDir ? rawDir.toLowerCase() : void 0;
513
+ let payloadSchema;
514
+ let correlationKey;
515
+ if (edgeType === "messageFlow") {
516
+ const mfExt = el.extensionElements;
517
+ if (mfExt) {
518
+ const mfConfig = asElements(mfExt.values).find((v) => v.$type === "aranza:MessageFlowConfig");
519
+ if (mfConfig) {
520
+ payloadSchema = asString(mfConfig.payloadSchema) || void 0;
521
+ correlationKey = asString(mfConfig.correlationKey) || void 0;
522
+ }
523
+ }
524
+ }
447
525
  const data = {
448
526
  edgeType,
449
527
  ...label ? { label } : {},
450
528
  ...documentation ? { documentation } : {},
451
- ...condExpr?.body ? { conditionExpression: condExpr.body } : {}
529
+ ...condExpr?.body ? { conditionExpression: condExpr.body } : {},
530
+ ...associationDirection ? { associationDirection } : {},
531
+ ...payloadSchema ? { payloadSchema } : {},
532
+ ...correlationKey ? { correlationKey } : {}
452
533
  };
453
534
  const waypoints = ctx.waypoints.get(id);
454
535
  if (waypoints?.length) data.routingPoints = waypoints;
@@ -473,7 +554,7 @@ function handleCollaboration(collaboration, ctx, nodes, edges) {
473
554
  if (processRef) {
474
555
  const laneMembership = extractLaneMembership(processRef);
475
556
  walkFlowElements(
476
- asElements(processRef.flowElements),
557
+ [...asElements(processRef.flowElements), ...asElements(processRef.artifacts)],
477
558
  id,
478
559
  { ...ctx, laneMembership },
479
560
  nodes,
@@ -505,7 +586,7 @@ function addLaneNodes(laneSet, poolId, ctx, nodes) {
505
586
  data: { elementType: "Lane", ...label ? { label } : {} },
506
587
  width: shape?.width ?? 570,
507
588
  height: shape?.height ?? 120,
508
- parentId: poolId
589
+ ...poolId ? { parentId: poolId } : {}
509
590
  });
510
591
  const child = lane.childLaneSet;
511
592
  if (child) addLaneNodes(child, poolId, ctx, nodes);
@@ -539,9 +620,9 @@ async function parseBpmnXml(xml) {
539
620
  } else if (rootEl.$type === "bpmn:Process") {
540
621
  const laneMembership = extractLaneMembership(rootEl);
541
622
  const laneSet = rootEl.laneSet;
542
- if (laneSet) addLaneNodes(laneSet, "", ctx, nodes);
623
+ if (laneSet) addLaneNodes(laneSet, void 0, ctx, nodes);
543
624
  walkFlowElements(
544
- asElements(rootEl.flowElements),
625
+ [...asElements(rootEl.flowElements), ...asElements(rootEl.artifacts)],
545
626
  void 0,
546
627
  { ...ctx, laneMembership },
547
628
  nodes,
@@ -714,7 +795,10 @@ function buildAranzaExtensionElements(moddle, node) {
714
795
  const formKey = typeof node.data.formKey === "string" ? node.data.formKey : void 0;
715
796
  const candidateUsers = typeof node.data.candidateUsers === "string" ? node.data.candidateUsers : void 0;
716
797
  const candidateGroups = typeof node.data.candidateGroups === "string" ? node.data.candidateGroups : void 0;
717
- if (!priority && !owner && !sla && !connector && !action && !flowableType && !flowableDelegateExpression && !decisionRef && !formKey && !candidateUsers && !candidateGroups) {
798
+ const dueDate = typeof node.data.dueDate === "string" ? node.data.dueDate : void 0;
799
+ const skipExpression = typeof node.data.skipExpression === "string" ? node.data.skipExpression : void 0;
800
+ const businessCalendarName = typeof node.data.businessCalendarName === "string" ? node.data.businessCalendarName : void 0;
801
+ if (!priority && !owner && !sla && !connector && !action && !flowableType && !flowableDelegateExpression && !decisionRef && !formKey && !candidateUsers && !candidateGroups && !dueDate && !skipExpression && !businessCalendarName) {
718
802
  return null;
719
803
  }
720
804
  const configAttrs = {};
@@ -729,9 +813,24 @@ function buildAranzaExtensionElements(moddle, node) {
729
813
  if (formKey) configAttrs.formKey = formKey;
730
814
  if (candidateUsers) configAttrs.candidateUsers = candidateUsers;
731
815
  if (candidateGroups) configAttrs.candidateGroups = candidateGroups;
732
- const taskConfig = moddle.create("aranza:TaskConfig", configAttrs);
733
- return moddle.create("bpmn:ExtensionElements", { values: [taskConfig] });
816
+ if (dueDate) configAttrs.dueDate = dueDate;
817
+ if (skipExpression) configAttrs.skipExpression = skipExpression;
818
+ if (businessCalendarName) configAttrs.businessCalendarName = businessCalendarName;
819
+ const values = [moddle.create("aranza:TaskConfig", configAttrs)];
820
+ const inlineDecisionTable = node.data.inlineDecisionTable;
821
+ if (inlineDecisionTable && typeof inlineDecisionTable === "object") {
822
+ const tbl = inlineDecisionTable;
823
+ const { hitPolicy, ...rest } = tbl;
824
+ values.push(
825
+ moddle.create("aranza:InlineDecision", {
826
+ hitPolicy: hitPolicy ?? "UNIQUE",
827
+ tableJson: JSON.stringify(rest)
828
+ })
829
+ );
830
+ }
831
+ return moddle.create("bpmn:ExtensionElements", { values });
734
832
  }
833
+ var ARTIFACT_ELEMENT_TYPES = /* @__PURE__ */ new Set(["Annotation", "Group"]);
735
834
  function buildSemanticModel(moddle, nodes, edges, opts) {
736
835
  const defId = opts.id ?? "Definitions_1";
737
836
  const defName = opts.name;
@@ -766,14 +865,24 @@ function buildSemanticModel(moddle, nodes, edges, opts) {
766
865
  }
767
866
  const messageFlowEdges = edges.filter((e) => e.data?.edgeType === "messageFlow");
768
867
  const conversationLinkEdges = edges.filter((e) => e.data?.edgeType === "conversationLink");
769
- const messageFlows = messageFlowEdges.map(
770
- (e) => moddle.create("bpmn:MessageFlow", {
868
+ const messageFlows = messageFlowEdges.map((e) => {
869
+ const ps = typeof e.data?.payloadSchema === "string" ? e.data.payloadSchema : void 0;
870
+ const ck = typeof e.data?.correlationKey === "string" ? e.data.correlationKey : void 0;
871
+ const mfAttrs = {
771
872
  id: e.id,
772
873
  name: e.data?.label ?? "",
773
874
  sourceRef: { id: e.source },
774
875
  targetRef: { id: e.target }
775
- })
776
- );
876
+ };
877
+ if (ps || ck) {
878
+ const cfg = moddle.create("aranza:MessageFlowConfig", {
879
+ ...ps ? { payloadSchema: ps } : {},
880
+ ...ck ? { correlationKey: ck } : {}
881
+ });
882
+ mfAttrs.extensionElements = moddle.create("bpmn:ExtensionElements", { values: [cfg] });
883
+ }
884
+ return moddle.create("bpmn:MessageFlow", mfAttrs);
885
+ });
777
886
  const conversationLinks = conversationLinkEdges.map(
778
887
  (e) => moddle.create("bpmn:ConversationLink", {
779
888
  id: e.id,
@@ -827,10 +936,31 @@ function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId,
827
936
  };
828
937
  const myNodes = (poolId ? allNodes.filter((n) => belongsToPool(n)) : allNodes.filter((n) => n.data.elementType !== "Pool" && n.data.elementType !== "Lane")).filter((n) => !isInsideSubProcess(n));
829
938
  const myLanes = laneNodes.filter((l) => poolId ? l.parentId === poolId : true);
939
+ const presentDataObjectIds = new Set(
940
+ myNodes.filter((n) => n.data.elementType === "DataObject").map((n) => n.id)
941
+ );
830
942
  const flowElements = [];
943
+ const artifacts = [];
944
+ for (const node of myNodes) {
945
+ if (node.data.elementType === "DataObjectReference") {
946
+ const explicitRef = typeof node.data.dataObjectRef === "string" ? node.data.dataObjectRef : null;
947
+ if (!explicitRef || !presentDataObjectIds.has(explicitRef)) {
948
+ const syntheticId = `DataObject_${node.id}`;
949
+ if (!presentDataObjectIds.has(syntheticId)) {
950
+ flowElements.push(moddle.create("bpmn:DataObject", { id: syntheticId }));
951
+ presentDataObjectIds.add(syntheticId);
952
+ }
953
+ }
954
+ }
955
+ }
831
956
  for (const node of myNodes) {
832
957
  const el = buildFlowElement(moddle, node, allNodes, allEdges);
833
- if (el) flowElements.push(el);
958
+ if (!el) continue;
959
+ if (ARTIFACT_ELEMENT_TYPES.has(node.data.elementType)) {
960
+ artifacts.push(el);
961
+ } else {
962
+ flowElements.push(el);
963
+ }
834
964
  }
835
965
  const myNodeIds = new Set(myNodes.map((n) => n.id));
836
966
  const myEdges = allEdges.filter(
@@ -838,7 +968,12 @@ function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId,
838
968
  );
839
969
  for (const edge of myEdges) {
840
970
  const edgeMeta = buildEdgeElement(moddle, edge);
841
- if (edgeMeta) flowElements.push(edgeMeta);
971
+ if (!edgeMeta) continue;
972
+ if (edge.data?.edgeType === "association") {
973
+ artifacts.push(edgeMeta);
974
+ } else {
975
+ flowElements.push(edgeMeta);
976
+ }
842
977
  }
843
978
  const elementById = new Map(
844
979
  flowElements.filter((element) => typeof element.id === "string").map((element) => [element.id, element])
@@ -854,7 +989,8 @@ function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId,
854
989
  const process = moddle.create("bpmn:Process", {
855
990
  id: processId,
856
991
  isExecutable: opts.process?.executable ?? true,
857
- flowElements
992
+ flowElements,
993
+ ...artifacts.length > 0 ? { artifacts } : {}
858
994
  });
859
995
  if (opts.process?.documentation) {
860
996
  process.documentation = [
@@ -886,6 +1022,10 @@ function buildFlowElement(moddle, node, allNodes, allEdges) {
886
1022
  id: node.id,
887
1023
  name: label ?? ""
888
1024
  };
1025
+ if (elementType === "Annotation") {
1026
+ delete attrs.name;
1027
+ attrs.text = label ?? "";
1028
+ }
889
1029
  if (node.data.documentation) {
890
1030
  attrs.documentation = [
891
1031
  moddle.create("bpmn:Documentation", { text: node.data.documentation })
@@ -904,22 +1044,16 @@ function buildFlowElement(moddle, node, allNodes, allEdges) {
904
1044
  if (elementType === "CallActivity" && node.data.calledElement) {
905
1045
  attrs.calledElement = node.data.calledElement;
906
1046
  }
1047
+ if (elementType === "DataObjectReference") {
1048
+ const refId = typeof node.data.dataObjectRef === "string" ? node.data.dataObjectRef : `DataObject_${node.id}`;
1049
+ attrs.dataObjectRef = { id: refId };
1050
+ }
907
1051
  if (elementType === "ScriptTask") {
908
1052
  const scriptFormat = typeof node.data.scriptFormat === "string" ? node.data.scriptFormat : void 0;
909
1053
  const script = typeof node.data.script === "string" ? node.data.script : void 0;
910
1054
  if (scriptFormat) attrs.scriptFormat = scriptFormat;
911
1055
  if (script) attrs.script = script;
912
1056
  }
913
- if (elementType === "UserTask") {
914
- const flowableAttrs = {};
915
- const fk = typeof node.data.formKey === "string" ? node.data.formKey : void 0;
916
- const cu = typeof node.data.candidateUsers === "string" ? node.data.candidateUsers : void 0;
917
- const cg = typeof node.data.candidateGroups === "string" ? node.data.candidateGroups : void 0;
918
- if (fk) flowableAttrs["flowable:formKey"] = fk;
919
- if (cu) flowableAttrs["flowable:candidateUsers"] = cu;
920
- if (cg) flowableAttrs["flowable:candidateGroups"] = cg;
921
- if (Object.keys(flowableAttrs).length > 0) attrs.$attrs = flowableAttrs;
922
- }
923
1057
  if (elementType === "ServiceTask") {
924
1058
  const flowableAttrs = {};
925
1059
  const flowableType = typeof node.data.flowableType === "string" ? node.data.flowableType : void 0;
@@ -936,7 +1070,9 @@ function buildFlowElement(moddle, node, allNodes, allEdges) {
936
1070
  if (aranzaConfig) attrs.extensionElements = aranzaConfig;
937
1071
  const isSubProcess = elementType === "SubProcess" || elementType === "Transaction" || elementType === "EventSubProcess" || elementType === "AdHocSubProcess";
938
1072
  if (isSubProcess) {
939
- attrs.flowElements = buildNestedFlowElements(moddle, node, allNodes, allEdges);
1073
+ const nested = buildNestedFlowElements(moddle, node, allNodes, allEdges);
1074
+ attrs.flowElements = nested.flowElements;
1075
+ if (nested.artifacts.length > 0) attrs.artifacts = nested.artifacts;
940
1076
  if (elementType === "EventSubProcess" || node.data.subProcessVariant === "event") {
941
1077
  attrs.triggeredByEvent = true;
942
1078
  }
@@ -946,6 +1082,29 @@ function buildFlowElement(moddle, node, allNodes, allEdges) {
946
1082
  });
947
1083
  }
948
1084
  }
1085
+ const loopType = typeof node.data.loopType === "string" ? node.data.loopType : "none";
1086
+ if (loopType && loopType !== "none") {
1087
+ if (loopType === "loop") {
1088
+ const lcAttrs = { id: uid("LoopChar", node.id) };
1089
+ const loopCondition = typeof node.data.loopCondition === "string" ? node.data.loopCondition : void 0;
1090
+ if (loopCondition) {
1091
+ lcAttrs.loopCondition = moddle.create("bpmn:FormalExpression", { body: loopCondition });
1092
+ }
1093
+ attrs.loopCharacteristics = moddle.create("bpmn:StandardLoopCharacteristics", lcAttrs);
1094
+ } else {
1095
+ const isSequential = loopType === "sequentialMultiple";
1096
+ const lcAttrs = { id: uid("LoopChar", node.id), isSequential };
1097
+ const loopCardinality = typeof node.data.loopCardinality === "string" ? node.data.loopCardinality : void 0;
1098
+ const loopCompletionCondition = typeof node.data.loopCompletionCondition === "string" ? node.data.loopCompletionCondition : void 0;
1099
+ if (loopCardinality) {
1100
+ lcAttrs.loopCardinality = moddle.create("bpmn:FormalExpression", { body: loopCardinality });
1101
+ }
1102
+ if (loopCompletionCondition) {
1103
+ lcAttrs.completionCondition = moddle.create("bpmn:FormalExpression", { body: loopCompletionCondition });
1104
+ }
1105
+ attrs.loopCharacteristics = moddle.create("bpmn:MultiInstanceLoopCharacteristics", lcAttrs);
1106
+ }
1107
+ }
949
1108
  const element = moddle.create(moddleType, attrs);
950
1109
  return element;
951
1110
  }
@@ -953,16 +1112,42 @@ function buildNestedFlowElements(moddle, parent, allNodes, allEdges) {
953
1112
  const childNodes = allNodes.filter((node) => node.parentId === parent.id);
954
1113
  const childNodeIds = new Set(childNodes.map((node) => node.id));
955
1114
  const flowElements = [];
1115
+ const artifacts = [];
1116
+ const presentDataObjectIds = new Set(
1117
+ childNodes.filter((n) => n.data.elementType === "DataObject").map((n) => n.id)
1118
+ );
1119
+ for (const node of childNodes) {
1120
+ if (node.data.elementType === "DataObjectReference") {
1121
+ const explicitRef = typeof node.data.dataObjectRef === "string" ? node.data.dataObjectRef : null;
1122
+ if (!explicitRef || !presentDataObjectIds.has(explicitRef)) {
1123
+ const syntheticId = `DataObject_${node.id}`;
1124
+ if (!presentDataObjectIds.has(syntheticId)) {
1125
+ flowElements.push(moddle.create("bpmn:DataObject", { id: syntheticId }));
1126
+ presentDataObjectIds.add(syntheticId);
1127
+ }
1128
+ }
1129
+ }
1130
+ }
956
1131
  for (const child of childNodes) {
957
1132
  const element = buildFlowElement(moddle, child, allNodes, allEdges);
958
- if (element) flowElements.push(element);
1133
+ if (!element) continue;
1134
+ if (ARTIFACT_ELEMENT_TYPES.has(child.data.elementType)) {
1135
+ artifacts.push(element);
1136
+ } else {
1137
+ flowElements.push(element);
1138
+ }
959
1139
  }
960
1140
  for (const edge of allEdges) {
961
1141
  if (!childNodeIds.has(edge.source) || !childNodeIds.has(edge.target)) continue;
962
1142
  const element = buildEdgeElement(moddle, edge);
963
- if (element) flowElements.push(element);
1143
+ if (!element) continue;
1144
+ if (edge.data?.edgeType === "association") {
1145
+ artifacts.push(element);
1146
+ } else {
1147
+ flowElements.push(element);
1148
+ }
964
1149
  }
965
- return flowElements;
1150
+ return { flowElements, artifacts };
966
1151
  }
967
1152
  function buildEdgeElement(moddle, edge) {
968
1153
  if (!edge.data) return null;
@@ -984,6 +1169,9 @@ function buildEdgeElement(moddle, edge) {
984
1169
  body: edge.data.conditionExpression
985
1170
  });
986
1171
  }
1172
+ if (edge.data.edgeType === "association" && edge.data.associationDirection && edge.data.associationDirection !== "none") {
1173
+ attrs.associationDirection = edge.data.associationDirection === "both" ? "Both" : "One";
1174
+ }
987
1175
  return moddle.create(moddleType, attrs);
988
1176
  }
989
1177
  function buildBpmnDI(moddle, definitions, nodes, edges) {
@@ -1087,5 +1275,5 @@ async function serializeBpmnXml(nodes, edges, opts = {}) {
1087
1275
  }
1088
1276
 
1089
1277
  export { parseBpmnXml, serializeBpmnXml };
1090
- //# sourceMappingURL=chunk-HLCUGTEK.js.map
1091
- //# sourceMappingURL=chunk-HLCUGTEK.js.map
1278
+ //# sourceMappingURL=chunk-YUE5EM3W.js.map
1279
+ //# sourceMappingURL=chunk-YUE5EM3W.js.map