callman-core 1.29.0 → 1.31.0
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.
- package/dist/ai/prompts/diagram.d.ts.map +1 -1
- package/dist/ai/prompts/diagram.js +24 -7
- package/dist/ai/prompts/diagram.js.map +1 -1
- package/dist/ai/types.d.ts +1 -1
- package/dist/ai/types.d.ts.map +1 -1
- package/dist/diagram/componentCatalog.d.ts +3 -0
- package/dist/diagram/componentCatalog.d.ts.map +1 -1
- package/dist/diagram/componentCatalog.js +5 -1
- package/dist/diagram/componentCatalog.js.map +1 -1
- package/dist/diagram/database/derive.d.ts +14 -0
- package/dist/diagram/database/derive.d.ts.map +1 -0
- package/dist/diagram/database/derive.js +114 -0
- package/dist/diagram/database/derive.js.map +1 -0
- package/dist/diagram/database/diff.d.ts +48 -0
- package/dist/diagram/database/diff.d.ts.map +1 -0
- package/dist/diagram/database/diff.js +109 -0
- package/dist/diagram/database/diff.js.map +1 -0
- package/dist/diagram/database/edit.d.ts +113 -0
- package/dist/diagram/database/edit.d.ts.map +1 -0
- package/dist/diagram/database/edit.js +359 -0
- package/dist/diagram/database/edit.js.map +1 -0
- package/dist/diagram/database/fromSchema.d.ts +12 -0
- package/dist/diagram/database/fromSchema.d.ts.map +1 -0
- package/dist/diagram/database/fromSchema.js +182 -0
- package/dist/diagram/database/fromSchema.js.map +1 -0
- package/dist/diagram/database/index.d.ts +9 -0
- package/dist/diagram/database/index.d.ts.map +1 -0
- package/dist/diagram/database/index.js +14 -0
- package/dist/diagram/database/index.js.map +1 -0
- package/dist/diagram/database/model.d.ts +93 -0
- package/dist/diagram/database/model.d.ts.map +1 -0
- package/dist/diagram/database/model.js +294 -0
- package/dist/diagram/database/model.js.map +1 -0
- package/dist/diagram/database/patch.d.ts +14 -0
- package/dist/diagram/database/patch.d.ts.map +1 -0
- package/dist/diagram/database/patch.js +186 -0
- package/dist/diagram/database/patch.js.map +1 -0
- package/dist/diagram/database/place.d.ts +4 -0
- package/dist/diagram/database/place.d.ts.map +1 -0
- package/dist/diagram/database/place.js +22 -0
- package/dist/diagram/database/place.js.map +1 -0
- package/dist/diagram/database/types.d.ts +50 -0
- package/dist/diagram/database/types.d.ts.map +1 -0
- package/dist/diagram/database/types.js +106 -0
- package/dist/diagram/database/types.js.map +1 -0
- package/dist/diagram/index.d.ts +1 -0
- package/dist/diagram/index.d.ts.map +1 -1
- package/dist/diagram/index.js +1 -0
- package/dist/diagram/index.js.map +1 -1
- package/dist/diagram/layout.d.ts +1 -0
- package/dist/diagram/layout.d.ts.map +1 -1
- package/dist/diagram/layout.js +2 -1
- package/dist/diagram/layout.js.map +1 -1
- package/dist/diagram/ops.d.ts +1 -1
- package/dist/diagram/ops.d.ts.map +1 -1
- package/dist/diagram/ops.js +42 -0
- package/dist/diagram/ops.js.map +1 -1
- package/dist/diagram/opsReference.d.ts +1 -1
- package/dist/diagram/opsReference.d.ts.map +1 -1
- package/dist/diagram/opsReference.js +9 -0
- package/dist/diagram/opsReference.js.map +1 -1
- package/dist/diagram/patchInput.d.ts +65 -1
- package/dist/diagram/patchInput.d.ts.map +1 -1
- package/dist/diagram/patchInput.js +414 -11
- package/dist/diagram/patchInput.js.map +1 -1
- package/dist/diagram/schema.d.ts +2 -2
- package/dist/diagram/schema.d.ts.map +1 -1
- package/dist/diagram/schema.js +3 -3
- package/dist/diagram/schema.js.map +1 -1
- package/dist/diagram/views.d.ts +13 -0
- package/dist/diagram/views.d.ts.map +1 -1
- package/dist/diagram/views.js +49 -0
- package/dist/diagram/views.js.map +1 -1
- package/dist/host/db/introspection/index.d.ts +9 -0
- package/dist/host/db/introspection/index.d.ts.map +1 -0
- package/dist/host/db/introspection/index.js +35 -0
- package/dist/host/db/introspection/index.js.map +1 -0
- package/dist/host/db/introspection/mongo.d.ts +7 -0
- package/dist/host/db/introspection/mongo.d.ts.map +1 -0
- package/dist/host/db/introspection/mongo.js +183 -0
- package/dist/host/db/introspection/mongo.js.map +1 -0
- package/dist/host/db/introspection/mssql.d.ts +6 -0
- package/dist/host/db/introspection/mssql.d.ts.map +1 -0
- package/dist/host/db/introspection/mssql.js +211 -0
- package/dist/host/db/introspection/mssql.js.map +1 -0
- package/dist/host/db/introspection/mysql.d.ts +5 -0
- package/dist/host/db/introspection/mysql.d.ts.map +1 -0
- package/dist/host/db/introspection/mysql.js +163 -0
- package/dist/host/db/introspection/mysql.js.map +1 -0
- package/dist/host/db/introspection/oracle.d.ts +12 -0
- package/dist/host/db/introspection/oracle.d.ts.map +1 -0
- package/dist/host/db/introspection/oracle.js +225 -0
- package/dist/host/db/introspection/oracle.js.map +1 -0
- package/dist/host/db/introspection/postgres.d.ts +5 -0
- package/dist/host/db/introspection/postgres.d.ts.map +1 -0
- package/dist/host/db/introspection/postgres.js +172 -0
- package/dist/host/db/introspection/postgres.js.map +1 -0
- package/dist/host/db/introspection/shared.d.ts +29 -0
- package/dist/host/db/introspection/shared.d.ts.map +1 -0
- package/dist/host/db/introspection/shared.js +119 -0
- package/dist/host/db/introspection/shared.js.map +1 -0
- package/dist/host/db/introspection/types.d.ts +58 -0
- package/dist/host/db/introspection/types.d.ts.map +1 -0
- package/dist/host/db/introspection/types.js +6 -0
- package/dist/host/db/introspection/types.js.map +1 -0
- package/dist/host/db/mongoAdapter.d.ts +1 -0
- package/dist/host/db/mongoAdapter.d.ts.map +1 -1
- package/dist/host/db/mongoAdapter.js +13 -0
- package/dist/host/db/mongoAdapter.js.map +1 -1
- package/dist/host/db/mssqlAdapter.d.ts +1 -0
- package/dist/host/db/mssqlAdapter.d.ts.map +1 -1
- package/dist/host/db/mssqlAdapter.js +3 -1
- package/dist/host/db/mssqlAdapter.js.map +1 -1
- package/dist/host/db/mysqlAdapter.d.ts +1 -0
- package/dist/host/db/mysqlAdapter.d.ts.map +1 -1
- package/dist/host/db/mysqlAdapter.js +11 -0
- package/dist/host/db/mysqlAdapter.js.map +1 -1
- package/dist/host/db/oracleAdapter.d.ts +1 -0
- package/dist/host/db/oracleAdapter.d.ts.map +1 -1
- package/dist/host/db/oracleAdapter.js +22 -0
- package/dist/host/db/oracleAdapter.js.map +1 -1
- package/dist/host/db/postgresAdapter.d.ts +1 -0
- package/dist/host/db/postgresAdapter.d.ts.map +1 -1
- package/dist/host/db/postgresAdapter.js +13 -0
- package/dist/host/db/postgresAdapter.js.map +1 -1
- package/dist/host/db/queryExecutor.d.ts +2 -1
- package/dist/host/db/queryExecutor.d.ts.map +1 -1
- package/dist/host/db/queryExecutor.js +1 -1
- package/dist/host/db/queryExecutor.js.map +1 -1
- package/dist/host/index.d.ts +7 -0
- package/dist/host/index.d.ts.map +1 -1
- package/dist/host/index.js +9 -0
- package/dist/host/index.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/ui-test/commands.d.ts +54 -0
- package/dist/ui-test/commands.d.ts.map +1 -0
- package/dist/ui-test/commands.js +436 -0
- package/dist/ui-test/commands.js.map +1 -0
- package/dist/ui-test/flow-lint.d.ts +43 -0
- package/dist/ui-test/flow-lint.d.ts.map +1 -0
- package/dist/ui-test/flow-lint.js +229 -0
- package/dist/ui-test/flow-lint.js.map +1 -0
- package/dist-cjs/ai/prompts/diagram.js +23 -6
- package/dist-cjs/ai/prompts/diagram.js.map +1 -1
- package/dist-cjs/diagram/componentCatalog.js +5 -1
- package/dist-cjs/diagram/componentCatalog.js.map +1 -1
- package/dist-cjs/diagram/database/derive.js +119 -0
- package/dist-cjs/diagram/database/derive.js.map +1 -0
- package/dist-cjs/diagram/database/diff.js +115 -0
- package/dist-cjs/diagram/database/diff.js.map +1 -0
- package/dist-cjs/diagram/database/edit.js +366 -0
- package/dist-cjs/diagram/database/edit.js.map +1 -0
- package/dist-cjs/diagram/database/fromSchema.js +188 -0
- package/dist-cjs/diagram/database/fromSchema.js.map +1 -0
- package/dist-cjs/diagram/database/index.js +32 -0
- package/dist-cjs/diagram/database/index.js.map +1 -0
- package/dist-cjs/diagram/database/model.js +311 -0
- package/dist-cjs/diagram/database/model.js.map +1 -0
- package/dist-cjs/diagram/database/patch.js +190 -0
- package/dist-cjs/diagram/database/patch.js.map +1 -0
- package/dist-cjs/diagram/database/place.js +26 -0
- package/dist-cjs/diagram/database/place.js.map +1 -0
- package/dist-cjs/diagram/database/types.js +122 -0
- package/dist-cjs/diagram/database/types.js.map +1 -0
- package/dist-cjs/diagram/index.js +1 -0
- package/dist-cjs/diagram/index.js.map +1 -1
- package/dist-cjs/diagram/layout.js +3 -2
- package/dist-cjs/diagram/layout.js.map +1 -1
- package/dist-cjs/diagram/ops.js +42 -0
- package/dist-cjs/diagram/ops.js.map +1 -1
- package/dist-cjs/diagram/opsReference.js +9 -0
- package/dist-cjs/diagram/opsReference.js.map +1 -1
- package/dist-cjs/diagram/patchInput.js +414 -11
- package/dist-cjs/diagram/patchInput.js.map +1 -1
- package/dist-cjs/diagram/schema.js +3 -3
- package/dist-cjs/diagram/schema.js.map +1 -1
- package/dist-cjs/diagram/views.js +51 -1
- package/dist-cjs/diagram/views.js.map +1 -1
- package/dist-cjs/host/db/introspection/index.js +59 -0
- package/dist-cjs/host/db/introspection/index.js.map +1 -0
- package/dist-cjs/host/db/introspection/mongo.js +189 -0
- package/dist-cjs/host/db/introspection/mongo.js.map +1 -0
- package/dist-cjs/host/db/introspection/mssql.js +216 -0
- package/dist-cjs/host/db/introspection/mssql.js.map +1 -0
- package/dist-cjs/host/db/introspection/mysql.js +167 -0
- package/dist-cjs/host/db/introspection/mysql.js.map +1 -0
- package/dist-cjs/host/db/introspection/oracle.js +230 -0
- package/dist-cjs/host/db/introspection/oracle.js.map +1 -0
- package/dist-cjs/host/db/introspection/postgres.js +176 -0
- package/dist-cjs/host/db/introspection/postgres.js.map +1 -0
- package/dist-cjs/host/db/introspection/shared.js +133 -0
- package/dist-cjs/host/db/introspection/shared.js.map +1 -0
- package/dist-cjs/host/db/introspection/types.js +7 -0
- package/dist-cjs/host/db/introspection/types.js.map +1 -0
- package/dist-cjs/host/db/mongoAdapter.js +15 -1
- package/dist-cjs/host/db/mongoAdapter.js.map +1 -1
- package/dist-cjs/host/db/mssqlAdapter.js +5 -2
- package/dist-cjs/host/db/mssqlAdapter.js.map +1 -1
- package/dist-cjs/host/db/mysqlAdapter.js +13 -1
- package/dist-cjs/host/db/mysqlAdapter.js.map +1 -1
- package/dist-cjs/host/db/oracleAdapter.js +24 -1
- package/dist-cjs/host/db/oracleAdapter.js.map +1 -1
- package/dist-cjs/host/db/postgresAdapter.js +15 -1
- package/dist-cjs/host/db/postgresAdapter.js.map +1 -1
- package/dist-cjs/host/db/queryExecutor.js +5 -4
- package/dist-cjs/host/db/queryExecutor.js.map +1 -1
- package/dist-cjs/host/index.js +24 -1
- package/dist-cjs/host/index.js.map +1 -1
- package/dist-cjs/index.js +2 -0
- package/dist-cjs/index.js.map +1 -1
- package/dist-cjs/ui-test/commands.js +441 -0
- package/dist-cjs/ui-test/commands.js.map +1 -0
- package/dist-cjs/ui-test/flow-lint.js +235 -0
- package/dist-cjs/ui-test/flow-lint.js.map +1 -0
- package/package.json +3 -1
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// by the MCP server (behind its zod schemas), the AI EDIT mode and imports.
|
|
6
6
|
// Moved from the MCP server's build.ts / patch.ts.
|
|
7
7
|
import { BPMN_CONTAINER_TYPES, bpmnElementForType, getBpmnType, isBpmnContainerType, suggestBpmnTypes } from "./bpmn/types.js";
|
|
8
|
+
import { applyDatabaseEdits, DATABASE_GRAMMAR_VERSION, DatabaseEditError, databaseEntitySize, DB_NODE_TYPES, emptyDatabaseModel, findEntity, isValidCardinality, kindForDatabaseType, markersForCardinality, parseDatabaseModel, serializeDatabaseModel, suggestDatabaseTypes, } from "./database/index.js";
|
|
8
9
|
import { DIAGRAM_COMPONENT_CATALOG, getDiagramComponent, searchDiagramComponents } from "./componentCatalog.js";
|
|
9
10
|
import { isBusComponentType, isDefaultEdgeStyle, semanticStyle } from "./edgeSemantics.js";
|
|
10
11
|
import { absolutePosition, absoluteRect, boundingBox, indexNodes, toParentRelative } from "./geometry.js";
|
|
@@ -52,6 +53,8 @@ export const isContainerType = (type) => {
|
|
|
52
53
|
};
|
|
53
54
|
export const containerTypes = () => DIAGRAM_COMPONENT_CATALOG.filter((entry) => entry.container || entry.swimlane).map((entry) => entry.type);
|
|
54
55
|
export const parentWarning = (id, parentId, parentType, kind = "canvas") => {
|
|
56
|
+
if (kind === "database")
|
|
57
|
+
return `Node ${id} sits inside "${parentId}" — database diagrams have no containers; the parent is ignored.`;
|
|
55
58
|
if (kind === "bpmn") {
|
|
56
59
|
return isBpmnContainerType(parentType)
|
|
57
60
|
? null
|
|
@@ -77,6 +80,16 @@ export const edgeStyleFor = (semantic, color) => {
|
|
|
77
80
|
};
|
|
78
81
|
const resolveType = (type, id, strict, warnings, opIndex, kind = "canvas") => {
|
|
79
82
|
const trimmed = type.trim();
|
|
83
|
+
if (kind === "database") {
|
|
84
|
+
if (DB_NODE_TYPES.includes(trimmed))
|
|
85
|
+
return { type: trimmed, known: true };
|
|
86
|
+
const suggestions = suggestDatabaseTypes(trimmed);
|
|
87
|
+
if (strict) {
|
|
88
|
+
throw new DiagramOpError("DIAGRAM_UNKNOWN_COMPONENT_TYPE", `Unknown database type "${trimmed}" on ${id}. A database diagram has db.table, db.view and db.collection (prefer the DATABASE OPS: addTable, addColumn, addRelationship …), or pass strictTypes:false to draw it as a table.`, opIndex, { unknownTypes: [{ type: trimmed, suggestions }] });
|
|
89
|
+
}
|
|
90
|
+
warnings.push(`Unknown database type "${trimmed}" on ${id} → drawn as a table`);
|
|
91
|
+
return { type: "db.table", known: false };
|
|
92
|
+
}
|
|
80
93
|
if (kind === "bpmn") {
|
|
81
94
|
if (getBpmnType(trimmed))
|
|
82
95
|
return { type: trimmed, known: true };
|
|
@@ -100,18 +113,38 @@ const resolveType = (type, id, strict, warnings, opIndex, kind = "canvas") => {
|
|
|
100
113
|
};
|
|
101
114
|
const nodeFromInput = (input, id, strict, warnings, opIndex, kind = "canvas") => {
|
|
102
115
|
const { type, known } = resolveType(input.type, id, strict, warnings, opIndex, kind);
|
|
103
|
-
const def = kind === "
|
|
116
|
+
const def = kind === "canvas" ? getDiagramComponent(type) : undefined;
|
|
104
117
|
const bpmn = kind === "bpmn" ? getBpmnType(type) : undefined;
|
|
105
|
-
const
|
|
106
|
-
|
|
118
|
+
const dbRaw = kind === "database" ? (input.data?.db ?? {}) : undefined;
|
|
119
|
+
const label = kind === "database"
|
|
120
|
+
? (typeof dbRaw?.name === "string" && dbRaw.name.trim()) || input.label || id
|
|
121
|
+
: input.label !== undefined || !known
|
|
122
|
+
? (input.label ?? input.type)
|
|
123
|
+
: def?.defaultLabel;
|
|
124
|
+
// A BPMN node always knows which element it stands for; a database node its
|
|
125
|
+
// table name and kind (its `columns` stay the authoring input until the
|
|
126
|
+
// model absorbs them).
|
|
107
127
|
const data = kind === "bpmn"
|
|
108
128
|
? { ...(input.data ?? {}), bpmn: { ...(input.data?.bpmn ?? {}), element: bpmnElementForType(type) ?? "task" } }
|
|
109
|
-
:
|
|
129
|
+
: kind === "database"
|
|
130
|
+
? { ...(input.data ?? {}), db: { ...dbRaw, name: label, kind: kindForDatabaseType(type) } }
|
|
131
|
+
: input.data;
|
|
132
|
+
const dbColumns = Array.isArray(dbRaw?.columns) ? dbRaw.columns : [];
|
|
133
|
+
const dbSize = kind === "database"
|
|
134
|
+
? databaseEntitySize({
|
|
135
|
+
name: String(label),
|
|
136
|
+
...(typeof dbRaw?.schema === "string" ? { schema: dbRaw.schema } : {}),
|
|
137
|
+
columns: dbColumns.map((column) => {
|
|
138
|
+
const raw = (column ?? {});
|
|
139
|
+
return { name: typeof raw.name === "string" ? raw.name : "", dataType: typeof raw.dataType === "string" ? raw.dataType : typeof raw.type === "string" ? raw.type : "" };
|
|
140
|
+
}),
|
|
141
|
+
})
|
|
142
|
+
: undefined;
|
|
110
143
|
const node = {
|
|
111
144
|
id,
|
|
112
145
|
type,
|
|
113
146
|
position: input.position ?? { x: 0, y: 0 },
|
|
114
|
-
size: input.size ?? bpmn?.size ?? def?.defaultSize ?? { width: 140, height: 60 },
|
|
147
|
+
size: input.size ?? bpmn?.size ?? dbSize ?? def?.defaultSize ?? { width: 140, height: 60 },
|
|
115
148
|
...(label !== undefined ? { label } : {}),
|
|
116
149
|
...(input.parent ? { parentId: input.parent } : {}),
|
|
117
150
|
...(input.style ? { style: applyStyleInput(undefined, input.style) } : {}),
|
|
@@ -130,19 +163,26 @@ const edgeFromInput = (input, id, typeOf, kind = "canvas") => {
|
|
|
130
163
|
// A fresh edge into a broker reads as a bus line — the studio's own rule.
|
|
131
164
|
if (kind === "canvas" && !semantic && (isBusComponentType(typeOf(input.source)) || isBusComponentType(typeOf(input.target))))
|
|
132
165
|
semantic = "bus";
|
|
133
|
-
// A BPMN flow is a sequence flow unless said otherwise
|
|
166
|
+
// A BPMN flow is a sequence flow unless said otherwise; a database edge is
|
|
167
|
+
// a relationship (manual, N:1 unless said otherwise) with crow's-foot ends.
|
|
168
|
+
const dbRaw = kind === "database" ? (input.data?.db ?? {}) : undefined;
|
|
169
|
+
const cardinality = isValidCardinality(dbRaw?.cardinality) ? dbRaw.cardinality : "N:1";
|
|
134
170
|
const data = kind === "bpmn"
|
|
135
171
|
? { ...(input.data ?? {}), bpmn: { flow: "sequence", ...(input.data?.bpmn ?? {}) } }
|
|
136
|
-
:
|
|
172
|
+
: kind === "database"
|
|
173
|
+
? { ...(input.data ?? {}), db: { kind: "manual", sourceColumns: [], targetColumns: [], ...dbRaw, cardinality } }
|
|
174
|
+
: input.data;
|
|
175
|
+
const dbMarkers = kind === "database" ? markersForCardinality(cardinality) : undefined;
|
|
137
176
|
const style = edgeStyleFor(semantic, input.color);
|
|
177
|
+
const markerStart = input.markerStart ?? dbMarkers?.markerStart;
|
|
138
178
|
return {
|
|
139
179
|
id,
|
|
140
180
|
source: input.source,
|
|
141
181
|
target: input.target,
|
|
142
182
|
...(input.label ? { label: input.label } : {}),
|
|
143
183
|
...(input.routing ? { routing: input.routing } : {}),
|
|
144
|
-
markerEnd: input.markerEnd ?? "classicThin",
|
|
145
|
-
...(
|
|
184
|
+
markerEnd: input.markerEnd ?? dbMarkers?.markerEnd ?? "classicThin",
|
|
185
|
+
...(markerStart && markerStart !== "none" ? { markerStart } : {}),
|
|
146
186
|
...(input.sourceSide ? { sourceHandle: input.sourceSide } : {}),
|
|
147
187
|
...(input.targetSide ? { targetHandle: input.targetSide } : {}),
|
|
148
188
|
...(style && (!isDefaultEdgeStyle(style) || semantic === "sync" || input.color) ? { style } : {}),
|
|
@@ -152,7 +192,9 @@ const edgeFromInput = (input, id, typeOf, kind = "canvas") => {
|
|
|
152
192
|
// --- lowering -----------------------------------------------------------------------
|
|
153
193
|
export const lowerPatchOps = (doc, input, options = {}) => {
|
|
154
194
|
const strict = options.strictTypes !== false;
|
|
155
|
-
const kind = options.kind ?? (doc.source?.format === "bpmn" ? "bpmn" : "canvas");
|
|
195
|
+
const kind = options.kind ?? (doc.source?.format === "bpmn" ? "bpmn" : doc.source?.format === "database" ? "database" : "canvas");
|
|
196
|
+
if (kind === "database")
|
|
197
|
+
return lowerDatabasePatchOps(doc, input, { ...options, strict });
|
|
156
198
|
const warnings = [];
|
|
157
199
|
const unpositionedNodeIds = [];
|
|
158
200
|
const idMap = {};
|
|
@@ -442,12 +484,373 @@ export const lowerPatchOps = (doc, input, options = {}) => {
|
|
|
442
484
|
case "relayout":
|
|
443
485
|
relayout = { scope: op.scope, ...(op.direction ? { direction: op.direction } : {}) };
|
|
444
486
|
return;
|
|
487
|
+
case "addTable":
|
|
488
|
+
case "renameTable":
|
|
489
|
+
case "removeTable":
|
|
490
|
+
case "setTableComment":
|
|
491
|
+
case "addColumn":
|
|
492
|
+
case "alterColumn":
|
|
493
|
+
case "removeColumn":
|
|
494
|
+
case "setPrimaryKey":
|
|
495
|
+
case "addRelationship":
|
|
496
|
+
case "updateRelationship":
|
|
497
|
+
case "removeRelationship":
|
|
498
|
+
case "hideTable":
|
|
499
|
+
case "showTable":
|
|
500
|
+
throw new DiagramOpError("DIAGRAM_INVALID_OP", `"${op.op}" is a database-diagram op; this diagram is a ${kind} diagram.`, index);
|
|
445
501
|
default:
|
|
446
502
|
throw new DiagramOpError("DIAGRAM_INVALID_OP", `Unknown op "${op.op}"`, index);
|
|
447
503
|
}
|
|
448
504
|
});
|
|
449
505
|
return { ops, warnings, unpositionedNodeIds, ...(relayout ? { relayout } : {}), idMap };
|
|
450
506
|
};
|
|
507
|
+
// --- database diagrams -------------------------------------------------------------
|
|
508
|
+
//
|
|
509
|
+
// Every structural op (semantic or generic) becomes an edit of the database
|
|
510
|
+
// model; the batch then yields ONE setSource op (the model re-derives the
|
|
511
|
+
// nodes/edges) followed by the presentation ops (positions, visibility,
|
|
512
|
+
// routing) that address nodes by their entity ids.
|
|
513
|
+
const DATABASE_ERROR_CODES = {
|
|
514
|
+
DIAGRAM_TABLE_NOT_FOUND: "DIAGRAM_TABLE_NOT_FOUND",
|
|
515
|
+
DIAGRAM_COLUMN_NOT_FOUND: "DIAGRAM_COLUMN_NOT_FOUND",
|
|
516
|
+
DIAGRAM_RELATIONSHIP_NOT_FOUND: "DIAGRAM_RELATIONSHIP_NOT_FOUND",
|
|
517
|
+
DIAGRAM_DUPLICATE_TABLE: "DIAGRAM_DUPLICATE_TABLE",
|
|
518
|
+
DIAGRAM_DUPLICATE_COLUMN: "DIAGRAM_DUPLICATE_COLUMN",
|
|
519
|
+
DIAGRAM_INVALID_OP: "DIAGRAM_INVALID_OP",
|
|
520
|
+
};
|
|
521
|
+
const columnInputsOf = (value) => {
|
|
522
|
+
if (!Array.isArray(value))
|
|
523
|
+
return undefined;
|
|
524
|
+
return value
|
|
525
|
+
.filter((item) => Boolean(item) && typeof item === "object" && typeof item.name === "string")
|
|
526
|
+
.map((item) => ({
|
|
527
|
+
...(typeof item.id === "string" ? { id: item.id } : {}),
|
|
528
|
+
name: String(item.name),
|
|
529
|
+
dataType: typeof item.dataType === "string" ? item.dataType : typeof item.type === "string" ? item.type : "",
|
|
530
|
+
...(typeof item.nullable === "boolean" ? { nullable: item.nullable } : {}),
|
|
531
|
+
...(typeof item.primaryKey === "boolean" ? { primaryKey: item.primaryKey } : {}),
|
|
532
|
+
...(typeof item.unique === "boolean" ? { unique: item.unique } : {}),
|
|
533
|
+
...(item.defaultValue !== undefined && item.defaultValue !== null ? { defaultValue: String(item.defaultValue) } : {}),
|
|
534
|
+
...(typeof item.autoIncrement === "boolean" ? { autoIncrement: item.autoIncrement } : {}),
|
|
535
|
+
...(typeof item.comment === "string" ? { comment: item.comment } : {}),
|
|
536
|
+
}));
|
|
537
|
+
};
|
|
538
|
+
const lowerDatabasePatchOps = (doc, input, options) => {
|
|
539
|
+
const warnings = [];
|
|
540
|
+
const idMap = {};
|
|
541
|
+
const presentation = [];
|
|
542
|
+
const positioned = new Map();
|
|
543
|
+
const unpositionedNodeIds = [];
|
|
544
|
+
let relayout;
|
|
545
|
+
const parsed = doc.source?.format === "database" ? parseDatabaseModel(doc.source.text) : null;
|
|
546
|
+
if (parsed && !parsed.ok)
|
|
547
|
+
throw new DiagramOpError("DIAGRAM_DOCUMENT_INVALID", `The database model cannot be read: ${parsed.errors.join("; ")}`);
|
|
548
|
+
let model = parsed?.model ?? emptyDatabaseModel();
|
|
549
|
+
let changed = false;
|
|
550
|
+
const mapId = (id) => idMap[id] ?? id;
|
|
551
|
+
const run = (edits, index) => {
|
|
552
|
+
try {
|
|
553
|
+
const result = applyDatabaseEdits(model, edits);
|
|
554
|
+
model = result.model;
|
|
555
|
+
changed = changed || result.changed;
|
|
556
|
+
warnings.push(...result.warnings);
|
|
557
|
+
Object.assign(idMap, result.idMap);
|
|
558
|
+
return result;
|
|
559
|
+
}
|
|
560
|
+
catch (error) {
|
|
561
|
+
if (error instanceof DatabaseEditError)
|
|
562
|
+
throw new DiagramOpError(DATABASE_ERROR_CODES[error.code], error.message, index);
|
|
563
|
+
throw error;
|
|
564
|
+
}
|
|
565
|
+
};
|
|
566
|
+
const entityIdOf = (ref, index) => {
|
|
567
|
+
const entity = findEntity(model, mapId(ref));
|
|
568
|
+
if (!entity)
|
|
569
|
+
throw new DiagramOpError("DIAGRAM_TABLE_NOT_FOUND", `Table "${ref}" does not exist.`, index);
|
|
570
|
+
return entity.id;
|
|
571
|
+
};
|
|
572
|
+
const relationshipIdOf = (ref) => mapId(ref);
|
|
573
|
+
const noContainers = (index) => {
|
|
574
|
+
throw new DiagramOpError("DIAGRAM_INVALID_OP", "Database diagrams have no containers (group / ungroup / reparent do not apply).", index);
|
|
575
|
+
};
|
|
576
|
+
const endInput = (value) => (typeof value === "string" ? value : { ...value, table: mapId(value.table) });
|
|
577
|
+
input.forEach((op, index) => {
|
|
578
|
+
switch (op.op) {
|
|
579
|
+
case "setTitle":
|
|
580
|
+
presentation.push({ op: "setTitle", title: op.title });
|
|
581
|
+
return;
|
|
582
|
+
case "addTable": {
|
|
583
|
+
const result = run([{ kind: "addTable", table: op.table }], index);
|
|
584
|
+
const id = result.addedEntityIds[0];
|
|
585
|
+
if (op.position)
|
|
586
|
+
positioned.set(id, op.position);
|
|
587
|
+
else
|
|
588
|
+
unpositionedNodeIds.push(id);
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
case "renameTable":
|
|
592
|
+
run([{ kind: "renameTable", table: mapId(op.table), name: op.name, ...(op.schema !== undefined ? { schema: op.schema } : {}) }], index);
|
|
593
|
+
return;
|
|
594
|
+
case "removeTable":
|
|
595
|
+
run([{ kind: "removeTable", table: mapId(op.table) }], index);
|
|
596
|
+
return;
|
|
597
|
+
case "setTableComment":
|
|
598
|
+
run([{ kind: "setTableComment", table: mapId(op.table), comment: op.comment }], index);
|
|
599
|
+
return;
|
|
600
|
+
case "addColumn":
|
|
601
|
+
run([{ kind: "addColumn", table: mapId(op.table), column: op.column, ...(op.after !== undefined ? { after: op.after } : {}) }], index);
|
|
602
|
+
return;
|
|
603
|
+
case "alterColumn":
|
|
604
|
+
run([{ kind: "alterColumn", table: mapId(op.table), column: op.column, changes: op.changes }], index);
|
|
605
|
+
return;
|
|
606
|
+
case "removeColumn":
|
|
607
|
+
run([{ kind: "removeColumn", table: mapId(op.table), column: op.column }], index);
|
|
608
|
+
return;
|
|
609
|
+
case "setPrimaryKey":
|
|
610
|
+
run([{ kind: "setPrimaryKey", table: mapId(op.table), columns: op.columns }], index);
|
|
611
|
+
return;
|
|
612
|
+
case "addRelationship":
|
|
613
|
+
run([
|
|
614
|
+
{
|
|
615
|
+
kind: "addRelationship",
|
|
616
|
+
...(op.id ? { id: op.id } : {}),
|
|
617
|
+
source: endInput(op.source),
|
|
618
|
+
target: endInput(op.target),
|
|
619
|
+
...(op.cardinality ? { cardinality: op.cardinality } : {}),
|
|
620
|
+
...(op.kind ? { relationshipKind: op.kind } : {}),
|
|
621
|
+
...(op.name ? { name: op.name } : {}),
|
|
622
|
+
...(op.label ? { label: op.label } : {}),
|
|
623
|
+
},
|
|
624
|
+
], index);
|
|
625
|
+
return;
|
|
626
|
+
case "updateRelationship": {
|
|
627
|
+
const { kind: relationshipKind, source, target, ...rest } = op.changes;
|
|
628
|
+
run([
|
|
629
|
+
{
|
|
630
|
+
kind: "updateRelationship",
|
|
631
|
+
relationship: relationshipIdOf(op.relationship),
|
|
632
|
+
changes: { ...rest, ...(source !== undefined ? { source: endInput(source) } : {}), ...(target !== undefined ? { target: endInput(target) } : {}), ...(relationshipKind ? { relationshipKind } : {}) },
|
|
633
|
+
},
|
|
634
|
+
], index);
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
637
|
+
case "removeRelationship":
|
|
638
|
+
run([{ kind: "removeRelationship", relationship: relationshipIdOf(op.relationship) }], index);
|
|
639
|
+
return;
|
|
640
|
+
case "hideTable":
|
|
641
|
+
presentation.push({ op: "updateNode", id: entityIdOf(op.table, index), changes: { hidden: true } });
|
|
642
|
+
return;
|
|
643
|
+
case "showTable":
|
|
644
|
+
presentation.push({ op: "updateNode", id: entityIdOf(op.table, index), changes: { hidden: false } });
|
|
645
|
+
return;
|
|
646
|
+
case "addNode": {
|
|
647
|
+
const { type } = resolveType(op.node.type, op.node.id ?? op.node.label ?? "node", options.strict, warnings, index, "database");
|
|
648
|
+
if (op.node.parent)
|
|
649
|
+
warnings.push(parentWarning(op.node.id ?? "node", op.node.parent, undefined, "database") ?? "");
|
|
650
|
+
const raw = op.node.data?.db ?? {};
|
|
651
|
+
const name = (typeof raw.name === "string" && raw.name.trim()) || (op.node.label ?? "").trim() || op.node.id?.trim() || "table";
|
|
652
|
+
const result = run([
|
|
653
|
+
{
|
|
654
|
+
kind: "addTable",
|
|
655
|
+
table: {
|
|
656
|
+
...(op.node.id?.trim() ? { id: op.node.id.trim() } : {}),
|
|
657
|
+
name,
|
|
658
|
+
...(typeof raw.schema === "string" && raw.schema.trim() ? { schema: raw.schema.trim() } : {}),
|
|
659
|
+
kind: kindForDatabaseType(type),
|
|
660
|
+
...(columnInputsOf(raw.columns ?? raw.columnInputs) ? { columns: columnInputsOf(raw.columns ?? raw.columnInputs) } : {}),
|
|
661
|
+
...(typeof raw.comment === "string" && raw.comment.trim() ? { comment: raw.comment.trim() } : {}),
|
|
662
|
+
},
|
|
663
|
+
},
|
|
664
|
+
], index);
|
|
665
|
+
const id = result.addedEntityIds[0];
|
|
666
|
+
if (op.node.position)
|
|
667
|
+
positioned.set(id, op.node.position);
|
|
668
|
+
else
|
|
669
|
+
unpositionedNodeIds.push(id);
|
|
670
|
+
if (op.node.hidden)
|
|
671
|
+
presentation.push({ op: "updateNode", id, changes: { hidden: true } });
|
|
672
|
+
if (op.node.collapsed)
|
|
673
|
+
presentation.push({ op: "updateNode", id, changes: { collapsed: true } });
|
|
674
|
+
if (op.node.locked)
|
|
675
|
+
presentation.push({ op: "updateNode", id, changes: { locked: true } });
|
|
676
|
+
if (op.node.style)
|
|
677
|
+
presentation.push({ op: "updateNode", id, changes: { style: styleInputToChanges(undefined, op.node.style) } });
|
|
678
|
+
if (op.node.size)
|
|
679
|
+
presentation.push({ op: "resizeNode", id, size: op.node.size });
|
|
680
|
+
return;
|
|
681
|
+
}
|
|
682
|
+
case "updateNode": {
|
|
683
|
+
const id = entityIdOf(op.id, index);
|
|
684
|
+
const changes = op.changes;
|
|
685
|
+
if (changes.parent)
|
|
686
|
+
noContainers(index);
|
|
687
|
+
const edits = [];
|
|
688
|
+
if (changes.type !== undefined) {
|
|
689
|
+
const { type } = resolveType(changes.type, id, options.strict, warnings, index, "database");
|
|
690
|
+
edits.push({ kind: "setTableKind", table: id, entityKind: kindForDatabaseType(type) });
|
|
691
|
+
}
|
|
692
|
+
const raw = changes.data && typeof changes.data.db === "object" && changes.data.db ? changes.data.db : undefined;
|
|
693
|
+
const requestedName = typeof raw?.name === "string" ? raw.name : typeof changes.label === "string" ? changes.label : undefined;
|
|
694
|
+
if (requestedName !== undefined) {
|
|
695
|
+
const dot = requestedName.lastIndexOf(".");
|
|
696
|
+
const schema = typeof raw?.schema === "string" ? raw.schema : dot > 0 ? requestedName.slice(0, dot) : undefined;
|
|
697
|
+
edits.push({ kind: "renameTable", table: id, name: dot > 0 && typeof raw?.name !== "string" ? requestedName.slice(dot + 1) : requestedName, ...(schema !== undefined ? { schema } : {}) });
|
|
698
|
+
}
|
|
699
|
+
else if (typeof raw?.schema === "string") {
|
|
700
|
+
const entity = findEntity(model, id);
|
|
701
|
+
if (entity)
|
|
702
|
+
edits.push({ kind: "renameTable", table: id, name: entity.name, schema: raw.schema || null });
|
|
703
|
+
}
|
|
704
|
+
if (raw && "comment" in raw)
|
|
705
|
+
edits.push({ kind: "setTableComment", table: id, comment: typeof raw.comment === "string" ? raw.comment : null });
|
|
706
|
+
const columns = raw ? columnInputsOf(raw.columns ?? raw.columnInputs) : undefined;
|
|
707
|
+
if (columns)
|
|
708
|
+
edits.push({ kind: "setColumns", table: id, columns });
|
|
709
|
+
if (edits.length > 0)
|
|
710
|
+
run(edits, index);
|
|
711
|
+
const nodeChanges = {};
|
|
712
|
+
if (changes.rotation !== undefined)
|
|
713
|
+
nodeChanges.rotation = changes.rotation;
|
|
714
|
+
if (changes.locked !== undefined)
|
|
715
|
+
nodeChanges.locked = changes.locked;
|
|
716
|
+
if (changes.hidden !== undefined)
|
|
717
|
+
nodeChanges.hidden = changes.hidden;
|
|
718
|
+
if (changes.collapsed !== undefined)
|
|
719
|
+
nodeChanges.collapsed = changes.collapsed;
|
|
720
|
+
if (changes.style !== undefined)
|
|
721
|
+
nodeChanges.style = changes.style === null ? null : styleInputToChanges(doc.nodes.find((node) => node.id === id)?.style, changes.style);
|
|
722
|
+
if (Object.keys(nodeChanges).length > 0)
|
|
723
|
+
presentation.push({ op: "updateNode", id, changes: nodeChanges });
|
|
724
|
+
if (changes.size !== undefined)
|
|
725
|
+
presentation.push({ op: "resizeNode", id, size: changes.size });
|
|
726
|
+
if (changes.position !== undefined)
|
|
727
|
+
presentation.push({ op: "moveNodes", moves: [{ id, position: changes.position }] });
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
case "removeNode":
|
|
731
|
+
run([{ kind: "removeTable", table: entityIdOf(op.id, index) }], index);
|
|
732
|
+
return;
|
|
733
|
+
case "addEdge": {
|
|
734
|
+
const raw = op.edge.data?.db ?? {};
|
|
735
|
+
const refs = (value) => (Array.isArray(value) ? value.filter((item) => typeof item === "string") : []);
|
|
736
|
+
const result = run([
|
|
737
|
+
{
|
|
738
|
+
kind: "addRelationship",
|
|
739
|
+
...(op.edge.id?.trim() ? { id: op.edge.id.trim() } : {}),
|
|
740
|
+
source: { table: entityIdOf(op.edge.source, index), columns: refs(raw.sourceColumns) },
|
|
741
|
+
target: { table: entityIdOf(op.edge.target, index), columns: refs(raw.targetColumns) },
|
|
742
|
+
...(isValidCardinality(raw.cardinality) ? { cardinality: raw.cardinality } : {}),
|
|
743
|
+
relationshipKind: raw.kind === "foreignKey" ? "foreignKey" : "manual",
|
|
744
|
+
...(typeof raw.name === "string" ? { name: raw.name } : {}),
|
|
745
|
+
...(op.edge.label ? { label: op.edge.label } : {}),
|
|
746
|
+
},
|
|
747
|
+
], index);
|
|
748
|
+
const id = result.addedRelationshipIds[0];
|
|
749
|
+
if (id && (op.edge.routing || op.edge.sourceSide || op.edge.targetSide || op.edge.color)) {
|
|
750
|
+
const edgeChanges = {};
|
|
751
|
+
if (op.edge.routing)
|
|
752
|
+
edgeChanges.routing = op.edge.routing;
|
|
753
|
+
if (op.edge.sourceSide)
|
|
754
|
+
edgeChanges.sourceHandle = op.edge.sourceSide;
|
|
755
|
+
if (op.edge.targetSide)
|
|
756
|
+
edgeChanges.targetHandle = op.edge.targetSide;
|
|
757
|
+
if (op.edge.color)
|
|
758
|
+
edgeChanges.style = { stroke: toTokenRef(op.edge.color) };
|
|
759
|
+
presentation.push({ op: "updateEdge", id, changes: edgeChanges });
|
|
760
|
+
}
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
763
|
+
case "updateEdge": {
|
|
764
|
+
const id = relationshipIdOf(op.id);
|
|
765
|
+
const changes = op.changes;
|
|
766
|
+
const raw = changes.data && typeof changes.data.db === "object" && changes.data.db ? changes.data.db : undefined;
|
|
767
|
+
const refs = (value) => (Array.isArray(value) ? value.filter((item) => typeof item === "string") : undefined);
|
|
768
|
+
const relationshipChanges = {};
|
|
769
|
+
if (changes.source !== undefined || refs(raw?.sourceColumns))
|
|
770
|
+
relationshipChanges.source = { table: changes.source !== undefined ? entityIdOf(changes.source, index) : (findEntity(model, id) ? model.relationships.find((r) => r.id === id)?.source.entityId ?? "" : ""), columns: refs(raw?.sourceColumns) ?? (changes.source !== undefined ? [] : undefined) };
|
|
771
|
+
if (changes.target !== undefined || refs(raw?.targetColumns))
|
|
772
|
+
relationshipChanges.target = { table: changes.target !== undefined ? entityIdOf(changes.target, index) : model.relationships.find((r) => r.id === id)?.target.entityId ?? "", columns: refs(raw?.targetColumns) ?? (changes.target !== undefined ? [] : undefined) };
|
|
773
|
+
if (isValidCardinality(raw?.cardinality))
|
|
774
|
+
relationshipChanges.cardinality = raw.cardinality;
|
|
775
|
+
if (raw && (raw.kind === "manual" || raw.kind === "foreignKey"))
|
|
776
|
+
relationshipChanges.relationshipKind = raw.kind;
|
|
777
|
+
if (raw && "name" in raw)
|
|
778
|
+
relationshipChanges.name = typeof raw.name === "string" ? raw.name : null;
|
|
779
|
+
if (changes.label !== undefined)
|
|
780
|
+
relationshipChanges.label = changes.label === "" ? null : changes.label;
|
|
781
|
+
if (Object.keys(relationshipChanges).length > 0)
|
|
782
|
+
run([{ kind: "updateRelationship", relationship: id, changes: relationshipChanges }], index);
|
|
783
|
+
const edgeChanges = {};
|
|
784
|
+
if (changes.routing !== undefined)
|
|
785
|
+
edgeChanges.routing = changes.routing;
|
|
786
|
+
if (changes.sourceSide !== undefined)
|
|
787
|
+
edgeChanges.sourceHandle = changes.sourceSide;
|
|
788
|
+
if (changes.targetSide !== undefined)
|
|
789
|
+
edgeChanges.targetHandle = changes.targetSide;
|
|
790
|
+
if (changes.color !== undefined)
|
|
791
|
+
edgeChanges.style = { stroke: changes.color === null ? null : toTokenRef(changes.color) };
|
|
792
|
+
if (Object.keys(edgeChanges).length > 0)
|
|
793
|
+
presentation.push({ op: "updateEdge", id, changes: edgeChanges });
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
case "removeEdge":
|
|
797
|
+
run([{ kind: "removeRelationship", relationship: relationshipIdOf(op.id) }], index);
|
|
798
|
+
return;
|
|
799
|
+
case "moveNode":
|
|
800
|
+
presentation.push({ op: "moveNodes", moves: [{ id: entityIdOf(op.id, index), position: op.position }] });
|
|
801
|
+
return;
|
|
802
|
+
case "setEdgeRoute": {
|
|
803
|
+
const changes = {};
|
|
804
|
+
if (op.routing !== undefined)
|
|
805
|
+
changes.routing = op.routing;
|
|
806
|
+
if (op.sourceSide !== undefined)
|
|
807
|
+
changes.sourceHandle = op.sourceSide;
|
|
808
|
+
if (op.targetSide !== undefined)
|
|
809
|
+
changes.targetHandle = op.targetSide;
|
|
810
|
+
if (op.waypoints !== undefined)
|
|
811
|
+
changes.waypoints = op.waypoints;
|
|
812
|
+
if (Object.keys(changes).length === 0) {
|
|
813
|
+
changes.waypoints = null;
|
|
814
|
+
changes.sourceAnchor = null;
|
|
815
|
+
changes.targetAnchor = null;
|
|
816
|
+
}
|
|
817
|
+
presentation.push({ op: "updateEdge", id: relationshipIdOf(op.id), changes });
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
820
|
+
case "reorder": {
|
|
821
|
+
const id = entityIdOf(op.id, index);
|
|
822
|
+
const count = doc.nodes.filter((node) => !node.parentId).length;
|
|
823
|
+
presentation.push({ op: "reorder", kind: "node", id, index: op.index === "front" ? Math.max(0, count - 1) : op.index === "back" ? 0 : op.index });
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
case "setCanvas":
|
|
827
|
+
presentation.push({ op: "setCanvas", changes: op.canvas });
|
|
828
|
+
return;
|
|
829
|
+
case "relayout":
|
|
830
|
+
relayout = { scope: op.scope, ...(op.direction ? { direction: op.direction } : {}) };
|
|
831
|
+
return;
|
|
832
|
+
case "reparent":
|
|
833
|
+
case "group":
|
|
834
|
+
case "ungroup":
|
|
835
|
+
noContainers(index);
|
|
836
|
+
return;
|
|
837
|
+
default:
|
|
838
|
+
throw new DiagramOpError("DIAGRAM_INVALID_OP", `Unknown op "${op.op}"`, index);
|
|
839
|
+
}
|
|
840
|
+
});
|
|
841
|
+
const ops = [];
|
|
842
|
+
if (changed) {
|
|
843
|
+
ops.push({
|
|
844
|
+
op: "setSource",
|
|
845
|
+
source: { format: "database", text: serializeDatabaseModel(model), diagramType: "database", grammar: DATABASE_GRAMMAR_VERSION, valid: true },
|
|
846
|
+
resync: true,
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
for (const [id, position] of positioned)
|
|
850
|
+
ops.push({ op: "moveNodes", moves: [{ id, position }] });
|
|
851
|
+
ops.push(...presentation);
|
|
852
|
+
return { ops, warnings: warnings.filter(Boolean), unpositionedNodeIds, ...(relayout ? { relayout } : {}), idMap };
|
|
853
|
+
};
|
|
451
854
|
export const buildDiagramFromInput = (input, options = {}) => {
|
|
452
855
|
const kind = options.kind ?? "canvas";
|
|
453
856
|
const strict = options.strictTypes !== false;
|
|
@@ -476,7 +879,7 @@ export const buildDiagramFromInput = (input, options = {}) => {
|
|
|
476
879
|
const entry = error.data?.unknownTypes?.[0];
|
|
477
880
|
if (entry)
|
|
478
881
|
unknown.push(entry);
|
|
479
|
-
return nodeFromInput({ ...node, type: kind === "bpmn" ? "bpmn.task" : "rect", label: node.label ?? node.type }, id, false, [], index, kind);
|
|
882
|
+
return nodeFromInput({ ...node, type: kind === "bpmn" ? "bpmn.task" : kind === "database" ? "db.table" : "rect", label: node.label ?? node.type }, id, false, [], index, kind);
|
|
480
883
|
}
|
|
481
884
|
throw error;
|
|
482
885
|
}
|