@d34dman/flowdrop 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/README.md +307 -215
  2. package/dist/adapters/WorkflowAdapter.d.ts +1 -1
  3. package/dist/adapters/WorkflowAdapter.js +30 -30
  4. package/dist/api/client.d.ts +24 -1
  5. package/dist/api/client.js +55 -38
  6. package/dist/api/enhanced-client.d.ts +46 -0
  7. package/dist/api/enhanced-client.js +211 -0
  8. package/dist/clients/ApiClient.d.ts +19 -23
  9. package/dist/clients/ApiClient.js +36 -34
  10. package/dist/components/App.svelte +1299 -230
  11. package/dist/components/App.svelte.d.ts +21 -1
  12. package/dist/components/CanvasBanner.svelte +50 -44
  13. package/dist/components/CanvasBanner.svelte.d.ts +5 -19
  14. package/dist/components/ConfigForm.svelte +555 -0
  15. package/dist/components/ConfigForm.svelte.d.ts +32 -0
  16. package/dist/components/ConfigModal.svelte +261 -0
  17. package/dist/components/ConfigModal.svelte.d.ts +31 -0
  18. package/dist/components/ConfigSidebar.svelte +934 -0
  19. package/dist/components/ConfigSidebar.svelte.d.ts +51 -0
  20. package/dist/components/ConnectionLine.svelte +32 -0
  21. package/dist/components/ConnectionLine.svelte.d.ts +3 -0
  22. package/dist/components/GatewayNode.svelte +471 -0
  23. package/dist/components/GatewayNode.svelte.d.ts +15 -0
  24. package/dist/components/LoadingSpinner.svelte +23 -23
  25. package/dist/components/LoadingSpinner.svelte.d.ts +1 -1
  26. package/dist/components/Logo.svelte +82 -0
  27. package/dist/components/Logo.svelte.d.ts +26 -0
  28. package/dist/components/LogsSidebar.svelte +565 -0
  29. package/dist/components/LogsSidebar.svelte.d.ts +34 -0
  30. package/dist/components/MarkdownDisplay.svelte +28 -0
  31. package/dist/components/MarkdownDisplay.svelte.d.ts +7 -0
  32. package/dist/components/Navbar.svelte +663 -0
  33. package/dist/components/Navbar.svelte.d.ts +21 -0
  34. package/dist/components/NodeSidebar.svelte +629 -488
  35. package/dist/components/NodeSidebar.svelte.d.ts +1 -2
  36. package/dist/components/NodeStatusOverlay.svelte +327 -0
  37. package/dist/components/NodeStatusOverlay.svelte.d.ts +11 -0
  38. package/dist/components/NotesNode.svelte +566 -0
  39. package/dist/components/NotesNode.svelte.d.ts +43 -0
  40. package/dist/components/PipelineStatus.svelte +331 -0
  41. package/dist/components/PipelineStatus.svelte.d.ts +18 -0
  42. package/dist/components/SimpleNode.svelte +447 -0
  43. package/dist/components/SimpleNode.svelte.d.ts +24 -0
  44. package/dist/components/SquareNode.svelte +346 -0
  45. package/dist/components/SquareNode.svelte.d.ts +24 -0
  46. package/dist/components/StatusIcon.svelte +112 -0
  47. package/dist/components/StatusIcon.svelte.d.ts +10 -0
  48. package/dist/components/StatusLabel.svelte +33 -0
  49. package/dist/components/StatusLabel.svelte.d.ts +7 -0
  50. package/dist/components/ToolNode.svelte +385 -0
  51. package/dist/components/ToolNode.svelte.d.ts +36 -0
  52. package/dist/components/UniversalNode.svelte +126 -0
  53. package/dist/components/UniversalNode.svelte.d.ts +15 -0
  54. package/dist/components/WorkflowEditor.svelte +871 -528
  55. package/dist/components/WorkflowEditor.svelte.d.ts +15 -5
  56. package/dist/components/WorkflowNode.svelte +428 -542
  57. package/dist/components/WorkflowNode.svelte.d.ts +7 -3
  58. package/dist/config/apiConfig.d.ts +33 -0
  59. package/dist/config/apiConfig.js +39 -0
  60. package/dist/config/defaultPortConfig.d.ts +6 -0
  61. package/dist/config/defaultPortConfig.js +192 -0
  62. package/dist/config/demo.d.ts +58 -0
  63. package/dist/config/demo.js +142 -0
  64. package/dist/config/endpoints.d.ts +106 -0
  65. package/dist/config/endpoints.js +128 -0
  66. package/dist/data/samples.d.ts +38 -4
  67. package/dist/data/samples.js +2789 -737
  68. package/dist/examples/adapter-usage.d.ts +4 -4
  69. package/dist/examples/adapter-usage.js +21 -26
  70. package/dist/examples/api-client-usage.d.ts +6 -6
  71. package/dist/examples/api-client-usage.js +55 -54
  72. package/dist/index.d.ts +23 -15
  73. package/dist/index.js +23 -15
  74. package/dist/mocks/app-environment.d.ts +8 -0
  75. package/dist/mocks/app-environment.js +16 -0
  76. package/dist/mocks/app-forms.d.ts +2 -0
  77. package/dist/mocks/app-forms.js +21 -0
  78. package/dist/mocks/app-navigation.d.ts +5 -0
  79. package/dist/mocks/app-navigation.js +34 -0
  80. package/dist/mocks/app-stores.d.ts +14 -0
  81. package/dist/mocks/app-stores.js +26 -0
  82. package/dist/services/api.d.ts +13 -3
  83. package/dist/services/api.js +91 -36
  84. package/dist/services/globalSave.d.ts +20 -0
  85. package/dist/services/globalSave.js +165 -0
  86. package/dist/services/nodeExecutionService.d.ts +63 -0
  87. package/dist/services/nodeExecutionService.js +261 -0
  88. package/dist/services/portConfigApi.d.ts +14 -0
  89. package/dist/services/portConfigApi.js +69 -0
  90. package/dist/services/toastService.d.ts +147 -0
  91. package/dist/services/toastService.js +235 -0
  92. package/dist/services/workflowStorage.d.ts +2 -2
  93. package/dist/services/workflowStorage.js +10 -10
  94. package/dist/stores/workflowStore.d.ts +53 -0
  95. package/dist/stores/workflowStore.js +264 -0
  96. package/dist/styles/base.css +896 -363
  97. package/dist/svelte-app.d.ts +52 -5
  98. package/dist/svelte-app.js +128 -6
  99. package/dist/types/config.d.ts +291 -0
  100. package/dist/types/config.js +4 -0
  101. package/dist/types/index.d.ts +231 -19
  102. package/dist/types/index.js +1 -1
  103. package/dist/utils/colors.d.ts +67 -33
  104. package/dist/utils/colors.js +183 -118
  105. package/dist/utils/config.d.ts +41 -0
  106. package/dist/utils/config.js +248 -0
  107. package/dist/utils/connections.d.ts +40 -3
  108. package/dist/utils/connections.js +115 -44
  109. package/dist/utils/icons.d.ts +1 -1
  110. package/dist/utils/icons.js +71 -70
  111. package/dist/utils/nodeStatus.d.ts +53 -0
  112. package/dist/utils/nodeStatus.js +183 -0
  113. package/dist/utils/nodeTypes.d.ts +57 -0
  114. package/dist/utils/nodeTypes.js +109 -0
  115. package/dist/utils/nodeWrapper.d.ts +39 -0
  116. package/dist/utils/nodeWrapper.js +62 -0
  117. package/package.json +132 -97
  118. package/dist/app.css +0 -0
  119. package/dist/components/Node.svelte +0 -38
  120. package/dist/components/Node.svelte.d.ts +0 -4
