-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathbpmn-interop.zod.ts
More file actions
189 lines (148 loc) · 8.6 KB
/
Copy pathbpmn-interop.zod.ts
File metadata and controls
189 lines (148 loc) · 8.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
/**
* @module automation/bpmn-interop
*
* BPMN XML Interoperability Protocol
*
* Defines the specification for importing and exporting BPMN 2.0 XML
* process definitions. This enables interoperability with external BPM
* tools (Camunda, Activiti, jBPM, etc.) via a plugin-based approach.
*
* **Priority:** Low — long-term planning, not a core requirement.
*/
import { z } from 'zod';
// ─── BPMN Element Mapping ────────────────────────────────────────────
/**
* Mapping between a BPMN XML element type and an ObjectStack FlowNodeAction.
* Used during import/export to translate between the two models.
*/
import { lazySchema } from '../shared/lazy-schema';
export const BpmnElementMappingSchema = lazySchema(() => z.object({
/** BPMN XML element type (e.g., "bpmn:parallelGateway", "bpmn:serviceTask") */
bpmnType: z.string().describe('BPMN XML element type (e.g., "bpmn:parallelGateway")'),
/** Corresponding ObjectStack FlowNodeAction */
flowNodeAction: z.string().describe('ObjectStack FlowNodeAction value'),
/** Whether this mapping is bidirectional (supports both import and export) */
bidirectional: z.boolean().default(true).describe('Whether the mapping supports both import and export'),
/** Notes about mapping limitations or special handling */
notes: z.string().optional().describe('Notes about mapping limitations'),
}).describe('Mapping between BPMN XML element and ObjectStack FlowNodeAction'));
export type BpmnElementMapping = z.infer<typeof BpmnElementMappingSchema>;
// ─── BPMN Import Options ─────────────────────────────────────────────
/**
* Strategy for handling BPMN elements that have no direct ObjectStack mapping.
*/
export const BpmnUnmappedStrategySchema = lazySchema(() => z.enum([
'skip', // Skip unmapped elements silently
'warn', // Import with warnings
'error', // Fail on unmapped elements
'comment', // Import as annotation/comment nodes
]).describe('Strategy for unmapped BPMN elements during import'));
export type BpmnUnmappedStrategy = z.infer<typeof BpmnUnmappedStrategySchema>;
/**
* Options for importing a BPMN 2.0 XML process definition into an ObjectStack flow.
*/
export const BpmnImportOptionsSchema = lazySchema(() => z.object({
/** Strategy for unmapped BPMN elements */
unmappedStrategy: BpmnUnmappedStrategySchema.default('warn')
.describe('How to handle unmapped BPMN elements'),
/** Custom element mappings (override or extend built-in mappings) */
customMappings: z.array(BpmnElementMappingSchema).optional()
.describe('Custom element mappings to override or extend defaults'),
/** Whether to import BPMN DI (diagram interchange) layout positions */
importLayout: z.boolean().default(true)
.describe('Import BPMN DI layout positions into canvas node coordinates'),
/** Whether to import BPMN documentation as node descriptions */
importDocumentation: z.boolean().default(true)
.describe('Import BPMN documentation elements as node descriptions'),
/** Target flow name (if not derived from BPMN process name) */
flowName: z.string().optional()
.describe('Override flow name (defaults to BPMN process name)'),
/** Whether to validate the imported flow against ObjectStack schema */
validateAfterImport: z.boolean().default(true)
.describe('Validate imported flow against FlowSchema after import'),
}).describe('Options for importing BPMN 2.0 XML into an ObjectStack flow'));
export type BpmnImportOptions = z.infer<typeof BpmnImportOptionsSchema>;
// ─── BPMN Export Options ─────────────────────────────────────────────
/**
* BPMN XML target version for export.
*/
export const BpmnVersionSchema = lazySchema(() => z.enum([
'2.0', // BPMN 2.0 (most common, default)
'2.0.2', // BPMN 2.0.2 (latest revision)
]).describe('BPMN specification version for export'));
export type BpmnVersion = z.infer<typeof BpmnVersionSchema>;
/**
* Options for exporting an ObjectStack flow as BPMN 2.0 XML.
*/
export const BpmnExportOptionsSchema = lazySchema(() => z.object({
/** Target BPMN version */
version: BpmnVersionSchema.default('2.0')
.describe('Target BPMN specification version'),
/** Whether to include BPMN DI (diagram interchange) layout data */
includeLayout: z.boolean().default(true)
.describe('Include BPMN DI layout data from canvas positions'),
/** Whether to include ObjectStack-specific extensions as BPMN extension elements */
includeExtensions: z.boolean().default(false)
.describe('Include ObjectStack extensions in BPMN extensionElements'),
/** Custom element mappings (override built-in for export) */
customMappings: z.array(BpmnElementMappingSchema).optional()
.describe('Custom element mappings for export'),
/** Whether to pretty-print the XML output */
prettyPrint: z.boolean().default(true)
.describe('Pretty-print XML output with indentation'),
/** XML namespace prefix for BPMN elements */
namespacePrefix: z.string().default('bpmn')
.describe('XML namespace prefix for BPMN elements'),
}).describe('Options for exporting an ObjectStack flow as BPMN 2.0 XML'));
export type BpmnExportOptions = z.infer<typeof BpmnExportOptionsSchema>;
// ─── BPMN Import/Export Result ───────────────────────────────────────
/**
* Diagnostic message from BPMN import/export operations.
*/
export const BpmnDiagnosticSchema = lazySchema(() => z.object({
/** Severity level */
severity: z.enum(['info', 'warning', 'error']).describe('Diagnostic severity'),
/** Human-readable message */
message: z.string().describe('Diagnostic message'),
/** BPMN element ID (if applicable) */
bpmnElementId: z.string().optional().describe('BPMN element ID related to this diagnostic'),
/** ObjectStack node ID (if applicable) */
nodeId: z.string().optional().describe('ObjectStack node ID related to this diagnostic'),
}).describe('Diagnostic message from BPMN import/export'));
export type BpmnDiagnostic = z.infer<typeof BpmnDiagnosticSchema>;
/**
* Result of a BPMN import or export operation.
*/
export const BpmnInteropResultSchema = lazySchema(() => z.object({
/** Whether the operation completed successfully */
success: z.boolean().describe('Whether the operation completed successfully'),
/** Diagnostic messages (warnings, errors, info) */
diagnostics: z.array(BpmnDiagnosticSchema).default([])
.describe('Diagnostic messages from the operation'),
/** Number of elements successfully mapped */
mappedCount: z.number().int().min(0).default(0)
.describe('Number of elements successfully mapped'),
/** Number of elements skipped or unmapped */
unmappedCount: z.number().int().min(0).default(0)
.describe('Number of elements that could not be mapped'),
}).describe('Result of a BPMN import/export operation'));
export type BpmnInteropResult = z.infer<typeof BpmnInteropResultSchema>;
// ─── Built-in Element Mappings ───────────────────────────────────────
/**
* Built-in element mappings between BPMN 2.0 XML types and ObjectStack FlowNodeAction.
* Import/export plugins should use these as defaults, with user overrides applied on top.
*/
export const BUILT_IN_BPMN_MAPPINGS: BpmnElementMapping[] = [
{ bpmnType: 'bpmn:startEvent', flowNodeAction: 'start', bidirectional: true },
{ bpmnType: 'bpmn:endEvent', flowNodeAction: 'end', bidirectional: true },
{ bpmnType: 'bpmn:exclusiveGateway', flowNodeAction: 'decision', bidirectional: true },
{ bpmnType: 'bpmn:parallelGateway', flowNodeAction: 'parallel_gateway', bidirectional: true },
{ bpmnType: 'bpmn:serviceTask', flowNodeAction: 'http', bidirectional: true, notes: 'Maps HTTP/connector tasks' },
{ bpmnType: 'bpmn:scriptTask', flowNodeAction: 'script', bidirectional: true },
{ bpmnType: 'bpmn:userTask', flowNodeAction: 'screen', bidirectional: true },
{ bpmnType: 'bpmn:callActivity', flowNodeAction: 'subflow', bidirectional: true },
{ bpmnType: 'bpmn:intermediateCatchEvent', flowNodeAction: 'wait', bidirectional: true, notes: 'Timer/signal/message catch events' },
{ bpmnType: 'bpmn:boundaryEvent', flowNodeAction: 'boundary_event', bidirectional: true },
{ bpmnType: 'bpmn:task', flowNodeAction: 'assignment', bidirectional: true, notes: 'Generic BPMN task maps to assignment' },
];