@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
package/dist/index.cjs CHANGED
@@ -2518,7 +2518,29 @@ var ARANZA_DESCRIPTOR = {
2518
2518
  { name: "formKey", isAttr: true, type: "String" },
2519
2519
  // UserTask: Flowable task assignment — comma-separated ids
2520
2520
  { name: "candidateUsers", isAttr: true, type: "String" },
2521
- { name: "candidateGroups", isAttr: true, type: "String" }
2521
+ { name: "candidateGroups", isAttr: true, type: "String" },
2522
+ // UserTask: scheduling + skip expression
2523
+ { name: "dueDate", isAttr: true, type: "String" },
2524
+ { name: "skipExpression", isAttr: true, type: "String" },
2525
+ { name: "businessCalendarName", isAttr: true, type: "String" }
2526
+ ]
2527
+ },
2528
+ {
2529
+ // BusinessRuleTask: simplified inline decision table (JSON-serialized)
2530
+ name: "InlineDecision",
2531
+ superClass: ["Element"],
2532
+ properties: [
2533
+ { name: "hitPolicy", isAttr: true, type: "String" },
2534
+ { name: "tableJson", isAttr: true, type: "String" }
2535
+ ]
2536
+ },
2537
+ {
2538
+ // MessageFlow: payload schema + correlation key for executable BPMN
2539
+ name: "MessageFlowConfig",
2540
+ superClass: ["Element"],
2541
+ properties: [
2542
+ { name: "payloadSchema", isAttr: true, type: "String" },
2543
+ { name: "correlationKey", isAttr: true, type: "String" }
2522
2544
  ]
2523
2545
  }
2524
2546
  ],
@@ -2809,7 +2831,20 @@ function extractAranzaExtensions(el) {
2809
2831
  }
2810
2832
  const ext = el.extensionElements;
2811
2833
  if (!ext) return result;
2812
- const taskConfig = asElements(ext.values).find((v) => v.$type === "aranza:TaskConfig");
2834
+ const extValues = asElements(ext.values);
2835
+ const inlineDecision = extValues.find((v) => v.$type === "aranza:InlineDecision");
2836
+ if (inlineDecision) {
2837
+ const hitPolicy = asString(inlineDecision.hitPolicy) ?? "UNIQUE";
2838
+ const tableJson = asString(inlineDecision.tableJson);
2839
+ if (tableJson) {
2840
+ try {
2841
+ const parsed = JSON.parse(tableJson);
2842
+ result.inlineDecisionTable = { hitPolicy, ...parsed };
2843
+ } catch {
2844
+ }
2845
+ }
2846
+ }
2847
+ const taskConfig = extValues.find((v) => v.$type === "aranza:TaskConfig");
2813
2848
  if (!taskConfig) return result;
2814
2849
  const priority = asString(taskConfig.priority);
