@01.software/sdk 0.2.9-dev.260306.2ae88fe → 0.2.9-dev.260309.c56872d
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/{auth-7rMGkvN0.d.cts → auth-BieKA-OQ.d.ts} +13 -2
- package/dist/{auth-wTPFmG0W.d.ts → auth-CAV8xgZk.d.cts} +13 -2
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +2 -2
- package/dist/auth.d.ts +2 -2
- package/dist/auth.js.map +1 -1
- package/dist/components.d.cts +1 -1
- package/dist/components.d.ts +1 -1
- package/dist/flow.cjs +319 -61
- package/dist/flow.cjs.map +1 -1
- package/dist/flow.d.cts +88 -44
- package/dist/flow.d.ts +88 -44
- package/dist/flow.js +316 -57
- package/dist/flow.js.map +1 -1
- package/dist/index.cjs +208 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +227 -39
- package/dist/index.d.ts +227 -39
- package/dist/index.js +208 -22
- package/dist/index.js.map +1 -1
- package/dist/{payload-types-Dp1qa5_Z.d.cts → payload-types-2wbfaDxp.d.cts} +948 -130
- package/dist/{payload-types-Dp1qa5_Z.d.ts → payload-types-2wbfaDxp.d.ts} +948 -130
- package/dist/{webhook-BQQe_xSK.d.ts → webhook-Byzl1A0g.d.cts} +2 -2
- package/dist/{webhook-BPpNKVcz.d.cts → webhook-I6ZDGW1d.d.ts} +2 -2
- package/dist/webhook.cjs +1 -1
- package/dist/webhook.cjs.map +1 -1
- package/dist/webhook.d.cts +2 -2
- package/dist/webhook.d.ts +2 -2
- package/dist/webhook.js +1 -1
- package/dist/webhook.js.map +1 -1
- package/package.json +22 -21
package/dist/flow.js
CHANGED
|
@@ -15,89 +15,342 @@ var __spreadValues = (a, b) => {
|
|
|
15
15
|
}
|
|
16
16
|
return a;
|
|
17
17
|
};
|
|
18
|
+
var __async = (__this, __arguments, generator) => {
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
var fulfilled = (value) => {
|
|
21
|
+
try {
|
|
22
|
+
step(generator.next(value));
|
|
23
|
+
} catch (e) {
|
|
24
|
+
reject(e);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
var rejected = (value) => {
|
|
28
|
+
try {
|
|
29
|
+
step(generator.throw(value));
|
|
30
|
+
} catch (e) {
|
|
31
|
+
reject(e);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
35
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
36
|
+
});
|
|
37
|
+
};
|
|
18
38
|
|
|
19
39
|
// src/components/FlowRenderer/index.tsx
|
|
20
40
|
import React from "react";
|
|
21
41
|
import {
|
|
22
42
|
ReactFlow,
|
|
43
|
+
ReactFlowProvider,
|
|
23
44
|
Background
|
|
24
45
|
} from "@xyflow/react";
|
|
25
46
|
|
|
26
47
|
// src/components/FlowRenderer/types.ts
|
|
27
|
-
|
|
48
|
+
function isDynamicNode(node) {
|
|
49
|
+
return node.type === "dynamic";
|
|
50
|
+
}
|
|
51
|
+
function isFrameNode(node) {
|
|
52
|
+
return node.type === "frame";
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// src/components/FlowRenderer/built-in-node-types.ts
|
|
56
|
+
var BUILT_IN_NODE_TYPES = [
|
|
57
|
+
{
|
|
58
|
+
slug: "text",
|
|
59
|
+
name: "Text",
|
|
60
|
+
color: "#e5e7eb",
|
|
61
|
+
defaultSize: { width: 200, height: 200 },
|
|
62
|
+
fields: [{ name: "body", label: "Body", fieldType: "textarea" }]
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
slug: "image",
|
|
66
|
+
name: "Image",
|
|
67
|
+
color: "#e5e7eb",
|
|
68
|
+
transparentBackground: true,
|
|
69
|
+
defaultSize: { width: 200, height: 200 },
|
|
70
|
+
fields: [
|
|
71
|
+
{ name: "image", label: "Image", fieldType: "image" },
|
|
72
|
+
{ name: "alt", label: "Alt Text", fieldType: "text" },
|
|
73
|
+
{ name: "caption", label: "Caption", fieldType: "text" }
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
// src/components/FlowRenderer/built-in-edge-types.ts
|
|
79
|
+
var BUILT_IN_EDGE_TYPES = [
|
|
80
|
+
{
|
|
81
|
+
slug: "default",
|
|
82
|
+
name: "Default",
|
|
83
|
+
color: "",
|
|
84
|
+
strokeWidth: 2,
|
|
85
|
+
animated: true,
|
|
86
|
+
lineStyle: "default",
|
|
87
|
+
fields: []
|
|
88
|
+
}
|
|
89
|
+
];
|
|
90
|
+
|
|
91
|
+
// src/components/FlowRenderer/useFlow.ts
|
|
92
|
+
import { useQuery } from "@tanstack/react-query";
|
|
93
|
+
import { useMemo } from "react";
|
|
94
|
+
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
95
|
+
function isId(value) {
|
|
96
|
+
return UUID_RE.test(value);
|
|
97
|
+
}
|
|
98
|
+
function apiNodeTypeToNodeTypeDef(doc) {
|
|
99
|
+
var _a, _b, _c, _d;
|
|
100
|
+
return {
|
|
101
|
+
slug: String((_a = doc.slug) != null ? _a : ""),
|
|
102
|
+
name: String((_b = doc.name) != null ? _b : ""),
|
|
103
|
+
color: String((_c = doc.color) != null ? _c : "#e5e7eb"),
|
|
104
|
+
defaultSize: (_d = doc.defaultSize) != null ? _d : { width: 200, height: 200 },
|
|
105
|
+
fields: Array.isArray(doc.fields) ? doc.fields : [],
|
|
106
|
+
transparentBackground: Boolean(doc.transparentBackground)
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function apiEdgeTypeToEdgeTypeDef(doc) {
|
|
110
|
+
var _a, _b, _c, _d, _e, _f;
|
|
111
|
+
return {
|
|
112
|
+
slug: String((_a = doc.slug) != null ? _a : ""),
|
|
113
|
+
name: String((_b = doc.title) != null ? _b : ""),
|
|
114
|
+
color: String((_c = doc.color) != null ? _c : ""),
|
|
115
|
+
strokeWidth: (_d = doc.strokeWidth) != null ? _d : 2,
|
|
116
|
+
animated: (_e = doc.animated) != null ? _e : true,
|
|
117
|
+
lineStyle: String((_f = doc.lineStyle) != null ? _f : "default"),
|
|
118
|
+
fields: Array.isArray(doc.fields) ? doc.fields : []
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function useFlow(slugOrId, options) {
|
|
122
|
+
var _a, _b;
|
|
123
|
+
const { client, enabled = true } = options;
|
|
124
|
+
const idDetected = isId(slugOrId);
|
|
125
|
+
const flowQuery = useQuery({
|
|
126
|
+
queryKey: ["flows", slugOrId],
|
|
127
|
+
queryFn: () => __async(null, null, function* () {
|
|
128
|
+
if (idDetected) {
|
|
129
|
+
return client.from("flows").findById(slugOrId);
|
|
130
|
+
}
|
|
131
|
+
const result = yield client.from("flows").find({
|
|
132
|
+
where: { slug: { equals: slugOrId } },
|
|
133
|
+
limit: 1
|
|
134
|
+
});
|
|
135
|
+
const doc = result.docs[0];
|
|
136
|
+
if (!doc) throw new Error(`Flow not found: ${slugOrId}`);
|
|
137
|
+
return doc;
|
|
138
|
+
}),
|
|
139
|
+
enabled
|
|
140
|
+
}, client.queryClient);
|
|
141
|
+
const nodeTypesQuery = useQuery({
|
|
142
|
+
queryKey: ["flow-node-types"],
|
|
143
|
+
queryFn: () => __async(null, null, function* () {
|
|
144
|
+
const result = yield client.from("flow-node-types").find({ limit: 100 });
|
|
145
|
+
return result.docs;
|
|
146
|
+
}),
|
|
147
|
+
enabled
|
|
148
|
+
}, client.queryClient);
|
|
149
|
+
const edgeTypesQuery = useQuery({
|
|
150
|
+
queryKey: ["flow-edge-types"],
|
|
151
|
+
queryFn: () => __async(null, null, function* () {
|
|
152
|
+
const result = yield client.from("flow-edge-types").find({ limit: 100 });
|
|
153
|
+
return result.docs;
|
|
154
|
+
}),
|
|
155
|
+
enabled
|
|
156
|
+
}, client.queryClient);
|
|
157
|
+
const nodeTypeDefs = useMemo(() => {
|
|
158
|
+
var _a2;
|
|
159
|
+
const apiDefs = ((_a2 = nodeTypesQuery.data) != null ? _a2 : []).map(apiNodeTypeToNodeTypeDef);
|
|
160
|
+
const builtInSlugs = new Set(BUILT_IN_NODE_TYPES.map((t) => t.slug));
|
|
161
|
+
const customDefs = apiDefs.filter((d) => !builtInSlugs.has(d.slug));
|
|
162
|
+
return [...BUILT_IN_NODE_TYPES, ...customDefs];
|
|
163
|
+
}, [nodeTypesQuery.data]);
|
|
164
|
+
const edgeTypeDefs = useMemo(() => {
|
|
165
|
+
var _a2;
|
|
166
|
+
const apiDefs = ((_a2 = edgeTypesQuery.data) != null ? _a2 : []).map(apiEdgeTypeToEdgeTypeDef);
|
|
167
|
+
const builtInSlugs = new Set(BUILT_IN_EDGE_TYPES.map((t) => t.slug));
|
|
168
|
+
const customDefs = apiDefs.filter((d) => !builtInSlugs.has(d.slug));
|
|
169
|
+
return [...BUILT_IN_EDGE_TYPES, ...customDefs];
|
|
170
|
+
}, [edgeTypesQuery.data]);
|
|
171
|
+
const flow = flowQuery.data;
|
|
172
|
+
const canvas = flow == null ? void 0 : flow.canvas;
|
|
173
|
+
return {
|
|
174
|
+
data: canvas,
|
|
175
|
+
nodeTypeDefs,
|
|
176
|
+
edgeTypeDefs,
|
|
177
|
+
flow,
|
|
178
|
+
isLoading: flowQuery.isLoading || nodeTypesQuery.isLoading || edgeTypesQuery.isLoading,
|
|
179
|
+
error: (_b = (_a = flowQuery.error) != null ? _a : nodeTypesQuery.error) != null ? _b : edgeTypesQuery.error
|
|
180
|
+
};
|
|
181
|
+
}
|
|
28
182
|
|
|
29
183
|
// src/components/FlowRenderer/index.tsx
|
|
30
|
-
function
|
|
31
|
-
|
|
32
|
-
|
|
184
|
+
function sanitizeUrl(url) {
|
|
185
|
+
if (!url) return url;
|
|
186
|
+
try {
|
|
187
|
+
const parsed = new URL(url);
|
|
188
|
+
if (parsed.protocol === "http:" || parsed.protocol === "https:") return url;
|
|
189
|
+
return void 0;
|
|
190
|
+
} catch (e) {
|
|
191
|
+
return void 0;
|
|
192
|
+
}
|
|
33
193
|
}
|
|
34
|
-
function
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
194
|
+
function renderFieldValue(key, val, fieldDef) {
|
|
195
|
+
if (val == null || val === "") return null;
|
|
196
|
+
const fieldType = fieldDef == null ? void 0 : fieldDef.fieldType;
|
|
197
|
+
if (fieldType === "image" || typeof val === "object" && val !== null && "url" in val) {
|
|
198
|
+
const imgUrl = typeof val === "string" ? val : val == null ? void 0 : val.url;
|
|
199
|
+
const safeUrl = sanitizeUrl(imgUrl);
|
|
200
|
+
if (!safeUrl) return null;
|
|
201
|
+
return /* @__PURE__ */ React.createElement(
|
|
202
|
+
"img",
|
|
203
|
+
{
|
|
204
|
+
key,
|
|
205
|
+
src: safeUrl,
|
|
206
|
+
alt: "",
|
|
207
|
+
style: { width: "100%", marginTop: 8, borderRadius: 4 }
|
|
208
|
+
}
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
if (fieldType === "url") {
|
|
212
|
+
const safeUrl = sanitizeUrl(String(val));
|
|
213
|
+
if (!safeUrl) return null;
|
|
214
|
+
return /* @__PURE__ */ React.createElement(
|
|
215
|
+
"a",
|
|
216
|
+
{
|
|
217
|
+
key,
|
|
218
|
+
href: safeUrl,
|
|
219
|
+
target: "_blank",
|
|
220
|
+
rel: "noopener noreferrer",
|
|
221
|
+
style: { display: "block", marginTop: 4, fontSize: "0.85em", color: "#3b82f6", wordBreak: "break-all" }
|
|
222
|
+
},
|
|
223
|
+
String(val)
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
if (fieldType === "color") {
|
|
227
|
+
return /* @__PURE__ */ React.createElement("div", { key, style: { display: "flex", alignItems: "center", gap: 6, marginTop: 4 } }, /* @__PURE__ */ React.createElement(
|
|
228
|
+
"span",
|
|
229
|
+
{
|
|
230
|
+
style: {
|
|
231
|
+
display: "inline-block",
|
|
232
|
+
width: 14,
|
|
233
|
+
height: 14,
|
|
234
|
+
borderRadius: 3,
|
|
235
|
+
backgroundColor: String(val),
|
|
236
|
+
border: "1px solid rgba(0,0,0,0.1)",
|
|
237
|
+
flexShrink: 0
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
), /* @__PURE__ */ React.createElement("span", { style: { fontSize: "0.85em" } }, String(val)));
|
|
241
|
+
}
|
|
242
|
+
if (fieldType === "toggle") {
|
|
243
|
+
const isOn = val === true || val === "true";
|
|
244
|
+
return /* @__PURE__ */ React.createElement("p", { key, style: { margin: "4px 0 0", fontSize: "0.85em" } }, isOn ? "On" : "Off");
|
|
245
|
+
}
|
|
246
|
+
return /* @__PURE__ */ React.createElement("p", { key, style: { margin: "4px 0 0", fontSize: "0.85em", whiteSpace: "pre-wrap" } }, String(val));
|
|
44
247
|
}
|
|
45
|
-
function
|
|
248
|
+
function DefaultDynamicNode({ data }) {
|
|
46
249
|
const d = data;
|
|
47
|
-
return /* @__PURE__ */ React.createElement("div", { style: { padding: 12 } }, /* @__PURE__ */ React.createElement("strong", null, d.label), d.
|
|
48
|
-
|
|
250
|
+
return /* @__PURE__ */ React.createElement("div", { style: { padding: 12 } }, /* @__PURE__ */ React.createElement("strong", null, d.label), d.fields && Object.entries(d.fields).map(([key, val]) => renderFieldValue(key, val)));
|
|
251
|
+
}
|
|
252
|
+
function EnhancedDynamicNode({ data, typeDef }) {
|
|
253
|
+
const fieldMap = new Map(typeDef.fields.map((f) => [f.name, f]));
|
|
254
|
+
const transparent = typeDef.transparentBackground;
|
|
255
|
+
return /* @__PURE__ */ React.createElement("div", { style: { padding: transparent ? 0 : void 0 } }, !transparent && /* @__PURE__ */ React.createElement(
|
|
256
|
+
"div",
|
|
49
257
|
{
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
258
|
+
style: {
|
|
259
|
+
backgroundColor: typeDef.color,
|
|
260
|
+
padding: "4px 12px",
|
|
261
|
+
borderRadius: "6px 6px 0 0",
|
|
262
|
+
fontSize: "0.75em",
|
|
263
|
+
fontWeight: 600,
|
|
264
|
+
color: "rgba(0,0,0,0.6)"
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
typeDef.name
|
|
268
|
+
), /* @__PURE__ */ React.createElement("div", { style: { padding: transparent ? 0 : 12 } }, /* @__PURE__ */ React.createElement("strong", { style: { display: "block", marginBottom: 4 } }, data.label), data.fields && Object.entries(data.fields).map(([key, val]) => {
|
|
269
|
+
const fieldDef = fieldMap.get(key);
|
|
270
|
+
return renderFieldValue(key, val, fieldDef);
|
|
271
|
+
})));
|
|
55
272
|
}
|
|
56
|
-
function
|
|
273
|
+
function DefaultFrameNode({ data }) {
|
|
274
|
+
var _a, _b;
|
|
57
275
|
const d = data;
|
|
58
|
-
|
|
276
|
+
const color = (_a = d.color) != null ? _a : "rgba(128,128,128,0.06)";
|
|
277
|
+
const padding = (_b = d.padding) != null ? _b : 20;
|
|
278
|
+
return /* @__PURE__ */ React.createElement(
|
|
279
|
+
"div",
|
|
280
|
+
{
|
|
281
|
+
style: {
|
|
282
|
+
backgroundColor: color,
|
|
283
|
+
padding,
|
|
284
|
+
width: "100%",
|
|
285
|
+
height: "100%",
|
|
286
|
+
borderRadius: 8,
|
|
287
|
+
border: "2px dashed rgba(128,128,128,0.3)"
|
|
288
|
+
}
|
|
289
|
+
},
|
|
290
|
+
/* @__PURE__ */ React.createElement(
|
|
291
|
+
"div",
|
|
292
|
+
{
|
|
293
|
+
style: {
|
|
294
|
+
fontSize: 11,
|
|
295
|
+
fontWeight: 600,
|
|
296
|
+
color: "rgba(128,128,128,0.6)",
|
|
297
|
+
userSelect: "none"
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
d.label
|
|
301
|
+
)
|
|
302
|
+
);
|
|
59
303
|
}
|
|
60
|
-
function createNodeTypes(
|
|
304
|
+
function createNodeTypes(nodeRenderers, nodeTypeDefsMap) {
|
|
61
305
|
const types = {};
|
|
62
|
-
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
types.note = DefaultNoteNode;
|
|
85
|
-
}
|
|
306
|
+
types.dynamic = ((props) => {
|
|
307
|
+
const d = props.data;
|
|
308
|
+
const typeDef = nodeTypeDefsMap == null ? void 0 : nodeTypeDefsMap.get(d.nodeTypeSlug);
|
|
309
|
+
const CustomRenderer = nodeRenderers == null ? void 0 : nodeRenderers[d.nodeTypeSlug];
|
|
310
|
+
if (CustomRenderer) {
|
|
311
|
+
return /* @__PURE__ */ React.createElement(
|
|
312
|
+
CustomRenderer,
|
|
313
|
+
{
|
|
314
|
+
id: props.id,
|
|
315
|
+
nodeTypeSlug: d.nodeTypeSlug,
|
|
316
|
+
label: d.label,
|
|
317
|
+
fields: d.fields,
|
|
318
|
+
nodeTypeDef: typeDef
|
|
319
|
+
}
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
if (typeDef) {
|
|
323
|
+
return /* @__PURE__ */ React.createElement(EnhancedDynamicNode, { data: d, typeDef });
|
|
324
|
+
}
|
|
325
|
+
return /* @__PURE__ */ React.createElement(DefaultDynamicNode, __spreadValues({}, props));
|
|
326
|
+
});
|
|
327
|
+
types.frame = DefaultFrameNode;
|
|
86
328
|
return types;
|
|
87
329
|
}
|
|
88
330
|
function FlowRenderer({
|
|
89
331
|
data,
|
|
90
332
|
className,
|
|
91
333
|
style,
|
|
92
|
-
|
|
334
|
+
nodeRenderers,
|
|
335
|
+
nodeTypeDefs,
|
|
93
336
|
background = true,
|
|
94
337
|
interactive = false,
|
|
95
|
-
fitView = true
|
|
338
|
+
fitView = true,
|
|
339
|
+
onNodeClick,
|
|
340
|
+
onEdgeClick
|
|
96
341
|
}) {
|
|
97
342
|
var _a, _b;
|
|
98
|
-
const
|
|
343
|
+
const nodeTypeDefsMap = React.useMemo(() => {
|
|
344
|
+
if (!(nodeTypeDefs == null ? void 0 : nodeTypeDefs.length)) return void 0;
|
|
345
|
+
return new Map(nodeTypeDefs.map((d) => [d.slug, d]));
|
|
346
|
+
}, [nodeTypeDefs]);
|
|
347
|
+
const nodeTypes = React.useMemo(
|
|
348
|
+
() => createNodeTypes(nodeRenderers, nodeTypeDefsMap),
|
|
349
|
+
[nodeRenderers, nodeTypeDefsMap]
|
|
350
|
+
);
|
|
351
|
+
if (!data) return null;
|
|
99
352
|
const defaultViewport = !fitView && data.viewport ? data.viewport : void 0;
|
|
100
|
-
return /* @__PURE__ */ React.createElement("div", { className, style: __spreadValues({ width: "100%", height: "100%" }, style) }, /* @__PURE__ */ React.createElement(
|
|
353
|
+
return /* @__PURE__ */ React.createElement(ReactFlowProvider, null, /* @__PURE__ */ React.createElement("div", { className, style: __spreadValues({ width: "100%", height: "100%" }, style) }, /* @__PURE__ */ React.createElement(
|
|
101
354
|
ReactFlow,
|
|
102
355
|
{
|
|
103
356
|
nodes: (_a = data.nodes) != null ? _a : [],
|
|
@@ -105,19 +358,25 @@ function FlowRenderer({
|
|
|
105
358
|
nodeTypes,
|
|
106
359
|
defaultViewport,
|
|
107
360
|
fitView,
|
|
361
|
+
onNodeClick,
|
|
362
|
+
onEdgeClick,
|
|
108
363
|
nodesDraggable: interactive,
|
|
109
364
|
nodesConnectable: false,
|
|
110
|
-
elementsSelectable: interactive,
|
|
365
|
+
elementsSelectable: interactive || !!onNodeClick || !!onEdgeClick,
|
|
111
366
|
panOnDrag: interactive,
|
|
112
367
|
zoomOnScroll: interactive,
|
|
113
368
|
zoomOnPinch: interactive,
|
|
114
369
|
zoomOnDoubleClick: false
|
|
115
370
|
},
|
|
116
371
|
background && /* @__PURE__ */ React.createElement(Background, null)
|
|
117
|
-
));
|
|
372
|
+
)));
|
|
118
373
|
}
|
|
119
374
|
export {
|
|
120
|
-
|
|
121
|
-
|
|
375
|
+
BUILT_IN_EDGE_TYPES,
|
|
376
|
+
BUILT_IN_NODE_TYPES,
|
|
377
|
+
FlowRenderer,
|
|
378
|
+
isDynamicNode,
|
|
379
|
+
isFrameNode,
|
|
380
|
+
useFlow
|
|
122
381
|
};
|
|
123
382
|
//# sourceMappingURL=flow.js.map
|
package/dist/flow.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/FlowRenderer/index.tsx","../src/components/FlowRenderer/types.ts"],"sourcesContent":["'use client'\n\nimport React from 'react'\nimport {\n ReactFlow,\n Background,\n type NodeTypes,\n type NodeProps,\n} from '@xyflow/react'\nimport type {\n CanvasData,\n FlowNodeComponents,\n TextNodeData,\n ImageNodeData,\n IframeNodeData,\n NoteNodeData,\n} from './types'\n\nexport { FLOW_NODE_TYPES } from './types'\nexport type { CanvasData, FlowNodeComponents } from './types'\nexport type {\n FlowNodeType,\n FlowNode,\n FlowEdge,\n FlowViewport,\n FlowNodeData,\n TextNodeData,\n ImageNodeData,\n IframeNodeData,\n NoteNodeData,\n TextNodeSlotProps,\n ImageNodeSlotProps,\n IframeNodeSlotProps,\n NoteNodeSlotProps,\n FlowNodePosition,\n} from './types'\n\n// ── Default node renderers ──\n\nfunction DefaultTextNode({ data }: NodeProps) {\n const d = data as unknown as TextNodeData\n return (\n <div style={{ padding: 12 }}>\n <strong>{d.label}</strong>\n {d.body && <p style={{ margin: '8px 0 0', whiteSpace: 'pre-wrap' }}>{d.body}</p>}\n </div>\n )\n}\n\nfunction DefaultImageNode({ data }: NodeProps) {\n const d = data as unknown as ImageNodeData\n return (\n <div style={{ padding: 12 }}>\n <strong>{d.label}</strong>\n {d.imageUrl && (\n <img\n src={d.imageUrl}\n alt={d.alt || d.label}\n style={{ width: '100%', marginTop: 8, borderRadius: 4 }}\n />\n )}\n {d.caption && (\n <p style={{ margin: '4px 0 0', fontSize: '0.85em', opacity: 0.7 }}>{d.caption}</p>\n )}\n </div>\n )\n}\n\nfunction DefaultIframeNode({ data }: NodeProps) {\n const d = data as unknown as IframeNodeData\n return (\n <div style={{ padding: 12 }}>\n <strong>{d.label}</strong>\n {d.url && (\n <iframe\n src={d.url}\n title={d.label}\n style={{ width: '100%', height: 150, border: 'none', marginTop: 8, borderRadius: 4 }}\n />\n )}\n </div>\n )\n}\n\nfunction DefaultNoteNode({ data }: NodeProps) {\n const d = data as unknown as NoteNodeData\n return (\n <div style={{ padding: 12, backgroundColor: d.color || '#fef3c7', borderRadius: 4 }}>\n <strong>{d.label}</strong>\n {d.body && <p style={{ margin: '8px 0 0', whiteSpace: 'pre-wrap' }}>{d.body}</p>}\n </div>\n )\n}\n\nfunction createNodeTypes(components?: FlowNodeComponents): NodeTypes {\n const types: NodeTypes = {} as NodeTypes\n\n if (components?.Text) {\n const Text = components.Text\n types.text = (({ id, data }: NodeProps) => (\n <Text id={id} data={data as unknown as TextNodeData} />\n )) as NodeTypes[string]\n } else {\n types.text = DefaultTextNode as NodeTypes[string]\n }\n\n if (components?.Image) {\n const Image = components.Image\n types.image = (({ id, data }: NodeProps) => (\n <Image id={id} data={data as unknown as ImageNodeData} />\n )) as NodeTypes[string]\n } else {\n types.image = DefaultImageNode as NodeTypes[string]\n }\n\n if (components?.Iframe) {\n const Iframe = components.Iframe\n types.iframe = (({ id, data }: NodeProps) => (\n <Iframe id={id} data={data as unknown as IframeNodeData} />\n )) as NodeTypes[string]\n } else {\n types.iframe = DefaultIframeNode as NodeTypes[string]\n }\n\n if (components?.Note) {\n const Note = components.Note\n types.note = (({ id, data }: NodeProps) => (\n <Note id={id} data={data as unknown as NoteNodeData} />\n )) as NodeTypes[string]\n } else {\n types.note = DefaultNoteNode as NodeTypes[string]\n }\n\n return types\n}\n\n// ── FlowRenderer ──\n\n/**\n * Renders a Flow canvas in read-only mode.\n *\n * Requires `@xyflow/react` peer dependency and its CSS:\n * ```ts\n * import '@xyflow/react/dist/style.css'\n * ```\n */\nexport interface FlowRendererProps {\n /** Canvas data from Flow document's `canvas` field */\n data: CanvasData\n /** Container className */\n className?: string\n /** Container style */\n style?: React.CSSProperties\n /** Custom node type components (memoize or define outside component to avoid re-renders) */\n nodeComponents?: FlowNodeComponents\n /** Show background pattern (default: true) */\n background?: boolean\n /** Allow user interaction - pan, zoom (default: false for read-only display) */\n interactive?: boolean\n /** Fit view on mount (default: true) */\n fitView?: boolean\n}\n\nexport function FlowRenderer({\n data,\n className,\n style,\n nodeComponents,\n background = true,\n interactive = false,\n fitView = true,\n}: FlowRendererProps) {\n const nodeTypes = React.useMemo(() => createNodeTypes(nodeComponents), [nodeComponents])\n\n const defaultViewport = !fitView && data.viewport ? data.viewport : undefined\n\n return (\n <div className={className} style={{ width: '100%', height: '100%', ...style }}>\n <ReactFlow\n nodes={(data.nodes ?? []) as unknown as Parameters<typeof ReactFlow>[0]['nodes']}\n edges={(data.edges ?? []) as unknown as Parameters<typeof ReactFlow>[0]['edges']}\n nodeTypes={nodeTypes}\n defaultViewport={defaultViewport}\n fitView={fitView}\n nodesDraggable={interactive}\n nodesConnectable={false}\n elementsSelectable={interactive}\n panOnDrag={interactive}\n zoomOnScroll={interactive}\n zoomOnPinch={interactive}\n zoomOnDoubleClick={false}\n >\n {background && <Background />}\n </ReactFlow>\n </div>\n )\n}\n","import type React from 'react'\n\n// ── Node type constants ──\n\nexport const FLOW_NODE_TYPES = ['text', 'image', 'iframe', 'note'] as const\n\nexport type FlowNodeType = (typeof FLOW_NODE_TYPES)[number]\n\n// ── Per-type data ──\n\ninterface BaseNodeData {\n label: string\n}\n\nexport interface TextNodeData extends BaseNodeData {\n nodeType: 'text'\n body?: string\n}\n\nexport interface ImageNodeData extends BaseNodeData {\n nodeType: 'image'\n imageId?: string\n imageUrl?: string\n alt?: string\n caption?: string\n}\n\nexport interface IframeNodeData extends BaseNodeData {\n nodeType: 'iframe'\n url?: string\n}\n\nexport interface NoteNodeData extends BaseNodeData {\n nodeType: 'note'\n body?: string\n color?: string\n}\n\nexport type FlowNodeData = (TextNodeData | ImageNodeData | IframeNodeData | NoteNodeData) &\n Record<string, unknown>\n\n// ── Canvas types (mirrors @xyflow/react but standalone) ──\n\nexport interface FlowNodePosition {\n x: number\n y: number\n}\n\nexport interface FlowNode {\n id: string\n type?: string\n position: FlowNodePosition\n data: FlowNodeData\n style?: React.CSSProperties\n width?: number\n height?: number\n measured?: { width?: number; height?: number }\n [key: string]: unknown\n}\n\nexport interface FlowEdge {\n id: string\n source: string\n target: string\n sourceHandle?: string | null\n targetHandle?: string | null\n type?: string\n style?: React.CSSProperties\n [key: string]: unknown\n}\n\nexport interface FlowViewport {\n x: number\n y: number\n zoom: number\n}\n\nexport interface CanvasData {\n nodes: FlowNode[]\n edges: FlowEdge[]\n viewport: FlowViewport\n}\n\n// ── Component slot props ──\n\nexport interface TextNodeSlotProps {\n id: string\n data: TextNodeData\n}\n\nexport interface ImageNodeSlotProps {\n id: string\n data: ImageNodeData\n}\n\nexport interface IframeNodeSlotProps {\n id: string\n data: IframeNodeData\n}\n\nexport interface NoteNodeSlotProps {\n id: string\n data: NoteNodeData\n}\n\nexport interface FlowNodeComponents {\n Text?: React.ComponentType<TextNodeSlotProps>\n Image?: React.ComponentType<ImageNodeSlotProps>\n Iframe?: React.ComponentType<IframeNodeSlotProps>\n Note?: React.ComponentType<NoteNodeSlotProps>\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/components/FlowRenderer/index.tsx","../src/components/FlowRenderer/types.ts","../src/components/FlowRenderer/built-in-node-types.ts","../src/components/FlowRenderer/built-in-edge-types.ts","../src/components/FlowRenderer/useFlow.ts"],"sourcesContent":["'use client'\n\nimport React from 'react'\nimport {\n ReactFlow,\n ReactFlowProvider,\n Background,\n type NodeTypes,\n type NodeProps,\n} from '@xyflow/react'\nimport type {\n CanvasData,\n DynamicNodeData,\n DynamicNodeSlotProps,\n FlowEdge,\n FlowNode,\n FrameNodeData,\n NodeTypeDef,\n NodeTypeFieldDef,\n} from './types'\n\nexport type {\n CanvasData,\n DynamicNodeSlotProps,\n FlowNode,\n FlowEdge,\n FlowViewport,\n FlowNodePosition,\n FlowNodeData,\n DynamicNodeData,\n FrameNodeData,\n NodeTypeDef,\n NodeTypeFieldDef,\n EdgeTypeDef,\n} from './types'\nexport { isDynamicNode, isFrameNode } from './types'\nexport { BUILT_IN_NODE_TYPES } from './built-in-node-types'\nexport { BUILT_IN_EDGE_TYPES } from './built-in-edge-types'\nexport { useFlow } from './useFlow'\nexport type { UseFlowOptions, UseFlowResult } from './useFlow'\n\n// ── Helpers ──\n\nfunction sanitizeUrl(url: string | undefined): string | undefined {\n if (!url) return url\n try {\n const parsed = new URL(url)\n if (parsed.protocol === 'http:' || parsed.protocol === 'https:') return url\n return undefined\n } catch {\n return undefined\n }\n}\n\n// ── Field renderer (type-aware) ──\n\nfunction renderFieldValue(\n key: string,\n val: unknown,\n fieldDef?: NodeTypeFieldDef,\n): React.ReactNode {\n if (val == null || val === '') return null\n\n const fieldType = fieldDef?.fieldType\n\n // Image field\n if (fieldType === 'image' || (typeof val === 'object' && val !== null && 'url' in val)) {\n const imgUrl = typeof val === 'string' ? val : (val as { url?: string })?.url\n const safeUrl = sanitizeUrl(imgUrl)\n if (!safeUrl) return null\n return (\n <img\n key={key}\n src={safeUrl}\n alt=\"\"\n style={{ width: '100%', marginTop: 8, borderRadius: 4 }}\n />\n )\n }\n\n // URL field\n if (fieldType === 'url') {\n const safeUrl = sanitizeUrl(String(val))\n if (!safeUrl) return null\n return (\n <a\n key={key}\n href={safeUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{ display: 'block', marginTop: 4, fontSize: '0.85em', color: '#3b82f6', wordBreak: 'break-all' }}\n >\n {String(val)}\n </a>\n )\n }\n\n // Color field\n if (fieldType === 'color') {\n return (\n <div key={key} style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: 4 }}>\n <span\n style={{\n display: 'inline-block',\n width: 14,\n height: 14,\n borderRadius: 3,\n backgroundColor: String(val),\n border: '1px solid rgba(0,0,0,0.1)',\n flexShrink: 0,\n }}\n />\n <span style={{ fontSize: '0.85em' }}>{String(val)}</span>\n </div>\n )\n }\n\n // Toggle field\n if (fieldType === 'toggle') {\n const isOn = val === true || val === 'true'\n return (\n <p key={key} style={{ margin: '4px 0 0', fontSize: '0.85em' }}>\n {isOn ? 'On' : 'Off'}\n </p>\n )\n }\n\n // Text / textarea / number / select / fallback\n return (\n <p key={key} style={{ margin: '4px 0 0', fontSize: '0.85em', whiteSpace: 'pre-wrap' }}>\n {String(val)}\n </p>\n )\n}\n\n// ── Default dynamic node renderer ──\n\nfunction DefaultDynamicNode({ data }: NodeProps) {\n const d = data as unknown as DynamicNodeData\n return (\n <div style={{ padding: 12 }}>\n <strong>{d.label}</strong>\n {d.fields &&\n Object.entries(d.fields).map(([key, val]) => renderFieldValue(key, val))}\n </div>\n )\n}\n\n// ── Enhanced dynamic node renderer (with NodeTypeDef) ──\n\nfunction EnhancedDynamicNode({ data, typeDef }: { data: DynamicNodeData; typeDef: NodeTypeDef }) {\n const fieldMap = new Map(typeDef.fields.map((f) => [f.name, f]))\n const transparent = typeDef.transparentBackground\n\n return (\n <div style={{ padding: transparent ? 0 : undefined }}>\n {/* Color badge header (shows type name) */}\n {!transparent && (\n <div\n style={{\n backgroundColor: typeDef.color,\n padding: '4px 12px',\n borderRadius: '6px 6px 0 0',\n fontSize: '0.75em',\n fontWeight: 600,\n color: 'rgba(0,0,0,0.6)',\n }}\n >\n {typeDef.name}\n </div>\n )}\n <div style={{ padding: transparent ? 0 : 12 }}>\n <strong style={{ display: 'block', marginBottom: 4 }}>{data.label}</strong>\n {data.fields &&\n Object.entries(data.fields).map(([key, val]) => {\n const fieldDef = fieldMap.get(key)\n return renderFieldValue(key, val, fieldDef)\n })}\n </div>\n </div>\n )\n}\n\n// ── Default frame node renderer (#15) ──\n\nfunction DefaultFrameNode({ data }: NodeProps) {\n const d = data as unknown as FrameNodeData\n const color = d.color ?? 'rgba(128,128,128,0.06)'\n const padding = d.padding ?? 20\n return (\n <div\n style={{\n backgroundColor: color,\n padding,\n width: '100%',\n height: '100%',\n borderRadius: 8,\n border: '2px dashed rgba(128,128,128,0.3)',\n }}\n >\n <div\n style={{\n fontSize: 11,\n fontWeight: 600,\n color: 'rgba(128,128,128,0.6)',\n userSelect: 'none',\n }}\n >\n {d.label}\n </div>\n </div>\n )\n}\n\n// ── Node types builder ──\n\nfunction createNodeTypes(\n nodeRenderers?: Record<string, React.ComponentType<DynamicNodeSlotProps>>,\n nodeTypeDefsMap?: Map<string, NodeTypeDef>,\n): NodeTypes {\n const types: NodeTypes = {} as NodeTypes\n\n // Dynamic node type\n types.dynamic = ((props: NodeProps) => {\n const d = props.data as unknown as DynamicNodeData\n const typeDef = nodeTypeDefsMap?.get(d.nodeTypeSlug)\n const CustomRenderer = nodeRenderers?.[d.nodeTypeSlug]\n if (CustomRenderer) {\n return (\n <CustomRenderer\n id={props.id}\n nodeTypeSlug={d.nodeTypeSlug}\n label={d.label}\n fields={d.fields}\n nodeTypeDef={typeDef}\n />\n )\n }\n // Use enhanced renderer when type def is available\n if (typeDef) {\n return <EnhancedDynamicNode data={d} typeDef={typeDef} />\n }\n return <DefaultDynamicNode {...props} />\n }) as NodeTypes[string]\n\n // Frame node type\n types.frame = DefaultFrameNode as NodeTypes[string]\n\n return types\n}\n\n// ── FlowRenderer ──\n\n/**\n * Renders a Flow canvas in read-only mode.\n *\n * Requires `@xyflow/react` peer dependency and its CSS:\n * ```ts\n * import '@xyflow/react/dist/style.css'\n * ```\n */\nexport interface FlowRendererProps {\n /** Canvas data from Flow document's `canvas` field */\n data: CanvasData\n /** Container className */\n className?: string\n /** Container style */\n style?: React.CSSProperties\n /** Custom renderers by node type slug (e.g., `{ 'product-card': MyProductCard }`) */\n nodeRenderers?: Record<string, React.ComponentType<DynamicNodeSlotProps>>\n /** Node type definitions for enhanced rendering (color badges, field-type-aware display) */\n nodeTypeDefs?: NodeTypeDef[]\n /** Show background pattern (default: true) */\n background?: boolean\n /** Allow user interaction - pan, zoom (default: false for read-only display) */\n interactive?: boolean\n /** Fit view on mount (default: true) */\n fitView?: boolean\n /** Called when a node is clicked */\n onNodeClick?: (event: React.MouseEvent, node: FlowNode) => void\n /** Called when an edge is clicked */\n onEdgeClick?: (event: React.MouseEvent, edge: FlowEdge) => void\n}\n\nexport function FlowRenderer({\n data,\n className,\n style,\n nodeRenderers,\n nodeTypeDefs,\n background = true,\n interactive = false,\n fitView = true,\n onNodeClick,\n onEdgeClick,\n}: FlowRendererProps) {\n const nodeTypeDefsMap = React.useMemo(() => {\n if (!nodeTypeDefs?.length) return undefined\n return new Map(nodeTypeDefs.map((d) => [d.slug, d]))\n }, [nodeTypeDefs])\n\n const nodeTypes = React.useMemo(\n () => createNodeTypes(nodeRenderers, nodeTypeDefsMap),\n [nodeRenderers, nodeTypeDefsMap],\n )\n\n // Guard: null/undefined data (#8)\n if (!data) return null\n\n const defaultViewport = !fitView && data.viewport ? data.viewport : undefined\n\n return (\n <ReactFlowProvider>\n <div className={className} style={{ width: '100%', height: '100%', ...style }}>\n <ReactFlow\n nodes={(data.nodes ?? []) as unknown as Parameters<typeof ReactFlow>[0]['nodes']}\n edges={(data.edges ?? []) as unknown as Parameters<typeof ReactFlow>[0]['edges']}\n nodeTypes={nodeTypes}\n defaultViewport={defaultViewport}\n fitView={fitView}\n onNodeClick={onNodeClick as Parameters<typeof ReactFlow>[0]['onNodeClick']}\n onEdgeClick={onEdgeClick as Parameters<typeof ReactFlow>[0]['onEdgeClick']}\n nodesDraggable={interactive}\n nodesConnectable={false}\n elementsSelectable={interactive || !!onNodeClick || !!onEdgeClick}\n panOnDrag={interactive}\n zoomOnScroll={interactive}\n zoomOnPinch={interactive}\n zoomOnDoubleClick={false}\n >\n {background && <Background />}\n </ReactFlow>\n </div>\n </ReactFlowProvider>\n )\n}\n","import type React from 'react'\n\n// ── Dynamic node data ──\n\nexport interface DynamicNodeData {\n nodeTypeSlug: string\n label: string\n fields: Record<string, unknown>\n}\n\nexport type FlowNodeData = DynamicNodeData & Record<string, unknown>\n\n// ── Canvas types (mirrors @xyflow/react but standalone) ──\n\nexport interface FlowNodePosition {\n x: number\n y: number\n}\n\nexport interface FlowNode {\n id: string\n type?: string\n position: FlowNodePosition\n data: FlowNodeData\n style?: React.CSSProperties\n width?: number\n height?: number\n measured?: { width?: number; height?: number }\n draggable?: boolean\n [key: string]: unknown\n}\n\nexport interface FlowEdge {\n id: string\n source: string\n target: string\n sourceHandle?: string | null\n targetHandle?: string | null\n type?: string\n style?: React.CSSProperties\n edgeTypeSlug?: string\n fields?: Record<string, unknown>\n [key: string]: unknown\n}\n\nexport interface FlowViewport {\n x: number\n y: number\n zoom: number\n}\n\nexport interface CanvasData {\n nodes: FlowNode[]\n edges: FlowEdge[]\n viewport: FlowViewport\n}\n\n// ── Node type definitions (mirrors console's NodeTypeDef) ──\n\nexport interface NodeTypeFieldDef {\n name: string\n label: string\n fieldType: 'text' | 'textarea' | 'number' | 'url' | 'color' | 'image' | 'select' | 'toggle'\n options?: { label: string; value: string }[]\n defaultValue?: string\n required?: boolean\n}\n\nexport interface NodeTypeDef {\n slug: string\n name: string\n color: string\n defaultSize: { width: number; height: number }\n fields: NodeTypeFieldDef[]\n transparentBackground?: boolean\n}\n\n// ── Edge type definitions (mirrors console's EdgeTypeDef) ──\n\nexport interface EdgeTypeDef {\n slug: string\n name: string\n color: string\n strokeWidth: number\n animated: boolean\n lineStyle: string\n fields: NodeTypeFieldDef[]\n}\n\n// ── Type guards ──\n\nexport function isDynamicNode(node: FlowNode): node is FlowNode & { data: DynamicNodeData } {\n return node.type === 'dynamic'\n}\n\nexport function isFrameNode(node: FlowNode): node is FlowNode & { data: FrameNodeData } {\n return node.type === 'frame'\n}\n\n// ── Component slot props ──\n\nexport interface DynamicNodeSlotProps {\n id: string\n nodeTypeSlug: string\n label: string\n fields: Record<string, unknown>\n nodeTypeDef?: NodeTypeDef\n}\n\n// ── Frame node data ──\n\nexport interface FrameNodeData {\n label: string\n color?: string\n padding?: number\n}\n","import type { NodeTypeDef } from './types'\n\nexport const BUILT_IN_NODE_TYPES: NodeTypeDef[] = [\n {\n slug: 'text',\n name: 'Text',\n color: '#e5e7eb',\n defaultSize: { width: 200, height: 200 },\n fields: [{ name: 'body', label: 'Body', fieldType: 'textarea' }],\n },\n {\n slug: 'image',\n name: 'Image',\n color: '#e5e7eb',\n transparentBackground: true,\n defaultSize: { width: 200, height: 200 },\n fields: [\n { name: 'image', label: 'Image', fieldType: 'image' },\n { name: 'alt', label: 'Alt Text', fieldType: 'text' },\n { name: 'caption', label: 'Caption', fieldType: 'text' },\n ],\n },\n]\n","import type { EdgeTypeDef } from './types'\n\nexport const BUILT_IN_EDGE_TYPES: EdgeTypeDef[] = [\n {\n slug: 'default',\n name: 'Default',\n color: '',\n strokeWidth: 2,\n animated: true,\n lineStyle: 'default',\n fields: [],\n },\n]\n","'use client'\n\nimport { useQuery, type QueryClient } from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport type { CanvasData, NodeTypeDef, EdgeTypeDef } from './types'\nimport { BUILT_IN_NODE_TYPES } from './built-in-node-types'\nimport { BUILT_IN_EDGE_TYPES } from './built-in-edge-types'\n\n// ── Client interface (matches SDK's client shape) ──\n\ninterface FlowClient {\n from(collection: string): {\n find(options?: Record<string, unknown>): Promise<{ docs: Record<string, unknown>[] }>\n findById(id: string, options?: Record<string, unknown>): Promise<Record<string, unknown>>\n }\n queryClient: QueryClient\n}\n\n// ── Options & Result ──\n\nexport interface UseFlowOptions {\n client: FlowClient\n enabled?: boolean\n}\n\nexport interface UseFlowResult {\n data: CanvasData | undefined\n nodeTypeDefs: NodeTypeDef[]\n edgeTypeDefs: EdgeTypeDef[]\n flow: Record<string, unknown> | undefined\n isLoading: boolean\n error: Error | null\n}\n\n// ── Helpers ──\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i\n\nfunction isId(value: string): boolean {\n return UUID_RE.test(value)\n}\n\nfunction apiNodeTypeToNodeTypeDef(doc: Record<string, unknown>): NodeTypeDef {\n return {\n slug: String(doc.slug ?? ''),\n name: String(doc.name ?? ''),\n color: String(doc.color ?? '#e5e7eb'),\n defaultSize: (doc.defaultSize as NodeTypeDef['defaultSize']) ?? { width: 200, height: 200 },\n fields: Array.isArray(doc.fields)\n ? (doc.fields as NodeTypeDef['fields'])\n : [],\n transparentBackground: Boolean(doc.transparentBackground),\n }\n}\n\nfunction apiEdgeTypeToEdgeTypeDef(doc: Record<string, unknown>): EdgeTypeDef {\n return {\n slug: String(doc.slug ?? ''),\n name: String(doc.title ?? ''),\n color: String(doc.color ?? ''),\n strokeWidth: (doc.strokeWidth as number) ?? 2,\n animated: (doc.animated as boolean) ?? true,\n lineStyle: String(doc.lineStyle ?? 'default'),\n fields: Array.isArray(doc.fields)\n ? (doc.fields as EdgeTypeDef['fields'])\n : [],\n }\n}\n\n// ── Hook ──\n\nexport function useFlow(slugOrId: string, options: UseFlowOptions): UseFlowResult {\n const { client, enabled = true } = options\n const idDetected = isId(slugOrId)\n\n // Fetch flow document\n const flowQuery = useQuery<Record<string, unknown>>({\n queryKey: ['flows', slugOrId],\n queryFn: async () => {\n if (idDetected) {\n return client.from('flows').findById(slugOrId)\n }\n const result = await client.from('flows').find({\n where: { slug: { equals: slugOrId } },\n limit: 1,\n })\n const doc = result.docs[0]\n if (!doc) throw new Error(`Flow not found: ${slugOrId}`)\n return doc\n },\n enabled,\n }, client.queryClient)\n\n // Fetch tenant's custom node types\n const nodeTypesQuery = useQuery<Record<string, unknown>[]>({\n queryKey: ['flow-node-types'],\n queryFn: async () => {\n const result = await client.from('flow-node-types').find({ limit: 100 })\n return result.docs\n },\n enabled,\n }, client.queryClient)\n\n // Fetch tenant's custom edge types\n const edgeTypesQuery = useQuery<Record<string, unknown>[]>({\n queryKey: ['flow-edge-types'],\n queryFn: async () => {\n const result = await client.from('flow-edge-types').find({ limit: 100 })\n return result.docs\n },\n enabled,\n }, client.queryClient)\n\n // Merge built-in + API node types\n const nodeTypeDefs = useMemo<NodeTypeDef[]>(() => {\n const apiDefs = (nodeTypesQuery.data ?? []).map(apiNodeTypeToNodeTypeDef)\n const builtInSlugs = new Set(BUILT_IN_NODE_TYPES.map((t) => t.slug))\n // Built-in slugs are reserved — exclude API types with same slug\n const customDefs = apiDefs.filter((d) => !builtInSlugs.has(d.slug))\n return [...BUILT_IN_NODE_TYPES, ...customDefs]\n }, [nodeTypesQuery.data])\n\n // Merge built-in + API edge types\n const edgeTypeDefs = useMemo<EdgeTypeDef[]>(() => {\n const apiDefs = (edgeTypesQuery.data ?? []).map(apiEdgeTypeToEdgeTypeDef)\n const builtInSlugs = new Set(BUILT_IN_EDGE_TYPES.map((t) => t.slug))\n const customDefs = apiDefs.filter((d) => !builtInSlugs.has(d.slug))\n return [...BUILT_IN_EDGE_TYPES, ...customDefs]\n }, [edgeTypesQuery.data])\n\n const flow = flowQuery.data\n const canvas = flow?.canvas as CanvasData | undefined\n\n return {\n data: canvas,\n nodeTypeDefs,\n edgeTypeDefs,\n flow,\n isLoading: flowQuery.isLoading || nodeTypesQuery.isLoading || edgeTypesQuery.isLoading,\n error: (flowQuery.error as Error | null) ?? (nodeTypesQuery.error as Error | null) ?? (edgeTypesQuery.error as Error | null),\n }\n}\n"],"mappings":"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","names":["_a"]}
|