@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,72 @@
1
+ import type { XmlElement } from "../types/xml-element.js";
2
+ /** Zeebe task definition extension. */
3
+ export interface ZeebeTaskDefinition {
4
+ type: string;
5
+ retries?: string;
6
+ }
7
+ /** A single Zeebe IO mapping entry. */
8
+ export interface ZeebeIoMappingEntry {
9
+ source: string;
10
+ target: string;
11
+ }
12
+ /** Zeebe IO mapping extension. */
13
+ export interface ZeebeIoMapping {
14
+ inputs: ZeebeIoMappingEntry[];
15
+ outputs: ZeebeIoMappingEntry[];
16
+ }
17
+ /** A single Zeebe task header entry. */
18
+ export interface ZeebeTaskHeaderEntry {
19
+ key: string;
20
+ value: string;
21
+ }
22
+ /** Zeebe task headers extension. */
23
+ export interface ZeebeTaskHeaders {
24
+ headers: ZeebeTaskHeaderEntry[];
25
+ }
26
+ /** A single Zeebe property entry. */
27
+ export interface ZeebePropertyEntry {
28
+ name: string;
29
+ value: string;
30
+ }
31
+ /** Zeebe properties extension. */
32
+ export interface ZeebeProperties {
33
+ properties: ZeebePropertyEntry[];
34
+ }
35
+ /** Zeebe ad-hoc sub-process extension (AI Agent job worker pattern). */
36
+ export interface ZeebeAdHoc {
37
+ /** Variable name that collects tool call results from child tasks. */
38
+ outputCollection?: string;
39
+ /** FEEL expression mapping each child task's result into the collection. */
40
+ outputElement?: string;
41
+ /** FEEL expression selecting which child element IDs to activate (BPMN-native mode). */
42
+ activeElementsCollection?: string;
43
+ }
44
+ /** Zeebe form definition extension for user tasks. */
45
+ export interface ZeebeFormDefinition {
46
+ /** ID of the Camunda Form linked to this user task. */
47
+ formId: string;
48
+ }
49
+ /** Zeebe called decision extension for business rule tasks. */
50
+ export interface ZeebeCalledDecision {
51
+ /** ID of the DMN decision to invoke. */
52
+ decisionId: string;
53
+ /** Process variable that receives the decision result. */
54
+ resultVariable: string;
55
+ }
56
+ /** Collected Zeebe extensions on a service task. */
57
+ export interface ZeebeExtensions {
58
+ taskDefinition?: ZeebeTaskDefinition;
59
+ ioMapping?: ZeebeIoMapping;
60
+ taskHeaders?: ZeebeTaskHeaders;
61
+ properties?: ZeebeProperties;
62
+ adHoc?: ZeebeAdHoc;
63
+ /** Camunda Form linked to a user task (zeebe:formDefinition). */
64
+ formDefinition?: ZeebeFormDefinition;
65
+ /** DMN decision invoked by a business rule task (zeebe:calledDecision). */
66
+ calledDecision?: ZeebeCalledDecision;
67
+ /** Unrecognized extension elements preserved for roundtrip. */
68
+ unknownElements?: XmlElement[];
69
+ }
70
+ /** Convert Zeebe extensions to XmlElement array for the BPMN model. */
71
+ export declare function zeebeExtensionsToXmlElements(extensions: ZeebeExtensions): XmlElement[];
72
+ //# sourceMappingURL=zeebe-extensions.d.ts.map
@@ -0,0 +1,96 @@
1
+ /** Convert Zeebe extensions to XmlElement array for the BPMN model. */
2
+ export function zeebeExtensionsToXmlElements(extensions) {
3
+ const elements = [];
4
+ if (extensions.taskDefinition) {
5
+ const attrs = {
6
+ type: extensions.taskDefinition.type,
7
+ };
8
+ if (extensions.taskDefinition.retries !== undefined) {
9
+ attrs.retries = extensions.taskDefinition.retries;
10
+ }
11
+ elements.push({
12
+ name: "zeebe:taskDefinition",
13
+ attributes: attrs,
14
+ children: [],
15
+ });
16
+ }
17
+ if (extensions.ioMapping) {
18
+ const children = [];
19
+ for (const input of extensions.ioMapping.inputs) {
20
+ children.push({
21
+ name: "zeebe:input",
22
+ attributes: { source: input.source, target: input.target },
23
+ children: [],
24
+ });
25
+ }
26
+ for (const output of extensions.ioMapping.outputs) {
27
+ children.push({
28
+ name: "zeebe:output",
29
+ attributes: { source: output.source, target: output.target },
30
+ children: [],
31
+ });
32
+ }
33
+ elements.push({
34
+ name: "zeebe:ioMapping",
35
+ attributes: {},
36
+ children,
37
+ });
38
+ }
39
+ if (extensions.taskHeaders) {
40
+ const children = extensions.taskHeaders.headers.map((header) => ({
41
+ name: "zeebe:header",
42
+ attributes: { key: header.key, value: header.value },
43
+ children: [],
44
+ }));
45
+ elements.push({
46
+ name: "zeebe:taskHeaders",
47
+ attributes: {},
48
+ children,
49
+ });
50
+ }
51
+ if (extensions.properties) {
52
+ const children = extensions.properties.properties.map((prop) => ({
53
+ name: "zeebe:property",
54
+ attributes: { name: prop.name, value: prop.value },
55
+ children: [],
56
+ }));
57
+ elements.push({
58
+ name: "zeebe:properties",
59
+ attributes: {},
60
+ children,
61
+ });
62
+ }
63
+ if (extensions.adHoc) {
64
+ const attrs = {};
65
+ const { outputCollection, outputElement, activeElementsCollection } = extensions.adHoc;
66
+ if (outputCollection)
67
+ attrs.outputCollection = outputCollection;
68
+ if (outputElement)
69
+ attrs.outputElement = outputElement;
70
+ if (activeElementsCollection)
71
+ attrs.activeElementsCollection = activeElementsCollection;
72
+ elements.push({ name: "zeebe:adHoc", attributes: attrs, children: [] });
73
+ }
74
+ if (extensions.formDefinition) {
75
+ elements.push({
76
+ name: "zeebe:formDefinition",
77
+ attributes: { formId: extensions.formDefinition.formId },
78
+ children: [],
79
+ });
80
+ }
81
+ if (extensions.calledDecision) {
82
+ elements.push({
83
+ name: "zeebe:calledDecision",
84
+ attributes: {
85
+ decisionId: extensions.calledDecision.decisionId,
86
+ resultVariable: extensions.calledDecision.resultVariable,
87
+ },
88
+ children: [],
89
+ });
90
+ }
91
+ if (extensions.unknownElements) {
92
+ elements.push(...extensions.unknownElements);
93
+ }
94
+ return elements;
95
+ }
96
+ //# sourceMappingURL=zeebe-extensions.js.map
@@ -0,0 +1,44 @@
1
+ import type { DmnAggregation, DmnDefinitions, DmnTypeRef, HitPolicy } from "./dmn-model.js";
2
+ export interface CompactDmnInput {
3
+ id: string;
4
+ label?: string;
5
+ expression?: string;
6
+ typeRef?: DmnTypeRef;
7
+ }
8
+ export interface CompactDmnOutput {
9
+ id: string;
10
+ label?: string;
11
+ name?: string;
12
+ typeRef?: DmnTypeRef;
13
+ }
14
+ export interface CompactDmnRule {
15
+ id: string;
16
+ inputs: string[];
17
+ outputs: string[];
18
+ description?: string;
19
+ }
20
+ export interface CompactDmnDecision {
21
+ id: string;
22
+ name?: string;
23
+ hitPolicy?: HitPolicy;
24
+ aggregation?: DmnAggregation;
25
+ inputs: CompactDmnInput[];
26
+ outputs: CompactDmnOutput[];
27
+ rules: CompactDmnRule[];
28
+ /** IDs of decisions or inputData this decision requires */
29
+ requires?: string[];
30
+ }
31
+ export interface CompactDmn {
32
+ id: string;
33
+ name: string;
34
+ decisions: CompactDmnDecision[];
35
+ inputData: Array<{
36
+ id: string;
37
+ name?: string;
38
+ }>;
39
+ }
40
+ /** Convert a DmnDefinitions model to a token-efficient CompactDmn representation. */
41
+ export declare function compactifyDmn(defs: DmnDefinitions): CompactDmn;
42
+ /** Convert a CompactDmn back to a full DmnDefinitions model with auto-layout applied. */
43
+ export declare function expandDmn(compact: CompactDmn): DmnDefinitions;
44
+ //# sourceMappingURL=compact.d.ts.map
@@ -0,0 +1,125 @@
1
+ import { generateId } from "../types/id-generator.js";
2
+ import { layoutDmn } from "./dmn-layout.js";
3
+ // ── Compactify ────────────────────────────────────────────────────────────────
4
+ /** Convert a DmnDefinitions model to a token-efficient CompactDmn representation. */
5
+ export function compactifyDmn(defs) {
6
+ const decisions = defs.decisions.map((d) => {
7
+ const requires = [];
8
+ for (const req of d.informationRequirements) {
9
+ const src = req.requiredDecision ?? req.requiredInput;
10
+ if (src)
11
+ requires.push(src);
12
+ }
13
+ const dt = d.decisionTable;
14
+ return {
15
+ id: d.id,
16
+ name: d.name,
17
+ hitPolicy: dt?.hitPolicy,
18
+ aggregation: dt?.aggregation,
19
+ inputs: (dt?.inputs ?? []).map((i) => ({
20
+ id: i.id,
21
+ label: i.label,
22
+ expression: i.inputExpression.text,
23
+ typeRef: i.inputExpression.typeRef,
24
+ })),
25
+ outputs: (dt?.outputs ?? []).map((o) => ({
26
+ id: o.id,
27
+ label: o.label,
28
+ name: o.name,
29
+ typeRef: o.typeRef,
30
+ })),
31
+ rules: (dt?.rules ?? []).map((r) => ({
32
+ id: r.id,
33
+ inputs: r.inputEntries.map((e) => e.text),
34
+ outputs: r.outputEntries.map((e) => e.text),
35
+ description: r.description,
36
+ })),
37
+ requires: requires.length > 0 ? requires : undefined,
38
+ };
39
+ });
40
+ return {
41
+ id: defs.id,
42
+ name: defs.name,
43
+ decisions,
44
+ inputData: defs.inputData.map((d) => ({ id: d.id, name: d.name })),
45
+ };
46
+ }
47
+ // ── Expand ────────────────────────────────────────────────────────────────────
48
+ /** Convert a CompactDmn back to a full DmnDefinitions model with auto-layout applied. */
49
+ export function expandDmn(compact) {
50
+ const inputData = compact.inputData.map((d) => ({ id: d.id, name: d.name }));
51
+ const decisions = compact.decisions.map((cd) => {
52
+ // Build requirement links
53
+ const informationRequirements = (cd.requires ?? []).map((srcId) => ({
54
+ id: generateId("InformationRequirement"),
55
+ requiredDecision: compact.decisions.some((d) => d.id === srcId) ? srcId : undefined,
56
+ requiredInput: compact.inputData.some((d) => d.id === srcId) ? srcId : undefined,
57
+ }));
58
+ // Build decision table
59
+ let decisionTable;
60
+ if (cd.inputs.length > 0 || cd.outputs.length > 0 || cd.rules.length > 0) {
61
+ const inputs = cd.inputs.map((i) => ({
62
+ id: i.id,
63
+ label: i.label,
64
+ inputExpression: {
65
+ id: generateId("inputExpression"),
66
+ typeRef: i.typeRef,
67
+ text: i.expression,
68
+ },
69
+ }));
70
+ const outputs = cd.outputs.map((o) => ({
71
+ id: o.id,
72
+ label: o.label,
73
+ name: o.name,
74
+ typeRef: o.typeRef,
75
+ }));
76
+ const rules = cd.rules.map((r) => ({
77
+ id: r.id,
78
+ description: r.description,
79
+ inputEntries: r.inputs.map((text, idx) => ({
80
+ id: generateId(`inputEntry_${idx}`),
81
+ text,
82
+ })),
83
+ outputEntries: r.outputs.map((text, idx) => ({
84
+ id: generateId(`outputEntry_${idx}`),
85
+ text,
86
+ })),
87
+ }));
88
+ decisionTable = {
89
+ id: generateId("decisionTable"),
90
+ hitPolicy: cd.hitPolicy,
91
+ aggregation: cd.aggregation,
92
+ inputs,
93
+ outputs,
94
+ rules,
95
+ };
96
+ }
97
+ return {
98
+ id: cd.id,
99
+ name: cd.name,
100
+ decisionTable,
101
+ informationRequirements,
102
+ knowledgeRequirements: [],
103
+ authorityRequirements: [],
104
+ };
105
+ });
106
+ const defs = {
107
+ id: compact.id,
108
+ name: compact.name,
109
+ namespace: "http://bpmn.io/schema/dmn",
110
+ namespaces: {
111
+ "": "https://www.omg.org/spec/DMN/20191111/MODEL/",
112
+ dmndi: "https://www.omg.org/spec/DMN/20191111/DMNDI/",
113
+ dc: "http://www.omg.org/spec/DMN/20180521/DC/",
114
+ },
115
+ modelerAttributes: {},
116
+ decisions,
117
+ inputData,
118
+ knowledgeSources: [],
119
+ businessKnowledgeModels: [],
120
+ textAnnotations: [],
121
+ associations: [],
122
+ };
123
+ return layoutDmn(defs);
124
+ }
125
+ //# sourceMappingURL=compact.js.map
@@ -0,0 +1,59 @@
1
+ import type { DmnDefinitions, DmnTypeRef, HitPolicy } from "./dmn-model.js";
2
+ /** Options for creating a decision table input column. */
3
+ export interface InputOptions {
4
+ /** Display label for the input column. */
5
+ label?: string;
6
+ /** FEEL expression for the input (e.g., variable name). */
7
+ expression: string;
8
+ /** Data type of the input. */
9
+ typeRef?: DmnTypeRef;
10
+ }
11
+ /** Options for creating a decision table output column. */
12
+ export interface OutputOptions {
13
+ /** Display label for the output column. */
14
+ label?: string;
15
+ /** Variable name for the output. */
16
+ name: string;
17
+ /** Data type of the output. */
18
+ typeRef?: DmnTypeRef;
19
+ }
20
+ /** Options for creating a decision table rule (row). */
21
+ export interface RuleOptions {
22
+ /** Human-readable description/annotation for this rule. */
23
+ description?: string;
24
+ /** Input entry values (unary tests), one per input column. */
25
+ inputs: string[];
26
+ /** Output entry values (literal expressions), one per output column. */
27
+ outputs: string[];
28
+ }
29
+ /** Fluent builder for constructing DMN decision tables. */
30
+ export declare class DecisionTableBuilder {
31
+ private readonly decisionId;
32
+ private decisionName;
33
+ private tableId;
34
+ private hitPolicyValue;
35
+ private readonly inputColumns;
36
+ private readonly outputColumns;
37
+ private readonly ruleRows;
38
+ constructor(decisionId: string);
39
+ /** Set the display name for this decision. */
40
+ name(name: string): this;
41
+ /** Set the hit policy for this decision table. */
42
+ hitPolicy(policy: HitPolicy): this;
43
+ /** Add an input column to the decision table. */
44
+ input(options: InputOptions): this;
45
+ /** Add an output column to the decision table. */
46
+ output(options: OutputOptions): this;
47
+ /**
48
+ * Add a rule (row) to the decision table.
49
+ *
50
+ * @throws {ValidationError} If the number of input or output values does not
51
+ * match the number of columns declared with `.input()` / `.output()`.
52
+ */
53
+ rule(options: RuleOptions): this;
54
+ /** Build the DMN definitions model. */
55
+ build(): DmnDefinitions;
56
+ /** Build and export as DMN XML string. */
57
+ toXml(): string;
58
+ }
59
+ //# sourceMappingURL=dmn-builder.d.ts.map
@@ -0,0 +1,144 @@
1
+ import { ValidationError } from "../errors.js";
2
+ import { generateId } from "../types/id-generator.js";
3
+ import { serializeDmn } from "./dmn-serializer.js";
4
+ const DMN_MODEL_NS = "https://www.omg.org/spec/DMN/20191111/MODEL/";
5
+ const DMN_DI_NS = "https://www.omg.org/spec/DMN/20191111/DMNDI/";
6
+ const DC_NS = "http://www.omg.org/spec/DMN/20180521/DC/";
7
+ const MODELER_NS = "http://camunda.org/schema/modeler/1.0";
8
+ const DEFAULT_NAMESPACE = "http://camunda.org/schema/1.0/dmn";
9
+ /** Fluent builder for constructing DMN decision tables. */
10
+ export class DecisionTableBuilder {
11
+ decisionId;
12
+ decisionName;
13
+ tableId;
14
+ hitPolicyValue = "UNIQUE";
15
+ inputColumns = [];
16
+ outputColumns = [];
17
+ ruleRows = [];
18
+ constructor(decisionId) {
19
+ this.decisionId = decisionId;
20
+ this.decisionName = decisionId;
21
+ this.tableId = generateId("DecisionTable");
22
+ }
23
+ /** Set the display name for this decision. */
24
+ name(name) {
25
+ this.decisionName = name;
26
+ return this;
27
+ }
28
+ /** Set the hit policy for this decision table. */
29
+ hitPolicy(policy) {
30
+ this.hitPolicyValue = policy;
31
+ return this;
32
+ }
33
+ /** Add an input column to the decision table. */
34
+ input(options) {
35
+ const inputId = generateId("Input");
36
+ const exprId = generateId("InputExpression");
37
+ this.inputColumns.push({
38
+ id: inputId,
39
+ label: options.label,
40
+ inputExpression: {
41
+ id: exprId,
42
+ typeRef: options.typeRef,
43
+ text: options.expression,
44
+ },
45
+ });
46
+ return this;
47
+ }
48
+ /** Add an output column to the decision table. */
49
+ output(options) {
50
+ const outputId = generateId("Output");
51
+ this.outputColumns.push({
52
+ id: outputId,
53
+ label: options.label,
54
+ name: options.name,
55
+ typeRef: options.typeRef,
56
+ });
57
+ return this;
58
+ }
59
+ /**
60
+ * Add a rule (row) to the decision table.
61
+ *
62
+ * @throws {ValidationError} If the number of input or output values does not
63
+ * match the number of columns declared with `.input()` / `.output()`.
64
+ */
65
+ rule(options) {
66
+ if (options.inputs.length !== this.inputColumns.length) {
67
+ throw new ValidationError(`Rule has ${options.inputs.length} inputs but table has ${this.inputColumns.length} input columns`);
68
+ }
69
+ if (options.outputs.length !== this.outputColumns.length) {
70
+ throw new ValidationError(`Rule has ${options.outputs.length} outputs but table has ${this.outputColumns.length} output columns`);
71
+ }
72
+ const inputEntries = options.inputs.map((text) => ({
73
+ id: generateId("UnaryTests"),
74
+ text,
75
+ }));
76
+ const outputEntries = options.outputs.map((text) => ({
77
+ id: generateId("LiteralExpression"),
78
+ text,
79
+ }));
80
+ this.ruleRows.push({
81
+ id: generateId("DecisionRule"),
82
+ description: options.description,
83
+ inputEntries,
84
+ outputEntries,
85
+ });
86
+ return this;
87
+ }
88
+ /** Build the DMN definitions model. */
89
+ build() {
90
+ const decisionTable = {
91
+ id: this.tableId,
92
+ hitPolicy: this.hitPolicyValue === "UNIQUE" ? undefined : this.hitPolicyValue,
93
+ inputs: this.inputColumns,
94
+ outputs: this.outputColumns,
95
+ rules: this.ruleRows,
96
+ };
97
+ const decision = {
98
+ id: this.decisionId,
99
+ name: this.decisionName,
100
+ decisionTable,
101
+ informationRequirements: [],
102
+ knowledgeRequirements: [],
103
+ authorityRequirements: [],
104
+ };
105
+ const diagram = {
106
+ shapes: [
107
+ {
108
+ dmnElementRef: this.decisionId,
109
+ bounds: { x: 160, y: 100, width: 180, height: 80 },
110
+ },
111
+ ],
112
+ edges: [],
113
+ };
114
+ return {
115
+ id: generateId("Definitions"),
116
+ name: "DRD",
117
+ namespace: DEFAULT_NAMESPACE,
118
+ exporter: "bpmn-sdk",
119
+ exporterVersion: "0.0.1",
120
+ namespaces: {
121
+ "": DMN_MODEL_NS,
122
+ dmndi: DMN_DI_NS,
123
+ dc: DC_NS,
124
+ modeler: MODELER_NS,
125
+ },
126
+ modelerAttributes: {
127
+ executionPlatform: "Camunda Cloud",
128
+ executionPlatformVersion: "8.5.0",
129
+ },
130
+ decisions: [decision],
131
+ inputData: [],
132
+ knowledgeSources: [],
133
+ businessKnowledgeModels: [],
134
+ textAnnotations: [],
135
+ associations: [],
136
+ diagram,
137
+ };
138
+ }
139
+ /** Build and export as DMN XML string. */
140
+ toXml() {
141
+ return serializeDmn(this.build());
142
+ }
143
+ }
144
+ //# sourceMappingURL=dmn-builder.js.map
@@ -0,0 +1,57 @@
1
+ import type { DmnDefinitions } from "./dmn-model.js";
2
+ declare const SIZES: {
3
+ readonly decision: {
4
+ readonly width: 180;
5
+ readonly height: 80;
6
+ };
7
+ readonly inputData: {
8
+ readonly width: 125;
9
+ readonly height: 45;
10
+ };
11
+ readonly knowledgeSource: {
12
+ readonly width: 100;
13
+ readonly height: 63;
14
+ };
15
+ readonly businessKnowledgeModel: {
16
+ readonly width: 160;
17
+ readonly height: 80;
18
+ };
19
+ };
20
+ type NodeKind = keyof typeof SIZES;
21
+ /**
22
+ * Auto-layout a DMN definitions object.
23
+ * Assigns DMNDI diagram positions to all DRG elements using a left-to-right
24
+ * layered layout based on the requirement DAG.
25
+ */
26
+ export declare function layoutDmn(defs: DmnDefinitions): DmnDefinitions;
27
+ export interface DmnElementPosition {
28
+ id: string;
29
+ name?: string;
30
+ kind: NodeKind;
31
+ ref: {
32
+ cx: number;
33
+ cy: number;
34
+ };
35
+ auto: {
36
+ cx: number;
37
+ cy: number;
38
+ };
39
+ delta: {
40
+ dx: number;
41
+ dy: number;
42
+ };
43
+ distance: number;
44
+ }
45
+ export interface DmnBenchmarkResult {
46
+ fileName: string;
47
+ elementCount: number;
48
+ matchedCount: number;
49
+ avgDistance: number;
50
+ p90Distance: number;
51
+ maxDistance: number;
52
+ elements: DmnElementPosition[];
53
+ }
54
+ /** Parse the reference layout, strip DMNDI, run auto-layout, and compare. */
55
+ export declare function benchmarkDmnLayout(xml: string, fileName: string): DmnBenchmarkResult;
56
+ export {};
57
+ //# sourceMappingURL=dmn-layout.d.ts.map