2815
2850
  if (priority === "critical" || priority === "high" || priority === "medium" || priority === "low") {
@@ -2835,6 +2870,12 @@ function extractAranzaExtensions(el) {
2835
2870
  if (candidateUsers) result.candidateUsers = candidateUsers;
2836
2871
  const candidateGroups = asString(taskConfig.candidateGroups);
2837
2872
  if (candidateGroups) result.candidateGroups = candidateGroups;
2873
+ const dueDate = asString(taskConfig.dueDate);
2874
+ if (dueDate) result.dueDate = dueDate;
2875
+ const skipExpression = asString(taskConfig.skipExpression);
2876
+ if (skipExpression) result.skipExpression = skipExpression;
2877
+ const businessCalendarName = asString(taskConfig.businessCalendarName);
2878
+ if (businessCalendarName) result.businessCalendarName = businessCalendarName;
2838
2879
  return result;
2839
2880
  }
2840
2881
  function extractCompletionCondition(el) {
@@ -2843,6 +2884,25 @@ function extractCompletionCondition(el) {
2843
2884
  if (typeof cc === "string") return cc.trim() || void 0;
2844
2885
  return asString(cc.body);
2845
2886
  }
2887
+ function extractLoopCharacteristics(el) {
2888
+ const lc = el.loopCharacteristics;
2889
+ if (!lc) return {};
2890
+ if (lc.$type === "bpmn:StandardLoopCharacteristics") {
2891
+ const loopCondition = asString(lc.loopCondition?.body);
2892
+ return { loopType: "loop", ...loopCondition ? { loopCondition } : {} };
2893
+ }
2894
+ if (lc.$type === "bpmn:MultiInstanceLoopCharacteristics") {
2895
+ const loopType = lc.isSequential === true ? "sequentialMultiple" : "parallelMultiple";
2896
+ const loopCardinality = asString(lc.loopCardinality?.body);
2897
+ const loopCompletionCondition = asString(lc.completionCondition?.body);
2898
+ return {
2899
+ loopType,
2900
+ ...loopCardinality ? { loopCardinality } : {},
2901
+ ...loopCompletionCondition ? { loopCompletionCondition } : {}
2902
+ };
2903
+ }
2904
+ return {};
2905
+ }
2846
2906
  function walkFlowElements(elements, parentId, ctx, nodes, edges) {
2847
2907
  for (const el of elements) {
2848
2908
  const { $type, id } = el;
@@ -2860,7 +2920,7 @@ function walkFlowElements(elements, parentId, ctx, nodes, edges) {
2860
2920
  }
2861
2921
  buildNode(el, elementType, parentId, ctx, nodes);
2862
2922
  if ($type === "bpmn:SubProcess" || $type === "bpmn:Transaction" || $type === "bpmn:AdHocSubProcess") {
2863
- const children = asElements(el.flowElements);
2923
+ const children = [...asElements(el.flowElements), ...asElements(el.artifacts)];
2864
2924
  const laneMembership = extractLaneMembership(el);
2865
2925
  walkFlowElements(children, id, { ...ctx, laneMembership }, nodes, edges);
2866
2926
  }
@@ -2873,7 +2933,7 @@ function buildNode(el, elementType, parentId, ctx, nodes) {
2873
2933
  const x = shape?.x ?? ctx.autoX.value;
2874
2934
  const y = shape?.y ?? 100;
2875
2935
  if (!shape) ctx.autoX.value += (meta?.defaultWidth ?? 120) + 20;
2876
- const label = asString(el.name);
2936
+ const label = elementType === "Annotation" ? asString(el.text) ?? asString(el.name) : asString(el.name);
2877
2937
  const documentation = extractDocumentation(el);
2878
2938
  const trigger = extractTrigger(el);
2879
2939
  const eventDefinition = extractEventDefinition(el);
@@ -2884,6 +2944,8 @@ function buildNode(el, elementType, parentId, ctx, nodes) {
2884
2944
  const scriptFormat = elementType === "ScriptTask" ? asString(el.scriptFormat) : void 0;
2885
2945
  const script = elementType === "ScriptTask" ? asString(el.script) : void 0;
2886
2946
  const completionCondition = elementType === "AdHocSubProcess" ? extractCompletionCondition(el) : void 0;
2947
+ const loopChars = extractLoopCharacteristics(el);
2948
+ const dataObjectRef = elementType === "DataObjectReference" ? asString(el.dataObjectRef?.id) : void 0;
2887
2949
  const data = {
2888
2950
  elementType,
2889
2951
  ...label ? { label } : {},
@@ -2904,6 +2966,8 @@ function buildNode(el, elementType, parentId, ctx, nodes) {
2904
2966
  ...scriptFormat ? { scriptFormat } : {},
2905
2967
  ...script ? { script } : {},
2906
2968
  ...completionCondition ? { completionCondition } : {},
2969
+ ...dataObjectRef ? { dataObjectRef } : {},
2970
+ ...loopChars,
2907
2971
  ...aranzaExt
2908
2972
  };
2909
2973
  if (elementType === "SubProcess" || elementType === "Transaction" || elementType === "EventSubProcess" || elementType === "AdHocSubProcess") {
@@ -2936,11 +3000,28 @@ function buildEdge(el, edgeType, ctx, edges) {
2936
3000
  const label = asString(el.name);
2937
3001
  const documentation = extractDocumentation(el);
2938
3002
  const condExpr = el.conditionExpression;
3003
+ const rawDir = asString(el.associationDirection);
3004
+ const associationDirection = edgeType === "association" && rawDir ? rawDir.toLowerCase() : void 0;
3005
+ let payloadSchema;
3006
+ let correlationKey;
3007
+ if (edgeType === "messageFlow") {
3008
+ const mfExt = el.extensionElements;
3009
+ if (mfExt) {
3010
+ const mfConfig = asElements(mfExt.values).find((v) => v.$type === "aranza:MessageFlowConfig");
3011
+ if (mfConfig) {
3012
+ payloadSchema = asString(mfConfig.payloadSchema) || void 0;
3013
+ correlationKey = asString(mfConfig.correlationKey) || void 0;
3014
+ }
3015
+ }
3016
+ }
2939
3017
  const data = {
2940
3018
  edgeType,
2941
3019
  ...label ? { label } : {},
2942
3020
  ...documentation ? { documentation } : {},
2943
- ...condExpr?.body ? { conditionExpression: condExpr.body } : {}
3021
+ ...condExpr?.body ? { conditionExpression: condExpr.body } : {},
3022
+ ...associationDirection ? { associationDirection } : {},
3023
+ ...payloadSchema ? { payloadSchema } : {},
3024
+ ...correlationKey ? { correlationKey } : {}
2944
3025
  };
2945
3026
  const waypoints = ctx.waypoints.get(id);
2946
3027
  if (waypoints?.length) data.routingPoints = waypoints;
@@ -2965,7 +3046,7 @@ function handleCollaboration(collaboration, ctx, nodes, edges) {
2965
3046
  if (processRef) {
2966
3047
  const laneMembership = extractLaneMembership(processRef);
2967
3048
  walkFlowElements(
2968
- asElements(processRef.flowElements),
3049
+ [...asElements(processRef.flowElements), ...asElements(processRef.artifacts)],
2969
3050
  id,
2970
3051
  { ...ctx, laneMembership },
2971
3052
  nodes,
@@ -2997,7 +3078,7 @@ function addLaneNodes(laneSet, poolId, ctx, nodes) {
2997
3078
  data: { elementType: "Lane", ...label ? { label } : {} },
2998
3079
  width: shape?.width ?? 570,
2999
3080
  height: shape?.height ?? 120,
3000
- parentId: poolId
3081
+ ...poolId ? { parentId: poolId } : {}
3001
3082
  });
3002
3083
  const child = lane.childLaneSet;
3003
3084
  if (child) addLaneNodes(child, poolId, ctx, nodes);
@@ -3031,9 +3112,9 @@ async function parseBpmnXml(xml) {
3031
3112
  } else if (rootEl.$type === "bpmn:Process") {
3032
3113
  const laneMembership = extractLaneMembership(rootEl);
3033
3114
  const laneSet = rootEl.laneSet;
3034
- if (laneSet) addLaneNodes(laneSet, "", ctx, nodes);
3115
+ if (laneSet) addLaneNodes(laneSet, void 0, ctx, nodes);
3035
3116
  walkFlowElements(
3036
- asElements(rootEl.flowElements),
3117
+ [...asElements(rootEl.flowElements), ...asElements(rootEl.artifacts)],
3037
3118
  void 0,
3038
3119
  { ...ctx, laneMembership },
3039
3120
  nodes,
@@ -3206,7 +3287,10 @@ function buildAranzaExtensionElements(moddle, node) {
3206
3287
  const formKey = typeof node.data.formKey === "string" ? node.data.formKey : void 0;
3207
3288
  const candidateUsers = typeof node.data.candidateUsers === "string" ? node.data.candidateUsers : void 0;
3208
3289
  const candidateGroups = typeof node.data.candidateGroups === "string" ? node.data.candidateGroups : void 0;
3209
- if (!priority && !owner && !sla && !connector && !action && !flowableType && !flowableDelegateExpression && !decisionRef && !formKey && !candidateUsers && !candidateGroups) {
3290
+ const dueDate = typeof node.data.dueDate === "string" ? node.data.dueDate : void 0;
3291
+ const skipExpression = typeof node.data.skipExpression === "string" ? node.data.skipExpression : void 0;
3292
+ const businessCalendarName = typeof node.data.businessCalendarName === "string" ? node.data.businessCalendarName : void 0;
3293
+ if (!priority && !owner && !sla && !connector && !action && !flowableType && !flowableDelegateExpression && !decisionRef && !formKey && !candidateUsers && !candidateGroups && !dueDate && !skipExpression && !businessCalendarName) {
3210
3294
  return null;
3211
3295
  }
3212
3296
  const configAttrs = {};
@@ -3221,9 +3305,24 @@ function buildAranzaExtensionElements(moddle, node) {
3221
3305
  if (formKey) configAttrs.formKey = formKey;
3222
3306
  if (candidateUsers) configAttrs.candidateUsers = candidateUsers;
3223
3307
  if (candidateGroups) configAttrs.candidateGroups = candidateGroups;
3224
- const taskConfig = moddle.create("aranza:TaskConfig", configAttrs);
3225
- return moddle.create("bpmn:ExtensionElements", { values: [taskConfig] });
3308
+ if (dueDate) configAttrs.dueDate = dueDate;
3309
+ if (skipExpression) configAttrs.skipExpression = skipExpression;
3310
+ if (businessCalendarName) configAttrs.businessCalendarName = businessCalendarName;
3311
+ const values = [moddle.create("aranza:TaskConfig", configAttrs)];
3312
+ const inlineDecisionTable = node.data.inlineDecisionTable;
3313
+ if (inlineDecisionTable && typeof inlineDecisionTable === "object") {
3314
+ const tbl = inlineDecisionTable;
3315
+ const { hitPolicy, ...rest } = tbl;
3316
+ values.push(
3317
+ moddle.create("aranza:InlineDecision", {
3318
+ hitPolicy: hitPolicy ?? "UNIQUE",
3319
+ tableJson: JSON.stringify(rest)
3320
+ })
3321
+ );
3322
+ }
3323
+ return moddle.create("bpmn:ExtensionElements", { values });
3226
3324
  }
3325
+ var ARTIFACT_ELEMENT_TYPES = /* @__PURE__ */ new Set(["Annotation", "Group"]);
3227
3326
  function buildSemanticModel(moddle, nodes, edges, opts) {
3228
3327
  const defId = opts.id ?? "Definitions_1";
3229
3328
  const defName = opts.name;
@@ -3258,14 +3357,24 @@ function buildSemanticModel(moddle, nodes, edges, opts) {
3258
3357
  }
3259
3358
  const messageFlowEdges = edges.filter((e) => e.data?.edgeType === "messageFlow");
3260
3359
  const conversationLinkEdges = edges.filter((e) => e.data?.edgeType === "conversationLink");
3261
- const messageFlows = messageFlowEdges.map(
3262
- (e) => moddle.create("bpmn:MessageFlow", {
3360
+ const messageFlows = messageFlowEdges.map((e) => {
3361
+ const ps = typeof e.data?.payloadSchema === "string" ? e.data.payloadSchema : void 0;
3362
+ const ck = typeof e.data?.correlationKey === "string" ? e.data.correlationKey : void 0;
3363
+ const mfAttrs = {
3263
3364
  id: e.id,
3264
3365
  name: e.data?.label ?? "",
3265
3366
  sourceRef: { id: e.source },
3266
3367
  targetRef: { id: e.target }
3267
- })
3268
- );
3368
+ };
3369
+ if (ps || ck) {
3370
+ const cfg = moddle.create("aranza:MessageFlowConfig", {
3371
+ ...ps ? { payloadSchema: ps } : {},
3372
+ ...ck ? { correlationKey: ck } : {}
3373
+ });
3374
+ mfAttrs.extensionElements = moddle.create("bpmn:ExtensionElements", { values: [cfg] });
3375
+ }
3376
+ return moddle.create("bpmn:MessageFlow", mfAttrs);
3377
+ });
3269
3378
  const conversationLinks = conversationLinkEdges.map(
3270
3379
  (e) => moddle.create("bpmn:ConversationLink", {
3271
3380
  id: e.id,
@@ -3319,10 +3428,31 @@ function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId,
3319
3428
  };
3320
3429
  const myNodes = (poolId ? allNodes.filter((n) => belongsToPool(n)) : allNodes.filter((n) => n.data.elementType !== "Pool" && n.data.elementType !== "Lane")).filter((n) => !isInsideSubProcess(n));
3321
3430
  const myLanes = laneNodes.filter((l) => poolId ? l.parentId === poolId : true);
3431
+ const presentDataObjectIds = new Set(
3432
+ myNodes.filter((n) => n.data.elementType === "DataObject").map((n) => n.id)
3433
+ );
3322
3434
  const flowElements = [];
3435
+ const artifacts = [];
3436
+ for (const node of myNodes) {
3437
+ if (node.data.elementType === "DataObjectReference") {
3438
+ const explicitRef = typeof node.data.dataObjectRef === "string" ? node.data.dataObjectRef : null;
3439
+ if (!explicitRef || !presentDataObjectIds.has(explicitRef)) {
3440
+ const syntheticId = `DataObject_${node.id}`;
3441
+ if (!presentDataObjectIds.has(syntheticId)) {
3442
+ flowElements.push(moddle.create("bpmn:DataObject", { id: syntheticId }));
3443
+ presentDataObjectIds.add(syntheticId);
3444
+ }
3445
+ }
3446
+ }
3447
+ }
3323
3448
  for (const node of myNodes) {
3324
3449
  const el = buildFlowElement(moddle, node, allNodes, allEdges);
3325
- if (el) flowElements.push(el);
3450
+ if (!el) continue;
3451
+ if (ARTIFACT_ELEMENT_TYPES.has(node.data.elementType)) {
3452
+ artifacts.push(el);
3453
+ } else {
3454
+ flowElements.push(el);
3455
+ }
3326
3456
  }
3327
3457
  const myNodeIds = new Set(myNodes.map((n) => n.id));
3328
3458
  const myEdges = allEdges.filter(
@@ -3330,7 +3460,12 @@ function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId,
3330
3460
  );
3331
3461
  for (const edge of myEdges) {
3332
3462
  const edgeMeta = buildEdgeElement(moddle, edge);
3333
- if (edgeMeta) flowElements.push(edgeMeta);
3463
+ if (!edgeMeta) continue;
3464
+ if (edge.data?.edgeType === "association") {
3465
+ artifacts.push(edgeMeta);
3466
+ } else {
3467
+ flowElements.push(edgeMeta);
3468
+ }
3334
3469
  }
3335
3470
  const elementById = new Map(
3336
3471
  flowElements.filter((element) => typeof element.id === "string").map((element) => [element.id, element])
@@ -3346,7 +3481,8 @@ function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId,
3346
3481
  const process = moddle.create("bpmn:Process", {
3347
3482
  id: processId,
3348
3483
  isExecutable: opts.process?.executable ?? true,
3349
- flowElements
3484
+ flowElements,
3485
+ ...artifacts.length > 0 ? { artifacts } : {}
3350
3486
  });
3351
3487
  if (opts.process?.documentation) {
3352
3488
  process.documentation = [
@@ -3378,6 +3514,10 @@ function buildFlowElement(moddle, node, allNodes, allEdges) {
3378
3514
  id: node.id,
3379
3515
  name: label ?? ""
3380
3516
  };
3517
+ if (elementType === "Annotation") {
3518
+ delete attrs.name;
3519
+ attrs.text = label ?? "";
3520
+ }
3381
3521
  if (node.data.documentation) {
3382
3522
  attrs.documentation = [
3383
3523
  moddle.create("bpmn:Documentation", { text: node.data.documentation })
@@ -3396,22 +3536,16 @@ function buildFlowElement(moddle, node, allNodes, allEdges) {
3396
3536
  if (elementType === "CallActivity" && node.data.calledElement) {
3397
3537
  attrs.calledElement = node.data.calledElement;
3398
3538
  }
3539
+ if (elementType === "DataObjectReference") {
3540
+ const refId = typeof node.data.dataObjectRef === "string" ? node.data.dataObjectRef : `DataObject_${node.id}`;
3541
+ attrs.dataObjectRef = { id: refId };
3542
+ }
3399
3543
  if (elementType === "ScriptTask") {
3400
3544
  const scriptFormat = typeof node.data.scriptFormat === "string" ? node.data.scriptFormat : void 0;
3401
3545
  const script = typeof node.data.script === "string" ? node.data.script : void 0;
3402
3546
  if (scriptFormat) attrs.scriptFormat = scriptFormat;
3403
3547
  if (script) attrs.script = script;
3404
3548
  }
3405
- if (elementType === "UserTask") {
3406
- const flowableAttrs = {};
3407
- const fk = typeof node.data.formKey === "string" ? node.data.formKey : void 0;
3408
- const cu = typeof node.data.candidateUsers === "string" ? node.data.candidateUsers : void 0;
3409
- const cg = typeof node.data.candidateGroups === "string" ? node.data.candidateGroups : void 0;
3410
- if (fk) flowableAttrs["flowable:formKey"] = fk;
3411
- if (cu) flowableAttrs["flowable:candidateUsers"] = cu;
3412
- if (cg) flowableAttrs["flowable:candidateGroups"] = cg;
3413
- if (Object.keys(flowableAttrs).length > 0) attrs.$attrs = flowableAttrs;
3414
- }
3415
3549
  if (elementType === "ServiceTask") {
3416
3550
  const flowableAttrs = {};
3417
3551
  const flowableType = typeof node.data.flowableType === "string" ? node.data.flowableType : void 0;
@@ -3428,7 +3562,9 @@ function buildFlowElement(moddle, node, allNodes, allEdges) {
3428
3562
  if (aranzaConfig) attrs.extensionElements = aranzaConfig;
3429
3563
  const isSubProcess2 = elementType === "SubProcess" || elementType === "Transaction" || elementType === "EventSubProcess" || elementType === "AdHocSubProcess";
3430
3564
  if (isSubProcess2) {
3431
- attrs.flowElements = buildNestedFlowElements(moddle, node, allNodes, allEdges);
3565
+ const nested = buildNestedFlowElements(moddle, node, allNodes, allEdges);
3566
+ attrs.flowElements = nested.flowElements;
3567
+ if (nested.artifacts.length > 0) attrs.artifacts = nested.artifacts;
3432
3568
  if (elementType === "EventSubProcess" || node.data.subProcessVariant === "event") {
3433
3569
  attrs.triggeredByEvent = true;
3434
3570
  }
@@ -3438,6 +3574,29 @@ function buildFlowElement(moddle, node, allNodes, allEdges) {
3438
3574
  });
3439
3575
  }
3440
3576
  }
3577
+ const loopType = typeof node.data.loopType === "string" ? node.data.loopType : "none";
3578
+ if (loopType && loopType !== "none") {
3579
+ if (loopType === "loop") {
3580
+ const lcAttrs = { id: uid("LoopChar", node.id) };
3581
+ const loopCondition = typeof node.data.loopCondition === "string" ? node.data.loopCondition : void 0;
3582
+ if (loopCondition) {
3583
+ lcAttrs.loopCondition = moddle.create("bpmn:FormalExpression", { body: loopCondition });
3584
+ }
3585
+ attrs.loopCharacteristics = moddle.create("bpmn:StandardLoopCharacteristics", lcAttrs);
3586
+ } else {
3587
+ const isSequential = loopType === "sequentialMultiple";
3588
+ const lcAttrs = { id: uid("LoopChar", node.id), isSequential };
3589
+ const loopCardinality = typeof node.data.loopCardinality === "string" ? node.data.loopCardinality : void 0;
3590
+ const loopCompletionCondition = typeof node.data.loopCompletionCondition === "string" ? node.data.loopCompletionCondition : void 0;
3591
+ if (loopCardinality) {
3592
+ lcAttrs.loopCardinality = moddle.create("bpmn:FormalExpression", { body: loopCardinality });
3593
+ }
3594
+ if (loopCompletionCondition) {
3595
+ lcAttrs.completionCondition = moddle.create("bpmn:FormalExpression", { body: loopCompletionCondition });
3596
+ }
3597
+ attrs.loopCharacteristics = moddle.create("bpmn:MultiInstanceLoopCharacteristics", lcAttrs);
3598
+ }
3599
+ }
3441
3600
  const element = moddle.create(moddleType, attrs);
3442
3601
  return element;
3443
3602
  }
@@ -3445,16 +3604,42 @@ function buildNestedFlowElements(moddle, parent, allNodes, allEdges) {
3445
3604
  const childNodes = allNodes.filter((node) => node.parentId === parent.id);
3446
3605
  const childNodeIds = new Set(childNodes.map((node) => node.id));
3447
3606
  const flowElements = [];
3607
+ const artifacts = [];
3608
+ const presentDataObjectIds = new Set(
3609
+ childNodes.filter((n) => n.data.elementType === "DataObject").map((n) => n.id)
3610
+ );
3611
+ for (const node of childNodes) {
3612
+ if (node.data.elementType === "DataObjectReference") {
3613
+ const explicitRef = typeof node.data.dataObjectRef === "string" ? node.data.dataObjectRef : null;
3614
+ if (!explicitRef || !presentDataObjectIds.has(explicitRef)) {
3615
+ const syntheticId = `DataObject_${node.id}`;
3616
+ if (!presentDataObjectIds.has(syntheticId)) {
3617
+ flowElements.push(moddle.create("bpmn:DataObject", { id: syntheticId }));
3618
+ presentDataObjectIds.add(syntheticId);
3619
+ }
3620
+ }
3621
+ }
3622
+ }
3448
3623
  for (const child of childNodes) {
3449
3624
  const element = buildFlowElement(moddle, child, allNodes, allEdges);
3450
- if (element) flowElements.push(element);
3625
+ if (!element) continue;
3626
+ if (ARTIFACT_ELEMENT_TYPES.has(child.data.elementType)) {
3627
+ artifacts.push(element);
3628
+ } else {
3629
+ flowElements.push(element);
3630
+ }
3451
3631
  }
3452
3632
  for (const edge of allEdges) {
3453
3633
  if (!childNodeIds.has(edge.source) || !childNodeIds.has(edge.target)) continue;
3454
3634
  const element = buildEdgeElement(moddle, edge);
3455
- if (element) flowElements.push(element);
3635
+ if (!element) continue;
3636
+ if (edge.data?.edgeType === "association") {
3637
+ artifacts.push(element);
3638
+ } else {
3639
+ flowElements.push(element);
3640
+ }
3456
3641
  }
3457
- return flowElements;
3642
+ return { flowElements, artifacts };
3458
3643
  }
3459
3644
  function buildEdgeElement(moddle, edge) {
3460
3645
  if (!edge.data) return null;
@@ -3476,6 +3661,9 @@ function buildEdgeElement(moddle, edge) {
3476
3661
  body: edge.data.conditionExpression
3477
3662
  });
3478
3663
  }
3664
+ if (edge.data.edgeType === "association" && edge.data.associationDirection && edge.data.associationDirection !== "none") {
3665
+ attrs.associationDirection = edge.data.associationDirection === "both" ? "Both" : "One";
3666
+ }
3479
3667
  return moddle.create(moddleType, attrs);
3480
3668
  }
3481
3669
  function buildBpmnDI(moddle, definitions, nodes, edges) {