@d34dman/flowdrop 0.0.1 → 0.0.2
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/README.md +307 -215
- package/dist/adapters/WorkflowAdapter.d.ts +1 -1
- package/dist/adapters/WorkflowAdapter.js +30 -30
- package/dist/api/client.d.ts +24 -1
- package/dist/api/client.js +55 -38
- package/dist/api/enhanced-client.d.ts +46 -0
- package/dist/api/enhanced-client.js +211 -0
- package/dist/clients/ApiClient.d.ts +19 -23
- package/dist/clients/ApiClient.js +36 -34
- package/dist/components/App.svelte +1299 -230
- package/dist/components/App.svelte.d.ts +21 -1
- package/dist/components/CanvasBanner.svelte +50 -44
- package/dist/components/CanvasBanner.svelte.d.ts +5 -19
- package/dist/components/ConfigForm.svelte +555 -0
- package/dist/components/ConfigForm.svelte.d.ts +32 -0
- package/dist/components/ConfigModal.svelte +261 -0
- package/dist/components/ConfigModal.svelte.d.ts +31 -0
- package/dist/components/ConfigSidebar.svelte +934 -0
- package/dist/components/ConfigSidebar.svelte.d.ts +51 -0
- package/dist/components/ConnectionLine.svelte +32 -0
- package/dist/components/ConnectionLine.svelte.d.ts +3 -0
- package/dist/components/GatewayNode.svelte +471 -0
- package/dist/components/GatewayNode.svelte.d.ts +15 -0
- package/dist/components/LoadingSpinner.svelte +23 -23
- package/dist/components/LoadingSpinner.svelte.d.ts +1 -1
- package/dist/components/Logo.svelte +82 -0
- package/dist/components/Logo.svelte.d.ts +26 -0
- package/dist/components/LogsSidebar.svelte +565 -0
- package/dist/components/LogsSidebar.svelte.d.ts +34 -0
- package/dist/components/MarkdownDisplay.svelte +28 -0
- package/dist/components/MarkdownDisplay.svelte.d.ts +7 -0
- package/dist/components/Navbar.svelte +663 -0
- package/dist/components/Navbar.svelte.d.ts +21 -0
- package/dist/components/NodeSidebar.svelte +629 -488
- package/dist/components/NodeSidebar.svelte.d.ts +1 -2
- package/dist/components/NodeStatusOverlay.svelte +327 -0
- package/dist/components/NodeStatusOverlay.svelte.d.ts +11 -0
- package/dist/components/NotesNode.svelte +566 -0
- package/dist/components/NotesNode.svelte.d.ts +43 -0
- package/dist/components/PipelineStatus.svelte +331 -0
- package/dist/components/PipelineStatus.svelte.d.ts +18 -0
- package/dist/components/SimpleNode.svelte +447 -0
- package/dist/components/SimpleNode.svelte.d.ts +24 -0
- package/dist/components/SquareNode.svelte +346 -0
- package/dist/components/SquareNode.svelte.d.ts +24 -0
- package/dist/components/StatusIcon.svelte +112 -0
- package/dist/components/StatusIcon.svelte.d.ts +10 -0
- package/dist/components/StatusLabel.svelte +33 -0
- package/dist/components/StatusLabel.svelte.d.ts +7 -0
- package/dist/components/ToolNode.svelte +385 -0
- package/dist/components/ToolNode.svelte.d.ts +36 -0
- package/dist/components/UniversalNode.svelte +126 -0
- package/dist/components/UniversalNode.svelte.d.ts +15 -0
- package/dist/components/WorkflowEditor.svelte +871 -528
- package/dist/components/WorkflowEditor.svelte.d.ts +15 -5
- package/dist/components/WorkflowNode.svelte +428 -542
- package/dist/components/WorkflowNode.svelte.d.ts +7 -3
- package/dist/config/apiConfig.d.ts +33 -0
- package/dist/config/apiConfig.js +39 -0
- package/dist/config/defaultPortConfig.d.ts +6 -0
- package/dist/config/defaultPortConfig.js +192 -0
- package/dist/config/demo.d.ts +58 -0
- package/dist/config/demo.js +142 -0
- package/dist/config/endpoints.d.ts +106 -0
- package/dist/config/endpoints.js +128 -0
- package/dist/data/samples.d.ts +38 -4
- package/dist/data/samples.js +2789 -737
- package/dist/examples/adapter-usage.d.ts +4 -4
- package/dist/examples/adapter-usage.js +21 -26
- package/dist/examples/api-client-usage.d.ts +6 -6
- package/dist/examples/api-client-usage.js +55 -54
- package/dist/index.d.ts +23 -15
- package/dist/index.js +23 -15
- package/dist/mocks/app-environment.d.ts +8 -0
- package/dist/mocks/app-environment.js +16 -0
- package/dist/mocks/app-forms.d.ts +2 -0
- package/dist/mocks/app-forms.js +21 -0
- package/dist/mocks/app-navigation.d.ts +5 -0
- package/dist/mocks/app-navigation.js +34 -0
- package/dist/mocks/app-stores.d.ts +14 -0
- package/dist/mocks/app-stores.js +26 -0
- package/dist/services/api.d.ts +13 -3
- package/dist/services/api.js +91 -36
- package/dist/services/globalSave.d.ts +20 -0
- package/dist/services/globalSave.js +165 -0
- package/dist/services/nodeExecutionService.d.ts +63 -0
- package/dist/services/nodeExecutionService.js +261 -0
- package/dist/services/portConfigApi.d.ts +14 -0
- package/dist/services/portConfigApi.js +69 -0
- package/dist/services/toastService.d.ts +147 -0
- package/dist/services/toastService.js +235 -0
- package/dist/services/workflowStorage.d.ts +2 -2
- package/dist/services/workflowStorage.js +10 -10
- package/dist/stores/workflowStore.d.ts +53 -0
- package/dist/stores/workflowStore.js +264 -0
- package/dist/styles/base.css +896 -363
- package/dist/svelte-app.d.ts +52 -5
- package/dist/svelte-app.js +128 -6
- package/dist/types/config.d.ts +291 -0
- package/dist/types/config.js +4 -0
- package/dist/types/index.d.ts +231 -19
- package/dist/types/index.js +1 -1
- package/dist/utils/colors.d.ts +67 -33
- package/dist/utils/colors.js +183 -118
- package/dist/utils/config.d.ts +41 -0
- package/dist/utils/config.js +248 -0
- package/dist/utils/connections.d.ts +40 -3
- package/dist/utils/connections.js +115 -44
- package/dist/utils/icons.d.ts +1 -1
- package/dist/utils/icons.js +71 -70
- package/dist/utils/nodeStatus.d.ts +53 -0
- package/dist/utils/nodeStatus.js +183 -0
- package/dist/utils/nodeTypes.d.ts +57 -0
- package/dist/utils/nodeTypes.js +109 -0
- package/dist/utils/nodeWrapper.d.ts +39 -0
- package/dist/utils/nodeWrapper.js +62 -0
- package/package.json +129 -97
- package/dist/components/Node.svelte +0 -38
- package/dist/components/Node.svelte.d.ts +0 -4
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced API Client for FlowDrop
|
|
3
|
+
* Uses configurable endpoints for all API actions
|
|
4
|
+
*/
|
|
5
|
+
import { buildEndpointUrl, getEndpointMethod, getEndpointHeaders } from '../config/endpoints.js';
|
|
6
|
+
/**
|
|
7
|
+
* Enhanced HTTP API client for FlowDrop with configurable endpoints
|
|
8
|
+
*/
|
|
9
|
+
export class EnhancedFlowDropApiClient {
|
|
10
|
+
config;
|
|
11
|
+
constructor(config) {
|
|
12
|
+
this.config = config;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Make HTTP request with error handling and retry logic
|
|
16
|
+
*/
|
|
17
|
+
async request(endpointKey, endpointPath, params, options = {}) {
|
|
18
|
+
const url = buildEndpointUrl(this.config, endpointPath, params);
|
|
19
|
+
const method = getEndpointMethod(this.config, endpointKey);
|
|
20
|
+
const headers = getEndpointHeaders(this.config, endpointKey);
|
|
21
|
+
const config = {
|
|
22
|
+
method,
|
|
23
|
+
headers,
|
|
24
|
+
...options
|
|
25
|
+
};
|
|
26
|
+
let lastError = null;
|
|
27
|
+
const maxAttempts = this.config.retry?.enabled ? this.config.retry.maxAttempts : 1;
|
|
28
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
29
|
+
try {
|
|
30
|
+
const response = await fetch(url, config);
|
|
31
|
+
if (!response.ok) {
|
|
32
|
+
const errorData = await response.json().catch(() => ({}));
|
|
33
|
+
throw new Error(errorData.error || `HTTP ${response.status}: ${response.statusText}`);
|
|
34
|
+
}
|
|
35
|
+
const data = await response.json();
|
|
36
|
+
return data;
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
40
|
+
// Don't retry on last attempt
|
|
41
|
+
if (attempt === maxAttempts) {
|
|
42
|
+
console.error(`API request failed after ${maxAttempts} attempts:`, lastError);
|
|
43
|
+
throw lastError;
|
|
44
|
+
}
|
|
45
|
+
// Wait before retry
|
|
46
|
+
const delay = this.config.retry?.delay || 1000;
|
|
47
|
+
const backoffDelay = this.config.retry?.backoff === 'exponential' ? delay * Math.pow(2, attempt - 1) : delay;
|
|
48
|
+
await new Promise((resolve) => setTimeout(resolve, backoffDelay));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
throw lastError;
|
|
52
|
+
}
|
|
53
|
+
// Node API Methods
|
|
54
|
+
async getAvailableNodes() {
|
|
55
|
+
const response = await this.request('nodes.list', this.config.endpoints.nodes.list);
|
|
56
|
+
if (!response.success || !response.data) {
|
|
57
|
+
throw new Error(response.error || 'Failed to fetch available nodes');
|
|
58
|
+
}
|
|
59
|
+
return response.data;
|
|
60
|
+
}
|
|
61
|
+
async getNodesByCategory(category) {
|
|
62
|
+
const response = await this.request('nodes.byCategory', this.config.endpoints.nodes.byCategory, { category });
|
|
63
|
+
if (!response.success || !response.data) {
|
|
64
|
+
throw new Error(response.error || 'Failed to fetch nodes by category');
|
|
65
|
+
}
|
|
66
|
+
return response.data;
|
|
67
|
+
}
|
|
68
|
+
async getNodeMetadata(nodeId) {
|
|
69
|
+
const response = await this.request('nodes.metadata', this.config.endpoints.nodes.metadata, { id: nodeId });
|
|
70
|
+
if (!response.success || !response.data) {
|
|
71
|
+
throw new Error(response.error || 'Failed to fetch node metadata');
|
|
72
|
+
}
|
|
73
|
+
return response.data;
|
|
74
|
+
}
|
|
75
|
+
// Workflow API Methods
|
|
76
|
+
async saveWorkflow(workflow) {
|
|
77
|
+
const response = await this.request('workflows.create', this.config.endpoints.workflows.create, undefined, {
|
|
78
|
+
method: 'POST',
|
|
79
|
+
body: JSON.stringify(workflow)
|
|
80
|
+
});
|
|
81
|
+
if (!response.success || !response.data) {
|
|
82
|
+
throw new Error(response.error || 'Failed to save workflow');
|
|
83
|
+
}
|
|
84
|
+
return response.data;
|
|
85
|
+
}
|
|
86
|
+
async updateWorkflow(workflowId, workflow) {
|
|
87
|
+
const response = await this.request('workflows.update', this.config.endpoints.workflows.update, { id: workflowId }, {
|
|
88
|
+
method: 'PUT',
|
|
89
|
+
body: JSON.stringify(workflow)
|
|
90
|
+
});
|
|
91
|
+
if (!response.success || !response.data) {
|
|
92
|
+
throw new Error(response.error || 'Failed to update workflow');
|
|
93
|
+
}
|
|
94
|
+
return response.data;
|
|
95
|
+
}
|
|
96
|
+
async loadWorkflow(workflowId) {
|
|
97
|
+
const response = await this.request('workflows.get', this.config.endpoints.workflows.get, { id: workflowId });
|
|
98
|
+
if (!response.success || !response.data) {
|
|
99
|
+
throw new Error(response.error || 'Failed to load workflow');
|
|
100
|
+
}
|
|
101
|
+
return response.data;
|
|
102
|
+
}
|
|
103
|
+
async listWorkflows() {
|
|
104
|
+
const response = await this.request('workflows.list', this.config.endpoints.workflows.list);
|
|
105
|
+
if (!response.success || !response.data) {
|
|
106
|
+
throw new Error(response.error || 'Failed to list workflows');
|
|
107
|
+
}
|
|
108
|
+
return response.data;
|
|
109
|
+
}
|
|
110
|
+
async deleteWorkflow(workflowId) {
|
|
111
|
+
const response = await this.request('workflows.delete', this.config.endpoints.workflows.delete, { id: workflowId }, { method: 'DELETE' });
|
|
112
|
+
if (!response.success) {
|
|
113
|
+
throw new Error(response.error || 'Failed to delete workflow');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
async validateWorkflow(workflow) {
|
|
117
|
+
const response = await this.request('workflows.validate', this.config.endpoints.workflows.validate, undefined, {
|
|
118
|
+
method: 'POST',
|
|
119
|
+
body: JSON.stringify(workflow)
|
|
120
|
+
});
|
|
121
|
+
if (!response.success || !response.data) {
|
|
122
|
+
throw new Error(response.error || 'Failed to validate workflow');
|
|
123
|
+
}
|
|
124
|
+
return response.data;
|
|
125
|
+
}
|
|
126
|
+
async exportWorkflow(workflowId) {
|
|
127
|
+
const response = await this.request('workflows.export', this.config.endpoints.workflows.export, { id: workflowId });
|
|
128
|
+
if (!response.success || !response.data) {
|
|
129
|
+
throw new Error(response.error || 'Failed to export workflow');
|
|
130
|
+
}
|
|
131
|
+
return response.data;
|
|
132
|
+
}
|
|
133
|
+
async importWorkflow(workflowJson) {
|
|
134
|
+
const response = await this.request('workflows.import', this.config.endpoints.workflows.import, undefined, {
|
|
135
|
+
method: 'POST',
|
|
136
|
+
body: JSON.stringify({ workflow: workflowJson })
|
|
137
|
+
});
|
|
138
|
+
if (!response.success || !response.data) {
|
|
139
|
+
throw new Error(response.error || 'Failed to import workflow');
|
|
140
|
+
}
|
|
141
|
+
return response.data;
|
|
142
|
+
}
|
|
143
|
+
// Execution API Methods
|
|
144
|
+
async executeWorkflow(workflowId, inputs) {
|
|
145
|
+
const response = await this.request('executions.execute', this.config.endpoints.executions.execute, { id: workflowId }, {
|
|
146
|
+
method: 'POST',
|
|
147
|
+
body: JSON.stringify({ inputs })
|
|
148
|
+
});
|
|
149
|
+
if (!response.success || !response.data) {
|
|
150
|
+
throw new Error(response.error || 'Failed to execute workflow');
|
|
151
|
+
}
|
|
152
|
+
return response.data;
|
|
153
|
+
}
|
|
154
|
+
async getExecutionStatus(executionId) {
|
|
155
|
+
const response = await this.request('executions.status', this.config.endpoints.executions.status, { id: executionId });
|
|
156
|
+
if (!response.success || !response.data) {
|
|
157
|
+
throw new Error(response.error || 'Failed to get execution status');
|
|
158
|
+
}
|
|
159
|
+
return response.data;
|
|
160
|
+
}
|
|
161
|
+
async cancelExecution(executionId) {
|
|
162
|
+
const response = await this.request('executions.cancel', this.config.endpoints.executions.cancel, { id: executionId }, { method: 'POST' });
|
|
163
|
+
if (!response.success) {
|
|
164
|
+
throw new Error(response.error || 'Failed to cancel execution');
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
async getExecutionLogs(executionId) {
|
|
168
|
+
const response = await this.request('executions.logs', this.config.endpoints.executions.logs, { id: executionId });
|
|
169
|
+
if (!response.success || !response.data) {
|
|
170
|
+
throw new Error(response.error || 'Failed to get execution logs');
|
|
171
|
+
}
|
|
172
|
+
return response.data;
|
|
173
|
+
}
|
|
174
|
+
// Template API Methods
|
|
175
|
+
async listTemplates() {
|
|
176
|
+
const response = await this.request('templates.list', this.config.endpoints.templates.list);
|
|
177
|
+
if (!response.success || !response.data) {
|
|
178
|
+
throw new Error(response.error || 'Failed to list templates');
|
|
179
|
+
}
|
|
180
|
+
return response.data;
|
|
181
|
+
}
|
|
182
|
+
async getTemplate(templateId) {
|
|
183
|
+
const response = await this.request('templates.get', this.config.endpoints.templates.get, { id: templateId });
|
|
184
|
+
if (!response.success || !response.data) {
|
|
185
|
+
throw new Error(response.error || 'Failed to get template');
|
|
186
|
+
}
|
|
187
|
+
return response.data;
|
|
188
|
+
}
|
|
189
|
+
// System API Methods
|
|
190
|
+
async getSystemHealth() {
|
|
191
|
+
const response = await this.request('system.health', this.config.endpoints.system.health);
|
|
192
|
+
if (!response.success || !response.data) {
|
|
193
|
+
throw new Error(response.error || 'Failed to get system health');
|
|
194
|
+
}
|
|
195
|
+
return response.data;
|
|
196
|
+
}
|
|
197
|
+
async getSystemConfig() {
|
|
198
|
+
const response = await this.request('system.config', this.config.endpoints.system.config);
|
|
199
|
+
if (!response.success || !response.data) {
|
|
200
|
+
throw new Error(response.error || 'Failed to get system config');
|
|
201
|
+
}
|
|
202
|
+
return response.data;
|
|
203
|
+
}
|
|
204
|
+
async getSystemVersion() {
|
|
205
|
+
const response = await this.request('system.version', this.config.endpoints.system.version);
|
|
206
|
+
if (!response.success || !response.data) {
|
|
207
|
+
throw new Error(response.error || 'Failed to get system version');
|
|
208
|
+
}
|
|
209
|
+
return response.data;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* FlowDrop API Client
|
|
3
3
|
* Type-safe client for the FlowDrop API
|
|
4
4
|
*/
|
|
5
|
-
import type { NodeMetadata, Workflow, ApiResponse, NodesResponse, WorkflowResponse, WorkflowsResponse } from
|
|
5
|
+
import type { NodeMetadata, Workflow, ApiResponse, NodesResponse, WorkflowResponse, WorkflowsResponse } from '../types/index.js';
|
|
6
6
|
/**
|
|
7
7
|
* API Client Configuration
|
|
8
8
|
*/
|
|
@@ -43,8 +43,8 @@ export interface WorkflowsQuery {
|
|
|
43
43
|
tags?: string;
|
|
44
44
|
limit?: number;
|
|
45
45
|
offset?: number;
|
|
46
|
-
sort?:
|
|
47
|
-
order?:
|
|
46
|
+
sort?: 'created_at' | 'updated_at' | 'name';
|
|
47
|
+
order?: 'asc' | 'desc';
|
|
48
48
|
}
|
|
49
49
|
/**
|
|
50
50
|
* Create workflow request
|
|
@@ -52,8 +52,8 @@ export interface WorkflowsQuery {
|
|
|
52
52
|
export interface CreateWorkflowRequest {
|
|
53
53
|
name: string;
|
|
54
54
|
description?: string;
|
|
55
|
-
nodes?:
|
|
56
|
-
edges?:
|
|
55
|
+
nodes?: unknown[];
|
|
56
|
+
edges?: unknown[];
|
|
57
57
|
tags?: string[];
|
|
58
58
|
}
|
|
59
59
|
/**
|
|
@@ -62,8 +62,8 @@ export interface CreateWorkflowRequest {
|
|
|
62
62
|
export interface UpdateWorkflowRequest {
|
|
63
63
|
name?: string;
|
|
64
64
|
description?: string;
|
|
65
|
-
nodes?:
|
|
66
|
-
edges?:
|
|
65
|
+
nodes?: unknown[];
|
|
66
|
+
edges?: unknown[];
|
|
67
67
|
tags?: string[];
|
|
68
68
|
}
|
|
69
69
|
/**
|
|
@@ -138,7 +138,7 @@ export declare class ApiClient {
|
|
|
138
138
|
/**
|
|
139
139
|
* Export workflow
|
|
140
140
|
*/
|
|
141
|
-
exportWorkflow(id: string, format?:
|
|
141
|
+
exportWorkflow(id: string, format?: 'json' | 'yaml'): Promise<Workflow>;
|
|
142
142
|
/**
|
|
143
143
|
* Import workflow
|
|
144
144
|
*/
|
|
@@ -154,11 +154,11 @@ export declare class ApiClient {
|
|
|
154
154
|
/**
|
|
155
155
|
* Get workflows by tag
|
|
156
156
|
*/
|
|
157
|
-
getWorkflowsByTag(tag: string, query?: Omit<WorkflowsQuery,
|
|
157
|
+
getWorkflowsByTag(tag: string, query?: Omit<WorkflowsQuery, 'tags'>): Promise<WorkflowsResponse>;
|
|
158
158
|
/**
|
|
159
159
|
* Get node types by category
|
|
160
160
|
*/
|
|
161
|
-
getNodeTypesByCategory(category: string, query?: Omit<NodeTypesQuery,
|
|
161
|
+
getNodeTypesByCategory(category: string, query?: Omit<NodeTypesQuery, 'category'>): Promise<NodesResponse>;
|
|
162
162
|
}
|
|
163
163
|
/**
|
|
164
164
|
* API Error Class
|
|
@@ -172,32 +172,28 @@ export declare class ApiError extends Error {
|
|
|
172
172
|
/**
|
|
173
173
|
* Execution response types
|
|
174
174
|
*/
|
|
175
|
-
export
|
|
175
|
+
export type ExecutionResponse = ApiResponse<{
|
|
176
176
|
executionId: string;
|
|
177
|
-
status:
|
|
177
|
+
status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
|
|
178
178
|
message: string;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
export interface ExecutionStatusResponse extends ApiResponse<{
|
|
179
|
+
}>;
|
|
180
|
+
export type ExecutionStatusResponse = ApiResponse<{
|
|
182
181
|
executionId: string;
|
|
183
|
-
status:
|
|
182
|
+
status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
|
|
184
183
|
result?: unknown;
|
|
185
184
|
error?: string;
|
|
186
185
|
startTime: string;
|
|
187
186
|
endTime?: string;
|
|
188
187
|
duration?: number;
|
|
189
188
|
nodeResults?: Record<string, unknown>;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
export interface ValidationResponse extends ApiResponse<{
|
|
189
|
+
}>;
|
|
190
|
+
export type ValidationResponse = ApiResponse<{
|
|
193
191
|
valid: boolean;
|
|
194
192
|
errors: string[];
|
|
195
193
|
warnings: string[];
|
|
196
194
|
suggestions?: string[];
|
|
197
|
-
}
|
|
198
|
-
}
|
|
195
|
+
}>;
|
|
199
196
|
/**
|
|
200
197
|
* Type for node type response
|
|
201
198
|
*/
|
|
202
|
-
export
|
|
203
|
-
}
|
|
199
|
+
export type NodeTypeResponse = ApiResponse<NodeMetadata>;
|
|
@@ -14,7 +14,7 @@ export class ApiClient {
|
|
|
14
14
|
...config
|
|
15
15
|
};
|
|
16
16
|
this.defaultHeaders = {
|
|
17
|
-
|
|
17
|
+
'Content-Type': 'application/json',
|
|
18
18
|
...config.headers
|
|
19
19
|
};
|
|
20
20
|
if (config.apiKey) {
|
|
@@ -49,10 +49,10 @@ export class ApiClient {
|
|
|
49
49
|
if (error instanceof ApiError) {
|
|
50
50
|
throw error;
|
|
51
51
|
}
|
|
52
|
-
if (error instanceof Error && error.name ===
|
|
53
|
-
throw new ApiError(408,
|
|
52
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
53
|
+
throw new ApiError(408, 'Request timeout', 'TIMEOUT');
|
|
54
54
|
}
|
|
55
|
-
throw new ApiError(500, error instanceof Error ? error.message :
|
|
55
|
+
throw new ApiError(500, error instanceof Error ? error.message : 'Network error', 'NETWORK_ERROR');
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
// ===== HEALTH CHECK =====
|
|
@@ -60,7 +60,7 @@ export class ApiClient {
|
|
|
60
60
|
* Check API health
|
|
61
61
|
*/
|
|
62
62
|
async healthCheck() {
|
|
63
|
-
return this.request(
|
|
63
|
+
return this.request('GET', '/health');
|
|
64
64
|
}
|
|
65
65
|
// ===== NODE TYPES =====
|
|
66
66
|
/**
|
|
@@ -69,21 +69,21 @@ export class ApiClient {
|
|
|
69
69
|
async getNodeTypes(query) {
|
|
70
70
|
const params = new URLSearchParams();
|
|
71
71
|
if (query?.category)
|
|
72
|
-
params.append(
|
|
72
|
+
params.append('category', query.category);
|
|
73
73
|
if (query?.search)
|
|
74
|
-
params.append(
|
|
74
|
+
params.append('search', query.search);
|
|
75
75
|
if (query?.limit)
|
|
76
|
-
params.append(
|
|
76
|
+
params.append('limit', query.limit.toString());
|
|
77
77
|
if (query?.offset)
|
|
78
|
-
params.append(
|
|
79
|
-
const path = `/nodes${params.toString() ? `?${params.toString()}` :
|
|
80
|
-
return this.request(
|
|
78
|
+
params.append('offset', query.offset.toString());
|
|
79
|
+
const path = `/nodes${params.toString() ? `?${params.toString()}` : ''}`;
|
|
80
|
+
return this.request('GET', path);
|
|
81
81
|
}
|
|
82
82
|
/**
|
|
83
83
|
* Get node type by ID
|
|
84
84
|
*/
|
|
85
85
|
async getNodeType(id) {
|
|
86
|
-
return this.request(
|
|
86
|
+
return this.request('GET', `/nodes/${id}`);
|
|
87
87
|
}
|
|
88
88
|
// ===== WORKFLOWS =====
|
|
89
89
|
/**
|
|
@@ -92,82 +92,82 @@ export class ApiClient {
|
|
|
92
92
|
async getWorkflows(query) {
|
|
93
93
|
const params = new URLSearchParams();
|
|
94
94
|
if (query?.search)
|
|
95
|
-
params.append(
|
|
95
|
+
params.append('search', query.search);
|
|
96
96
|
if (query?.tags)
|
|
97
|
-
params.append(
|
|
97
|
+
params.append('tags', query.tags);
|
|
98
98
|
if (query?.limit)
|
|
99
|
-
params.append(
|
|
99
|
+
params.append('limit', query.limit.toString());
|
|
100
100
|
if (query?.offset)
|
|
101
|
-
params.append(
|
|
101
|
+
params.append('offset', query.offset.toString());
|
|
102
102
|
if (query?.sort)
|
|
103
|
-
params.append(
|
|
103
|
+
params.append('sort', query.sort);
|
|
104
104
|
if (query?.order)
|
|
105
|
-
params.append(
|
|
106
|
-
const path = `/workflows${params.toString() ? `?${params.toString()}` :
|
|
107
|
-
return this.request(
|
|
105
|
+
params.append('order', query.order);
|
|
106
|
+
const path = `/workflows${params.toString() ? `?${params.toString()}` : ''}`;
|
|
107
|
+
return this.request('GET', path);
|
|
108
108
|
}
|
|
109
109
|
/**
|
|
110
110
|
* Get workflow by ID
|
|
111
111
|
*/
|
|
112
112
|
async getWorkflow(id) {
|
|
113
|
-
return this.request(
|
|
113
|
+
return this.request('GET', `/workflows/${id}`);
|
|
114
114
|
}
|
|
115
115
|
/**
|
|
116
116
|
* Create a new workflow
|
|
117
117
|
*/
|
|
118
118
|
async createWorkflow(data) {
|
|
119
|
-
return this.request(
|
|
119
|
+
return this.request('POST', '/workflows', data);
|
|
120
120
|
}
|
|
121
121
|
/**
|
|
122
122
|
* Update workflow
|
|
123
123
|
*/
|
|
124
124
|
async updateWorkflow(id, data) {
|
|
125
|
-
return this.request(
|
|
125
|
+
return this.request('PUT', `/workflows/${id}`, data);
|
|
126
126
|
}
|
|
127
127
|
/**
|
|
128
128
|
* Delete workflow
|
|
129
129
|
*/
|
|
130
130
|
async deleteWorkflow(id) {
|
|
131
|
-
return this.request(
|
|
131
|
+
return this.request('DELETE', `/workflows/${id}`);
|
|
132
132
|
}
|
|
133
133
|
// ===== WORKFLOW EXECUTION =====
|
|
134
134
|
/**
|
|
135
135
|
* Execute workflow
|
|
136
136
|
*/
|
|
137
137
|
async executeWorkflow(id, data) {
|
|
138
|
-
return this.request(
|
|
138
|
+
return this.request('POST', `/workflows/${id}/execute`, data);
|
|
139
139
|
}
|
|
140
140
|
/**
|
|
141
141
|
* Get execution status
|
|
142
142
|
*/
|
|
143
143
|
async getExecutionStatus(id) {
|
|
144
|
-
return this.request(
|
|
144
|
+
return this.request('GET', `/executions/${id}`);
|
|
145
145
|
}
|
|
146
146
|
/**
|
|
147
147
|
* Cancel execution
|
|
148
148
|
*/
|
|
149
149
|
async cancelExecution(id) {
|
|
150
|
-
return this.request(
|
|
150
|
+
return this.request('POST', `/executions/${id}/cancel`);
|
|
151
151
|
}
|
|
152
152
|
// ===== IMPORT/EXPORT =====
|
|
153
153
|
/**
|
|
154
154
|
* Export workflow
|
|
155
155
|
*/
|
|
156
|
-
async exportWorkflow(id, format =
|
|
157
|
-
return this.request(
|
|
156
|
+
async exportWorkflow(id, format = 'json') {
|
|
157
|
+
return this.request('GET', `/workflows/${id}/export?format=${format}`);
|
|
158
158
|
}
|
|
159
159
|
/**
|
|
160
160
|
* Import workflow
|
|
161
161
|
*/
|
|
162
162
|
async importWorkflow(workflow) {
|
|
163
|
-
return this.request(
|
|
163
|
+
return this.request('POST', '/workflows/import', workflow);
|
|
164
164
|
}
|
|
165
165
|
// ===== VALIDATION =====
|
|
166
166
|
/**
|
|
167
167
|
* Validate workflow
|
|
168
168
|
*/
|
|
169
169
|
async validateWorkflow(workflow) {
|
|
170
|
-
return this.request(
|
|
170
|
+
return this.request('POST', '/workflows/validate', workflow);
|
|
171
171
|
}
|
|
172
172
|
// ===== UTILITY METHODS =====
|
|
173
173
|
/**
|
|
@@ -176,10 +176,12 @@ export class ApiClient {
|
|
|
176
176
|
async waitForExecution(id, pollInterval = 1000) {
|
|
177
177
|
while (true) {
|
|
178
178
|
const status = await this.getExecutionStatus(id);
|
|
179
|
-
if (status.data?.status ===
|
|
179
|
+
if (status.data?.status === 'completed' ||
|
|
180
|
+
status.data?.status === 'failed' ||
|
|
181
|
+
status.data?.status === 'cancelled') {
|
|
180
182
|
return status;
|
|
181
183
|
}
|
|
182
|
-
await new Promise(resolve => setTimeout(resolve, pollInterval));
|
|
184
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
183
185
|
}
|
|
184
186
|
}
|
|
185
187
|
/**
|
|
@@ -207,6 +209,6 @@ export class ApiError extends Error {
|
|
|
207
209
|
this.status = status;
|
|
208
210
|
this.code = code;
|
|
209
211
|
this.details = details;
|
|
210
|
-
this.name =
|
|
212
|
+
this.name = 'ApiError';
|
|
211
213
|
}
|
|
212
214
|
}
|