@bpmnkit/core 0.0.8

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 (104) hide show
  1. package/README.md +185 -0
  2. package/dist/bpmn/auto-layout.d.ts +10 -0
  3. package/dist/bpmn/auto-layout.js +203 -0
  4. package/dist/bpmn/bpmn-builder.d.ts +381 -0
  5. package/dist/bpmn/bpmn-builder.js +1223 -0
  6. package/dist/bpmn/bpmn-model.d.ts +403 -0
  7. package/dist/bpmn/bpmn-model.js +2 -0
  8. package/dist/bpmn/bpmn-parser.d.ts +4 -0
  9. package/dist/bpmn/bpmn-parser.js +642 -0
  10. package/dist/bpmn/bpmn-serializer.d.ts +4 -0
  11. package/dist/bpmn/bpmn-serializer.js +515 -0
  12. package/dist/bpmn/compact.d.ts +91 -0
  13. package/dist/bpmn/compact.js +349 -0
  14. package/dist/bpmn/di-color.d.ts +9 -0
  15. package/dist/bpmn/di-color.js +32 -0
  16. package/dist/bpmn/index.d.ts +105 -0
  17. package/dist/bpmn/index.js +176 -0
  18. package/dist/bpmn/optimize/feel.d.ts +4 -0
  19. package/dist/bpmn/optimize/feel.js +186 -0
  20. package/dist/bpmn/optimize/flow.d.ts +4 -0
  21. package/dist/bpmn/optimize/flow.js +323 -0
  22. package/dist/bpmn/optimize/index.d.ts +5 -0
  23. package/dist/bpmn/optimize/index.js +51 -0
  24. package/dist/bpmn/optimize/naming.d.ts +8 -0
  25. package/dist/bpmn/optimize/naming.js +145 -0
  26. package/dist/bpmn/optimize/tasks.d.ts +4 -0
  27. package/dist/bpmn/optimize/tasks.js +273 -0
  28. package/dist/bpmn/optimize/types.d.ts +44 -0
  29. package/dist/bpmn/optimize/types.js +2 -0
  30. package/dist/bpmn/optimize/utils.d.ts +23 -0
  31. package/dist/bpmn/optimize/utils.js +129 -0
  32. package/dist/bpmn/rest-connector.d.ts +48 -0
  33. package/dist/bpmn/rest-connector.js +69 -0
  34. package/dist/bpmn/svg.d.ts +35 -0
  35. package/dist/bpmn/svg.js +557 -0
  36. package/dist/bpmn/type-guards.d.ts +136 -0
  37. package/dist/bpmn/type-guards.js +211 -0
  38. package/dist/bpmn/utils.d.ts +88 -0
  39. package/dist/bpmn/utils.js +207 -0
  40. package/dist/bpmn/zeebe-extensions.d.ts +72 -0
  41. package/dist/bpmn/zeebe-extensions.js +96 -0
  42. package/dist/dmn/compact.d.ts +44 -0
  43. package/dist/dmn/compact.js +125 -0
  44. package/dist/dmn/dmn-builder.d.ts +59 -0
  45. package/dist/dmn/dmn-builder.js +144 -0
  46. package/dist/dmn/dmn-layout.d.ts +57 -0
  47. package/dist/dmn/dmn-layout.js +256 -0
  48. package/dist/dmn/dmn-model.d.ts +158 -0
  49. package/dist/dmn/dmn-model.js +2 -0
  50. package/dist/dmn/dmn-parser.d.ts +4 -0
  51. package/dist/dmn/dmn-parser.js +275 -0
  52. package/dist/dmn/dmn-serializer.d.ts +4 -0
  53. package/dist/dmn/dmn-serializer.js +296 -0
  54. package/dist/dmn/index.d.ts +28 -0
  55. package/dist/dmn/index.js +51 -0
  56. package/dist/errors.d.ts +77 -0
  57. package/dist/errors.js +66 -0
  58. package/dist/form/compact.d.ts +20 -0
  59. package/dist/form/compact.js +146 -0
  60. package/dist/form/form-builder.d.ts +111 -0
  61. package/dist/form/form-builder.js +347 -0
  62. package/dist/form/form-model.d.ts +221 -0
  63. package/dist/form/form-model.js +2 -0
  64. package/dist/form/form-parser.d.ts +4 -0
  65. package/dist/form/form-parser.js +514 -0
  66. package/dist/form/form-serializer.d.ts +4 -0
  67. package/dist/form/form-serializer.js +240 -0
  68. package/dist/form/index.d.ts +27 -0
  69. package/dist/form/index.js +43 -0
  70. package/dist/index.d.ts +37 -0
  71. package/dist/index.js +19 -0
  72. package/dist/layout/bench.d.ts +86 -0
  73. package/dist/layout/bench.js +225 -0
  74. package/dist/layout/coordinates.d.ts +62 -0
  75. package/dist/layout/coordinates.js +868 -0
  76. package/dist/layout/crossing.d.ts +8 -0
  77. package/dist/layout/crossing.js +60 -0
  78. package/dist/layout/graph.d.ts +28 -0
  79. package/dist/layout/graph.js +126 -0
  80. package/dist/layout/index.d.ts +7 -0
  81. package/dist/layout/index.js +5 -0
  82. package/dist/layout/layers.d.ts +13 -0
  83. package/dist/layout/layers.js +49 -0
  84. package/dist/layout/layout-engine.d.ts +21 -0
  85. package/dist/layout/layout-engine.js +191 -0
  86. package/dist/layout/overlap.d.ts +10 -0
  87. package/dist/layout/overlap.js +70 -0
  88. package/dist/layout/routing.d.ts +26 -0
  89. package/dist/layout/routing.js +439 -0
  90. package/dist/layout/subprocess.d.ts +14 -0
  91. package/dist/layout/subprocess.js +77 -0
  92. package/dist/layout/types.d.ts +72 -0
  93. package/dist/layout/types.js +37 -0
  94. package/dist/types/id-generator.d.ts +8 -0
  95. package/dist/types/id-generator.js +31 -0
  96. package/dist/types/index.d.ts +3 -0
  97. package/dist/types/index.js +2 -0
  98. package/dist/types/xml-element.d.ts +12 -0
  99. package/dist/types/xml-element.js +2 -0
  100. package/dist/xml/index.d.ts +2 -0
  101. package/dist/xml/index.js +2 -0
  102. package/dist/xml/xml-parser.d.ts +13 -0
  103. package/dist/xml/xml-parser.js +271 -0
  104. package/package.json +38 -0