@@ -13,7 +13,7 @@
13
13
  * - External applications that want to integrate with FlowDrop
14
14
  * - Systems that need to generate or modify workflows programmatically
15
15
  */
16
- import { v4 as uuidv4 } from "uuid";
16
+ import { v4 as uuidv4 } from 'uuid';
17
17
  /**
18
18
  * Workflow Adapter Class
19
19
  * Provides a clean API for workflow operations without exposing SvelteFlow internals
@@ -34,7 +34,7 @@ export class WorkflowAdapter {
34
34
  nodes: [],
35
35
  edges: [],
36
36
  metadata: {
37
- version: "1.0.0",
37
+ version: '1.0.0',
38
38
  createdAt: new Date().toISOString(),
39
39
  updatedAt: new Date().toISOString()
40
40
  }
@@ -44,7 +44,7 @@ export class WorkflowAdapter {
44
44
  * Add a node to a workflow
45
45
  */
46
46
  addNode(workflow, nodeType, position, config) {
47
- const metadata = this.nodeTypes.find(nt => nt.id === nodeType);
47
+ const metadata = this.nodeTypes.find((nt) => nt.id === nodeType);
48
48
  if (!metadata) {
49
49
  throw new Error(`Node type '${nodeType}' not found`);
50
50
  }
@@ -66,12 +66,12 @@ export class WorkflowAdapter {
66
66
  * Remove a node from a workflow
67
67
  */
68
68
  removeNode(workflow, nodeId) {
69
- const nodeIndex = workflow.nodes.findIndex(n => n.id === nodeId);
69
+ const nodeIndex = workflow.nodes.findIndex((n) => n.id === nodeId);
70
70
  if (nodeIndex === -1)
71
71
  return false;
72
72
  workflow.nodes.splice(nodeIndex, 1);
73
73
  // Remove associated edges
74
- workflow.edges = workflow.edges.filter(edge => edge.source !== nodeId && edge.target !== nodeId);
74
+ workflow.edges = workflow.edges.filter((edge) => edge.source !== nodeId && edge.target !== nodeId);
75
75
  workflow.metadata.updatedAt = new Date().toISOString();
76
76
  return true;
77
77
  }
@@ -79,7 +79,7 @@ export class WorkflowAdapter {
79
79
  * Update node position
80
80
  */
81
81
  updateNodePosition(workflow, nodeId, position) {
82
- const node = workflow.nodes.find(n => n.id === nodeId);
82
+ const node = workflow.nodes.find((n) => n.id === nodeId);
83
83
  if (!node)
84
84
  return false;
85
85
  node.position = position;
@@ -90,7 +90,7 @@ export class WorkflowAdapter {
90
90
  * Update node configuration
91
91
  */
92
92
  updateNodeConfig(workflow, nodeId, config) {
93
- const node = workflow.nodes.find(n => n.id === nodeId);
93
+ const node = workflow.nodes.find((n) => n.id === nodeId);
94
94
  if (!node)
95
95
  return false;
96
96
  node.data.config = { ...node.data.config, ...config };
@@ -116,7 +116,7 @@ export class WorkflowAdapter {
116
116
  * Remove an edge from a workflow
117
117
  */
118
118
  removeEdge(workflow, edgeId) {
119
- const edgeIndex = workflow.edges.findIndex(e => e.id === edgeId);
119
+ const edgeIndex = workflow.edges.findIndex((e) => e.id === edgeId);
120
120
  if (edgeIndex === -1)
121
121
  return false;
122
122
  workflow.edges.splice(edgeIndex, 1);
@@ -127,20 +127,20 @@ export class WorkflowAdapter {
127
127
  * Get all nodes of a specific type
128
128
  */
129
129
  getNodesByType(workflow, nodeType) {
130
- return workflow.nodes.filter(node => node.type === nodeType);
130
+ return workflow.nodes.filter((node) => node.type === nodeType);
131
131
  }
132
132
  /**
133
133
  * Get all edges connected to a node
134
134
  */
135
135
  getNodeEdges(workflow, nodeId) {
136
- return workflow.edges.filter(edge => edge.source === nodeId || edge.target === nodeId);
136
+ return workflow.edges.filter((edge) => edge.source === nodeId || edge.target === nodeId);
137
137
  }
138
138
  /**
139
139
  * Get connected nodes (both incoming and outgoing)
140
140
  */
141
141
  getConnectedNodes(workflow, nodeId) {
142
142
  const connectedNodeIds = new Set();
143
- workflow.edges.forEach(edge => {
143
+ workflow.edges.forEach((edge) => {
144
144
  if (edge.source === nodeId) {
145
145
  connectedNodeIds.add(edge.target);
146
146
  }
@@ -148,7 +148,7 @@ export class WorkflowAdapter {
148
148
  connectedNodeIds.add(edge.source);
149
149
  }
150
150
  });
151
- return workflow.nodes.filter(node => connectedNodeIds.has(node.id));
151
+ return workflow.nodes.filter((node) => connectedNodeIds.has(node.id));
152
152
  }
153
153
  /**
154
154
  * Validate workflow structure
@@ -158,11 +158,11 @@ export class WorkflowAdapter {
158
158
  const warnings = [];
159
159
  // Check for empty workflow
160
160
  if (workflow.nodes.length === 0) {
161
- warnings.push("Workflow has no nodes");
161
+ warnings.push('Workflow has no nodes');
162
162
  }
163
163
  // Check for orphaned edges
164
- const nodeIds = new Set(workflow.nodes.map(n => n.id));
165
- workflow.edges.forEach(edge => {
164
+ const nodeIds = new Set(workflow.nodes.map((n) => n.id));
165
+ workflow.edges.forEach((edge) => {
166
166
  if (!nodeIds.has(edge.source)) {
167
167
  errors.push(`Edge ${edge.id} references non-existent source node ${edge.source}`);
168
168
  }
@@ -171,14 +171,14 @@ export class WorkflowAdapter {
171
171
  }
172
172
  });
173
173
  // Check for self-connections
174
- workflow.edges.forEach(edge => {
174
+ workflow.edges.forEach((edge) => {
175
175
  if (edge.source === edge.target) {
176
176
  errors.push(`Node ${edge.source} cannot connect to itself`);
177
177
  }
178
178
  });
179
179
  // Check for duplicate node IDs
180
180
  const nodeIdCounts = new Map();
181
- workflow.nodes.forEach(node => {
181
+ workflow.nodes.forEach((node) => {
182
182
  nodeIdCounts.set(node.id, (nodeIdCounts.get(node.id) || 0) + 1);
183
183
  });
184
184
  nodeIdCounts.forEach((count, id) => {
@@ -188,7 +188,7 @@ export class WorkflowAdapter {
188
188
  });
189
189
  // Check for duplicate edge IDs
190
190
  const edgeIdCounts = new Map();
191
- workflow.edges.forEach(edge => {
191
+ workflow.edges.forEach((edge) => {
192
192
  edgeIdCounts.set(edge.id, (edgeIdCounts.get(edge.id) || 0) + 1);
193
193
  });
194
194
  edgeIdCounts.forEach((count, id) => {
@@ -217,11 +217,11 @@ export class WorkflowAdapter {
217
217
  // Validate the imported workflow
218
218
  const validation = this.validateWorkflow(workflow);
219
219
  if (!validation.valid) {
220
- throw new Error(`Invalid workflow: ${validation.errors.join(", ")}`);
220
+ throw new Error(`Invalid workflow: ${validation.errors.join(', ')}`);
221
221
  }
222
222
  // Update metadata
223
223
  workflow.metadata = {
224
- version: workflow.metadata?.version || "1.0.0",
224
+ version: workflow.metadata?.version || '1.0.0',
225
225
  createdAt: workflow.metadata?.createdAt || new Date().toISOString(),
226
226
  updatedAt: new Date().toISOString(),
227
227
  author: workflow.metadata?.author,
@@ -230,7 +230,7 @@ export class WorkflowAdapter {
230
230
  return workflow;
231
231
  }
232
232
  catch (error) {
233
- throw new Error(`Failed to import workflow: ${error instanceof Error ? error.message : "Unknown error"}`);
233
+ throw new Error(`Failed to import workflow: ${error instanceof Error ? error.message : 'Unknown error'}`);
234
234
  }
235
235
  }
236
236
  /**
@@ -241,7 +241,7 @@ export class WorkflowAdapter {
241
241
  id: svelteFlowWorkflow.id,
242
242
  name: svelteFlowWorkflow.name,
243
243
  description: svelteFlowWorkflow.description,
244
- nodes: svelteFlowWorkflow.nodes.map(node => ({
244
+ nodes: svelteFlowWorkflow.nodes.map((node) => ({
245
245
  id: node.id,
246
246
  type: node.data.metadata.id,
247
247
  position: node.position,
@@ -251,7 +251,7 @@ export class WorkflowAdapter {
251
251
  metadata: node.data.metadata
252
252
  }
253
253
  })),
254
- edges: svelteFlowWorkflow.edges.map(edge => ({
254
+ edges: svelteFlowWorkflow.edges.map((edge) => ({
255
255
  id: edge.id,
256
256
  source: edge.source,
257
257
  target: edge.target,
@@ -269,9 +269,9 @@ export class WorkflowAdapter {
269
269
  id: workflow.id,
270
270
  name: workflow.name,
271
271
  description: workflow.description,
272
- nodes: workflow.nodes.map(node => ({
272
+ nodes: workflow.nodes.map((node) => ({
273
273
  id: node.id,
274
- type: "workflowNode",
274
+ type: 'workflowNode',
275
275
  position: node.position,
276
276
  deletable: true,
277
277
  data: {
@@ -281,7 +281,7 @@ export class WorkflowAdapter {
281
281
  nodeId: node.id
282
282
  }
283
283
  })),
284
- edges: workflow.edges.map(edge => ({
284
+ edges: workflow.edges.map((edge) => ({
285
285
  id: edge.id,
286
286
  source: edge.source,
287
287
  target: edge.target,
@@ -296,7 +296,7 @@ export class WorkflowAdapter {
296
296
  */
297
297
  getWorkflowStats(workflow) {
298
298
  const nodeTypeCounts = new Map();
299
- workflow.nodes.forEach(node => {
299
+ workflow.nodes.forEach((node) => {
300
300
  nodeTypeCounts.set(node.type, (nodeTypeCounts.get(node.type) || 0) + 1);
301
301
  });
302
302
  return {
@@ -313,12 +313,12 @@ export class WorkflowAdapter {
313
313
  const cloned = JSON.parse(JSON.stringify(workflow));
314
314
  // Generate new IDs for all nodes and edges
315
315
  const idMapping = new Map();
316
- cloned.nodes.forEach(node => {
316
+ cloned.nodes.forEach((node) => {
317
317
  const oldId = node.id;
318
318
  node.id = uuidv4();
319
319
  idMapping.set(oldId, node.id);
320
320
  });
321
- cloned.edges.forEach(edge => {
321
+ cloned.edges.forEach((edge) => {
322
322
  edge.id = uuidv4();
323
323
  edge.source = idMapping.get(edge.source) || edge.source;
324
324
  edge.target = idMapping.get(edge.target) || edge.target;
@@ -326,7 +326,7 @@ export class WorkflowAdapter {
326
326
  cloned.id = uuidv4();
327
327
  cloned.name = newName || `${workflow.name} (Copy)`;
328
328
  cloned.metadata = {
329
- version: cloned.metadata?.version || "1.0.0",
329
+ version: cloned.metadata?.version || '1.0.0',
330
330
  createdAt: new Date().toISOString(),
331
331
  updatedAt: new Date().toISOString(),
332
332
  author: cloned.metadata?.author,
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * API Client for FlowDrop Workflow Library
3
3
  */
4
- import type { NodeMetadata, Workflow, ExecutionResult } from "../types/index.js";
4
+ import type { NodeMetadata, Workflow, ExecutionResult, PortConfig } from '../types/index.js';
5
5
  /**
6
6
  * HTTP API client for FlowDrop
7
7
  */
@@ -76,4 +76,27 @@ export declare class FlowDropApiClient {
76
76
  * Import workflow from JSON
77
77
  */
78
78
  importWorkflow(workflowJson: string): Promise<Workflow>;
79
+ /**
80
+ * Fetch port configuration
81
+ */
82
+ getPortConfig(): Promise<PortConfig>;
83
+ /**
84
+ * Fetch pipeline data including job information and status
85
+ */
86
+ getPipelineData(pipelineId: string): Promise<{
87
+ status: string;
88
+ jobs: Array<Record<string, unknown>>;
89
+ node_statuses: Record<string, {
90
+ status: string;
91
+ [key: string]: unknown;
92
+ }>;
93
+ job_status_summary: {
94
+ total: number;
95
+ pending: number;
96
+ running: number;
97
+ completed: number;
98
+ failed: number;
99
+ cancelled: number;
100
+ };
101
+ }>;
79
102
  }
@@ -8,12 +8,12 @@ export class FlowDropApiClient {
8
8
  baseUrl;
9
9
  headers;
10
10
  constructor(baseUrl, apiKey) {
11
- this.baseUrl = baseUrl.replace(/\/$/, "");
11
+ this.baseUrl = baseUrl.replace(/\/$/, '');
12
12
  this.headers = {
13
- "Content-Type": "application/json",
13
+ 'Content-Type': 'application/json'
14
14
  };
15
15
  if (apiKey) {
16
- this.headers["Authorization"] = `Bearer ${apiKey}`;
16
+ this.headers['Authorization'] = `Bearer ${apiKey}`;
17
17
  }
18
18
  }
19
19
  /**
@@ -23,7 +23,7 @@ export class FlowDropApiClient {
23
23
  const url = `${this.baseUrl}${endpoint}`;
24
24
  const config = {
25
25
  headers: this.headers,
26
- ...options,
26
+ ...options
27
27
  };
28
28
  try {
29
29
  const response = await fetch(url, config);
@@ -34,17 +34,17 @@ export class FlowDropApiClient {
34
34
  return data;
35
35
  }
36
36
  catch (error) {
37
- console.error("API request failed:", error);
38
- throw new Error(`API request failed: ${error instanceof Error ? error.message : "Unknown error"}`);
37
+ console.error('API request failed:', error);
38
+ throw new Error(`API request failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
39
39
  }
40
40
  }
41
41
  /**
42
42
  * Fetch available node types and their metadata
43
43
  */
44
44
  async getAvailableNodes() {
45
- const response = await this.request("/api/nodes");
45
+ const response = await this.request('/api/flowdrop/nodes');
46
46
  if (!response.success || !response.data) {
47
- throw new Error(response.error || "Failed to fetch available nodes");
47
+ throw new Error(response.error || 'Failed to fetch available nodes');
48
48
  }
49
49
  return response.data;
50
50
  }
@@ -54,7 +54,7 @@ export class FlowDropApiClient {
54
54
  async getNodesByCategory(category) {
55
55
  const response = await this.request(`/api/nodes?category=${encodeURIComponent(category)}`);
56
56
  if (!response.success || !response.data) {
57
- throw new Error(response.error || "Failed to fetch nodes by category");
57
+ throw new Error(response.error || 'Failed to fetch nodes by category');
58
58
  }
59
59
  return response.data;
60
60
  }
@@ -64,7 +64,7 @@ export class FlowDropApiClient {
64
64
  async getNodeMetadata(nodeId) {
65
65
  const response = await this.request(`/api/nodes/${encodeURIComponent(nodeId)}`);
66
66
  if (!response.success || !response.data) {
67
- throw new Error(response.error || "Failed to fetch node metadata");
67
+ throw new Error(response.error || 'Failed to fetch node metadata');
68
68
  }
69
69
  return response.data;
70
70
  }
@@ -72,12 +72,12 @@ export class FlowDropApiClient {
72
72
  * Save a workflow
73
73
  */
74
74
  async saveWorkflow(workflow) {
75
- const response = await this.request("/api/workflows", {
76
- method: "POST",
77
- body: JSON.stringify(workflow),
75
+ const response = await this.request('/api/flowdrop/workflows', {
76
+ method: 'POST',
77
+ body: JSON.stringify(workflow)
78
78
  });
79
79
  if (!response.success || !response.data) {
80
- throw new Error(response.error || "Failed to save workflow");
80
+ throw new Error(response.error || 'Failed to save workflow');
81
81
  }
82
82
  return response.data;
83
83
  }
@@ -86,11 +86,11 @@ export class FlowDropApiClient {
86
86
  */
87
87
  async updateWorkflow(workflowId, workflow) {
88
88
  const response = await this.request(`/api/workflows/${encodeURIComponent(workflowId)}`, {
89
- method: "PUT",
90
- body: JSON.stringify(workflow),
89
+ method: 'PUT',
90
+ body: JSON.stringify(workflow)
91
91
  });
92
92
  if (!response.success || !response.data) {
93
- throw new Error(response.error || "Failed to update workflow");
93
+ throw new Error(response.error || 'Failed to update workflow');
94
94
  }
95
95
  return response.data;
96
96
  }
@@ -100,7 +100,7 @@ export class FlowDropApiClient {
100
100
  async loadWorkflow(workflowId) {
101
101
  const response = await this.request(`/api/workflows/${encodeURIComponent(workflowId)}`);
102
102
  if (!response.success || !response.data) {
103
- throw new Error(response.error || "Failed to load workflow");
103
+ throw new Error(response.error || 'Failed to load workflow');
104
104
  }
105
105
  return response.data;
106
106
  }
@@ -108,9 +108,9 @@ export class FlowDropApiClient {
108
108
  * List all workflows
109
109
  */
110
110
  async listWorkflows() {
111
- const response = await this.request("/api/workflows");
111
+ const response = await this.request('/api/flowdrop/workflows');
112
112
  if (!response.success || !response.data) {
113
- throw new Error(response.error || "Failed to list workflows");
113
+ throw new Error(response.error || 'Failed to list workflows');
114
114
  }
115
115
  return response.data;
116
116
  }
@@ -119,10 +119,10 @@ export class FlowDropApiClient {
119
119
  */
120
120
  async deleteWorkflow(workflowId) {
121
121
  const response = await this.request(`/api/workflows/${encodeURIComponent(workflowId)}`, {
122
- method: "DELETE",
122
+ method: 'DELETE'
123
123
  });
124
124
  if (!response.success) {
125
- throw new Error(response.error || "Failed to delete workflow");
125
+ throw new Error(response.error || 'Failed to delete workflow');
126
126
  }
127
127
  }
128
128
  /**
@@ -130,11 +130,11 @@ export class FlowDropApiClient {
130
130
  */
131
131
  async executeWorkflow(workflowId, inputs) {
132
132
  const response = await this.request(`/api/workflows/${encodeURIComponent(workflowId)}/execute`, {
133
- method: "POST",
134
- body: JSON.stringify({ inputs }),
133
+ method: 'POST',
134
+ body: JSON.stringify({ inputs })
135
135
  });
136
136
  if (!response.success || !response.data) {
137
- throw new Error(response.error || "Failed to execute workflow");
137
+ throw new Error(response.error || 'Failed to execute workflow');
138
138
  }
139
139
  return response.data;
140
140
  }
@@ -144,7 +144,7 @@ export class FlowDropApiClient {
144
144
  async getExecutionStatus(executionId) {
145
145
  const response = await this.request(`/api/executions/${encodeURIComponent(executionId)}`);
146
146
  if (!response.success || !response.data) {
147
- throw new Error(response.error || "Failed to get execution status");
147
+ throw new Error(response.error || 'Failed to get execution status');
148
148
  }
149
149
  return response.data;
150
150
  }
@@ -153,10 +153,10 @@ export class FlowDropApiClient {
153
153
  */
154
154
  async cancelExecution(executionId) {
155
155
  const response = await this.request(`/api/executions/${encodeURIComponent(executionId)}/cancel`, {
156
- method: "POST",
156
+ method: 'POST'
157
157
  });
158
158
  if (!response.success) {
159
- throw new Error(response.error || "Failed to cancel execution");
159
+ throw new Error(response.error || 'Failed to cancel execution');
160
160
  }
161
161
  }
162
162
  /**
@@ -165,7 +165,7 @@ export class FlowDropApiClient {
165
165
  async getExecutionLogs(executionId) {
166
166
  const response = await this.request(`/api/executions/${encodeURIComponent(executionId)}/logs`);
167
167
  if (!response.success || !response.data) {
168
- throw new Error(response.error || "Failed to get execution logs");
168
+ throw new Error(response.error || 'Failed to get execution logs');
169
169
  }
170
170
  return response.data;
171
171
  }
@@ -173,12 +173,12 @@ export class FlowDropApiClient {
173
173
  * Validate workflow configuration
174
174
  */
175
175
  async validateWorkflow(workflow) {
176
- const response = await this.request("/api/workflows/validate", {
177
- method: "POST",
178
- body: JSON.stringify(workflow),
176
+ const response = await this.request('/api/flowdrop/workflows/validate', {
177
+ method: 'POST',
178
+ body: JSON.stringify(workflow)
179
179
  });
180
180
  if (!response.success || !response.data) {
181
- throw new Error(response.error || "Failed to validate workflow");
181
+ throw new Error(response.error || 'Failed to validate workflow');
182
182
  }
183
183
  return response.data;
184
184
  }
@@ -188,7 +188,7 @@ export class FlowDropApiClient {
188
188
  async exportWorkflow(workflowId) {
189
189
  const response = await this.request(`/api/workflows/${encodeURIComponent(workflowId)}/export`);
190
190
  if (!response.success || !response.data) {
191
- throw new Error(response.error || "Failed to export workflow");
191
+ throw new Error(response.error || 'Failed to export workflow');
192
192
  }
193
193
  return response.data;
194
194
  }
@@ -196,13 +196,30 @@ export class FlowDropApiClient {
196
196
  * Import workflow from JSON
197
197
  */
198
198
  async importWorkflow(workflowJson) {
199
- const response = await this.request("/api/workflows/import", {
200
- method: "POST",
201
- body: JSON.stringify({ workflow: workflowJson }),
199
+ const response = await this.request('/api/flowdrop/workflows/import', {
200
+ method: 'POST',
201
+ body: JSON.stringify({ workflow: workflowJson })
202
202
  });
203
203
  if (!response.success || !response.data) {
204
- throw new Error(response.error || "Failed to import workflow");
204
+ throw new Error(response.error || 'Failed to import workflow');
205
205
  }
206
206
  return response.data;
207
207
  }
208
+ /**
209
+ * Fetch port configuration
210
+ */
211
+ async getPortConfig() {
212
+ const response = await this.request('/api/flowdrop/port-config');
213
+ if (!response.success || !response.data) {
214
+ throw new Error(response.error || 'Failed to fetch port configuration');
215
+ }
216
+ return response.data;
217
+ }
218
+ /**
219
+ * Fetch pipeline data including job information and status
220
+ */
221
+ async getPipelineData(pipelineId) {
222
+ const response = await this.request(`/api/flowdrop/pipeline/${encodeURIComponent(pipelineId)}`);
223
+ return response;
224
+ }
208
225
  }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Enhanced API Client for FlowDrop
3
+ * Uses configurable endpoints for all API actions
4
+ */
5
+ import type { NodeMetadata, Workflow, ExecutionResult } from '../types/index.js';
6
+ import type { EndpointConfig } from '../config/endpoints.js';
7
+ /**
8
+ * Enhanced HTTP API client for FlowDrop with configurable endpoints
9
+ */
10
+ export declare class EnhancedFlowDropApiClient {
11
+ private config;
12
+ constructor(config: EndpointConfig);
13
+ /**
14
+ * Make HTTP request with error handling and retry logic
15
+ */
16
+ private request;
17
+ getAvailableNodes(): Promise<NodeMetadata[]>;
18
+ getNodesByCategory(category: string): Promise<NodeMetadata[]>;
19
+ getNodeMetadata(nodeId: string): Promise<NodeMetadata>;
20
+ saveWorkflow(workflow: Workflow): Promise<Workflow>;
21
+ updateWorkflow(workflowId: string, workflow: Partial<Workflow>): Promise<Workflow>;
22
+ loadWorkflow(workflowId: string): Promise<Workflow>;
23
+ listWorkflows(): Promise<Workflow[]>;
24
+ deleteWorkflow(workflowId: string): Promise<void>;
25
+ validateWorkflow(workflow: Workflow): Promise<{
26
+ valid: boolean;
27
+ errors: string[];
28
+ }>;
29
+ exportWorkflow(workflowId: string): Promise<string>;
30
+ importWorkflow(workflowJson: string): Promise<Workflow>;
31
+ executeWorkflow(workflowId: string, inputs?: Record<string, unknown>): Promise<ExecutionResult>;
32
+ getExecutionStatus(executionId: string): Promise<ExecutionResult>;
33
+ cancelExecution(executionId: string): Promise<void>;
34
+ getExecutionLogs(executionId: string): Promise<string[]>;
35
+ listTemplates(): Promise<Workflow[]>;
36
+ getTemplate(templateId: string): Promise<Workflow>;
37
+ getSystemHealth(): Promise<{
38
+ status: string;
39
+ timestamp: number;
40
+ }>;
41
+ getSystemConfig(): Promise<Record<string, unknown>>;
42
+ getSystemVersion(): Promise<{
43
+ version: string;
44
+ build: string;
45
+ }>;
46
+ }