@octaviaflow/core 3.1.0-beta.65 → 3.1.0-beta.68
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/chunk-5AKA6EJB.js +3003 -0
- package/dist/chunk-5AKA6EJB.js.map +1 -0
- package/dist/chunk-JMSZOWT2.js +2616 -0
- package/dist/chunk-JMSZOWT2.js.map +1 -0
- package/dist/chunk-KZP2MNBO.js +2516 -0
- package/dist/chunk-KZP2MNBO.js.map +1 -0
- package/dist/chunk-S4LE4BFQ.js +5934 -0
- package/dist/chunk-S4LE4BFQ.js.map +1 -0
- package/dist/chunk-X7YETDK7.js +107 -0
- package/dist/chunk-X7YETDK7.js.map +1 -0
- package/dist/components/AgentCard/AgentCard.d.ts +5 -0
- package/dist/components/AgentCard/AgentCard.d.ts.map +1 -1
- package/dist/components/Catalog/Catalog.d.ts +116 -0
- package/dist/components/Catalog/Catalog.d.ts.map +1 -0
- package/dist/components/Catalog/index.d.ts +2 -0
- package/dist/components/Catalog/index.d.ts.map +1 -0
- package/dist/components/ExecutionConsole/ExecutionConsole.d.ts.map +1 -1
- package/dist/components/FlowMinimap/FlowMinimap.d.ts.map +1 -1
- package/dist/components/FlowToolbar/FlowToolbar.d.ts +27 -0
- package/dist/components/FlowToolbar/FlowToolbar.d.ts.map +1 -1
- package/dist/components/FlowToolbar/index.d.ts +1 -1
- package/dist/components/FlowToolbar/index.d.ts.map +1 -1
- package/dist/components/ItemDetail/ItemDetail.d.ts +57 -0
- package/dist/components/ItemDetail/ItemDetail.d.ts.map +1 -0
- package/dist/components/ItemDetail/index.d.ts +2 -0
- package/dist/components/ItemDetail/index.d.ts.map +1 -0
- package/dist/components/MessageBlockBuilder/BlockFieldsEditor.d.ts +18 -0
- package/dist/components/MessageBlockBuilder/BlockFieldsEditor.d.ts.map +1 -0
- package/dist/components/MessageBlockBuilder/MessageBlockBuilder.d.ts +6 -0
- package/dist/components/MessageBlockBuilder/MessageBlockBuilder.d.ts.map +1 -0
- package/dist/components/MessageBlockBuilder/MessagePreview.d.ts +9 -0
- package/dist/components/MessageBlockBuilder/MessagePreview.d.ts.map +1 -0
- package/dist/components/MessageBlockBuilder/TokenPanel.d.ts +17 -0
- package/dist/components/MessageBlockBuilder/TokenPanel.d.ts.map +1 -0
- package/dist/components/MessageBlockBuilder/glyphs.d.ts +18 -0
- package/dist/components/MessageBlockBuilder/glyphs.d.ts.map +1 -0
- package/dist/components/MessageBlockBuilder/index.d.ts +4 -0
- package/dist/components/MessageBlockBuilder/index.d.ts.map +1 -0
- package/dist/components/MessageBlockBuilder/internal.d.ts +33 -0
- package/dist/components/MessageBlockBuilder/internal.d.ts.map +1 -0
- package/dist/components/MessageBlockBuilder/platforms/googleChat.d.ts +7 -0
- package/dist/components/MessageBlockBuilder/platforms/googleChat.d.ts.map +1 -0
- package/dist/components/MessageBlockBuilder/platforms/index.d.ts +7 -0
- package/dist/components/MessageBlockBuilder/platforms/index.d.ts.map +1 -0
- package/dist/components/MessageBlockBuilder/platforms/slack.d.ts +7 -0
- package/dist/components/MessageBlockBuilder/platforms/slack.d.ts.map +1 -0
- package/dist/components/MessageBlockBuilder/platforms/teams.d.ts +7 -0
- package/dist/components/MessageBlockBuilder/platforms/teams.d.ts.map +1 -0
- package/dist/components/MessageBlockBuilder/types.d.ts +183 -0
- package/dist/components/MessageBlockBuilder/types.d.ts.map +1 -0
- package/dist/components/PlanCard/PlanCard.d.ts +35 -0
- package/dist/components/PlanCard/PlanCard.d.ts.map +1 -0
- package/dist/components/PlanCard/index.d.ts +2 -0
- package/dist/components/PlanCard/index.d.ts.map +1 -0
- package/dist/components/PlanPicker/PlanPicker.d.ts +16 -0
- package/dist/components/PlanPicker/PlanPicker.d.ts.map +1 -0
- package/dist/components/PlanPicker/context.d.ts +8 -0
- package/dist/components/PlanPicker/context.d.ts.map +1 -0
- package/dist/components/PlanPicker/index.d.ts +2 -0
- package/dist/components/PlanPicker/index.d.ts.map +1 -0
- package/dist/components/PricingCard/index.d.ts +1 -1
- package/dist/components/PricingCard/index.d.ts.map +1 -1
- package/dist/components/TemplateCard/TemplateCard.d.ts +27 -0
- package/dist/components/TemplateCard/TemplateCard.d.ts.map +1 -1
- package/dist/components/UsageMeter/UsageMeter.d.ts +41 -0
- package/dist/components/UsageMeter/UsageMeter.d.ts.map +1 -0
- package/dist/components/UsageMeter/index.d.ts +2 -0
- package/dist/components/UsageMeter/index.d.ts.map +1 -0
- package/dist/components/WorkflowShowcase/ShowcaseScene.d.ts +20 -0
- package/dist/components/WorkflowShowcase/ShowcaseScene.d.ts.map +1 -0
- package/dist/components/WorkflowShowcase/ShowcaseSignup.d.ts +14 -0
- package/dist/components/WorkflowShowcase/ShowcaseSignup.d.ts.map +1 -0
- package/dist/components/WorkflowShowcase/WorkflowShowcase.d.ts +48 -0
- package/dist/components/WorkflowShowcase/WorkflowShowcase.d.ts.map +1 -0
- package/dist/components/WorkflowShowcase/index.d.ts +3 -0
- package/dist/components/WorkflowShowcase/index.d.ts.map +1 -0
- package/dist/components/WorkflowShowcase/showcaseEngine.d.ts +102 -0
- package/dist/components/WorkflowShowcase/showcaseEngine.d.ts.map +1 -0
- package/dist/index.cjs +16261 -11888
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19366 -20520
- package/dist/index.js.map +1 -1
- package/dist/marketing/components/AssistantTranscript/AssistantTranscript.d.ts +15 -0
- package/dist/marketing/components/AssistantTranscript/AssistantTranscript.d.ts.map +1 -0
- package/dist/marketing/components/CtaBanner/CtaBanner.d.ts +16 -0
- package/dist/marketing/components/CtaBanner/CtaBanner.d.ts.map +1 -0
- package/dist/marketing/components/FeatureGrid/FeatureGrid.d.ts +15 -0
- package/dist/marketing/components/FeatureGrid/FeatureGrid.d.ts.map +1 -0
- package/dist/marketing/components/IntegrationsWall/IntegrationsWall.d.ts +19 -0
- package/dist/marketing/components/IntegrationsWall/IntegrationsWall.d.ts.map +1 -0
- package/dist/marketing/components/LiveConsole/LiveConsole.d.ts +21 -0
- package/dist/marketing/components/LiveConsole/LiveConsole.d.ts.map +1 -0
- package/dist/marketing/components/MarketingFooter/MarketingFooter.d.ts +25 -0
- package/dist/marketing/components/MarketingFooter/MarketingFooter.d.ts.map +1 -0
- package/dist/marketing/components/MarketingHero/MarketingHero.d.ts +11 -0
- package/dist/marketing/components/MarketingHero/MarketingHero.d.ts.map +1 -0
- package/dist/marketing/components/MarketingNav/MarketingNav.d.ts +17 -0
- package/dist/marketing/components/MarketingNav/MarketingNav.d.ts.map +1 -0
- package/dist/marketing/components/MarketingSection/MarketingSection.d.ts +15 -0
- package/dist/marketing/components/MarketingSection/MarketingSection.d.ts.map +1 -0
- package/dist/marketing/components/StatBand/StatBand.d.ts +16 -0
- package/dist/marketing/components/StatBand/StatBand.d.ts.map +1 -0
- package/dist/marketing/components/WorkflowShowcase/ShowcaseScene.d.ts +20 -0
- package/dist/marketing/components/WorkflowShowcase/ShowcaseScene.d.ts.map +1 -0
- package/dist/marketing/components/WorkflowShowcase/ShowcaseSignup.d.ts +14 -0
- package/dist/marketing/components/WorkflowShowcase/ShowcaseSignup.d.ts.map +1 -0
- package/dist/marketing/components/WorkflowShowcase/WorkflowShowcase.d.ts +48 -0
- package/dist/marketing/components/WorkflowShowcase/WorkflowShowcase.d.ts.map +1 -0
- package/dist/marketing/components/WorkflowShowcase/index.d.ts +3 -0
- package/dist/marketing/components/WorkflowShowcase/index.d.ts.map +1 -0
- package/dist/marketing/components/WorkflowShowcase/showcaseEngine.d.ts +102 -0
- package/dist/marketing/components/WorkflowShowcase/showcaseEngine.d.ts.map +1 -0
- package/dist/marketing/glyphs.d.ts +20 -0
- package/dist/marketing/glyphs.d.ts.map +1 -0
- package/dist/marketing/index.d.ts +13 -0
- package/dist/marketing/index.d.ts.map +1 -0
- package/dist/marketing.cjs +3985 -0
- package/dist/marketing.cjs.map +1 -0
- package/dist/marketing.js +1669 -0
- package/dist/marketing.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/workflow/components/FlowCanvas/FlowCanvas.d.ts +3 -3
- package/dist/workflow/components/FlowCanvas/FlowCanvas.d.ts.map +1 -1
- package/dist/workflow/components/FlowNode/FlowNode.d.ts.map +1 -1
- package/dist/workflow/components/Handle/Handle.d.ts.map +1 -1
- package/dist/workflow/components/HttpActionPanel/HttpActionPanel.d.ts +29 -0
- package/dist/workflow/components/HttpActionPanel/HttpActionPanel.d.ts.map +1 -0
- package/dist/workflow/components/HttpActionPanel/httpActionTypes.d.ts +135 -0
- package/dist/workflow/components/HttpActionPanel/httpActionTypes.d.ts.map +1 -0
- package/dist/workflow/components/NodeResizer/NodeResizer.d.ts.map +1 -1
- package/dist/workflow/index.d.ts +2 -0
- package/dist/workflow/index.d.ts.map +1 -1
- package/dist/workflow/layout/dagre.d.ts.map +1 -1
- package/dist/workflow/layout/elk.d.ts.map +1 -1
- package/dist/workflow/layout/types.d.ts +1 -1
- package/dist/workflow/layout/types.d.ts.map +1 -1
- package/dist/workflow/utils/parenting.d.ts +26 -6
- package/dist/workflow/utils/parenting.d.ts.map +1 -1
- package/dist/workflow.cjs +7118 -411
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.js +1598 -68
- package/dist/workflow.js.map +1 -1
- package/package.json +6 -1
package/dist/workflow.js
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
|
+
Accordion,
|
|
2
3
|
ActionNode,
|
|
4
|
+
Badge,
|
|
5
|
+
Banner,
|
|
6
|
+
CodeEditor,
|
|
7
|
+
Combobox,
|
|
3
8
|
ConditionNode,
|
|
4
9
|
DEFAULT_NODE_HEIGHT,
|
|
5
10
|
DEFAULT_NODE_KINDS,
|
|
6
11
|
DEFAULT_NODE_WIDTH,
|
|
12
|
+
Disclosure,
|
|
7
13
|
ErrorNode,
|
|
8
14
|
FlowCanvas,
|
|
9
15
|
FlowEdge,
|
|
@@ -12,10 +18,18 @@ import {
|
|
|
12
18
|
GroupNode,
|
|
13
19
|
Handle,
|
|
14
20
|
HttpRequestNode,
|
|
21
|
+
JsonViewer,
|
|
22
|
+
KeyValueEditor,
|
|
15
23
|
NodeResizer,
|
|
24
|
+
NumberInput,
|
|
16
25
|
OutputNode,
|
|
17
26
|
ParallelNode,
|
|
27
|
+
PasswordInput,
|
|
28
|
+
SegmentedControl,
|
|
29
|
+
Spinner,
|
|
18
30
|
StickyNode,
|
|
31
|
+
Switch,
|
|
32
|
+
Tabs,
|
|
19
33
|
TriggerNode,
|
|
20
34
|
WaitNode,
|
|
21
35
|
WebhookNode,
|
|
@@ -50,7 +64,12 @@ import {
|
|
|
50
64
|
useSelection,
|
|
51
65
|
useViewport,
|
|
52
66
|
useViewportOrNull
|
|
53
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-S4LE4BFQ.js";
|
|
68
|
+
import {
|
|
69
|
+
Button,
|
|
70
|
+
Input,
|
|
71
|
+
Select
|
|
72
|
+
} from "./chunk-KZP2MNBO.js";
|
|
54
73
|
import {
|
|
55
74
|
cn
|
|
56
75
|
} from "./chunk-ZAUUGK2Y.js";
|
|
@@ -244,7 +263,7 @@ function createDagreEngine(dagre, defaults = {}) {
|
|
|
244
263
|
}
|
|
245
264
|
for (const e of edges) {
|
|
246
265
|
if (e.hidden) continue;
|
|
247
|
-
g.setEdge(e.source, e.target, { id: e.id });
|
|
266
|
+
g.setEdge(e.source, e.target, { id: e.id }, e.id);
|
|
248
267
|
}
|
|
249
268
|
lib.layout(g);
|
|
250
269
|
const result = [];
|
|
@@ -302,6 +321,13 @@ function createElkEngine(elk, defaults = {}) {
|
|
|
302
321
|
const engineOptions = Object.fromEntries(
|
|
303
322
|
Object.entries(options?.engine ?? {}).map(([k, v]) => [k, String(v)])
|
|
304
323
|
);
|
|
324
|
+
const baseLayeredOptions = {
|
|
325
|
+
"elk.algorithm": algorithm,
|
|
326
|
+
"elk.direction": ELK_DIRECTION[direction],
|
|
327
|
+
"elk.spacing.nodeNode": String(nodeSpacing),
|
|
328
|
+
"elk.layered.spacing.nodeNodeBetweenLayers": String(rankSpacing),
|
|
329
|
+
"elk.layered.considerModelOrder.strategy": "NODES_AND_EDGES"
|
|
330
|
+
};
|
|
305
331
|
const buildChildren = (parentId) => {
|
|
306
332
|
const list = childrenByParent.get(parentId) ?? [];
|
|
307
333
|
return list.map((n) => ({
|
|
@@ -310,10 +336,7 @@ function createElkEngine(elk, defaults = {}) {
|
|
|
310
336
|
height: n.height ?? DEFAULT_NODE_HEIGHT,
|
|
311
337
|
children: childrenByParent.has(n.id) ? buildChildren(n.id) : void 0,
|
|
312
338
|
layoutOptions: childrenByParent.has(n.id) ? {
|
|
313
|
-
|
|
314
|
-
"elk.direction": ELK_DIRECTION[direction],
|
|
315
|
-
"elk.spacing.nodeNode": String(nodeSpacing),
|
|
316
|
-
"elk.layered.spacing.nodeNodeBetweenLayers": String(rankSpacing),
|
|
339
|
+
...baseLayeredOptions,
|
|
317
340
|
...engineOptions
|
|
318
341
|
} : void 0
|
|
319
342
|
}));
|
|
@@ -326,13 +349,8 @@ function createElkEngine(elk, defaults = {}) {
|
|
|
326
349
|
const graph = {
|
|
327
350
|
id: "root",
|
|
328
351
|
layoutOptions: {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
"elk.spacing.nodeNode": String(nodeSpacing),
|
|
332
|
-
"elk.layered.spacing.nodeNodeBetweenLayers": String(rankSpacing),
|
|
333
|
-
...Object.fromEntries(
|
|
334
|
-
Object.entries(options?.engine ?? {}).map(([k, v]) => [k, String(v)])
|
|
335
|
-
)
|
|
352
|
+
...baseLayeredOptions,
|
|
353
|
+
...engineOptions
|
|
336
354
|
},
|
|
337
355
|
children: buildChildren(void 0),
|
|
338
356
|
edges: elkEdges
|
|
@@ -621,11 +639,1510 @@ function ConfigPanel({
|
|
|
621
639
|
);
|
|
622
640
|
}
|
|
623
641
|
|
|
642
|
+
// src/workflow/components/HttpActionPanel/HttpActionPanel.tsx
|
|
643
|
+
import {
|
|
644
|
+
CheckmarkIcon,
|
|
645
|
+
CodeIcon,
|
|
646
|
+
CopyIcon,
|
|
647
|
+
DataViewAltIcon,
|
|
648
|
+
GlobeIcon,
|
|
649
|
+
ListIcon,
|
|
650
|
+
LockedIcon,
|
|
651
|
+
PlayIcon,
|
|
652
|
+
RenewIcon,
|
|
653
|
+
TagIcon
|
|
654
|
+
} from "@octaviaflow/icons";
|
|
655
|
+
import { useCallback as useCallback4, useId, useMemo as useMemo2, useRef as useRef4, useState as useState4 } from "react";
|
|
656
|
+
|
|
657
|
+
// src/workflow/components/HttpActionPanel/httpActionTypes.ts
|
|
658
|
+
var HTTP_METHODS = [
|
|
659
|
+
"GET",
|
|
660
|
+
"POST",
|
|
661
|
+
"PUT",
|
|
662
|
+
"PATCH",
|
|
663
|
+
"DELETE",
|
|
664
|
+
"HEAD",
|
|
665
|
+
"OPTIONS"
|
|
666
|
+
];
|
|
667
|
+
var HTTP_ACTION_DEFAULTS = {
|
|
668
|
+
apiType: "rest",
|
|
669
|
+
method: "GET",
|
|
670
|
+
url: "",
|
|
671
|
+
queryParams: [],
|
|
672
|
+
headers: [],
|
|
673
|
+
bodyType: "json",
|
|
674
|
+
formData: [],
|
|
675
|
+
graphqlQuery: "",
|
|
676
|
+
graphqlVariables: {},
|
|
677
|
+
auth: { type: "none" },
|
|
678
|
+
timeout: 3e4,
|
|
679
|
+
failOnError: true,
|
|
680
|
+
followRedirects: true,
|
|
681
|
+
retry: {
|
|
682
|
+
maxAttempts: 1,
|
|
683
|
+
retryOn: [429, 500, 502, 503, 504],
|
|
684
|
+
initialDelayMs: 1e3,
|
|
685
|
+
backoffFactor: 2,
|
|
686
|
+
maxDelayMs: 3e4
|
|
687
|
+
},
|
|
688
|
+
pagination: { type: "none" },
|
|
689
|
+
extract: {},
|
|
690
|
+
responseType: "json",
|
|
691
|
+
expectedContentTypes: []
|
|
692
|
+
};
|
|
693
|
+
function normalizeKeyValues(raw) {
|
|
694
|
+
if (Array.isArray(raw)) {
|
|
695
|
+
return raw.map((r) => ({
|
|
696
|
+
key: String(r.key ?? ""),
|
|
697
|
+
value: String(r.value ?? ""),
|
|
698
|
+
description: r.description,
|
|
699
|
+
enabled: r.enabled !== false
|
|
700
|
+
}));
|
|
701
|
+
}
|
|
702
|
+
if (raw && typeof raw === "object") {
|
|
703
|
+
return Object.entries(raw).map(([key, value]) => ({
|
|
704
|
+
key,
|
|
705
|
+
value: String(value),
|
|
706
|
+
enabled: true
|
|
707
|
+
}));
|
|
708
|
+
}
|
|
709
|
+
return [];
|
|
710
|
+
}
|
|
711
|
+
function normalizeAuth(raw) {
|
|
712
|
+
const r = raw ?? {};
|
|
713
|
+
const rawType = r.type ?? "none";
|
|
714
|
+
const type = rawType === "oauth2" ? "bearer" : rawType;
|
|
715
|
+
return {
|
|
716
|
+
type: ["none", "basic", "bearer", "apikey"].includes(type) ? type : "none",
|
|
717
|
+
username: r.username ?? "",
|
|
718
|
+
password: r.password ?? "",
|
|
719
|
+
token: r.token ?? r.accessToken ?? "",
|
|
720
|
+
apiKeyName: r.apiKeyName ?? "X-API-Key",
|
|
721
|
+
apiKeyValue: r.apiKeyValue ?? "",
|
|
722
|
+
apiKeyLocation: r.apiKeyLocation === "query" ? "query" : "header"
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
function effectiveUrl(baseUrl, url) {
|
|
726
|
+
const base = (baseUrl ?? "").trim();
|
|
727
|
+
if (!base) return url;
|
|
728
|
+
return `${base.replace(/\/$/, "")}/${url.replace(/^\//, "")}`;
|
|
729
|
+
}
|
|
730
|
+
function serializeKeyValues(rows) {
|
|
731
|
+
return rows.filter((r) => r.key || r.value).map((r) => ({
|
|
732
|
+
key: r.key,
|
|
733
|
+
value: r.value,
|
|
734
|
+
enabled: r.enabled !== false,
|
|
735
|
+
...r.description ? { description: r.description } : {}
|
|
736
|
+
}));
|
|
737
|
+
}
|
|
738
|
+
function validateHttpConfig(config) {
|
|
739
|
+
const errors = [];
|
|
740
|
+
const apiType = config.apiType ?? "rest";
|
|
741
|
+
if (apiType === "rest" && !config.method) errors.push("Method is required");
|
|
742
|
+
if (apiType === "graphql" && !String(config.graphqlQuery ?? "").trim()) {
|
|
743
|
+
errors.push("GraphQL query is required");
|
|
744
|
+
}
|
|
745
|
+
const hasConnection = Boolean(config.connectionId);
|
|
746
|
+
if (!config.url && !hasConnection) {
|
|
747
|
+
errors.push("URL is required");
|
|
748
|
+
} else if (config.url && !hasConnection && !config.baseUrl && !config.url.includes("{{")) {
|
|
749
|
+
try {
|
|
750
|
+
new URL(config.url);
|
|
751
|
+
} catch {
|
|
752
|
+
errors.push("Invalid URL format");
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
if (typeof config.timeout === "number" && config.timeout < 1e3) {
|
|
756
|
+
errors.push("Timeout must be at least 1000ms");
|
|
757
|
+
}
|
|
758
|
+
return { valid: errors.length === 0, errors };
|
|
759
|
+
}
|
|
760
|
+
function countGraphqlVariables(query) {
|
|
761
|
+
return new Set(query.match(/\$[A-Za-z_][A-Za-z0-9_]*/g) ?? []).size;
|
|
762
|
+
}
|
|
763
|
+
function shellTokens(input) {
|
|
764
|
+
const tokens = [];
|
|
765
|
+
const flat = input.replace(/\\\r?\n/g, " ");
|
|
766
|
+
const re = /'([^']*)'|"((?:[^"\\]|\\.)*)"|(\S+)/g;
|
|
767
|
+
let m = re.exec(flat);
|
|
768
|
+
while (m !== null) {
|
|
769
|
+
if (m[1] !== void 0) tokens.push(m[1]);
|
|
770
|
+
else if (m[2] !== void 0) tokens.push(m[2].replace(/\\(["\\])/g, "$1"));
|
|
771
|
+
else tokens.push(m[3]);
|
|
772
|
+
m = re.exec(flat);
|
|
773
|
+
}
|
|
774
|
+
return tokens;
|
|
775
|
+
}
|
|
776
|
+
function parseCurl(input) {
|
|
777
|
+
const tokens = shellTokens(input.trim());
|
|
778
|
+
if (!tokens.length || !/^curl$/i.test(tokens[0])) return null;
|
|
779
|
+
let method;
|
|
780
|
+
let url = "";
|
|
781
|
+
const headers = [];
|
|
782
|
+
const formData = [];
|
|
783
|
+
let bodyRaw;
|
|
784
|
+
let basicUser;
|
|
785
|
+
let followRedirects;
|
|
786
|
+
for (let i = 1; i < tokens.length; i++) {
|
|
787
|
+
const t = tokens[i];
|
|
788
|
+
const next = () => tokens[++i] ?? "";
|
|
789
|
+
if (t === "-X" || t === "--request") {
|
|
790
|
+
const m = next().toUpperCase();
|
|
791
|
+
if (HTTP_METHODS.includes(m)) method = m;
|
|
792
|
+
} else if (t === "-H" || t === "--header") {
|
|
793
|
+
const raw = next();
|
|
794
|
+
const idx = raw.indexOf(":");
|
|
795
|
+
if (idx > 0) {
|
|
796
|
+
headers.push({
|
|
797
|
+
key: raw.slice(0, idx).trim(),
|
|
798
|
+
value: raw.slice(idx + 1).trim(),
|
|
799
|
+
enabled: true
|
|
800
|
+
});
|
|
801
|
+
}
|
|
802
|
+
} else if (t === "-d" || t === "--data" || t === "--data-raw" || t === "--data-binary" || t === "--data-urlencode") {
|
|
803
|
+
bodyRaw = next();
|
|
804
|
+
} else if (t === "-F" || t === "--form") {
|
|
805
|
+
const raw = next();
|
|
806
|
+
const idx = raw.indexOf("=");
|
|
807
|
+
if (idx > 0) {
|
|
808
|
+
formData.push({ key: raw.slice(0, idx), value: raw.slice(idx + 1), enabled: true });
|
|
809
|
+
}
|
|
810
|
+
} else if (t === "-u" || t === "--user") {
|
|
811
|
+
basicUser = next();
|
|
812
|
+
} else if (t === "--url") {
|
|
813
|
+
url = next();
|
|
814
|
+
} else if (t === "-L" || t === "--location") {
|
|
815
|
+
followRedirects = true;
|
|
816
|
+
} else if (t.startsWith("-")) {
|
|
817
|
+
if ([
|
|
818
|
+
"-o",
|
|
819
|
+
"--output",
|
|
820
|
+
"-A",
|
|
821
|
+
"--user-agent",
|
|
822
|
+
"-e",
|
|
823
|
+
"--referer",
|
|
824
|
+
"-b",
|
|
825
|
+
"--cookie",
|
|
826
|
+
"--connect-timeout",
|
|
827
|
+
"-m",
|
|
828
|
+
"--max-time"
|
|
829
|
+
].includes(t)) {
|
|
830
|
+
next();
|
|
831
|
+
}
|
|
832
|
+
} else if (!url) {
|
|
833
|
+
url = t;
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
if (!url) return null;
|
|
837
|
+
const patch = { url, apiType: "rest" };
|
|
838
|
+
const qIdx = url.indexOf("?");
|
|
839
|
+
if (qIdx >= 0) {
|
|
840
|
+
const query = url.slice(qIdx + 1);
|
|
841
|
+
patch.url = url.slice(0, qIdx);
|
|
842
|
+
patch.queryParams = query.split("&").filter(Boolean).map((pair) => {
|
|
843
|
+
const eq = pair.indexOf("=");
|
|
844
|
+
const rawKey = eq >= 0 ? pair.slice(0, eq) : pair;
|
|
845
|
+
const rawValue = eq >= 0 ? pair.slice(eq + 1) : "";
|
|
846
|
+
const decode = (s) => {
|
|
847
|
+
try {
|
|
848
|
+
return decodeURIComponent(s.replace(/\+/g, "%20"));
|
|
849
|
+
} catch {
|
|
850
|
+
return s;
|
|
851
|
+
}
|
|
852
|
+
};
|
|
853
|
+
return { key: decode(rawKey), value: decode(rawValue), enabled: true };
|
|
854
|
+
});
|
|
855
|
+
}
|
|
856
|
+
const authHeaderIdx = headers.findIndex((h) => h.key.toLowerCase() === "authorization");
|
|
857
|
+
if (authHeaderIdx >= 0 && /^bearer\s+/i.test(headers[authHeaderIdx].value)) {
|
|
858
|
+
patch.auth = {
|
|
859
|
+
type: "bearer",
|
|
860
|
+
token: headers[authHeaderIdx].value.replace(/^bearer\s+/i, "")
|
|
861
|
+
};
|
|
862
|
+
headers.splice(authHeaderIdx, 1);
|
|
863
|
+
} else if (basicUser) {
|
|
864
|
+
const sep = basicUser.indexOf(":");
|
|
865
|
+
patch.auth = {
|
|
866
|
+
type: "basic",
|
|
867
|
+
username: sep >= 0 ? basicUser.slice(0, sep) : basicUser,
|
|
868
|
+
password: sep >= 0 ? basicUser.slice(sep + 1) : ""
|
|
869
|
+
};
|
|
870
|
+
}
|
|
871
|
+
if (headers.length) patch.headers = headers;
|
|
872
|
+
if (followRedirects !== void 0) patch.followRedirects = followRedirects;
|
|
873
|
+
if (formData.length) {
|
|
874
|
+
patch.bodyType = "form-data";
|
|
875
|
+
patch.formData = formData;
|
|
876
|
+
patch.method = method ?? "POST";
|
|
877
|
+
} else if (bodyRaw !== void 0) {
|
|
878
|
+
try {
|
|
879
|
+
patch.body = JSON.parse(bodyRaw);
|
|
880
|
+
patch.bodyType = "json";
|
|
881
|
+
} catch {
|
|
882
|
+
patch.body = bodyRaw;
|
|
883
|
+
patch.bodyType = "raw";
|
|
884
|
+
}
|
|
885
|
+
patch.method = method ?? "POST";
|
|
886
|
+
} else {
|
|
887
|
+
patch.method = method ?? "GET";
|
|
888
|
+
patch.bodyType = "none";
|
|
889
|
+
}
|
|
890
|
+
return patch;
|
|
891
|
+
}
|
|
892
|
+
function shellQuote(value) {
|
|
893
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
894
|
+
}
|
|
895
|
+
function buildCurl(config) {
|
|
896
|
+
const parts = ["curl"];
|
|
897
|
+
const method = config.apiType === "graphql" ? "POST" : config.method ?? "GET";
|
|
898
|
+
if (method !== "GET") parts.push(`-X ${method}`);
|
|
899
|
+
let url = effectiveUrl(config.baseUrl, config.url);
|
|
900
|
+
const params = normalizeKeyValues(config.queryParams).filter((p) => p.enabled !== false && p.key);
|
|
901
|
+
if (params.length) {
|
|
902
|
+
const qs = params.map((p) => `${encodeURIComponent(p.key)}=${encodeURIComponent(p.value)}`).join("&");
|
|
903
|
+
url += (url.includes("?") ? "&" : "?") + qs;
|
|
904
|
+
}
|
|
905
|
+
parts.push(shellQuote(url));
|
|
906
|
+
for (const h of normalizeKeyValues(config.headers).filter((h2) => h2.enabled !== false && h2.key)) {
|
|
907
|
+
parts.push(`-H ${shellQuote(`${h.key}: ${h.value}`)}`);
|
|
908
|
+
}
|
|
909
|
+
const auth = config.auth;
|
|
910
|
+
if (auth?.type === "bearer" && auth.token) {
|
|
911
|
+
parts.push(`-H ${shellQuote(`Authorization: Bearer ${auth.token}`)}`);
|
|
912
|
+
} else if (auth?.type === "basic" && auth.username) {
|
|
913
|
+
parts.push(`-u ${shellQuote(`${auth.username}:${auth.password ?? ""}`)}`);
|
|
914
|
+
} else if (auth?.type === "apikey" && auth.apiKeyName && auth.apiKeyValue) {
|
|
915
|
+
if ((auth.apiKeyLocation ?? "header") === "header") {
|
|
916
|
+
parts.push(`-H ${shellQuote(`${auth.apiKeyName}: ${auth.apiKeyValue}`)}`);
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
if (config.apiType === "graphql") {
|
|
920
|
+
const payload = JSON.stringify({
|
|
921
|
+
query: config.graphqlQuery ?? "",
|
|
922
|
+
variables: typeof config.graphqlVariables === "string" ? config.graphqlVariables : config.graphqlVariables ?? {}
|
|
923
|
+
});
|
|
924
|
+
parts.push(`-H ${shellQuote("Content-Type: application/json")}`);
|
|
925
|
+
parts.push(`-d ${shellQuote(payload)}`);
|
|
926
|
+
} else if (config.bodyType === "form-data") {
|
|
927
|
+
for (const f of normalizeKeyValues(config.formData).filter(
|
|
928
|
+
(f2) => f2.enabled !== false && f2.key
|
|
929
|
+
)) {
|
|
930
|
+
parts.push(`-F ${shellQuote(`${f.key}=${f.value}`)}`);
|
|
931
|
+
}
|
|
932
|
+
} else if (config.bodyType && config.bodyType !== "none" && config.body != null) {
|
|
933
|
+
const raw = typeof config.body === "string" ? config.body : JSON.stringify(config.body);
|
|
934
|
+
if (raw) {
|
|
935
|
+
if (config.bodyType === "json") {
|
|
936
|
+
parts.push(`-H ${shellQuote("Content-Type: application/json")}`);
|
|
937
|
+
}
|
|
938
|
+
parts.push(`-d ${shellQuote(raw)}`);
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
if (config.followRedirects !== false) parts.push("-L");
|
|
942
|
+
return parts.join(" ");
|
|
943
|
+
}
|
|
944
|
+
function inferJsonSchema(value, depth = 0) {
|
|
945
|
+
if (value === null || value === void 0) return { type: "null" };
|
|
946
|
+
if (Array.isArray(value)) {
|
|
947
|
+
if (!value.length || depth > 6) return { type: "array" };
|
|
948
|
+
return { type: "array", items: inferJsonSchema(value[0], depth + 1) };
|
|
949
|
+
}
|
|
950
|
+
if (typeof value === "object") {
|
|
951
|
+
if (depth > 6) return { type: "object" };
|
|
952
|
+
const properties = {};
|
|
953
|
+
for (const [k, v] of Object.entries(value)) {
|
|
954
|
+
properties[k] = inferJsonSchema(v, depth + 1);
|
|
955
|
+
}
|
|
956
|
+
return { type: "object", properties };
|
|
957
|
+
}
|
|
958
|
+
return { type: typeof value };
|
|
959
|
+
}
|
|
960
|
+
function countSchemaPaths(schema, depth = 0) {
|
|
961
|
+
if (!schema || typeof schema !== "object" || depth > 8) return 0;
|
|
962
|
+
const s = schema;
|
|
963
|
+
let count = 0;
|
|
964
|
+
if (s.type === "object" && s.properties) {
|
|
965
|
+
for (const child of Object.values(s.properties)) {
|
|
966
|
+
count += 1 + countSchemaPaths(child, depth + 1);
|
|
967
|
+
}
|
|
968
|
+
} else if (s.type === "array" && s.items) {
|
|
969
|
+
count += countSchemaPaths(s.items, depth + 1);
|
|
970
|
+
}
|
|
971
|
+
return count;
|
|
972
|
+
}
|
|
973
|
+
function statusTone(status) {
|
|
974
|
+
if (status < 300) return "success";
|
|
975
|
+
if (status < 400) return "info";
|
|
976
|
+
if (status < 500) return "warning";
|
|
977
|
+
return "error";
|
|
978
|
+
}
|
|
979
|
+
function formatBytes(size) {
|
|
980
|
+
return size < 1024 ? `${size} B` : `${(size / 1024).toFixed(1)} KB`;
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
// src/workflow/components/HttpActionPanel/HttpActionPanel.tsx
|
|
984
|
+
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
985
|
+
function toPairs(rows) {
|
|
986
|
+
return rows.map((r) => ({
|
|
987
|
+
key: r.key,
|
|
988
|
+
value: r.value,
|
|
989
|
+
enabled: r.enabled !== false,
|
|
990
|
+
description: r.description
|
|
991
|
+
}));
|
|
992
|
+
}
|
|
993
|
+
function textOf(raw) {
|
|
994
|
+
if (typeof raw === "string") return raw;
|
|
995
|
+
if (raw == null) return "";
|
|
996
|
+
try {
|
|
997
|
+
return JSON.stringify(raw, null, 2);
|
|
998
|
+
} catch {
|
|
999
|
+
return "";
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
function HttpActionPanel({
|
|
1003
|
+
value,
|
|
1004
|
+
onChange,
|
|
1005
|
+
disabled = false,
|
|
1006
|
+
connections,
|
|
1007
|
+
connectionsLoading = false,
|
|
1008
|
+
onSendPreview,
|
|
1009
|
+
className
|
|
1010
|
+
}) {
|
|
1011
|
+
const uid = useId();
|
|
1012
|
+
const cfgRef = useRef4({
|
|
1013
|
+
...HTTP_ACTION_DEFAULTS,
|
|
1014
|
+
...value,
|
|
1015
|
+
queryParams: normalizeKeyValues(value?.queryParams),
|
|
1016
|
+
headers: normalizeKeyValues(value?.headers),
|
|
1017
|
+
formData: normalizeKeyValues(value?.formData),
|
|
1018
|
+
auth: normalizeAuth(value?.auth),
|
|
1019
|
+
retry: {
|
|
1020
|
+
...HTTP_ACTION_DEFAULTS.retry,
|
|
1021
|
+
...value?.retry
|
|
1022
|
+
},
|
|
1023
|
+
pagination: {
|
|
1024
|
+
...HTTP_ACTION_DEFAULTS.pagination,
|
|
1025
|
+
...value?.pagination
|
|
1026
|
+
}
|
|
1027
|
+
});
|
|
1028
|
+
const [, force] = useState4(0);
|
|
1029
|
+
const emit = useCallback4(
|
|
1030
|
+
(patch) => {
|
|
1031
|
+
cfgRef.current = { ...cfgRef.current, ...patch };
|
|
1032
|
+
force((n) => n + 1);
|
|
1033
|
+
onChange?.(cfgRef.current);
|
|
1034
|
+
},
|
|
1035
|
+
[onChange]
|
|
1036
|
+
);
|
|
1037
|
+
const cfg = cfgRef.current;
|
|
1038
|
+
const connectionId = cfg.connectionId ?? "";
|
|
1039
|
+
const selectedConnection = connections?.find((c) => c.id === connectionId) ?? null;
|
|
1040
|
+
const endpoints = selectedConnection?.endpoints ?? [];
|
|
1041
|
+
const method = cfg.method ?? "GET";
|
|
1042
|
+
const url = cfg.url ?? "";
|
|
1043
|
+
const baseUrl = cfg.baseUrl ?? "";
|
|
1044
|
+
const fullUrl = connectionId ? url : effectiveUrl(baseUrl, url);
|
|
1045
|
+
const queryParams = normalizeKeyValues(cfg.queryParams);
|
|
1046
|
+
const headers = normalizeKeyValues(cfg.headers);
|
|
1047
|
+
const formData = normalizeKeyValues(cfg.formData);
|
|
1048
|
+
const auth = normalizeAuth(cfg.auth);
|
|
1049
|
+
const retry = cfg.retry ?? HTTP_ACTION_DEFAULTS.retry;
|
|
1050
|
+
const pagination = cfg.pagination ?? { type: "none" };
|
|
1051
|
+
const responseType = cfg.responseType ?? "json";
|
|
1052
|
+
const [bodyText, setBodyText] = useState4(() => textOf(cfg.body));
|
|
1053
|
+
const [bodyError, setBodyError] = useState4();
|
|
1054
|
+
const [gqlVarsText, setGqlVarsText] = useState4(() => textOf(cfg.graphqlVariables));
|
|
1055
|
+
const [gqlVarsError, setGqlVarsError] = useState4();
|
|
1056
|
+
const [retryOnText, setRetryOnText] = useState4(() => (retry?.retryOn ?? []).join(", "));
|
|
1057
|
+
const [expectedCtText, setExpectedCtText] = useState4(
|
|
1058
|
+
() => (cfg.expectedContentTypes ?? []).join(", ")
|
|
1059
|
+
);
|
|
1060
|
+
const [urlError, setUrlError] = useState4();
|
|
1061
|
+
const [extractRows, setExtractRows] = useState4(
|
|
1062
|
+
() => Object.entries(cfg.extract ?? {}).map(([key, v]) => ({ key, value: v, enabled: true }))
|
|
1063
|
+
);
|
|
1064
|
+
const [curlOpen, setCurlOpen] = useState4(false);
|
|
1065
|
+
const [curlText, setCurlText] = useState4("");
|
|
1066
|
+
const [curlError, setCurlError] = useState4();
|
|
1067
|
+
const [copiedCurl, setCopiedCurl] = useState4(false);
|
|
1068
|
+
const [copiedResult, setCopiedResult] = useState4(false);
|
|
1069
|
+
const applyCurl = () => {
|
|
1070
|
+
const patch = parseCurl(curlText);
|
|
1071
|
+
if (!patch) {
|
|
1072
|
+
setCurlError(
|
|
1073
|
+
"That doesn't look like a cURL command \u2014 it should start with `curl` and include a URL."
|
|
1074
|
+
);
|
|
1075
|
+
return;
|
|
1076
|
+
}
|
|
1077
|
+
setCurlError(void 0);
|
|
1078
|
+
setCurlText("");
|
|
1079
|
+
setCurlOpen(false);
|
|
1080
|
+
setBodyText(textOf(patch.body));
|
|
1081
|
+
setBodyError(void 0);
|
|
1082
|
+
emit({ ...patch, connectionId: void 0, baseUrl: void 0 });
|
|
1083
|
+
};
|
|
1084
|
+
const copyCurl = async () => {
|
|
1085
|
+
try {
|
|
1086
|
+
await navigator.clipboard?.writeText(buildCurl(cfg));
|
|
1087
|
+
setCopiedCurl(true);
|
|
1088
|
+
setTimeout(() => setCopiedCurl(false), 1600);
|
|
1089
|
+
} catch {
|
|
1090
|
+
}
|
|
1091
|
+
};
|
|
1092
|
+
const copyResult = async () => {
|
|
1093
|
+
if (preview.phase !== "success") return;
|
|
1094
|
+
const r = preview.response;
|
|
1095
|
+
const bundle = {
|
|
1096
|
+
request: {
|
|
1097
|
+
method: cfg.apiType === "graphql" ? "POST" : method,
|
|
1098
|
+
url: connectionId ? `${selectedConnection?.name ?? connectionId} \xB7 ${url}` : fullUrl
|
|
1099
|
+
},
|
|
1100
|
+
response: {
|
|
1101
|
+
status: r.status,
|
|
1102
|
+
statusText: r.statusText,
|
|
1103
|
+
ok: r.ok,
|
|
1104
|
+
durationMs: r.duration,
|
|
1105
|
+
sizeBytes: r.size,
|
|
1106
|
+
headers: r.headers,
|
|
1107
|
+
body: r.body
|
|
1108
|
+
}
|
|
1109
|
+
};
|
|
1110
|
+
try {
|
|
1111
|
+
await navigator.clipboard?.writeText(JSON.stringify(bundle, null, 2));
|
|
1112
|
+
setCopiedResult(true);
|
|
1113
|
+
setTimeout(() => setCopiedResult(false), 1600);
|
|
1114
|
+
} catch {
|
|
1115
|
+
}
|
|
1116
|
+
};
|
|
1117
|
+
const validateUrl = (nextUrl, nextBase, hasConnection) => {
|
|
1118
|
+
if (!nextUrl && !nextBase && !hasConnection) {
|
|
1119
|
+
setUrlError("URL is required");
|
|
1120
|
+
return;
|
|
1121
|
+
}
|
|
1122
|
+
if (!nextUrl || hasConnection || nextBase || nextUrl.includes("{{")) {
|
|
1123
|
+
setUrlError(void 0);
|
|
1124
|
+
return;
|
|
1125
|
+
}
|
|
1126
|
+
try {
|
|
1127
|
+
new URL(nextUrl);
|
|
1128
|
+
setUrlError(void 0);
|
|
1129
|
+
} catch {
|
|
1130
|
+
setUrlError("URL does not look valid");
|
|
1131
|
+
}
|
|
1132
|
+
};
|
|
1133
|
+
const bodyMode = cfg.apiType === "graphql" ? "graphql" : cfg.bodyType ?? "json";
|
|
1134
|
+
const gqlVarCount = useMemo2(
|
|
1135
|
+
() => countGraphqlVariables(cfg.graphqlQuery ?? ""),
|
|
1136
|
+
[cfg.graphqlQuery]
|
|
1137
|
+
);
|
|
1138
|
+
const handleBodyMode = (next) => {
|
|
1139
|
+
if (next === "graphql") {
|
|
1140
|
+
emit(method === "GET" ? { apiType: "graphql", method: "POST" } : { apiType: "graphql" });
|
|
1141
|
+
return;
|
|
1142
|
+
}
|
|
1143
|
+
emit({ apiType: "rest", bodyType: next });
|
|
1144
|
+
};
|
|
1145
|
+
const [preview, setPreview] = useState4({ phase: "idle" });
|
|
1146
|
+
const [schemaInfo, setSchemaInfo] = useState4(
|
|
1147
|
+
null
|
|
1148
|
+
);
|
|
1149
|
+
const lastSchemaKey = useRef4("");
|
|
1150
|
+
const inferAndEmitSchema = useCallback4(
|
|
1151
|
+
(response, forceRefresh = false) => {
|
|
1152
|
+
if (responseType === "binary") return;
|
|
1153
|
+
const snapshot = {
|
|
1154
|
+
status: response.status,
|
|
1155
|
+
statusText: response.statusText,
|
|
1156
|
+
ok: response.ok,
|
|
1157
|
+
headers: response.headers,
|
|
1158
|
+
body: response.body,
|
|
1159
|
+
duration: response.duration,
|
|
1160
|
+
attempts: 1,
|
|
1161
|
+
extracted: {}
|
|
1162
|
+
};
|
|
1163
|
+
const inferred = inferJsonSchema(snapshot);
|
|
1164
|
+
const key = JSON.stringify(inferred);
|
|
1165
|
+
if (!forceRefresh && key === lastSchemaKey.current) return;
|
|
1166
|
+
lastSchemaKey.current = key;
|
|
1167
|
+
emit({ _outputSchema: inferred });
|
|
1168
|
+
const bodySchema = inferred.properties?.body;
|
|
1169
|
+
const topKeys = Object.keys(bodySchema?.properties ?? inferred.properties ?? {});
|
|
1170
|
+
setSchemaInfo({ pathCount: countSchemaPaths(inferred), topKeys });
|
|
1171
|
+
},
|
|
1172
|
+
[emit, responseType]
|
|
1173
|
+
);
|
|
1174
|
+
const sendPreview = async () => {
|
|
1175
|
+
if (!onSendPreview) return;
|
|
1176
|
+
setPreview({ phase: "loading" });
|
|
1177
|
+
try {
|
|
1178
|
+
const response = await onSendPreview({
|
|
1179
|
+
method: cfg.apiType === "graphql" ? "POST" : method,
|
|
1180
|
+
url: connectionId ? url : fullUrl,
|
|
1181
|
+
connectionId: connectionId || void 0,
|
|
1182
|
+
headers,
|
|
1183
|
+
queryParams,
|
|
1184
|
+
bodyType: cfg.bodyType ?? "json",
|
|
1185
|
+
body: bodyText,
|
|
1186
|
+
formData,
|
|
1187
|
+
graphqlQuery: cfg.apiType === "graphql" ? cfg.graphqlQuery ?? "" : void 0,
|
|
1188
|
+
graphqlVariables: cfg.apiType === "graphql" ? gqlVarsText : void 0,
|
|
1189
|
+
auth,
|
|
1190
|
+
timeout: cfg.timeout ?? 3e4
|
|
1191
|
+
});
|
|
1192
|
+
setPreview({ phase: "success", response });
|
|
1193
|
+
inferAndEmitSchema(response);
|
|
1194
|
+
} catch (err) {
|
|
1195
|
+
setPreview({
|
|
1196
|
+
phase: "error",
|
|
1197
|
+
message: err instanceof Error ? err.message : "Request failed"
|
|
1198
|
+
});
|
|
1199
|
+
}
|
|
1200
|
+
};
|
|
1201
|
+
const previewUrlOk = Boolean(fullUrl) && !fullUrl.includes("{{");
|
|
1202
|
+
const canSend = Boolean(onSendPreview) && previewUrlOk && preview.phase !== "loading" && !disabled;
|
|
1203
|
+
const paramCount = queryParams.filter((r) => r.enabled !== false && r.key).length;
|
|
1204
|
+
const headerCount = headers.filter((r) => r.enabled !== false && r.key).length;
|
|
1205
|
+
const extractCount = extractRows.filter((r) => r.key).length;
|
|
1206
|
+
const advancedSummary = [];
|
|
1207
|
+
if ((cfg.timeout ?? 3e4) !== 3e4) advancedSummary.push(`${(cfg.timeout ?? 0) / 1e3}s`);
|
|
1208
|
+
if ((retry?.maxAttempts ?? 1) > 1) advancedSummary.push(`retry \xD7${retry?.maxAttempts}`);
|
|
1209
|
+
if (pagination.type !== "none") advancedSummary.push(pagination.type.replace("_", " "));
|
|
1210
|
+
if (extractCount > 0) advancedSummary.push(`${extractCount} extracted`);
|
|
1211
|
+
const kvTab = (rows, key, desc, keyPlaceholder) => /* @__PURE__ */ jsxs2("div", { className: "ods-http-panel__tab", children: [
|
|
1212
|
+
/* @__PURE__ */ jsx2("p", { className: "ods-http-panel__desc", children: desc }),
|
|
1213
|
+
/* @__PURE__ */ jsx2(
|
|
1214
|
+
KeyValueEditor,
|
|
1215
|
+
{
|
|
1216
|
+
pairs: toPairs(rows),
|
|
1217
|
+
onChange: (pairs) => emit({ [key]: serializeKeyValues(pairs) }),
|
|
1218
|
+
rowToggle: true,
|
|
1219
|
+
showDescription: true,
|
|
1220
|
+
keyPlaceholder,
|
|
1221
|
+
valuePlaceholder: "value or {{var}}",
|
|
1222
|
+
emptyLabel: "No entries yet \u2014 click Add to begin.",
|
|
1223
|
+
addLabel: "Add",
|
|
1224
|
+
size: "sm",
|
|
1225
|
+
disabled
|
|
1226
|
+
}
|
|
1227
|
+
)
|
|
1228
|
+
] });
|
|
1229
|
+
const paramsTab = kvTab(
|
|
1230
|
+
queryParams,
|
|
1231
|
+
"queryParams",
|
|
1232
|
+
/* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
1233
|
+
"Query parameters appended to the URL. Supports ",
|
|
1234
|
+
/* @__PURE__ */ jsx2("code", { children: "{{variable}}" }),
|
|
1235
|
+
" interpolation."
|
|
1236
|
+
] }),
|
|
1237
|
+
"param name"
|
|
1238
|
+
);
|
|
1239
|
+
const headersTab = kvTab(
|
|
1240
|
+
headers,
|
|
1241
|
+
"headers",
|
|
1242
|
+
/* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
1243
|
+
"Request headers. Auth headers are injected automatically from the Auth tab. Supports",
|
|
1244
|
+
" ",
|
|
1245
|
+
/* @__PURE__ */ jsx2("code", { children: "{{variable}}" }),
|
|
1246
|
+
" interpolation."
|
|
1247
|
+
] }),
|
|
1248
|
+
"Header-Name"
|
|
1249
|
+
);
|
|
1250
|
+
const bodyTab = /* @__PURE__ */ jsxs2("div", { className: "ods-http-panel__tab", children: [
|
|
1251
|
+
/* @__PURE__ */ jsx2(
|
|
1252
|
+
SegmentedControl,
|
|
1253
|
+
{
|
|
1254
|
+
size: "sm",
|
|
1255
|
+
"aria-label": "Body type",
|
|
1256
|
+
options: [
|
|
1257
|
+
{ value: "none", label: "None" },
|
|
1258
|
+
{ value: "json", label: "JSON" },
|
|
1259
|
+
{ value: "graphql", label: "GraphQL" },
|
|
1260
|
+
{ value: "raw", label: "Raw" },
|
|
1261
|
+
{ value: "form-data", label: "Form" },
|
|
1262
|
+
{ value: "xml", label: "XML" }
|
|
1263
|
+
],
|
|
1264
|
+
value: bodyMode,
|
|
1265
|
+
onChange: handleBodyMode
|
|
1266
|
+
}
|
|
1267
|
+
),
|
|
1268
|
+
bodyMode === "none" && /* @__PURE__ */ jsx2("p", { className: "ods-http-panel__empty", children: "No request body will be sent." }),
|
|
1269
|
+
(bodyMode === "json" || bodyMode === "raw" || bodyMode === "xml") && /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
1270
|
+
/* @__PURE__ */ jsx2(
|
|
1271
|
+
CodeEditor,
|
|
1272
|
+
{
|
|
1273
|
+
value: bodyText,
|
|
1274
|
+
language: bodyMode === "json" ? "json" : "plain",
|
|
1275
|
+
onChange: (next) => {
|
|
1276
|
+
setBodyText(next);
|
|
1277
|
+
if (bodyMode === "json" && next.trim()) {
|
|
1278
|
+
try {
|
|
1279
|
+
emit({ body: JSON.parse(next) });
|
|
1280
|
+
setBodyError(void 0);
|
|
1281
|
+
} catch {
|
|
1282
|
+
setBodyError("Invalid JSON");
|
|
1283
|
+
emit({ body: next });
|
|
1284
|
+
}
|
|
1285
|
+
} else {
|
|
1286
|
+
setBodyError(void 0);
|
|
1287
|
+
emit({ body: next || void 0 });
|
|
1288
|
+
}
|
|
1289
|
+
},
|
|
1290
|
+
readOnly: disabled,
|
|
1291
|
+
minHeight: 180,
|
|
1292
|
+
ariaLabel: "Request body"
|
|
1293
|
+
}
|
|
1294
|
+
),
|
|
1295
|
+
bodyError && /* @__PURE__ */ jsxs2("p", { className: "ods-http-panel__error", children: [
|
|
1296
|
+
"\u26A0 ",
|
|
1297
|
+
bodyError
|
|
1298
|
+
] }),
|
|
1299
|
+
/* @__PURE__ */ jsxs2("p", { className: "ods-http-panel__desc", children: [
|
|
1300
|
+
"Supports ",
|
|
1301
|
+
/* @__PURE__ */ jsx2("code", { children: "{{variable}}" }),
|
|
1302
|
+
" interpolation."
|
|
1303
|
+
] })
|
|
1304
|
+
] }),
|
|
1305
|
+
bodyMode === "graphql" && /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
1306
|
+
/* @__PURE__ */ jsx2(
|
|
1307
|
+
CodeEditor,
|
|
1308
|
+
{
|
|
1309
|
+
value: cfg.graphqlQuery ?? "",
|
|
1310
|
+
language: "plain",
|
|
1311
|
+
onChange: (next) => emit({ graphqlQuery: next }),
|
|
1312
|
+
readOnly: disabled,
|
|
1313
|
+
minHeight: 160,
|
|
1314
|
+
placeholder: "query ($id: ID!) {\n node(id: $id) { id }\n}",
|
|
1315
|
+
ariaLabel: "GraphQL query"
|
|
1316
|
+
}
|
|
1317
|
+
),
|
|
1318
|
+
/* @__PURE__ */ jsxs2(
|
|
1319
|
+
Disclosure,
|
|
1320
|
+
{
|
|
1321
|
+
size: "sm",
|
|
1322
|
+
title: "Variables",
|
|
1323
|
+
defaultOpen: Boolean(gqlVarsText.trim()) || gqlVarCount > 0,
|
|
1324
|
+
trailing: gqlVarCount > 0 ? /* @__PURE__ */ jsx2(Badge, { size: "sm", variant: "neutral", children: gqlVarCount }) : void 0,
|
|
1325
|
+
children: [
|
|
1326
|
+
/* @__PURE__ */ jsx2(
|
|
1327
|
+
CodeEditor,
|
|
1328
|
+
{
|
|
1329
|
+
value: gqlVarsText,
|
|
1330
|
+
language: "json",
|
|
1331
|
+
onChange: (next) => {
|
|
1332
|
+
setGqlVarsText(next);
|
|
1333
|
+
if (!next.trim()) {
|
|
1334
|
+
setGqlVarsError(void 0);
|
|
1335
|
+
emit({ graphqlVariables: {} });
|
|
1336
|
+
return;
|
|
1337
|
+
}
|
|
1338
|
+
try {
|
|
1339
|
+
emit({ graphqlVariables: JSON.parse(next) });
|
|
1340
|
+
setGqlVarsError(void 0);
|
|
1341
|
+
} catch {
|
|
1342
|
+
setGqlVarsError("Invalid JSON");
|
|
1343
|
+
}
|
|
1344
|
+
},
|
|
1345
|
+
readOnly: disabled,
|
|
1346
|
+
minHeight: 100,
|
|
1347
|
+
ariaLabel: "GraphQL variables (JSON)"
|
|
1348
|
+
}
|
|
1349
|
+
),
|
|
1350
|
+
gqlVarsError && /* @__PURE__ */ jsxs2("p", { className: "ods-http-panel__error", children: [
|
|
1351
|
+
"\u26A0 ",
|
|
1352
|
+
gqlVarsError
|
|
1353
|
+
] })
|
|
1354
|
+
]
|
|
1355
|
+
}
|
|
1356
|
+
)
|
|
1357
|
+
] }),
|
|
1358
|
+
bodyMode === "form-data" && /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
1359
|
+
/* @__PURE__ */ jsx2("p", { className: "ods-http-panel__desc", children: "Multipart form fields. Content-Type is set automatically with the boundary." }),
|
|
1360
|
+
/* @__PURE__ */ jsx2(
|
|
1361
|
+
KeyValueEditor,
|
|
1362
|
+
{
|
|
1363
|
+
pairs: toPairs(formData),
|
|
1364
|
+
onChange: (pairs) => emit({ formData: serializeKeyValues(pairs), bodyType: "form-data" }),
|
|
1365
|
+
rowToggle: true,
|
|
1366
|
+
keyPlaceholder: "field name",
|
|
1367
|
+
valuePlaceholder: "value or {{var}}",
|
|
1368
|
+
emptyLabel: "No fields yet \u2014 click Add to begin.",
|
|
1369
|
+
addLabel: "Add",
|
|
1370
|
+
size: "sm",
|
|
1371
|
+
disabled
|
|
1372
|
+
}
|
|
1373
|
+
)
|
|
1374
|
+
] })
|
|
1375
|
+
] });
|
|
1376
|
+
const authTab = /* @__PURE__ */ jsxs2("div", { className: "ods-http-panel__tab", children: [
|
|
1377
|
+
connectionId ? /* @__PURE__ */ jsxs2(Banner, { variant: "success", appearance: "subtle", size: "sm", children: [
|
|
1378
|
+
"Authentication is inherited from ",
|
|
1379
|
+
/* @__PURE__ */ jsx2("strong", { children: selectedConnection?.name }),
|
|
1380
|
+
" and refreshed automatically. Choose a type below only to override it for this step."
|
|
1381
|
+
] }) : /* @__PURE__ */ jsx2(Banner, { variant: "info", appearance: "subtle", size: "sm", children: "For OAuth 2.0 APIs that need a login screen, create an API connection and select it as the Source \u2014 the token is obtained once and refreshed automatically. Inline auth here is for non-interactive credentials only." }),
|
|
1382
|
+
/* @__PURE__ */ jsx2(
|
|
1383
|
+
Select,
|
|
1384
|
+
{
|
|
1385
|
+
id: `${uid}-auth-type`,
|
|
1386
|
+
label: connectionId ? "Override authentication" : "Authentication",
|
|
1387
|
+
value: auth.type,
|
|
1388
|
+
onChange: (next) => emit({ auth: { ...auth, type: next } }),
|
|
1389
|
+
disabled,
|
|
1390
|
+
options: [
|
|
1391
|
+
{ value: "none", label: connectionId ? "Inherit from connection" : "No auth" },
|
|
1392
|
+
{ value: "basic", label: "Basic auth (username + password)" },
|
|
1393
|
+
{ value: "bearer", label: "Bearer token" },
|
|
1394
|
+
{ value: "apikey", label: "API key" }
|
|
1395
|
+
]
|
|
1396
|
+
}
|
|
1397
|
+
),
|
|
1398
|
+
auth.type === "basic" && /* @__PURE__ */ jsxs2("div", { className: "ods-http-panel__grid", children: [
|
|
1399
|
+
/* @__PURE__ */ jsx2(
|
|
1400
|
+
Input,
|
|
1401
|
+
{
|
|
1402
|
+
id: `${uid}-auth-user`,
|
|
1403
|
+
label: "Username",
|
|
1404
|
+
value: auth.username ?? "",
|
|
1405
|
+
placeholder: "username or {{var}}",
|
|
1406
|
+
onChange: (e) => emit({ auth: { ...auth, username: e.target.value } }),
|
|
1407
|
+
disabled
|
|
1408
|
+
}
|
|
1409
|
+
),
|
|
1410
|
+
/* @__PURE__ */ jsx2(
|
|
1411
|
+
PasswordInput,
|
|
1412
|
+
{
|
|
1413
|
+
id: `${uid}-auth-pass`,
|
|
1414
|
+
label: "Password",
|
|
1415
|
+
value: auth.password ?? "",
|
|
1416
|
+
placeholder: "password or {{var}}",
|
|
1417
|
+
onChange: (next) => emit({ auth: { ...auth, password: next } }),
|
|
1418
|
+
disabled
|
|
1419
|
+
}
|
|
1420
|
+
)
|
|
1421
|
+
] }),
|
|
1422
|
+
auth.type === "bearer" && /* @__PURE__ */ jsx2(
|
|
1423
|
+
PasswordInput,
|
|
1424
|
+
{
|
|
1425
|
+
id: `${uid}-auth-token`,
|
|
1426
|
+
label: "Token",
|
|
1427
|
+
value: auth.token ?? "",
|
|
1428
|
+
placeholder: "your-token or {{step.token}}",
|
|
1429
|
+
onChange: (next) => emit({ auth: { ...auth, token: next } }),
|
|
1430
|
+
disabled
|
|
1431
|
+
}
|
|
1432
|
+
),
|
|
1433
|
+
auth.type === "apikey" && /* @__PURE__ */ jsxs2("div", { className: "ods-http-panel__grid", children: [
|
|
1434
|
+
/* @__PURE__ */ jsx2(
|
|
1435
|
+
Input,
|
|
1436
|
+
{
|
|
1437
|
+
id: `${uid}-auth-keyname`,
|
|
1438
|
+
label: "Key name",
|
|
1439
|
+
value: auth.apiKeyName ?? "",
|
|
1440
|
+
placeholder: "X-API-Key",
|
|
1441
|
+
onChange: (e) => emit({ auth: { ...auth, apiKeyName: e.target.value } }),
|
|
1442
|
+
disabled
|
|
1443
|
+
}
|
|
1444
|
+
),
|
|
1445
|
+
/* @__PURE__ */ jsx2(
|
|
1446
|
+
PasswordInput,
|
|
1447
|
+
{
|
|
1448
|
+
id: `${uid}-auth-keyval`,
|
|
1449
|
+
label: "Key value",
|
|
1450
|
+
value: auth.apiKeyValue ?? "",
|
|
1451
|
+
placeholder: "your-api-key or {{var}}",
|
|
1452
|
+
onChange: (next) => emit({ auth: { ...auth, apiKeyValue: next } }),
|
|
1453
|
+
disabled
|
|
1454
|
+
}
|
|
1455
|
+
),
|
|
1456
|
+
/* @__PURE__ */ jsx2(
|
|
1457
|
+
Select,
|
|
1458
|
+
{
|
|
1459
|
+
id: `${uid}-auth-keyloc`,
|
|
1460
|
+
label: "Send in",
|
|
1461
|
+
value: auth.apiKeyLocation ?? "header",
|
|
1462
|
+
onChange: (next) => emit({ auth: { ...auth, apiKeyLocation: next } }),
|
|
1463
|
+
disabled,
|
|
1464
|
+
options: [
|
|
1465
|
+
{ value: "header", label: "Request header" },
|
|
1466
|
+
{ value: "query", label: "Query parameter" }
|
|
1467
|
+
]
|
|
1468
|
+
}
|
|
1469
|
+
)
|
|
1470
|
+
] }),
|
|
1471
|
+
auth.type === "none" && /* @__PURE__ */ jsx2("p", { className: "ods-http-panel__empty", children: connectionId ? "This step uses the connection's authentication." : "No authentication will be added to this request." })
|
|
1472
|
+
] });
|
|
1473
|
+
const responseTab = /* @__PURE__ */ jsxs2("div", { className: "ods-http-panel__tab", children: [
|
|
1474
|
+
/* @__PURE__ */ jsx2(
|
|
1475
|
+
SegmentedControl,
|
|
1476
|
+
{
|
|
1477
|
+
size: "sm",
|
|
1478
|
+
"aria-label": "Response type",
|
|
1479
|
+
options: [
|
|
1480
|
+
{ value: "json", label: "JSON" },
|
|
1481
|
+
{ value: "text", label: "Text" },
|
|
1482
|
+
{ value: "binary", label: "Binary" }
|
|
1483
|
+
],
|
|
1484
|
+
value: responseType,
|
|
1485
|
+
onChange: (next) => emit({ responseType: next })
|
|
1486
|
+
}
|
|
1487
|
+
),
|
|
1488
|
+
/* @__PURE__ */ jsxs2("p", { className: "ods-http-panel__desc", children: [
|
|
1489
|
+
responseType === "json" && "Tries to parse the response body as JSON; falls back to raw text on parse failure.",
|
|
1490
|
+
responseType === "text" && "Returns the raw response body as a string. No JSON parsing.",
|
|
1491
|
+
responseType === "binary" && /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
1492
|
+
"Returns the response as bytes with ",
|
|
1493
|
+
/* @__PURE__ */ jsx2("code", { children: "fileName" }),
|
|
1494
|
+
", ",
|
|
1495
|
+
/* @__PURE__ */ jsx2("code", { children: "contentType" }),
|
|
1496
|
+
" and",
|
|
1497
|
+
" ",
|
|
1498
|
+
/* @__PURE__ */ jsx2("code", { children: "size" }),
|
|
1499
|
+
" on the step output \u2014 for downloads feeding file actions. Pagination is not compatible with binary responses."
|
|
1500
|
+
] })
|
|
1501
|
+
] }),
|
|
1502
|
+
/* @__PURE__ */ jsx2(
|
|
1503
|
+
Input,
|
|
1504
|
+
{
|
|
1505
|
+
id: `${uid}-expected-ct`,
|
|
1506
|
+
label: "Expected content-types (optional)",
|
|
1507
|
+
value: expectedCtText,
|
|
1508
|
+
placeholder: "application/pdf, application/json",
|
|
1509
|
+
helperText: "Comma-separated. A warning is logged when the response Content-Type matches none of these.",
|
|
1510
|
+
onChange: (e) => {
|
|
1511
|
+
setExpectedCtText(e.target.value);
|
|
1512
|
+
const parts = e.target.value.split(",").map((s) => s.trim()).filter(Boolean);
|
|
1513
|
+
emit({ expectedContentTypes: parts.length ? parts : void 0 });
|
|
1514
|
+
},
|
|
1515
|
+
disabled
|
|
1516
|
+
}
|
|
1517
|
+
),
|
|
1518
|
+
/* @__PURE__ */ jsxs2("div", { className: "ods-http-panel__schema", children: [
|
|
1519
|
+
/* @__PURE__ */ jsx2("span", { className: "ods-http-panel__schema-label", children: "Data stream schema" }),
|
|
1520
|
+
schemaInfo ? /* @__PURE__ */ jsxs2("p", { className: "ods-http-panel__desc", children: [
|
|
1521
|
+
/* @__PURE__ */ jsxs2(Badge, { size: "sm", variant: "success", children: [
|
|
1522
|
+
schemaInfo.pathCount,
|
|
1523
|
+
" paths"
|
|
1524
|
+
] }),
|
|
1525
|
+
" ",
|
|
1526
|
+
"Inferred from the last test send. Top-level keys:",
|
|
1527
|
+
" ",
|
|
1528
|
+
/* @__PURE__ */ jsx2("code", { children: schemaInfo.topKeys.join(", ") }),
|
|
1529
|
+
". Downstream binding (Field Mapper, Transform, ForEach) sees this shape immediately; Save persists it."
|
|
1530
|
+
] }) : /* @__PURE__ */ jsxs2("p", { className: "ods-http-panel__desc", children: [
|
|
1531
|
+
"No schema yet \u2014 hit ",
|
|
1532
|
+
/* @__PURE__ */ jsx2("strong", { children: "Send" }),
|
|
1533
|
+
" in the request bar. On success the response shape is inferred so downstream steps bind against real field names."
|
|
1534
|
+
] }),
|
|
1535
|
+
/* @__PURE__ */ jsx2(
|
|
1536
|
+
Button,
|
|
1537
|
+
{
|
|
1538
|
+
variant: "ghost",
|
|
1539
|
+
size: "sm",
|
|
1540
|
+
disabled: preview.phase !== "success" || responseType === "binary" || disabled,
|
|
1541
|
+
onClick: () => {
|
|
1542
|
+
if (preview.phase === "success") inferAndEmitSchema(preview.response, true);
|
|
1543
|
+
},
|
|
1544
|
+
children: "Refresh schema from last send"
|
|
1545
|
+
}
|
|
1546
|
+
)
|
|
1547
|
+
] })
|
|
1548
|
+
] });
|
|
1549
|
+
const tabItems = [
|
|
1550
|
+
{
|
|
1551
|
+
value: "params",
|
|
1552
|
+
label: paramCount ? `Params \xB7 ${paramCount}` : "Params",
|
|
1553
|
+
icon: /* @__PURE__ */ jsx2(ListIcon, { size: "sm" }),
|
|
1554
|
+
children: paramsTab
|
|
1555
|
+
},
|
|
1556
|
+
{
|
|
1557
|
+
value: "headers",
|
|
1558
|
+
label: headerCount ? `Headers \xB7 ${headerCount}` : "Headers",
|
|
1559
|
+
icon: /* @__PURE__ */ jsx2(TagIcon, { size: "sm" }),
|
|
1560
|
+
children: headersTab
|
|
1561
|
+
},
|
|
1562
|
+
{
|
|
1563
|
+
value: "body",
|
|
1564
|
+
label: bodyMode === "none" ? "Body" : `Body \xB7 ${bodyMode === "form-data" ? "form" : bodyMode}`,
|
|
1565
|
+
icon: /* @__PURE__ */ jsx2(CodeIcon, { size: "sm" }),
|
|
1566
|
+
children: bodyTab
|
|
1567
|
+
},
|
|
1568
|
+
{
|
|
1569
|
+
value: "auth",
|
|
1570
|
+
label: auth.type === "none" ? "Auth" : `Auth \xB7 ${auth.type}`,
|
|
1571
|
+
icon: /* @__PURE__ */ jsx2(LockedIcon, { size: "sm" }),
|
|
1572
|
+
children: authTab
|
|
1573
|
+
},
|
|
1574
|
+
{
|
|
1575
|
+
value: "response",
|
|
1576
|
+
label: responseType === "json" ? "Response" : `Response \xB7 ${responseType}`,
|
|
1577
|
+
icon: /* @__PURE__ */ jsx2(DataViewAltIcon, { size: "sm" }),
|
|
1578
|
+
children: responseTab
|
|
1579
|
+
}
|
|
1580
|
+
];
|
|
1581
|
+
return /* @__PURE__ */ jsxs2("div", { className: cn("ods-http-panel", className), children: [
|
|
1582
|
+
connections && /* @__PURE__ */ jsxs2("div", { className: "ods-http-panel__source", children: [
|
|
1583
|
+
/* @__PURE__ */ jsx2(
|
|
1584
|
+
Select,
|
|
1585
|
+
{
|
|
1586
|
+
id: `${uid}-connection`,
|
|
1587
|
+
label: "Source",
|
|
1588
|
+
placeholder: connectionsLoading ? "Loading\u2026" : "No connection (manual config)",
|
|
1589
|
+
options: connections.map((c) => ({ value: c.id, label: c.name, icon: c.icon })),
|
|
1590
|
+
value: connectionId,
|
|
1591
|
+
onChange: (next) => emit({ connectionId: next || void 0 }),
|
|
1592
|
+
disabled: disabled || connectionsLoading,
|
|
1593
|
+
helperText: connectionId ? `Base URL and auth are inherited from "${selectedConnection?.name}" at runtime.` : "Select a saved API connection to inherit base URL and auth, or configure manually."
|
|
1594
|
+
}
|
|
1595
|
+
),
|
|
1596
|
+
connectionId && endpoints.length > 0 && /* @__PURE__ */ jsx2(
|
|
1597
|
+
Combobox,
|
|
1598
|
+
{
|
|
1599
|
+
ariaLabel: "Endpoint",
|
|
1600
|
+
placeholder: `Search ${endpoints.length} discovered endpoints\u2026`,
|
|
1601
|
+
value: url,
|
|
1602
|
+
creatable: true,
|
|
1603
|
+
options: endpoints.map((e) => ({
|
|
1604
|
+
value: e.path,
|
|
1605
|
+
label: `${e.method} ${e.path}`,
|
|
1606
|
+
description: e.summary
|
|
1607
|
+
})),
|
|
1608
|
+
onChange: (nextPath) => {
|
|
1609
|
+
const match = endpoints.find((e) => e.path === nextPath);
|
|
1610
|
+
validateUrl(nextPath, baseUrl, true);
|
|
1611
|
+
emit(
|
|
1612
|
+
match && HTTP_METHODS.includes(match.method.toUpperCase()) ? { url: nextPath, method: match.method.toUpperCase() } : { url: nextPath }
|
|
1613
|
+
);
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
)
|
|
1617
|
+
] }),
|
|
1618
|
+
/* @__PURE__ */ jsxs2("div", { className: "ods-http-panel__bar", children: [
|
|
1619
|
+
/* @__PURE__ */ jsx2(
|
|
1620
|
+
Select,
|
|
1621
|
+
{
|
|
1622
|
+
id: `${uid}-method`,
|
|
1623
|
+
"aria-label": "HTTP method",
|
|
1624
|
+
className: cn(
|
|
1625
|
+
"ods-http-panel__method",
|
|
1626
|
+
`ods-http-panel__method--${method.toLowerCase()}`
|
|
1627
|
+
),
|
|
1628
|
+
value: method,
|
|
1629
|
+
onChange: (next) => emit({ method: next }),
|
|
1630
|
+
disabled,
|
|
1631
|
+
options: HTTP_METHODS.map((m) => ({ value: m, label: m }))
|
|
1632
|
+
}
|
|
1633
|
+
),
|
|
1634
|
+
/* @__PURE__ */ jsx2(
|
|
1635
|
+
Input,
|
|
1636
|
+
{
|
|
1637
|
+
id: `${uid}-url`,
|
|
1638
|
+
"aria-label": connectionId ? "Path" : "URL",
|
|
1639
|
+
"data-fx-droppable": "true",
|
|
1640
|
+
className: "ods-http-panel__url",
|
|
1641
|
+
value: url,
|
|
1642
|
+
placeholder: connectionId ? "/v1/users" : "https://api.example.com/v1/users or {{var}}",
|
|
1643
|
+
error: Boolean(urlError),
|
|
1644
|
+
errorMessage: urlError,
|
|
1645
|
+
onChange: (e) => {
|
|
1646
|
+
validateUrl(e.target.value, baseUrl, Boolean(connectionId));
|
|
1647
|
+
emit({ url: e.target.value });
|
|
1648
|
+
},
|
|
1649
|
+
disabled
|
|
1650
|
+
}
|
|
1651
|
+
),
|
|
1652
|
+
onSendPreview && /* @__PURE__ */ jsx2(
|
|
1653
|
+
Button,
|
|
1654
|
+
{
|
|
1655
|
+
variant: "primary",
|
|
1656
|
+
size: "md",
|
|
1657
|
+
leftIcon: preview.phase === "loading" ? void 0 : /* @__PURE__ */ jsx2(PlayIcon, { size: "sm" }),
|
|
1658
|
+
onClick: sendPreview,
|
|
1659
|
+
disabled: !canSend,
|
|
1660
|
+
children: preview.phase === "loading" ? "Sending\u2026" : "Send"
|
|
1661
|
+
}
|
|
1662
|
+
)
|
|
1663
|
+
] }),
|
|
1664
|
+
!connectionId && baseUrl && /* @__PURE__ */ jsxs2("p", { className: "ods-http-panel__effective", children: [
|
|
1665
|
+
/* @__PURE__ */ jsx2("span", { children: "Effective URL:" }),
|
|
1666
|
+
" ",
|
|
1667
|
+
/* @__PURE__ */ jsx2("code", { children: fullUrl || "\u2014" })
|
|
1668
|
+
] }),
|
|
1669
|
+
fullUrl.includes("{{") && /* @__PURE__ */ jsxs2("p", { className: "ods-http-panel__desc", children: [
|
|
1670
|
+
"\u26A0 URL contains ",
|
|
1671
|
+
/* @__PURE__ */ jsx2("code", { children: "{{variables}}" }),
|
|
1672
|
+
" \u2014 they resolve at run time; testing needs literal values."
|
|
1673
|
+
] }),
|
|
1674
|
+
/* @__PURE__ */ jsxs2("div", { className: "ods-http-panel__tools", children: [
|
|
1675
|
+
/* @__PURE__ */ jsxs2("span", { className: "ods-http-panel__hint", children: [
|
|
1676
|
+
"Use ",
|
|
1677
|
+
/* @__PURE__ */ jsx2("code", { children: "{{stepName.fieldPath}}" }),
|
|
1678
|
+
" to insert data from upstream steps."
|
|
1679
|
+
] }),
|
|
1680
|
+
/* @__PURE__ */ jsxs2("span", { className: "ods-http-panel__tools-actions", children: [
|
|
1681
|
+
/* @__PURE__ */ jsx2(Button, { variant: "ghost", size: "sm", onClick: () => setCurlOpen((o) => !o), children: "Import cURL" }),
|
|
1682
|
+
/* @__PURE__ */ jsx2(
|
|
1683
|
+
Button,
|
|
1684
|
+
{
|
|
1685
|
+
variant: "ghost",
|
|
1686
|
+
size: "sm",
|
|
1687
|
+
className: cn(copiedCurl && "ods-http-panel__copy-done"),
|
|
1688
|
+
leftIcon: copiedCurl ? /* @__PURE__ */ jsx2(CheckmarkIcon, { size: "sm" }) : /* @__PURE__ */ jsx2(CopyIcon, { size: "sm" }),
|
|
1689
|
+
onClick: copyCurl,
|
|
1690
|
+
children: copiedCurl ? "Copied" : "Copy as cURL"
|
|
1691
|
+
}
|
|
1692
|
+
)
|
|
1693
|
+
] })
|
|
1694
|
+
] }),
|
|
1695
|
+
curlOpen && /* @__PURE__ */ jsxs2("div", { className: "ods-http-panel__curl", children: [
|
|
1696
|
+
/* @__PURE__ */ jsx2(
|
|
1697
|
+
CodeEditor,
|
|
1698
|
+
{
|
|
1699
|
+
value: curlText,
|
|
1700
|
+
language: "plain",
|
|
1701
|
+
onChange: setCurlText,
|
|
1702
|
+
minHeight: 90,
|
|
1703
|
+
showLineNumbers: false,
|
|
1704
|
+
placeholder: "curl -X POST 'https://api.example.com/v1/users' -H 'Authorization: Bearer \u2026' -d '{\u2026}'",
|
|
1705
|
+
ariaLabel: "cURL command"
|
|
1706
|
+
}
|
|
1707
|
+
),
|
|
1708
|
+
curlError && /* @__PURE__ */ jsxs2("p", { className: "ods-http-panel__error", children: [
|
|
1709
|
+
"\u26A0 ",
|
|
1710
|
+
curlError
|
|
1711
|
+
] }),
|
|
1712
|
+
/* @__PURE__ */ jsxs2("div", { className: "ods-http-panel__curl-actions", children: [
|
|
1713
|
+
/* @__PURE__ */ jsx2(Button, { variant: "secondary", size: "sm", onClick: () => setCurlOpen(false), children: "Cancel" }),
|
|
1714
|
+
/* @__PURE__ */ jsx2(Button, { variant: "primary", size: "sm", onClick: applyCurl, disabled: !curlText.trim(), children: "Apply to request" })
|
|
1715
|
+
] })
|
|
1716
|
+
] }),
|
|
1717
|
+
/* @__PURE__ */ jsx2(Tabs, { items: tabItems, defaultValue: "params", className: "ods-http-panel__tabs" }),
|
|
1718
|
+
/* @__PURE__ */ jsxs2(
|
|
1719
|
+
Disclosure,
|
|
1720
|
+
{
|
|
1721
|
+
size: "sm",
|
|
1722
|
+
icon: /* @__PURE__ */ jsx2(GlobeIcon, { size: "sm" }),
|
|
1723
|
+
title: "Advanced options",
|
|
1724
|
+
description: "Base URL, timeout, retries, pagination, response extraction",
|
|
1725
|
+
trailing: advancedSummary.length ? /* @__PURE__ */ jsx2(Badge, { size: "sm", variant: "info", children: advancedSummary.join(" \xB7 ") }) : void 0,
|
|
1726
|
+
children: [
|
|
1727
|
+
/* @__PURE__ */ jsxs2("div", { className: "ods-http-panel__grid", children: [
|
|
1728
|
+
!connectionId && /* @__PURE__ */ jsx2(
|
|
1729
|
+
Input,
|
|
1730
|
+
{
|
|
1731
|
+
id: `${uid}-base-url`,
|
|
1732
|
+
label: "Base URL (optional)",
|
|
1733
|
+
value: baseUrl,
|
|
1734
|
+
placeholder: "https://api.example.com",
|
|
1735
|
+
helperText: "Combined with the request path to form the full URL.",
|
|
1736
|
+
onChange: (e) => {
|
|
1737
|
+
validateUrl(url, e.target.value, Boolean(connectionId));
|
|
1738
|
+
emit({ baseUrl: e.target.value || void 0 });
|
|
1739
|
+
},
|
|
1740
|
+
disabled
|
|
1741
|
+
}
|
|
1742
|
+
),
|
|
1743
|
+
/* @__PURE__ */ jsx2(
|
|
1744
|
+
NumberInput,
|
|
1745
|
+
{
|
|
1746
|
+
label: "Timeout (ms)",
|
|
1747
|
+
helperText: "Minimum 1000 ms",
|
|
1748
|
+
value: cfg.timeout ?? 3e4,
|
|
1749
|
+
min: 1e3,
|
|
1750
|
+
step: 1e3,
|
|
1751
|
+
onChange: (next) => {
|
|
1752
|
+
if (!Number.isNaN(next) && next >= 1e3) emit({ timeout: next });
|
|
1753
|
+
},
|
|
1754
|
+
disabled
|
|
1755
|
+
}
|
|
1756
|
+
),
|
|
1757
|
+
/* @__PURE__ */ jsxs2("div", { className: "ods-http-panel__switches", children: [
|
|
1758
|
+
/* @__PURE__ */ jsx2(
|
|
1759
|
+
Switch,
|
|
1760
|
+
{
|
|
1761
|
+
id: `${uid}-fail`,
|
|
1762
|
+
label: "Fail on non-2xx",
|
|
1763
|
+
checked: cfg.failOnError !== false,
|
|
1764
|
+
onChange: (next) => emit({ failOnError: next }),
|
|
1765
|
+
disabled,
|
|
1766
|
+
size: "sm"
|
|
1767
|
+
}
|
|
1768
|
+
),
|
|
1769
|
+
/* @__PURE__ */ jsx2(
|
|
1770
|
+
Switch,
|
|
1771
|
+
{
|
|
1772
|
+
id: `${uid}-redirects`,
|
|
1773
|
+
label: "Follow redirects",
|
|
1774
|
+
checked: cfg.followRedirects !== false,
|
|
1775
|
+
onChange: (next) => emit({ followRedirects: next }),
|
|
1776
|
+
disabled,
|
|
1777
|
+
size: "sm"
|
|
1778
|
+
}
|
|
1779
|
+
)
|
|
1780
|
+
] })
|
|
1781
|
+
] }),
|
|
1782
|
+
/* @__PURE__ */ jsx2(
|
|
1783
|
+
Disclosure,
|
|
1784
|
+
{
|
|
1785
|
+
size: "sm",
|
|
1786
|
+
title: "Retry",
|
|
1787
|
+
trailing: (retry?.maxAttempts ?? 1) > 1 ? /* @__PURE__ */ jsxs2(Badge, { size: "sm", variant: "info", children: [
|
|
1788
|
+
retry?.maxAttempts,
|
|
1789
|
+
" attempts"
|
|
1790
|
+
] }) : void 0,
|
|
1791
|
+
children: /* @__PURE__ */ jsxs2("div", { className: "ods-http-panel__grid", children: [
|
|
1792
|
+
/* @__PURE__ */ jsx2(
|
|
1793
|
+
NumberInput,
|
|
1794
|
+
{
|
|
1795
|
+
label: "Max attempts",
|
|
1796
|
+
helperText: "1 = no retry",
|
|
1797
|
+
value: retry?.maxAttempts ?? 1,
|
|
1798
|
+
min: 1,
|
|
1799
|
+
max: 10,
|
|
1800
|
+
onChange: (next) => {
|
|
1801
|
+
if (!Number.isNaN(next) && next >= 1 && retry) {
|
|
1802
|
+
emit({ retry: { ...retry, maxAttempts: next } });
|
|
1803
|
+
}
|
|
1804
|
+
},
|
|
1805
|
+
disabled
|
|
1806
|
+
}
|
|
1807
|
+
),
|
|
1808
|
+
/* @__PURE__ */ jsx2(
|
|
1809
|
+
Input,
|
|
1810
|
+
{
|
|
1811
|
+
id: `${uid}-retry-on`,
|
|
1812
|
+
label: "Retry on (status codes)",
|
|
1813
|
+
value: retryOnText,
|
|
1814
|
+
placeholder: "429, 500, 502, 503, 504",
|
|
1815
|
+
helperText: "Comma-separated HTTP status codes",
|
|
1816
|
+
onChange: (e) => {
|
|
1817
|
+
setRetryOnText(e.target.value);
|
|
1818
|
+
const codes = e.target.value.split(",").map((s) => Number.parseInt(s.trim(), 10)).filter((n) => !Number.isNaN(n));
|
|
1819
|
+
if (retry) emit({ retry: { ...retry, retryOn: codes } });
|
|
1820
|
+
},
|
|
1821
|
+
disabled
|
|
1822
|
+
}
|
|
1823
|
+
),
|
|
1824
|
+
/* @__PURE__ */ jsx2(
|
|
1825
|
+
NumberInput,
|
|
1826
|
+
{
|
|
1827
|
+
label: "Initial delay (ms)",
|
|
1828
|
+
value: retry?.initialDelayMs ?? 1e3,
|
|
1829
|
+
min: 100,
|
|
1830
|
+
step: 100,
|
|
1831
|
+
onChange: (next) => {
|
|
1832
|
+
if (!Number.isNaN(next) && retry)
|
|
1833
|
+
emit({ retry: { ...retry, initialDelayMs: next } });
|
|
1834
|
+
},
|
|
1835
|
+
disabled
|
|
1836
|
+
}
|
|
1837
|
+
),
|
|
1838
|
+
/* @__PURE__ */ jsx2(
|
|
1839
|
+
NumberInput,
|
|
1840
|
+
{
|
|
1841
|
+
label: "Backoff factor",
|
|
1842
|
+
helperText: "Delay multiplies by this each retry",
|
|
1843
|
+
value: retry?.backoffFactor ?? 2,
|
|
1844
|
+
min: 1,
|
|
1845
|
+
step: 0.5,
|
|
1846
|
+
onChange: (next) => {
|
|
1847
|
+
if (!Number.isNaN(next) && retry)
|
|
1848
|
+
emit({ retry: { ...retry, backoffFactor: next } });
|
|
1849
|
+
},
|
|
1850
|
+
disabled
|
|
1851
|
+
}
|
|
1852
|
+
),
|
|
1853
|
+
/* @__PURE__ */ jsx2(
|
|
1854
|
+
NumberInput,
|
|
1855
|
+
{
|
|
1856
|
+
label: "Max delay (ms)",
|
|
1857
|
+
value: retry?.maxDelayMs ?? 3e4,
|
|
1858
|
+
min: 1e3,
|
|
1859
|
+
step: 1e3,
|
|
1860
|
+
onChange: (next) => {
|
|
1861
|
+
if (!Number.isNaN(next) && retry) emit({ retry: { ...retry, maxDelayMs: next } });
|
|
1862
|
+
},
|
|
1863
|
+
disabled
|
|
1864
|
+
}
|
|
1865
|
+
)
|
|
1866
|
+
] })
|
|
1867
|
+
}
|
|
1868
|
+
),
|
|
1869
|
+
/* @__PURE__ */ jsxs2(
|
|
1870
|
+
Disclosure,
|
|
1871
|
+
{
|
|
1872
|
+
size: "sm",
|
|
1873
|
+
title: "Pagination",
|
|
1874
|
+
trailing: pagination.type !== "none" ? /* @__PURE__ */ jsx2(Badge, { size: "sm", variant: "success", children: pagination.type.replace("_", " ") }) : void 0,
|
|
1875
|
+
children: [
|
|
1876
|
+
/* @__PURE__ */ jsx2(
|
|
1877
|
+
Select,
|
|
1878
|
+
{
|
|
1879
|
+
id: `${uid}-pag-type`,
|
|
1880
|
+
label: "Strategy",
|
|
1881
|
+
value: pagination.type,
|
|
1882
|
+
onChange: (next) => emit({
|
|
1883
|
+
pagination: { ...pagination, type: next }
|
|
1884
|
+
}),
|
|
1885
|
+
disabled,
|
|
1886
|
+
options: [
|
|
1887
|
+
{ value: "none", label: "None (single request)" },
|
|
1888
|
+
{ value: "offset", label: "Offset / page number" },
|
|
1889
|
+
{ value: "cursor", label: "Cursor-based" },
|
|
1890
|
+
{ value: "link_header", label: 'Link header (rel="next")' },
|
|
1891
|
+
{ value: "next_url", label: "Next URL in response body" }
|
|
1892
|
+
]
|
|
1893
|
+
}
|
|
1894
|
+
),
|
|
1895
|
+
pagination.type !== "none" && /* @__PURE__ */ jsxs2("div", { className: "ods-http-panel__grid", children: [
|
|
1896
|
+
/* @__PURE__ */ jsx2(
|
|
1897
|
+
NumberInput,
|
|
1898
|
+
{
|
|
1899
|
+
label: "Max pages",
|
|
1900
|
+
helperText: "Safety cap against infinite loops",
|
|
1901
|
+
value: pagination.maxPages ?? 20,
|
|
1902
|
+
min: 1,
|
|
1903
|
+
onChange: (next) => {
|
|
1904
|
+
if (!Number.isNaN(next)) emit({ pagination: { ...pagination, maxPages: next } });
|
|
1905
|
+
},
|
|
1906
|
+
disabled
|
|
1907
|
+
}
|
|
1908
|
+
),
|
|
1909
|
+
/* @__PURE__ */ jsx2(
|
|
1910
|
+
Input,
|
|
1911
|
+
{
|
|
1912
|
+
id: `${uid}-pag-merge`,
|
|
1913
|
+
label: "Merge key (dot path)",
|
|
1914
|
+
value: pagination.mergeKey ?? "",
|
|
1915
|
+
placeholder: "data.items",
|
|
1916
|
+
helperText: "Array to merge across pages",
|
|
1917
|
+
onChange: (e) => emit({ pagination: { ...pagination, mergeKey: e.target.value } }),
|
|
1918
|
+
disabled
|
|
1919
|
+
}
|
|
1920
|
+
),
|
|
1921
|
+
(pagination.type === "offset" || pagination.type === "cursor") && /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
1922
|
+
/* @__PURE__ */ jsx2(
|
|
1923
|
+
Input,
|
|
1924
|
+
{
|
|
1925
|
+
id: `${uid}-pag-limitp`,
|
|
1926
|
+
label: "Limit param",
|
|
1927
|
+
value: pagination.limitParam ?? "limit",
|
|
1928
|
+
onChange: (e) => emit({ pagination: { ...pagination, limitParam: e.target.value } }),
|
|
1929
|
+
disabled
|
|
1930
|
+
}
|
|
1931
|
+
),
|
|
1932
|
+
/* @__PURE__ */ jsx2(
|
|
1933
|
+
NumberInput,
|
|
1934
|
+
{
|
|
1935
|
+
label: "Page size",
|
|
1936
|
+
value: pagination.limitValue ?? 100,
|
|
1937
|
+
min: 1,
|
|
1938
|
+
onChange: (next) => {
|
|
1939
|
+
if (!Number.isNaN(next)) {
|
|
1940
|
+
emit({ pagination: { ...pagination, limitValue: next } });
|
|
1941
|
+
}
|
|
1942
|
+
},
|
|
1943
|
+
disabled
|
|
1944
|
+
}
|
|
1945
|
+
)
|
|
1946
|
+
] }),
|
|
1947
|
+
pagination.type === "offset" && /* @__PURE__ */ jsx2(
|
|
1948
|
+
Input,
|
|
1949
|
+
{
|
|
1950
|
+
id: `${uid}-pag-offset`,
|
|
1951
|
+
label: "Offset param",
|
|
1952
|
+
value: pagination.offsetParam ?? "offset",
|
|
1953
|
+
onChange: (e) => emit({ pagination: { ...pagination, offsetParam: e.target.value } }),
|
|
1954
|
+
disabled
|
|
1955
|
+
}
|
|
1956
|
+
),
|
|
1957
|
+
pagination.type === "cursor" && /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
1958
|
+
/* @__PURE__ */ jsx2(
|
|
1959
|
+
Input,
|
|
1960
|
+
{
|
|
1961
|
+
id: `${uid}-pag-cres`,
|
|
1962
|
+
label: "Cursor in response (dot path)",
|
|
1963
|
+
value: pagination.cursorResponsePath ?? "",
|
|
1964
|
+
placeholder: "meta.next_cursor",
|
|
1965
|
+
onChange: (e) => emit({ pagination: { ...pagination, cursorResponsePath: e.target.value } }),
|
|
1966
|
+
disabled
|
|
1967
|
+
}
|
|
1968
|
+
),
|
|
1969
|
+
/* @__PURE__ */ jsx2(
|
|
1970
|
+
Input,
|
|
1971
|
+
{
|
|
1972
|
+
id: `${uid}-pag-creq`,
|
|
1973
|
+
label: "Cursor request param",
|
|
1974
|
+
value: pagination.cursorRequestParam ?? "cursor",
|
|
1975
|
+
onChange: (e) => emit({ pagination: { ...pagination, cursorRequestParam: e.target.value } }),
|
|
1976
|
+
disabled
|
|
1977
|
+
}
|
|
1978
|
+
)
|
|
1979
|
+
] }),
|
|
1980
|
+
pagination.type === "next_url" && /* @__PURE__ */ jsx2(
|
|
1981
|
+
Input,
|
|
1982
|
+
{
|
|
1983
|
+
id: `${uid}-pag-next`,
|
|
1984
|
+
label: "Next URL in response (dot path)",
|
|
1985
|
+
value: pagination.nextUrlResponsePath ?? "",
|
|
1986
|
+
placeholder: "links.next",
|
|
1987
|
+
onChange: (e) => emit({ pagination: { ...pagination, nextUrlResponsePath: e.target.value } }),
|
|
1988
|
+
disabled
|
|
1989
|
+
}
|
|
1990
|
+
)
|
|
1991
|
+
] })
|
|
1992
|
+
]
|
|
1993
|
+
}
|
|
1994
|
+
),
|
|
1995
|
+
/* @__PURE__ */ jsxs2(
|
|
1996
|
+
Disclosure,
|
|
1997
|
+
{
|
|
1998
|
+
size: "sm",
|
|
1999
|
+
title: "Response field extraction",
|
|
2000
|
+
trailing: extractCount > 0 ? /* @__PURE__ */ jsxs2(Badge, { size: "sm", variant: "info", children: [
|
|
2001
|
+
extractCount,
|
|
2002
|
+
" field",
|
|
2003
|
+
extractCount === 1 ? "" : "s"
|
|
2004
|
+
] }) : void 0,
|
|
2005
|
+
children: [
|
|
2006
|
+
/* @__PURE__ */ jsxs2("p", { className: "ods-http-panel__desc", children: [
|
|
2007
|
+
"Extract fields from the response with dot paths \u2014 available downstream as",
|
|
2008
|
+
" ",
|
|
2009
|
+
/* @__PURE__ */ jsx2("code", { children: "{{extracted.keyName}}" }),
|
|
2010
|
+
"."
|
|
2011
|
+
] }),
|
|
2012
|
+
/* @__PURE__ */ jsx2(
|
|
2013
|
+
KeyValueEditor,
|
|
2014
|
+
{
|
|
2015
|
+
pairs: extractRows.map((r) => ({ key: r.key, value: r.value })),
|
|
2016
|
+
onChange: (pairs) => {
|
|
2017
|
+
const rows = pairs.map((p) => ({ key: p.key, value: p.value, enabled: true }));
|
|
2018
|
+
setExtractRows(rows);
|
|
2019
|
+
const extract = {};
|
|
2020
|
+
for (const r of rows) if (r.key && r.value) extract[r.key] = r.value;
|
|
2021
|
+
emit({ extract: Object.keys(extract).length ? extract : void 0 });
|
|
2022
|
+
},
|
|
2023
|
+
keyPlaceholder: "outputKey",
|
|
2024
|
+
valuePlaceholder: "data.user.id",
|
|
2025
|
+
emptyLabel: "No extractions yet \u2014 click Add to begin.",
|
|
2026
|
+
addLabel: "Add",
|
|
2027
|
+
size: "sm",
|
|
2028
|
+
disabled
|
|
2029
|
+
}
|
|
2030
|
+
)
|
|
2031
|
+
]
|
|
2032
|
+
}
|
|
2033
|
+
)
|
|
2034
|
+
]
|
|
2035
|
+
}
|
|
2036
|
+
),
|
|
2037
|
+
preview.phase !== "idle" && /* @__PURE__ */ jsxs2("div", { className: "ods-http-panel__console", children: [
|
|
2038
|
+
/* @__PURE__ */ jsxs2("div", { className: "ods-http-panel__console-head", children: [
|
|
2039
|
+
/* @__PURE__ */ jsx2(
|
|
2040
|
+
"code",
|
|
2041
|
+
{
|
|
2042
|
+
className: cn(
|
|
2043
|
+
"ods-http-panel__console-method",
|
|
2044
|
+
`ods-http-panel__method--${method.toLowerCase()}`
|
|
2045
|
+
),
|
|
2046
|
+
children: cfg.apiType === "graphql" ? "POST" : method
|
|
2047
|
+
}
|
|
2048
|
+
),
|
|
2049
|
+
/* @__PURE__ */ jsx2("code", { className: "ods-http-panel__console-url", children: connectionId ? `${selectedConnection?.name ?? connectionId} \xB7 ${url || "\u2014"}` : fullUrl || "\u2014" }),
|
|
2050
|
+
preview.phase === "success" && /* @__PURE__ */ jsx2(
|
|
2051
|
+
Button,
|
|
2052
|
+
{
|
|
2053
|
+
variant: "ghost",
|
|
2054
|
+
size: "sm",
|
|
2055
|
+
className: cn(copiedResult && "ods-http-panel__copy-done"),
|
|
2056
|
+
leftIcon: copiedResult ? /* @__PURE__ */ jsx2(CheckmarkIcon, { size: "sm" }) : /* @__PURE__ */ jsx2(CopyIcon, { size: "sm" }),
|
|
2057
|
+
onClick: copyResult,
|
|
2058
|
+
children: copiedResult ? "Copied" : "Copy result"
|
|
2059
|
+
}
|
|
2060
|
+
),
|
|
2061
|
+
/* @__PURE__ */ jsx2(
|
|
2062
|
+
Button,
|
|
2063
|
+
{
|
|
2064
|
+
variant: "ghost",
|
|
2065
|
+
size: "sm",
|
|
2066
|
+
leftIcon: /* @__PURE__ */ jsx2(RenewIcon, { size: "sm" }),
|
|
2067
|
+
onClick: () => {
|
|
2068
|
+
setPreview({ phase: "idle" });
|
|
2069
|
+
},
|
|
2070
|
+
disabled: preview.phase === "loading",
|
|
2071
|
+
children: "Clear"
|
|
2072
|
+
}
|
|
2073
|
+
)
|
|
2074
|
+
] }),
|
|
2075
|
+
preview.phase === "loading" && /* @__PURE__ */ jsxs2("div", { className: "ods-http-panel__console-loading", children: [
|
|
2076
|
+
/* @__PURE__ */ jsx2(Spinner, { size: "sm" }),
|
|
2077
|
+
/* @__PURE__ */ jsx2("span", { children: "Sending request\u2026" })
|
|
2078
|
+
] }),
|
|
2079
|
+
preview.phase === "error" && /* @__PURE__ */ jsxs2(Banner, { variant: "error", appearance: "subtle", size: "sm", children: [
|
|
2080
|
+
/* @__PURE__ */ jsx2("strong", { children: "Request failed." }),
|
|
2081
|
+
" ",
|
|
2082
|
+
preview.message
|
|
2083
|
+
] }),
|
|
2084
|
+
preview.phase === "success" && /* @__PURE__ */ jsxs2("div", { className: "ods-http-panel__console-result", children: [
|
|
2085
|
+
/* @__PURE__ */ jsxs2("div", { className: "ods-http-panel__console-status", children: [
|
|
2086
|
+
/* @__PURE__ */ jsxs2(Badge, { size: "sm", variant: statusTone(preview.response.status), children: [
|
|
2087
|
+
preview.response.status,
|
|
2088
|
+
" ",
|
|
2089
|
+
preview.response.statusText
|
|
2090
|
+
] }),
|
|
2091
|
+
/* @__PURE__ */ jsxs2("span", { className: "ods-http-panel__meta", children: [
|
|
2092
|
+
preview.response.duration,
|
|
2093
|
+
"ms"
|
|
2094
|
+
] }),
|
|
2095
|
+
/* @__PURE__ */ jsx2("span", { className: "ods-http-panel__meta", children: formatBytes(preview.response.size) })
|
|
2096
|
+
] }),
|
|
2097
|
+
/* @__PURE__ */ jsx2(
|
|
2098
|
+
Accordion,
|
|
2099
|
+
{
|
|
2100
|
+
size: "sm",
|
|
2101
|
+
mode: "multiple",
|
|
2102
|
+
defaultValue: ["res-body"],
|
|
2103
|
+
items: [
|
|
2104
|
+
{
|
|
2105
|
+
id: "res-headers",
|
|
2106
|
+
label: "Response headers",
|
|
2107
|
+
trailing: /* @__PURE__ */ jsx2(Badge, { size: "sm", variant: "neutral", children: Object.keys(preview.response.headers).length }),
|
|
2108
|
+
content: /* @__PURE__ */ jsx2("div", { className: "ods-http-panel__res-headers", children: Object.entries(preview.response.headers).map(([k, v]) => /* @__PURE__ */ jsxs2("div", { className: "ods-http-panel__res-header", children: [
|
|
2109
|
+
/* @__PURE__ */ jsx2("span", { className: "ods-http-panel__res-header-key", children: k }),
|
|
2110
|
+
/* @__PURE__ */ jsx2("span", { className: "ods-http-panel__res-header-val", children: v })
|
|
2111
|
+
] }, k)) })
|
|
2112
|
+
},
|
|
2113
|
+
{
|
|
2114
|
+
id: "res-body",
|
|
2115
|
+
label: "Response body",
|
|
2116
|
+
trailing: !preview.response.ok ? /* @__PURE__ */ jsx2(Badge, { size: "sm", variant: "error", children: "Error" }) : null,
|
|
2117
|
+
content: (
|
|
2118
|
+
// Size guard: the tree view renders recursively (no
|
|
2119
|
+
// virtualization) — very large bodies fall back to text.
|
|
2120
|
+
preview.response.body !== null && typeof preview.response.body === "object" && preview.response.size <= 15e5 ? /* @__PURE__ */ jsx2(
|
|
2121
|
+
JsonViewer,
|
|
2122
|
+
{
|
|
2123
|
+
data: preview.response.body,
|
|
2124
|
+
mode: "view",
|
|
2125
|
+
maxHeight: 320,
|
|
2126
|
+
copyable: true
|
|
2127
|
+
}
|
|
2128
|
+
) : /* @__PURE__ */ jsx2("pre", { className: "ods-http-panel__res-body", children: typeof preview.response.body === "object" ? JSON.stringify(preview.response.body, null, 2) : String(
|
|
2129
|
+
preview.response.bodyRaw ?? preview.response.body ?? "(empty body)"
|
|
2130
|
+
) })
|
|
2131
|
+
)
|
|
2132
|
+
}
|
|
2133
|
+
]
|
|
2134
|
+
}
|
|
2135
|
+
)
|
|
2136
|
+
] })
|
|
2137
|
+
] })
|
|
2138
|
+
] });
|
|
2139
|
+
}
|
|
2140
|
+
|
|
624
2141
|
// src/workflow/components/FxPanel/FxPanel.tsx
|
|
625
2142
|
import {
|
|
626
|
-
useMemo as
|
|
627
|
-
useRef as
|
|
628
|
-
useState as
|
|
2143
|
+
useMemo as useMemo3,
|
|
2144
|
+
useRef as useRef5,
|
|
2145
|
+
useState as useState5
|
|
629
2146
|
} from "react";
|
|
630
2147
|
import {
|
|
631
2148
|
ChevronDownIcon,
|
|
@@ -638,7 +2155,7 @@ import {
|
|
|
638
2155
|
SearchIcon,
|
|
639
2156
|
ValueVariableIcon
|
|
640
2157
|
} from "@octaviaflow/icons";
|
|
641
|
-
import { jsx as
|
|
2158
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
642
2159
|
var KIND_ICON = {
|
|
643
2160
|
function: FunctionMathIcon,
|
|
644
2161
|
variable: ValueVariableIcon
|
|
@@ -697,18 +2214,18 @@ function FxPanel({
|
|
|
697
2214
|
className,
|
|
698
2215
|
style
|
|
699
2216
|
}) {
|
|
700
|
-
const [internalSearch, setInternalSearch] =
|
|
2217
|
+
const [internalSearch, setInternalSearch] = useState5(defaultSearch);
|
|
701
2218
|
const search = controlledSearch ?? internalSearch;
|
|
702
2219
|
const query = search.trim().toLowerCase();
|
|
703
2220
|
const setSearch = (next) => {
|
|
704
2221
|
if (controlledSearch === void 0) setInternalSearch(next);
|
|
705
2222
|
onSearchChange?.(next);
|
|
706
2223
|
};
|
|
707
|
-
const visibleCategories =
|
|
2224
|
+
const visibleCategories = useMemo3(
|
|
708
2225
|
() => categories.filter((c) => c.items.length > 0),
|
|
709
2226
|
[categories]
|
|
710
2227
|
);
|
|
711
|
-
const [internalCat, setInternalCat] =
|
|
2228
|
+
const [internalCat, setInternalCat] = useState5(
|
|
712
2229
|
defaultExpandedCategory !== void 0 ? defaultExpandedCategory : visibleCategories[0]?.id ?? null
|
|
713
2230
|
);
|
|
714
2231
|
const openCategoryId = controlledExpanded ?? internalCat;
|
|
@@ -716,7 +2233,7 @@ function FxPanel({
|
|
|
716
2233
|
if (controlledExpanded === void 0) setInternalCat(id);
|
|
717
2234
|
onExpandedCategoryChange?.(id);
|
|
718
2235
|
};
|
|
719
|
-
const [expandedItems, setExpandedItems] =
|
|
2236
|
+
const [expandedItems, setExpandedItems] = useState5(() => {
|
|
720
2237
|
const ids = /* @__PURE__ */ new Set();
|
|
721
2238
|
for (const cat of categories) {
|
|
722
2239
|
for (const item of cat.items) {
|
|
@@ -745,9 +2262,9 @@ function FxPanel({
|
|
|
745
2262
|
return next;
|
|
746
2263
|
});
|
|
747
2264
|
};
|
|
748
|
-
const [draggingId, setDraggingId] =
|
|
749
|
-
const [focusedId, setFocusedId] =
|
|
750
|
-
const hits =
|
|
2265
|
+
const [draggingId, setDraggingId] = useState5(null);
|
|
2266
|
+
const [focusedId, setFocusedId] = useState5(null);
|
|
2267
|
+
const hits = useMemo3(() => {
|
|
751
2268
|
if (!query) return null;
|
|
752
2269
|
const all = [];
|
|
753
2270
|
for (const cat of visibleCategories) {
|
|
@@ -771,7 +2288,7 @@ function FxPanel({
|
|
|
771
2288
|
e.dataTransfer.effectAllowed = "copy";
|
|
772
2289
|
}
|
|
773
2290
|
};
|
|
774
|
-
const listRef =
|
|
2291
|
+
const listRef = useRef5(null);
|
|
775
2292
|
const focusRow = (id) => {
|
|
776
2293
|
setFocusedId(id);
|
|
777
2294
|
requestAnimationFrame(() => {
|
|
@@ -829,7 +2346,7 @@ function FxPanel({
|
|
|
829
2346
|
break;
|
|
830
2347
|
}
|
|
831
2348
|
};
|
|
832
|
-
const searchRows =
|
|
2349
|
+
const searchRows = useMemo3(
|
|
833
2350
|
() => hits ? hits.map(({ hit }) => ({
|
|
834
2351
|
item: hit.item,
|
|
835
2352
|
depth: 0,
|
|
@@ -843,7 +2360,7 @@ function FxPanel({
|
|
|
843
2360
|
const mono = category.kind === "function";
|
|
844
2361
|
const draggable = !!item.insertValue;
|
|
845
2362
|
const isFocused = focusedId === item.id;
|
|
846
|
-
return /* @__PURE__ */
|
|
2363
|
+
return /* @__PURE__ */ jsxs3(
|
|
847
2364
|
"div",
|
|
848
2365
|
{
|
|
849
2366
|
"data-fx-row": item.id,
|
|
@@ -868,12 +2385,12 @@ function FxPanel({
|
|
|
868
2385
|
},
|
|
869
2386
|
title: item.insertValue,
|
|
870
2387
|
children: [
|
|
871
|
-
Array.from({ length: depth }, (_, i) => /* @__PURE__ */
|
|
872
|
-
hasChildren ? /* @__PURE__ */
|
|
873
|
-
/* @__PURE__ */
|
|
874
|
-
/* @__PURE__ */
|
|
875
|
-
mono ? /* @__PURE__ */
|
|
876
|
-
item.valueType && /* @__PURE__ */
|
|
2388
|
+
Array.from({ length: depth }, (_, i) => /* @__PURE__ */ jsx3("span", { className: "ods-flow-fx-panel__indent", "aria-hidden": "true" }, i)),
|
|
2389
|
+
hasChildren ? /* @__PURE__ */ jsx3("span", { className: "ods-flow-fx-panel__twisty", "aria-hidden": "true", children: expanded ? /* @__PURE__ */ jsx3(ChevronDownIcon, { size: "sm" }) : /* @__PURE__ */ jsx3(ChevronRightIcon, { size: "sm" }) }) : /* @__PURE__ */ jsx3("span", { className: "ods-flow-fx-panel__grip", "aria-hidden": "true", children: /* @__PURE__ */ jsx3(DraggableIcon, { size: "sm" }) }),
|
|
2390
|
+
/* @__PURE__ */ jsxs3("span", { className: "ods-flow-fx-panel__row-main", children: [
|
|
2391
|
+
/* @__PURE__ */ jsxs3("span", { className: "ods-flow-fx-panel__row-line", children: [
|
|
2392
|
+
mono ? /* @__PURE__ */ jsx3("code", { className: "ods-flow-fx-panel__row-label ods-flow-fx-panel__row-label--mono", children: item.label }) : /* @__PURE__ */ jsx3("span", { className: "ods-flow-fx-panel__row-label", children: item.label }),
|
|
2393
|
+
item.valueType && /* @__PURE__ */ jsx3(
|
|
877
2394
|
"span",
|
|
878
2395
|
{
|
|
879
2396
|
className: cn(
|
|
@@ -884,8 +2401,8 @@ function FxPanel({
|
|
|
884
2401
|
}
|
|
885
2402
|
)
|
|
886
2403
|
] }),
|
|
887
|
-
(item.description || crumb) && /* @__PURE__ */
|
|
888
|
-
crumb && /* @__PURE__ */
|
|
2404
|
+
(item.description || crumb) && /* @__PURE__ */ jsxs3("span", { className: "ods-flow-fx-panel__row-sub", children: [
|
|
2405
|
+
crumb && /* @__PURE__ */ jsx3("span", { className: "ods-flow-fx-panel__crumb", children: crumb }),
|
|
889
2406
|
item.description
|
|
890
2407
|
] })
|
|
891
2408
|
] })
|
|
@@ -894,29 +2411,29 @@ function FxPanel({
|
|
|
894
2411
|
item.id
|
|
895
2412
|
);
|
|
896
2413
|
};
|
|
897
|
-
return /* @__PURE__ */
|
|
2414
|
+
return /* @__PURE__ */ jsxs3(
|
|
898
2415
|
"aside",
|
|
899
2416
|
{
|
|
900
2417
|
className: cn("ods-flow-fx-panel", className),
|
|
901
2418
|
style: { width, ...style },
|
|
902
2419
|
"aria-label": typeof title === "string" ? title : "Data References",
|
|
903
2420
|
children: [
|
|
904
|
-
/* @__PURE__ */
|
|
905
|
-
/* @__PURE__ */
|
|
906
|
-
onClose && /* @__PURE__ */
|
|
2421
|
+
/* @__PURE__ */ jsxs3("header", { className: "ods-flow-fx-panel__header", children: [
|
|
2422
|
+
/* @__PURE__ */ jsx3("h3", { className: "ods-flow-fx-panel__title", children: title }),
|
|
2423
|
+
onClose && /* @__PURE__ */ jsx3(
|
|
907
2424
|
"button",
|
|
908
2425
|
{
|
|
909
2426
|
type: "button",
|
|
910
2427
|
className: "ods-flow-fx-panel__close",
|
|
911
2428
|
onClick: onClose,
|
|
912
2429
|
"aria-label": "Close data references",
|
|
913
|
-
children: /* @__PURE__ */
|
|
2430
|
+
children: /* @__PURE__ */ jsx3(CloseIcon, { size: "sm" })
|
|
914
2431
|
}
|
|
915
2432
|
)
|
|
916
2433
|
] }),
|
|
917
|
-
/* @__PURE__ */
|
|
918
|
-
/* @__PURE__ */
|
|
919
|
-
/* @__PURE__ */
|
|
2434
|
+
/* @__PURE__ */ jsxs3("div", { className: "ods-flow-fx-panel__search", children: [
|
|
2435
|
+
/* @__PURE__ */ jsx3("span", { className: "ods-flow-fx-panel__search-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx3(SearchIcon, { size: "sm" }) }),
|
|
2436
|
+
/* @__PURE__ */ jsx3(
|
|
920
2437
|
"input",
|
|
921
2438
|
{
|
|
922
2439
|
type: "text",
|
|
@@ -927,21 +2444,21 @@ function FxPanel({
|
|
|
927
2444
|
onChange: (e) => setSearch(e.target.value)
|
|
928
2445
|
}
|
|
929
2446
|
),
|
|
930
|
-
search && /* @__PURE__ */
|
|
2447
|
+
search && /* @__PURE__ */ jsx3(
|
|
931
2448
|
"button",
|
|
932
2449
|
{
|
|
933
2450
|
type: "button",
|
|
934
2451
|
className: "ods-flow-fx-panel__search-clear",
|
|
935
2452
|
onClick: () => setSearch(""),
|
|
936
2453
|
"aria-label": "Clear search",
|
|
937
|
-
children: /* @__PURE__ */
|
|
2454
|
+
children: /* @__PURE__ */ jsx3(CloseIcon, { size: "sm" })
|
|
938
2455
|
}
|
|
939
2456
|
)
|
|
940
2457
|
] }),
|
|
941
|
-
hint && !query && /* @__PURE__ */
|
|
942
|
-
/* @__PURE__ */
|
|
943
|
-
query && hits && (hits.length > 0 ? /* @__PURE__ */
|
|
944
|
-
/* @__PURE__ */
|
|
2458
|
+
hint && !query && /* @__PURE__ */ jsx3("p", { className: "ods-flow-fx-panel__hint", children: hint }),
|
|
2459
|
+
/* @__PURE__ */ jsxs3("div", { className: "ods-flow-fx-panel__list", ref: listRef, role: "tree", children: [
|
|
2460
|
+
query && hits && (hits.length > 0 ? /* @__PURE__ */ jsxs3("div", { className: "ods-flow-fx-panel__results", children: [
|
|
2461
|
+
/* @__PURE__ */ jsxs3("div", { className: "ods-flow-fx-panel__results-count", children: [
|
|
945
2462
|
hits.length,
|
|
946
2463
|
" ",
|
|
947
2464
|
hits.length === 1 ? "match" : "matches"
|
|
@@ -954,7 +2471,7 @@ function FxPanel({
|
|
|
954
2471
|
hit.ancestors.length ? hit.ancestors.join(" / ") : category.label
|
|
955
2472
|
)
|
|
956
2473
|
)
|
|
957
|
-
] }) : /* @__PURE__ */
|
|
2474
|
+
] }) : /* @__PURE__ */ jsx3("div", { className: "ods-flow-fx-panel__empty", children: emptyLabel })),
|
|
958
2475
|
!query && visibleCategories.map((cat) => {
|
|
959
2476
|
const isOpen = openCategoryId === cat.id;
|
|
960
2477
|
const kind = cat.kind ?? "function";
|
|
@@ -965,8 +2482,8 @@ function FxPanel({
|
|
|
965
2482
|
const rows = [];
|
|
966
2483
|
if (isOpen) flattenTree(cat.items, 0, expandedItems, rows);
|
|
967
2484
|
const allExpanded = hasTree && [...branchIds].every((id) => expandedItems.has(id));
|
|
968
|
-
return /* @__PURE__ */
|
|
969
|
-
/* @__PURE__ */
|
|
2485
|
+
return /* @__PURE__ */ jsxs3("div", { className: "ods-flow-fx-panel__category", children: [
|
|
2486
|
+
/* @__PURE__ */ jsxs3(
|
|
970
2487
|
"div",
|
|
971
2488
|
{
|
|
972
2489
|
className: cn(
|
|
@@ -974,7 +2491,7 @@ function FxPanel({
|
|
|
974
2491
|
isOpen && "ods-flow-fx-panel__cat-header--open"
|
|
975
2492
|
),
|
|
976
2493
|
children: [
|
|
977
|
-
/* @__PURE__ */
|
|
2494
|
+
/* @__PURE__ */ jsxs3(
|
|
978
2495
|
"button",
|
|
979
2496
|
{
|
|
980
2497
|
type: "button",
|
|
@@ -982,7 +2499,7 @@ function FxPanel({
|
|
|
982
2499
|
"aria-expanded": isOpen,
|
|
983
2500
|
onClick: () => setOpenCategory(isOpen ? null : cat.id),
|
|
984
2501
|
children: [
|
|
985
|
-
/* @__PURE__ */
|
|
2502
|
+
/* @__PURE__ */ jsx3(
|
|
986
2503
|
ChevronRightIcon,
|
|
987
2504
|
{
|
|
988
2505
|
size: "sm",
|
|
@@ -992,7 +2509,7 @@ function FxPanel({
|
|
|
992
2509
|
)
|
|
993
2510
|
}
|
|
994
2511
|
),
|
|
995
|
-
/* @__PURE__ */
|
|
2512
|
+
/* @__PURE__ */ jsxs3(
|
|
996
2513
|
"span",
|
|
997
2514
|
{
|
|
998
2515
|
className: cn(
|
|
@@ -1000,7 +2517,7 @@ function FxPanel({
|
|
|
1000
2517
|
`ods-flow-fx-panel__badge--${kind}`
|
|
1001
2518
|
),
|
|
1002
2519
|
children: [
|
|
1003
|
-
/* @__PURE__ */
|
|
2520
|
+
/* @__PURE__ */ jsx3(
|
|
1004
2521
|
KindIcon,
|
|
1005
2522
|
{
|
|
1006
2523
|
size: "sm",
|
|
@@ -1011,11 +2528,11 @@ function FxPanel({
|
|
|
1011
2528
|
]
|
|
1012
2529
|
}
|
|
1013
2530
|
),
|
|
1014
|
-
/* @__PURE__ */
|
|
2531
|
+
/* @__PURE__ */ jsx3("span", { className: "ods-flow-fx-panel__count", children: countLeaves(cat.items) })
|
|
1015
2532
|
]
|
|
1016
2533
|
}
|
|
1017
2534
|
),
|
|
1018
|
-
isOpen && hasTree && /* @__PURE__ */
|
|
2535
|
+
isOpen && hasTree && /* @__PURE__ */ jsx3(
|
|
1019
2536
|
"button",
|
|
1020
2537
|
{
|
|
1021
2538
|
type: "button",
|
|
@@ -1023,13 +2540,13 @@ function FxPanel({
|
|
|
1023
2540
|
"aria-label": allExpanded ? "Collapse all" : "Expand all",
|
|
1024
2541
|
title: allExpanded ? "Collapse all" : "Expand all",
|
|
1025
2542
|
onClick: () => setCategoryExpansion(cat, !allExpanded),
|
|
1026
|
-
children: allExpanded ? /* @__PURE__ */
|
|
2543
|
+
children: allExpanded ? /* @__PURE__ */ jsx3(CollapseAllIcon, { size: "sm" }) : /* @__PURE__ */ jsx3(ExpandAllIcon, { size: "sm" })
|
|
1027
2544
|
}
|
|
1028
2545
|
)
|
|
1029
2546
|
]
|
|
1030
2547
|
}
|
|
1031
2548
|
),
|
|
1032
|
-
isOpen && /* @__PURE__ */
|
|
2549
|
+
isOpen && /* @__PURE__ */ jsx3(
|
|
1033
2550
|
"div",
|
|
1034
2551
|
{
|
|
1035
2552
|
className: "ods-flow-fx-panel__rows",
|
|
@@ -1048,7 +2565,7 @@ function FxPanel({
|
|
|
1048
2565
|
|
|
1049
2566
|
// src/workflow/components/FxPanel/DataRefButton.tsx
|
|
1050
2567
|
import { DataReferenceIcon } from "@octaviaflow/icons";
|
|
1051
|
-
import { jsx as
|
|
2568
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1052
2569
|
function DataRefButton({
|
|
1053
2570
|
active = false,
|
|
1054
2571
|
label = "Data ref",
|
|
@@ -1056,7 +2573,7 @@ function DataRefButton({
|
|
|
1056
2573
|
type = "button",
|
|
1057
2574
|
...rest
|
|
1058
2575
|
}) {
|
|
1059
|
-
return /* @__PURE__ */
|
|
2576
|
+
return /* @__PURE__ */ jsxs4(
|
|
1060
2577
|
"button",
|
|
1061
2578
|
{
|
|
1062
2579
|
...rest,
|
|
@@ -1070,21 +2587,21 @@ function DataRefButton({
|
|
|
1070
2587
|
"aria-pressed": active,
|
|
1071
2588
|
title: active ? "Hide data references" : "Show data references",
|
|
1072
2589
|
children: [
|
|
1073
|
-
/* @__PURE__ */
|
|
2590
|
+
/* @__PURE__ */ jsx4(
|
|
1074
2591
|
DataReferenceIcon,
|
|
1075
2592
|
{
|
|
1076
2593
|
size: "sm",
|
|
1077
2594
|
className: "ods-flow-dataref-button__icon"
|
|
1078
2595
|
}
|
|
1079
2596
|
),
|
|
1080
|
-
label != null && /* @__PURE__ */
|
|
2597
|
+
label != null && /* @__PURE__ */ jsx4("span", { className: "ods-flow-dataref-button__label", children: label })
|
|
1081
2598
|
]
|
|
1082
2599
|
}
|
|
1083
2600
|
);
|
|
1084
2601
|
}
|
|
1085
2602
|
|
|
1086
2603
|
// src/workflow/components/NodeToolbar/NodeToolbar.tsx
|
|
1087
|
-
import { jsx as
|
|
2604
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
1088
2605
|
function NodeToolbar({
|
|
1089
2606
|
isVisible,
|
|
1090
2607
|
position = "top",
|
|
@@ -1099,7 +2616,7 @@ function NodeToolbar({
|
|
|
1099
2616
|
const show = isVisible ?? node.selected;
|
|
1100
2617
|
if (!show) return null;
|
|
1101
2618
|
const inverseScale = 1 / viewport.zoom;
|
|
1102
|
-
return /* @__PURE__ */
|
|
2619
|
+
return /* @__PURE__ */ jsx5(
|
|
1103
2620
|
"div",
|
|
1104
2621
|
{
|
|
1105
2622
|
className: cn("ods-node-toolbar", `ods-node-toolbar--${position}`, className),
|
|
@@ -1111,7 +2628,7 @@ function NodeToolbar({
|
|
|
1111
2628
|
onPointerDown: (e) => e.stopPropagation(),
|
|
1112
2629
|
onMouseDown: (e) => e.stopPropagation(),
|
|
1113
2630
|
onClick: (e) => e.stopPropagation(),
|
|
1114
|
-
children: /* @__PURE__ */
|
|
2631
|
+
children: /* @__PURE__ */ jsx5(
|
|
1115
2632
|
"div",
|
|
1116
2633
|
{
|
|
1117
2634
|
className: "ods-node-toolbar__inner",
|
|
@@ -1267,7 +2784,10 @@ export {
|
|
|
1267
2784
|
ForEachNode,
|
|
1268
2785
|
FxPanel,
|
|
1269
2786
|
GroupNode,
|
|
2787
|
+
HTTP_ACTION_DEFAULTS,
|
|
2788
|
+
HTTP_METHODS,
|
|
1270
2789
|
Handle,
|
|
2790
|
+
HttpActionPanel,
|
|
1271
2791
|
HttpRequestNode,
|
|
1272
2792
|
NodeResizer,
|
|
1273
2793
|
NodeToolbar,
|
|
@@ -1281,19 +2801,28 @@ export {
|
|
|
1281
2801
|
applyNodeChanges,
|
|
1282
2802
|
bezierPath2 as bezierPath,
|
|
1283
2803
|
bezierPath as bezierPathFn,
|
|
2804
|
+
buildCurl,
|
|
1284
2805
|
buildEdgePath,
|
|
1285
2806
|
buildNodeKindRegistry,
|
|
1286
2807
|
change,
|
|
1287
2808
|
clampToParentExtent,
|
|
1288
2809
|
collapseFor,
|
|
2810
|
+
countGraphqlVariables,
|
|
2811
|
+
countSchemaPaths,
|
|
1289
2812
|
createDagreEngine,
|
|
1290
2813
|
createElkEngine,
|
|
1291
2814
|
descendantsOf,
|
|
2815
|
+
effectiveUrl,
|
|
1292
2816
|
findAncestor,
|
|
1293
2817
|
findContainingGroup,
|
|
1294
2818
|
flowToScreen,
|
|
1295
2819
|
handleCentre,
|
|
2820
|
+
inferJsonSchema,
|
|
2821
|
+
normalizeAuth,
|
|
2822
|
+
normalizeKeyValues,
|
|
2823
|
+
parseCurl,
|
|
1296
2824
|
screenToFlow,
|
|
2825
|
+
serializeKeyValues,
|
|
1297
2826
|
smoothStepPath,
|
|
1298
2827
|
stepPath,
|
|
1299
2828
|
straightPath,
|
|
@@ -1313,6 +2842,7 @@ export {
|
|
|
1313
2842
|
useNodes,
|
|
1314
2843
|
useSelection,
|
|
1315
2844
|
useViewport,
|
|
1316
|
-
useViewportOrNull
|
|
2845
|
+
useViewportOrNull,
|
|
2846
|
+
validateHttpConfig
|
|
1317
2847
|
};
|
|
1318
2848
|
//# sourceMappingURL=workflow.js.map
|