@@ -0,0 +1,642 @@
1
+ import { ParseError } from "../errors.js";
2
+ import { parseXml } from "../xml/xml-parser.js";
3
+ // ---------------------------------------------------------------------------
4
+ // Helpers
5
+ // ---------------------------------------------------------------------------
6
+ function localName(name) {
7
+ const idx = name.indexOf(":");
8
+ return idx >= 0 ? name.slice(idx + 1) : name;
9
+ }
10
+ function findChildren(element, tagLocalName) {
11
+ return element.children.filter((c) => localName(c.name) === tagLocalName);
12
+ }
13
+ function findChild(element, tagLocalName) {
14
+ return element.children.find((c) => localName(c.name) === tagLocalName);
15
+ }
16
+ function attr(element, name) {
17
+ if (element.attributes[name] !== undefined)
18
+ return element.attributes[name];
19
+ for (const [key, value] of Object.entries(element.attributes)) {
20
+ if (localName(key) === name)
21
+ return value;
22
+ }
23
+ return undefined;
24
+ }
25
+ function requiredAttr(element, name) {
26
+ const value = attr(element, name);
27
+ if (value === undefined) {
28
+ throw new ParseError(`Missing required attribute "${name}" on <${element.name}>`);
29
+ }
30
+ return value;
31
+ }
32
+ /** Collect text from child <bpmn:incoming> / <bpmn:outgoing> elements. */
33
+ function collectFlowRefs(element, tag) {
34
+ return findChildren(element, tag)
35
+ .map((c) => c.text?.trim())
36
+ .filter((t) => !!t);
37
+ }
38
+ /** Known attribute names on flow nodes — everything else goes to unknownAttributes. */
39
+ const KNOWN_ATTRS = new Set([
40
+ "id",
41
+ "name",
42
+ "default",
43
+ "attachedToRef",
44
+ "cancelActivity",
45
+ "sourceRef",
46
+ "targetRef",
47
+ "associationDirection",
48
+ "isExecutable",
49
+ "isMarkerVisible",
50
+ "isExpanded",
51
+ "isHorizontal",
52
+ "bpmnElement",
53
+ "errorRef",
54
+ "escalationRef",
55
+ "errorCode",
56
+ "escalationCode",
57
+ "targetNamespace",
58
+ "exporter",
59
+ "exporterVersion",
60
+ "processRef",
61
+ ]);
62
+ /** Extract unknown (namespace-qualified) attributes from an element. */
63
+ function unknownAttrs(element) {
64
+ const result = {};
65
+ for (const [key, value] of Object.entries(element.attributes)) {
66
+ if (key.startsWith("xmlns:") || key === "xmlns")
67
+ continue;
68
+ if (KNOWN_ATTRS.has(key))
69
+ continue;
70
+ if (KNOWN_ATTRS.has(localName(key)))
71
+ continue;
72
+ result[key] = value;
73
+ }
74
+ return result;
75
+ }
76
+ /** Known child local names for flow nodes — anything else is an extension. */
77
+ const KNOWN_FLOW_CHILDREN = new Set([
78
+ "incoming",
79
+ "outgoing",
80
+ "documentation",
81
+ "extensionElements",
82
+ "conditionExpression",
83
+ "timerEventDefinition",
84
+ "errorEventDefinition",
85
+ "escalationEventDefinition",
86
+ "messageEventDefinition",
87
+ "signalEventDefinition",
88
+ "conditionalEventDefinition",
89
+ "linkEventDefinition",
90
+ "cancelEventDefinition",
91
+ "terminateEventDefinition",
92
+ "compensateEventDefinition",
93
+ "multiInstanceLoopCharacteristics",
94
+ // Sub-process children are handled separately
95
+ ]);
96
+ const KNOWN_PROCESS_CHILDREN = new Set([
97
+ "startEvent",
98
+ "endEvent",
99
+ "intermediateCatchEvent",
100
+ "intermediateThrowEvent",
101
+ "boundaryEvent",
102
+ "task",
103
+ "serviceTask",
104
+ "scriptTask",
105
+ "userTask",
106
+ "sendTask",
107
+ "receiveTask",
108
+ "businessRuleTask",
109
+ "manualTask",
110
+ "callActivity",
111
+ "subProcess",
112
+ "adHocSubProcess",
113
+ "eventSubProcess",
114
+ "transaction",
115
+ "exclusiveGateway",
116
+ "parallelGateway",
117
+ "inclusiveGateway",
118
+ "eventBasedGateway",
119
+ "complexGateway",
120
+ "sequenceFlow",
121
+ "textAnnotation",
122
+ "association",
123
+ "laneSet",
124
+ "extensionElements",
125
+ ]);
126
+ // ---------------------------------------------------------------------------
127
+ // Extension elements
128
+ // ---------------------------------------------------------------------------
129
+ function parseExtensionElements(element) {
130
+ const ext = findChild(element, "extensionElements");
131
+ return ext ? ext.children : [];
132
+ }
133
+ // ---------------------------------------------------------------------------
134
+ // Event definitions
135
+ // ---------------------------------------------------------------------------
136
+ function parseEventDefinitions(element) {
137
+ const defs = [];
138
+ for (const child of element.children) {
139
+ const ln = localName(child.name);
140
+ if (ln === "timerEventDefinition") {
141
+ const durationEl = findChild(child, "timeDuration");
142
+ const dateEl = findChild(child, "timeDate");
143
+ const cycleEl = findChild(child, "timeCycle");
144
+ defs.push({
145
+ type: "timer",
146
+ id: attr(child, "id"),
147
+ timeDuration: durationEl?.text?.trim(),
148
+ timeDurationAttributes: durationEl
149
+ ? Object.keys(durationEl.attributes).length > 0
150
+ ? { ...durationEl.attributes }
151
+ : undefined
152
+ : undefined,
153
+ timeDate: dateEl?.text?.trim(),
154
+ timeDateAttributes: dateEl
155
+ ? Object.keys(dateEl.attributes).length > 0
156
+ ? { ...dateEl.attributes }
157
+ : undefined
158
+ : undefined,
159
+ timeCycle: cycleEl?.text?.trim(),
160
+ timeCycleAttributes: cycleEl
161
+ ? Object.keys(cycleEl.attributes).length > 0
162
+ ? { ...cycleEl.attributes }
163
+ : undefined
164
+ : undefined,
165
+ });
166
+ }
167
+ else if (ln === "errorEventDefinition") {
168
+ defs.push({
169
+ type: "error",
170
+ id: attr(child, "id"),
171
+ errorRef: attr(child, "errorRef"),
172
+ });
173
+ }
174
+ else if (ln === "escalationEventDefinition") {
175
+ defs.push({
176
+ type: "escalation",
177
+ id: attr(child, "id"),
178
+ escalationRef: attr(child, "escalationRef"),
179
+ });
180
+ }
181
+ else if (ln === "messageEventDefinition") {
182
+ defs.push({
183
+ type: "message",
184
+ id: attr(child, "id"),
185
+ messageRef: attr(child, "messageRef"),
186
+ });
187
+ }
188
+ else if (ln === "signalEventDefinition") {
189
+ defs.push({
190
+ type: "signal",
191
+ id: attr(child, "id"),
192
+ signalRef: attr(child, "signalRef"),
193
+ });
194
+ }
195
+ else if (ln === "conditionalEventDefinition") {
196
+ const condEl = findChild(child, "condition");
197
+ defs.push({
198
+ type: "conditional",
199
+ id: attr(child, "id"),
200
+ condition: condEl?.text?.trim(),
201
+ });
202
+ }
203
+ else if (ln === "linkEventDefinition") {
204
+ defs.push({
205
+ type: "link",
206
+ id: attr(child, "id"),
207
+ name: attr(child, "name"),
208
+ });
209
+ }
210
+ else if (ln === "cancelEventDefinition") {
211
+ defs.push({ type: "cancel", id: attr(child, "id") });
212
+ }
213
+ else if (ln === "terminateEventDefinition") {
214
+ defs.push({ type: "terminate", id: attr(child, "id") });
215
+ }
216
+ else if (ln === "compensateEventDefinition") {
217
+ defs.push({
218
+ type: "compensate",
219
+ id: attr(child, "id"),
220
+ activityRef: attr(child, "activityRef"),
221
+ });
222
+ }
223
+ }
224
+ return defs;
225
+ }
226
+ // ---------------------------------------------------------------------------
227
+ // Multi-instance loop
228
+ // ---------------------------------------------------------------------------
229
+ function parseLoopCharacteristics(element) {
230
+ const loopEl = findChild(element, "multiInstanceLoopCharacteristics");
231
+ if (!loopEl)
232
+ return undefined;
233
+ return { extensionElements: parseExtensionElements(loopEl) };
234
+ }
235
+ // ---------------------------------------------------------------------------
236
+ // Flow elements
237
+ // ---------------------------------------------------------------------------
238
+ const FLOW_ELEMENT_TYPES = new Set([
239
+ "startEvent",
240
+ "endEvent",
241
+ "intermediateCatchEvent",
242
+ "intermediateThrowEvent",
243
+ "boundaryEvent",
244
+ "task",
245
+ "serviceTask",
246
+ "scriptTask",
247
+ "userTask",
248
+ "sendTask",
249
+ "receiveTask",
250
+ "businessRuleTask",
251
+ "manualTask",
252
+ "callActivity",
253
+ "subProcess",
254
+ "adHocSubProcess",
255
+ "eventSubProcess",
256
+ "transaction",
257
+ "exclusiveGateway",
258
+ "parallelGateway",
259
+ "inclusiveGateway",
260
+ "eventBasedGateway",
261
+ "complexGateway",
262
+ ]);
263
+ function parseFlowElement(element) {
264
+ const ln = localName(element.name);
265
+ if (!FLOW_ELEMENT_TYPES.has(ln))
266
+ return undefined;
267
+ const base = {
268
+ id: requiredAttr(element, "id"),
269
+ name: attr(element, "name"),
270
+ incoming: collectFlowRefs(element, "incoming"),
271
+ outgoing: collectFlowRefs(element, "outgoing"),
272
+ documentation: findChild(element, "documentation")?.text,
273
+ extensionElements: parseExtensionElements(element),
274
+ unknownAttributes: unknownAttrs(element),
275
+ };
276
+ switch (ln) {
277
+ case "startEvent":
278
+ case "endEvent":
279
+ case "intermediateCatchEvent":
280
+ case "intermediateThrowEvent":
281
+ return { ...base, type: ln, eventDefinitions: parseEventDefinitions(element) };
282
+ case "boundaryEvent":
283
+ return {
284
+ ...base,
285
+ type: "boundaryEvent",
286
+ attachedToRef: requiredAttr(element, "attachedToRef"),
287
+ cancelActivity: attr(element, "cancelActivity") !== undefined
288
+ ? attr(element, "cancelActivity") === "true"
289
+ : undefined,
290
+ eventDefinitions: parseEventDefinitions(element),
291
+ };
292
+ case "task":
293
+ case "serviceTask":
294
+ case "scriptTask":
295
+ case "userTask":
296
+ case "sendTask":
297
+ case "receiveTask":
298
+ case "businessRuleTask":
299
+ case "manualTask":
300
+ case "callActivity":
301
+ return { ...base, type: ln, loopCharacteristics: parseLoopCharacteristics(element) };
302
+ case "adHocSubProcess":
303
+ return {
304
+ ...base,
305
+ type: "adHocSubProcess",
306
+ loopCharacteristics: parseLoopCharacteristics(element),
307
+ ...parseProcessContents(element),
308
+ };
309
+ case "subProcess":
310
+ return {
311
+ ...base,
312
+ type: "subProcess",
313
+ triggeredByEvent: attr(element, "triggeredByEvent") !== undefined
314
+ ? attr(element, "triggeredByEvent") === "true"
315
+ : undefined,
316
+ loopCharacteristics: parseLoopCharacteristics(element),
317
+ ...parseProcessContents(element),
318
+ };
319
+ case "eventSubProcess":
320
+ return {
321
+ ...base,
322
+ type: "eventSubProcess",
323
+ ...parseProcessContents(element),
324
+ };
325
+ case "transaction":
326
+ return {
327
+ ...base,
328
+ type: "transaction",
329
+ loopCharacteristics: parseLoopCharacteristics(element),
330
+ ...parseProcessContents(element),
331
+ };
332
+ case "exclusiveGateway":
333
+ return { ...base, type: "exclusiveGateway", default: attr(element, "default") };
334
+ case "parallelGateway":
335
+ return { ...base, type: "parallelGateway" };
336
+ case "inclusiveGateway":
337
+ return { ...base, type: "inclusiveGateway", default: attr(element, "default") };
338
+ case "eventBasedGateway":
339
+ return { ...base, type: "eventBasedGateway" };
340
+ case "complexGateway":
341
+ return { ...base, type: "complexGateway", default: attr(element, "default") };
342
+ default:
343
+ return undefined;
344
+ }
345
+ }
346
+ // ---------------------------------------------------------------------------
347
+ // Sequence flows
348
+ // ---------------------------------------------------------------------------
349
+ function parseSequenceFlow(element) {
350
+ const condEl = findChild(element, "conditionExpression");
351
+ let conditionExpression;
352
+ if (condEl) {
353
+ conditionExpression = {
354
+ text: condEl.text ?? "",
355
+ attributes: { ...condEl.attributes },
356
+ };
357
+ }
358
+ return {
359
+ id: requiredAttr(element, "id"),
360
+ name: attr(element, "name"),
361
+ sourceRef: requiredAttr(element, "sourceRef"),
362
+ targetRef: requiredAttr(element, "targetRef"),
363
+ conditionExpression,
364
+ extensionElements: parseExtensionElements(element),
365
+ unknownAttributes: unknownAttrs(element),
366
+ };
367
+ }
368
+ // ---------------------------------------------------------------------------
369
+ // Annotations
370
+ // ---------------------------------------------------------------------------
371
+ function parseTextAnnotation(element) {
372
+ const textEl = findChild(element, "text");
373
+ return {
374
+ id: requiredAttr(element, "id"),
375
+ text: textEl?.text,
376
+ unknownAttributes: unknownAttrs(element),
377
+ };
378
+ }
379
+ function parseAssociation(element) {
380
+ return {
381
+ id: requiredAttr(element, "id"),
382
+ sourceRef: requiredAttr(element, "sourceRef"),
383
+ targetRef: requiredAttr(element, "targetRef"),
384
+ associationDirection: attr(element, "associationDirection"),
385
+ unknownAttributes: unknownAttrs(element),
386
+ };
387
+ }
388
+ // ---------------------------------------------------------------------------
389
+ // Process contents (shared between process and adHocSubProcess)
390
+ // ---------------------------------------------------------------------------
391
+ function parseProcessContents(element) {
392
+ const flowElements = [];
393
+ const sequenceFlows = [];
394
+ const textAnnotations = [];
395
+ const associations = [];
396
+ for (const child of element.children) {
397
+ const ln = localName(child.name);
398
+ if (FLOW_ELEMENT_TYPES.has(ln)) {
399
+ const fe = parseFlowElement(child);
400
+ if (fe)
401
+ flowElements.push(fe);
402
+ }
403
+ else if (ln === "sequenceFlow") {
404
+ sequenceFlows.push(parseSequenceFlow(child));
405
+ }
406
+ else if (ln === "textAnnotation") {
407
+ textAnnotations.push(parseTextAnnotation(child));
408
+ }
409
+ else if (ln === "association") {
410
+ associations.push(parseAssociation(child));
411
+ }
412
+ }
413
+ return { flowElements, sequenceFlows, textAnnotations, associations };
414
+ }
415
+ // ---------------------------------------------------------------------------
416
+ // Lanes
417
+ // ---------------------------------------------------------------------------
418
+ function parseLane(element) {
419
+ const flowNodeRefs = findChildren(element, "flowNodeRef")
420
+ .map((c) => c.text?.trim())
421
+ .filter((t) => !!t);
422
+ const childLaneSetEl = findChild(element, "childLaneSet");
423
+ return {
424
+ id: requiredAttr(element, "id"),
425
+ name: attr(element, "name"),
426
+ flowNodeRefs,
427
+ childLaneSet: childLaneSetEl ? parseLaneSet(childLaneSetEl) : undefined,
428
+ unknownAttributes: unknownAttrs(element),
429
+ };
430
+ }
431
+ function parseLaneSet(element) {
432
+ return {
433
+ id: attr(element, "id"),
434
+ lanes: findChildren(element, "lane").map(parseLane),
435
+ };
436
+ }
437
+ // ---------------------------------------------------------------------------
438
+ // Process
439
+ // ---------------------------------------------------------------------------
440
+ function parseProcess(element) {
441
+ const laneSetEl = findChild(element, "laneSet");
442
+ return {
443
+ id: requiredAttr(element, "id"),
444
+ name: attr(element, "name"),
445
+ isExecutable: attr(element, "isExecutable") === "true" ? true : undefined,
446
+ extensionElements: parseExtensionElements(element),
447
+ unknownAttributes: unknownAttrs(element),
448
+ laneSet: laneSetEl ? parseLaneSet(laneSetEl) : undefined,
449
+ ...parseProcessContents(element),
450
+ };
451
+ }
452
+ // ---------------------------------------------------------------------------
453
+ // Collaboration
454
+ // ---------------------------------------------------------------------------
455
+ function parseParticipant(element) {
456
+ return {
457
+ id: requiredAttr(element, "id"),
458
+ name: attr(element, "name"),
459
+ processRef: attr(element, "processRef"),
460
+ unknownAttributes: unknownAttrs(element),
461
+ };
462
+ }
463
+ function parseMessageFlow(element) {
464
+ return {
465
+ id: requiredAttr(element, "id"),
466
+ name: attr(element, "name"),
467
+ sourceRef: requiredAttr(element, "sourceRef"),
468
+ targetRef: requiredAttr(element, "targetRef"),
469
+ unknownAttributes: unknownAttrs(element),
470
+ };
471
+ }
472
+ function parseCollaboration(element) {
473
+ return {
474
+ id: requiredAttr(element, "id"),
475
+ participants: findChildren(element, "participant").map(parseParticipant),
476
+ messageFlows: findChildren(element, "messageFlow").map(parseMessageFlow),
477
+ textAnnotations: findChildren(element, "textAnnotation").map(parseTextAnnotation),
478
+ associations: findChildren(element, "association").map(parseAssociation),
479
+ extensionElements: parseExtensionElements(element),
480
+ unknownAttributes: unknownAttrs(element),
481
+ };
482
+ }
483
+ // ---------------------------------------------------------------------------
484
+ // Root elements
485
+ // ---------------------------------------------------------------------------
486
+ function parseError(element) {
487
+ return {
488
+ id: requiredAttr(element, "id"),
489
+ name: attr(element, "name"),
490
+ errorCode: attr(element, "errorCode"),
491
+ };
492
+ }
493
+ function parseEscalation(element) {
494
+ return {
495
+ id: requiredAttr(element, "id"),
496
+ name: attr(element, "name"),
497
+ escalationCode: attr(element, "escalationCode"),
498
+ };
499
+ }
500
+ function parseMessage(element) {
501
+ return {
502
+ id: requiredAttr(element, "id"),
503
+ name: attr(element, "name"),
504
+ unknownAttributes: unknownAttrs(element),
505
+ };
506
+ }
507
+ // ---------------------------------------------------------------------------
508
+ // Diagram interchange
509
+ // ---------------------------------------------------------------------------
510
+ function parseBounds(element) {
511
+ return {
512
+ x: Number(attr(element, "x") ?? "0"),
513
+ y: Number(attr(element, "y") ?? "0"),
514
+ width: Number(attr(element, "width") ?? "0"),
515
+ height: Number(attr(element, "height") ?? "0"),
516
+ };
517
+ }
518
+ function parseLabel(element) {
519
+ const labelEl = findChild(element, "BPMNLabel");
520
+ if (!labelEl)
521
+ return undefined;
522
+ const boundsEl = findChild(labelEl, "Bounds");
523
+ return { bounds: boundsEl ? parseBounds(boundsEl) : undefined };
524
+ }
525
+ function parseDiShape(element) {
526
+ const boundsEl = findChild(element, "Bounds");
527
+ if (!boundsEl)
528
+ throw new Error(`Missing <dc:Bounds> in shape "${attr(element, "id")}"`);
529
+ return {
530
+ id: requiredAttr(element, "id"),
531
+ bpmnElement: requiredAttr(element, "bpmnElement"),
532
+ isMarkerVisible: attr(element, "isMarkerVisible") !== undefined
533
+ ? attr(element, "isMarkerVisible") === "true"
534
+ : undefined,
535
+ isExpanded: attr(element, "isExpanded") !== undefined
536
+ ? attr(element, "isExpanded") === "true"
537
+ : undefined,
538
+ isHorizontal: attr(element, "isHorizontal") !== undefined
539
+ ? attr(element, "isHorizontal") === "true"
540
+ : undefined,
541
+ bounds: parseBounds(boundsEl),
542
+ label: parseLabel(element),
543
+ unknownAttributes: unknownAttrs(element),
544
+ };
545
+ }
546
+ function parseDiEdge(element) {
547
+ const waypoints = findChildren(element, "waypoint").map((w) => ({
548
+ x: Number(attr(w, "x") ?? "0"),
549
+ y: Number(attr(w, "y") ?? "0"),
550
+ }));
551
+ return {
552
+ id: requiredAttr(element, "id"),
553
+ bpmnElement: requiredAttr(element, "bpmnElement"),
554
+ waypoints,
555
+ label: parseLabel(element),
556
+ unknownAttributes: unknownAttrs(element),
557
+ };
558
+ }
559
+ function parseDiagram(element) {
560
+ const planeEl = findChild(element, "BPMNPlane");
561
+ if (!planeEl)
562
+ throw new Error("Missing <bpmndi:BPMNPlane> in diagram");
563
+ const shapes = [];
564
+ const edges = [];
565
+ for (const child of planeEl.children) {
566
+ const ln = localName(child.name);
567
+ if (ln === "BPMNShape")
568
+ shapes.push(parseDiShape(child));
569
+ else if (ln === "BPMNEdge")
570
+ edges.push(parseDiEdge(child));
571
+ }
572
+ return {
573
+ id: requiredAttr(element, "id"),
574
+ plane: {
575
+ id: requiredAttr(planeEl, "id"),
576
+ bpmnElement: requiredAttr(planeEl, "bpmnElement"),
577
+ shapes,
578
+ edges,
579
+ },
580
+ };
581
+ }
582
+ // ---------------------------------------------------------------------------
583
+ // Public API
584
+ // ---------------------------------------------------------------------------
585
+ /** Parse a BPMN XML string into a typed BpmnDefinitions model. */
586
+ export function parseBpmn(xml) {
587
+ const root = parseXml(xml);
588
+ if (localName(root.name) !== "definitions") {
589
+ throw new Error(`Expected <definitions> root element, got <${root.name}>`);
590
+ }
591
+ const namespaces = {};
592
+ const unknownAttributes = {};
593
+ for (const [key, value] of Object.entries(root.attributes)) {
594
+ if (key.startsWith("xmlns:")) {
595
+ namespaces[key.slice(6)] = value;
596
+ }
597
+ else if (key === "xmlns") {
598
+ namespaces[""] = value;
599
+ }
600
+ else if (KNOWN_ATTRS.has(key)) {
601
+ }
602
+ else {
603
+ unknownAttributes[key] = value;
604
+ }
605
+ }
606
+ const errors = [];
607
+ const escalations = [];
608
+ const messages = [];
609
+ const collaborations = [];
610
+ const processes = [];
611
+ const diagrams = [];
612
+ for (const child of root.children) {
613
+ const ln = localName(child.name);
614
+ if (ln === "error")
615
+ errors.push(parseError(child));
616
+ else if (ln === "escalation")
617
+ escalations.push(parseEscalation(child));
618
+ else if (ln === "message")
619
+ messages.push(parseMessage(child));
620
+ else if (ln === "collaboration")
621
+ collaborations.push(parseCollaboration(child));
622
+ else if (ln === "process")
623
+ processes.push(parseProcess(child));
624
+ else if (ln === "BPMNDiagram")
625
+ diagrams.push(parseDiagram(child));
626
+ }
627
+ return {
628
+ id: requiredAttr(root, "id"),
629
+ targetNamespace: requiredAttr(root, "targetNamespace"),
630
+ exporter: attr(root, "exporter"),
631
+ exporterVersion: attr(root, "exporterVersion"),
632
+ namespaces,
633
+ unknownAttributes,
634
+ errors,
635
+ escalations,
636
+ messages,
637
+ collaborations,
638
+ processes,
639
+ diagrams,
640
+ };
641
+ }
642
+ //# sourceMappingURL=bpmn-parser.js.map
@@ -0,0 +1,4 @@
1
+ import type { BpmnDefinitions } from "./bpmn-model.js";
2
+ /** Serialize a BpmnDefinitions model to a BPMN XML string. */
3
+ export declare function serializeBpmn(definitions: BpmnDefinitions): string;
4
+ //# sourceMappingURL=bpmn-serializer.d.ts.map