@d34dman/flowdrop 0.0.15 → 0.0.16
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 +0 -1
- package/dist/api/enhanced-client.d.ts +121 -5
- package/dist/api/enhanced-client.js +245 -66
- package/dist/components/App.svelte +145 -33
- package/dist/components/App.svelte.d.ts +27 -1
- package/dist/data/samples.js +9 -9
- package/dist/examples/adapter-usage.js +1 -1
- package/dist/index.d.ts +13 -6
- package/dist/index.js +12 -4
- package/dist/services/draftStorage.d.ts +171 -0
- package/dist/services/draftStorage.js +298 -0
- package/dist/stores/workflowStore.d.ts +104 -1
- package/dist/stores/workflowStore.js +251 -31
- package/dist/svelte-app.d.ts +112 -30
- package/dist/svelte-app.js +162 -39
- package/dist/types/auth.d.ts +278 -0
- package/dist/types/auth.js +244 -0
- package/dist/types/events.d.ts +163 -0
- package/dist/types/events.js +30 -0
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -1,44 +1,160 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Enhanced API Client for FlowDrop
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
|
+
* Uses configurable endpoints and supports pluggable authentication providers.
|
|
5
|
+
*
|
|
6
|
+
* @module api/enhanced-client
|
|
4
7
|
*/
|
|
5
|
-
import type { NodeMetadata, Workflow, ExecutionResult } from
|
|
6
|
-
import type { EndpointConfig } from
|
|
8
|
+
import type { NodeMetadata, Workflow, ExecutionResult } from "../types/index.js";
|
|
9
|
+
import type { EndpointConfig } from "../config/endpoints.js";
|
|
10
|
+
import type { AuthProvider } from "../types/auth.js";
|
|
11
|
+
/**
|
|
12
|
+
* API error with additional context
|
|
13
|
+
*/
|
|
14
|
+
export declare class ApiError extends Error {
|
|
15
|
+
/** HTTP status code */
|
|
16
|
+
readonly status: number;
|
|
17
|
+
/** Original error data from API */
|
|
18
|
+
readonly errorData: Record<string, unknown>;
|
|
19
|
+
/** Operation that was being performed */
|
|
20
|
+
readonly operation: string;
|
|
21
|
+
constructor(message: string, status: number, operation: string, errorData?: Record<string, unknown>);
|
|
22
|
+
}
|
|
7
23
|
/**
|
|
8
24
|
* Enhanced HTTP API client for FlowDrop with configurable endpoints
|
|
25
|
+
*
|
|
26
|
+
* Supports pluggable authentication via AuthProvider interface.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* // With AuthProvider
|
|
31
|
+
* const client = new EnhancedFlowDropApiClient(config, authProvider);
|
|
32
|
+
*
|
|
33
|
+
* // Backward compatible (uses config.auth)
|
|
34
|
+
* const client = new EnhancedFlowDropApiClient(config);
|
|
35
|
+
* ```
|
|
9
36
|
*/
|
|
10
37
|
export declare class EnhancedFlowDropApiClient {
|
|
11
38
|
private config;
|
|
12
|
-
|
|
39
|
+
private authProvider;
|
|
13
40
|
/**
|
|
14
|
-
*
|
|
41
|
+
* Create a new EnhancedFlowDropApiClient
|
|
42
|
+
*
|
|
43
|
+
* @param config - Endpoint configuration
|
|
44
|
+
* @param authProvider - Optional authentication provider (if not provided, uses config.auth)
|
|
45
|
+
*/
|
|
46
|
+
constructor(config: EndpointConfig, authProvider?: AuthProvider);
|
|
47
|
+
/**
|
|
48
|
+
* Make HTTP request with error handling, retry logic, and auth support
|
|
49
|
+
*
|
|
50
|
+
* @param endpointKey - Key identifying the endpoint (for method/header lookup)
|
|
51
|
+
* @param endpointPath - The endpoint path template
|
|
52
|
+
* @param params - URL parameters to substitute
|
|
53
|
+
* @param options - Additional fetch options
|
|
54
|
+
* @param operation - Description of the operation (for error messages)
|
|
15
55
|
*/
|
|
16
56
|
private request;
|
|
57
|
+
/**
|
|
58
|
+
* Update the auth provider
|
|
59
|
+
*
|
|
60
|
+
* Useful for updating auth after token refresh in parent application.
|
|
61
|
+
* Note: Per specification, this should rarely be needed as auth is typically
|
|
62
|
+
* set at mount time and requires remount to change.
|
|
63
|
+
*
|
|
64
|
+
* @param authProvider - New authentication provider
|
|
65
|
+
*/
|
|
66
|
+
setAuthProvider(authProvider: AuthProvider): void;
|
|
67
|
+
/**
|
|
68
|
+
* Get current auth provider
|
|
69
|
+
*
|
|
70
|
+
* @returns The current AuthProvider instance
|
|
71
|
+
*/
|
|
72
|
+
getAuthProvider(): AuthProvider;
|
|
73
|
+
/**
|
|
74
|
+
* Fetch all available node types
|
|
75
|
+
*/
|
|
17
76
|
getAvailableNodes(): Promise<NodeMetadata[]>;
|
|
77
|
+
/**
|
|
78
|
+
* Fetch nodes filtered by category
|
|
79
|
+
*/
|
|
18
80
|
getNodesByCategory(category: string): Promise<NodeMetadata[]>;
|
|
81
|
+
/**
|
|
82
|
+
* Fetch metadata for a specific node type
|
|
83
|
+
*/
|
|
19
84
|
getNodeMetadata(nodeId: string): Promise<NodeMetadata>;
|
|
85
|
+
/**
|
|
86
|
+
* Save a new workflow
|
|
87
|
+
*/
|
|
20
88
|
saveWorkflow(workflow: Workflow): Promise<Workflow>;
|
|
89
|
+
/**
|
|
90
|
+
* Update an existing workflow
|
|
91
|
+
*/
|
|
21
92
|
updateWorkflow(workflowId: string, workflow: Partial<Workflow>): Promise<Workflow>;
|
|
93
|
+
/**
|
|
94
|
+
* Load a workflow by ID
|
|
95
|
+
*/
|
|
22
96
|
loadWorkflow(workflowId: string): Promise<Workflow>;
|
|
97
|
+
/**
|
|
98
|
+
* List all workflows
|
|
99
|
+
*/
|
|
23
100
|
listWorkflows(): Promise<Workflow[]>;
|
|
101
|
+
/**
|
|
102
|
+
* Delete a workflow
|
|
103
|
+
*/
|
|
24
104
|
deleteWorkflow(workflowId: string): Promise<void>;
|
|
105
|
+
/**
|
|
106
|
+
* Validate a workflow
|
|
107
|
+
*/
|
|
25
108
|
validateWorkflow(workflow: Workflow): Promise<{
|
|
26
109
|
valid: boolean;
|
|
27
110
|
errors: string[];
|
|
28
111
|
}>;
|
|
112
|
+
/**
|
|
113
|
+
* Export a workflow as JSON string
|
|
114
|
+
*/
|
|
29
115
|
exportWorkflow(workflowId: string): Promise<string>;
|
|
116
|
+
/**
|
|
117
|
+
* Import a workflow from JSON
|
|
118
|
+
*/
|
|
30
119
|
importWorkflow(workflowJson: string): Promise<Workflow>;
|
|
120
|
+
/**
|
|
121
|
+
* Execute a workflow
|
|
122
|
+
*/
|
|
31
123
|
executeWorkflow(workflowId: string, inputs?: Record<string, unknown>): Promise<ExecutionResult>;
|
|
124
|
+
/**
|
|
125
|
+
* Get execution status
|
|
126
|
+
*/
|
|
32
127
|
getExecutionStatus(executionId: string): Promise<ExecutionResult>;
|
|
128
|
+
/**
|
|
129
|
+
* Cancel a running execution
|
|
130
|
+
*/
|
|
33
131
|
cancelExecution(executionId: string): Promise<void>;
|
|
132
|
+
/**
|
|
133
|
+
* Get execution logs
|
|
134
|
+
*/
|
|
34
135
|
getExecutionLogs(executionId: string): Promise<string[]>;
|
|
136
|
+
/**
|
|
137
|
+
* List available templates
|
|
138
|
+
*/
|
|
35
139
|
listTemplates(): Promise<Workflow[]>;
|
|
140
|
+
/**
|
|
141
|
+
* Get a template by ID
|
|
142
|
+
*/
|
|
36
143
|
getTemplate(templateId: string): Promise<Workflow>;
|
|
144
|
+
/**
|
|
145
|
+
* Get system health status
|
|
146
|
+
*/
|
|
37
147
|
getSystemHealth(): Promise<{
|
|
38
148
|
status: string;
|
|
39
149
|
timestamp: number;
|
|
40
150
|
}>;
|
|
151
|
+
/**
|
|
152
|
+
* Get system configuration
|
|
153
|
+
*/
|
|
41
154
|
getSystemConfig(): Promise<Record<string, unknown>>;
|
|
155
|
+
/**
|
|
156
|
+
* Get system version information
|
|
157
|
+
*/
|
|
42
158
|
getSystemVersion(): Promise<{
|
|
43
159
|
version: string;
|
|
44
160
|
build: string;
|
|
@@ -1,24 +1,80 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Enhanced API Client for FlowDrop
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
|
+
* Uses configurable endpoints and supports pluggable authentication providers.
|
|
5
|
+
*
|
|
6
|
+
* @module api/enhanced-client
|
|
4
7
|
*/
|
|
5
|
-
import { buildEndpointUrl, getEndpointMethod, getEndpointHeaders } from
|
|
8
|
+
import { buildEndpointUrl, getEndpointMethod, getEndpointHeaders } from "../config/endpoints.js";
|
|
9
|
+
import { createAuthProviderFromLegacyConfig } from "../types/auth.js";
|
|
10
|
+
/**
|
|
11
|
+
* API error with additional context
|
|
12
|
+
*/
|
|
13
|
+
export class ApiError extends Error {
|
|
14
|
+
/** HTTP status code */
|
|
15
|
+
status;
|
|
16
|
+
/** Original error data from API */
|
|
17
|
+
errorData;
|
|
18
|
+
/** Operation that was being performed */
|
|
19
|
+
operation;
|
|
20
|
+
constructor(message, status, operation, errorData = {}) {
|
|
21
|
+
super(message);
|
|
22
|
+
this.name = "ApiError";
|
|
23
|
+
this.status = status;
|
|
24
|
+
this.operation = operation;
|
|
25
|
+
this.errorData = errorData;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
6
28
|
/**
|
|
7
29
|
* Enhanced HTTP API client for FlowDrop with configurable endpoints
|
|
30
|
+
*
|
|
31
|
+
* Supports pluggable authentication via AuthProvider interface.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* // With AuthProvider
|
|
36
|
+
* const client = new EnhancedFlowDropApiClient(config, authProvider);
|
|
37
|
+
*
|
|
38
|
+
* // Backward compatible (uses config.auth)
|
|
39
|
+
* const client = new EnhancedFlowDropApiClient(config);
|
|
40
|
+
* ```
|
|
8
41
|
*/
|
|
9
42
|
export class EnhancedFlowDropApiClient {
|
|
10
43
|
config;
|
|
11
|
-
|
|
44
|
+
authProvider;
|
|
45
|
+
/**
|
|
46
|
+
* Create a new EnhancedFlowDropApiClient
|
|
47
|
+
*
|
|
48
|
+
* @param config - Endpoint configuration
|
|
49
|
+
* @param authProvider - Optional authentication provider (if not provided, uses config.auth)
|
|
50
|
+
*/
|
|
51
|
+
constructor(config, authProvider) {
|
|
12
52
|
this.config = config;
|
|
53
|
+
// Use provided AuthProvider or create one from legacy config
|
|
54
|
+
this.authProvider = authProvider ?? createAuthProviderFromLegacyConfig(config.auth);
|
|
13
55
|
}
|
|
14
56
|
/**
|
|
15
|
-
* Make HTTP request with error handling and
|
|
57
|
+
* Make HTTP request with error handling, retry logic, and auth support
|
|
58
|
+
*
|
|
59
|
+
* @param endpointKey - Key identifying the endpoint (for method/header lookup)
|
|
60
|
+
* @param endpointPath - The endpoint path template
|
|
61
|
+
* @param params - URL parameters to substitute
|
|
62
|
+
* @param options - Additional fetch options
|
|
63
|
+
* @param operation - Description of the operation (for error messages)
|
|
16
64
|
*/
|
|
17
|
-
async request(endpointKey, endpointPath, params, options = {}) {
|
|
65
|
+
async request(endpointKey, endpointPath, params, options = {}, operation = "API request") {
|
|
18
66
|
const url = buildEndpointUrl(this.config, endpointPath, params);
|
|
19
|
-
const method = getEndpointMethod(this.config, endpointKey);
|
|
20
|
-
const
|
|
21
|
-
|
|
67
|
+
const method = options.method ?? getEndpointMethod(this.config, endpointKey);
|
|
68
|
+
const configHeaders = getEndpointHeaders(this.config, endpointKey);
|
|
69
|
+
// Get auth headers from provider
|
|
70
|
+
const authHeaders = await this.authProvider.getAuthHeaders();
|
|
71
|
+
// Merge headers: config headers < auth headers < request-specific headers
|
|
72
|
+
const headers = {
|
|
73
|
+
...configHeaders,
|
|
74
|
+
...authHeaders,
|
|
75
|
+
...options.headers
|
|
76
|
+
};
|
|
77
|
+
const fetchConfig = {
|
|
22
78
|
method,
|
|
23
79
|
headers,
|
|
24
80
|
...options
|
|
@@ -27,184 +83,307 @@ export class EnhancedFlowDropApiClient {
|
|
|
27
83
|
const maxAttempts = this.config.retry?.enabled ? this.config.retry.maxAttempts : 1;
|
|
28
84
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
29
85
|
try {
|
|
30
|
-
const response = await fetch(url,
|
|
86
|
+
const response = await fetch(url, fetchConfig);
|
|
87
|
+
// Handle 401 Unauthorized
|
|
88
|
+
if (response.status === 401) {
|
|
89
|
+
if (this.authProvider.onUnauthorized) {
|
|
90
|
+
const refreshed = await this.authProvider.onUnauthorized();
|
|
91
|
+
if (refreshed && attempt < maxAttempts) {
|
|
92
|
+
// Get new auth headers and retry
|
|
93
|
+
const newAuthHeaders = await this.authProvider.getAuthHeaders();
|
|
94
|
+
fetchConfig.headers = {
|
|
95
|
+
...configHeaders,
|
|
96
|
+
...newAuthHeaders,
|
|
97
|
+
...options.headers
|
|
98
|
+
};
|
|
99
|
+
continue; // Retry with new headers
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
throw new ApiError("Unauthorized", 401, operation, {});
|
|
103
|
+
}
|
|
104
|
+
// Handle 403 Forbidden
|
|
105
|
+
if (response.status === 403) {
|
|
106
|
+
if (this.authProvider.onForbidden) {
|
|
107
|
+
await this.authProvider.onForbidden();
|
|
108
|
+
}
|
|
109
|
+
throw new ApiError("Forbidden", 403, operation, {});
|
|
110
|
+
}
|
|
111
|
+
// Handle other errors
|
|
31
112
|
if (!response.ok) {
|
|
32
113
|
const errorData = await response.json().catch(() => ({}));
|
|
33
|
-
throw new
|
|
114
|
+
throw new ApiError(errorData.error ?? `HTTP ${response.status}: ${response.statusText}`, response.status, operation, errorData);
|
|
34
115
|
}
|
|
35
116
|
const data = await response.json();
|
|
36
117
|
return data;
|
|
37
118
|
}
|
|
38
119
|
catch (error) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
120
|
+
// If it's already an ApiError, preserve it
|
|
121
|
+
if (error instanceof ApiError) {
|
|
122
|
+
lastError = error;
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
126
|
+
}
|
|
127
|
+
// Don't retry on auth errors (401, 403) or last attempt
|
|
128
|
+
if ((lastError instanceof ApiError &&
|
|
129
|
+
(lastError.status === 401 || lastError.status === 403)) ||
|
|
130
|
+
attempt === maxAttempts) {
|
|
131
|
+
console.error(`API request failed after ${attempt} attempts:`, lastError);
|
|
43
132
|
throw lastError;
|
|
44
133
|
}
|
|
45
134
|
// Wait before retry
|
|
46
|
-
const delay = this.config.retry?.delay
|
|
47
|
-
const backoffDelay = this.config.retry?.backoff ===
|
|
135
|
+
const delay = this.config.retry?.delay ?? 1000;
|
|
136
|
+
const backoffDelay = this.config.retry?.backoff === "exponential" ? delay * Math.pow(2, attempt - 1) : delay;
|
|
48
137
|
await new Promise((resolve) => setTimeout(resolve, backoffDelay));
|
|
49
138
|
}
|
|
50
139
|
}
|
|
51
140
|
throw lastError;
|
|
52
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* Update the auth provider
|
|
144
|
+
*
|
|
145
|
+
* Useful for updating auth after token refresh in parent application.
|
|
146
|
+
* Note: Per specification, this should rarely be needed as auth is typically
|
|
147
|
+
* set at mount time and requires remount to change.
|
|
148
|
+
*
|
|
149
|
+
* @param authProvider - New authentication provider
|
|
150
|
+
*/
|
|
151
|
+
setAuthProvider(authProvider) {
|
|
152
|
+
this.authProvider = authProvider;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Get current auth provider
|
|
156
|
+
*
|
|
157
|
+
* @returns The current AuthProvider instance
|
|
158
|
+
*/
|
|
159
|
+
getAuthProvider() {
|
|
160
|
+
return this.authProvider;
|
|
161
|
+
}
|
|
162
|
+
// =========================================================================
|
|
53
163
|
// Node API Methods
|
|
164
|
+
// =========================================================================
|
|
165
|
+
/**
|
|
166
|
+
* Fetch all available node types
|
|
167
|
+
*/
|
|
54
168
|
async getAvailableNodes() {
|
|
55
|
-
const response = await this.request(
|
|
169
|
+
const response = await this.request("nodes.list", this.config.endpoints.nodes.list, undefined, {}, "fetch available nodes");
|
|
56
170
|
if (!response.success || !response.data) {
|
|
57
|
-
throw new Error(response.error
|
|
171
|
+
throw new Error(response.error ?? "Failed to fetch available nodes");
|
|
58
172
|
}
|
|
59
173
|
return response.data;
|
|
60
174
|
}
|
|
175
|
+
/**
|
|
176
|
+
* Fetch nodes filtered by category
|
|
177
|
+
*/
|
|
61
178
|
async getNodesByCategory(category) {
|
|
62
|
-
const response = await this.request(
|
|
179
|
+
const response = await this.request("nodes.byCategory", this.config.endpoints.nodes.byCategory, { category }, {}, "fetch nodes by category");
|
|
63
180
|
if (!response.success || !response.data) {
|
|
64
|
-
throw new Error(response.error
|
|
181
|
+
throw new Error(response.error ?? "Failed to fetch nodes by category");
|
|
65
182
|
}
|
|
66
183
|
return response.data;
|
|
67
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* Fetch metadata for a specific node type
|
|
187
|
+
*/
|
|
68
188
|
async getNodeMetadata(nodeId) {
|
|
69
|
-
const response = await this.request(
|
|
189
|
+
const response = await this.request("nodes.metadata", this.config.endpoints.nodes.metadata, { id: nodeId }, {}, "fetch node metadata");
|
|
70
190
|
if (!response.success || !response.data) {
|
|
71
|
-
throw new Error(response.error
|
|
191
|
+
throw new Error(response.error ?? "Failed to fetch node metadata");
|
|
72
192
|
}
|
|
73
193
|
return response.data;
|
|
74
194
|
}
|
|
195
|
+
// =========================================================================
|
|
75
196
|
// Workflow API Methods
|
|
197
|
+
// =========================================================================
|
|
198
|
+
/**
|
|
199
|
+
* Save a new workflow
|
|
200
|
+
*/
|
|
76
201
|
async saveWorkflow(workflow) {
|
|
77
|
-
const response = await this.request(
|
|
78
|
-
method:
|
|
202
|
+
const response = await this.request("workflows.create", this.config.endpoints.workflows.create, undefined, {
|
|
203
|
+
method: "POST",
|
|
79
204
|
body: JSON.stringify(workflow)
|
|
80
|
-
});
|
|
205
|
+
}, "save workflow");
|
|
81
206
|
if (!response.success || !response.data) {
|
|
82
|
-
throw new Error(response.error
|
|
207
|
+
throw new Error(response.error ?? "Failed to save workflow");
|
|
83
208
|
}
|
|
84
209
|
return response.data;
|
|
85
210
|
}
|
|
211
|
+
/**
|
|
212
|
+
* Update an existing workflow
|
|
213
|
+
*/
|
|
86
214
|
async updateWorkflow(workflowId, workflow) {
|
|
87
|
-
const response = await this.request(
|
|
88
|
-
method:
|
|
215
|
+
const response = await this.request("workflows.update", this.config.endpoints.workflows.update, { id: workflowId }, {
|
|
216
|
+
method: "PUT",
|
|
89
217
|
body: JSON.stringify(workflow)
|
|
90
|
-
});
|
|
218
|
+
}, "update workflow");
|
|
91
219
|
if (!response.success || !response.data) {
|
|
92
|
-
throw new Error(response.error
|
|
220
|
+
throw new Error(response.error ?? "Failed to update workflow");
|
|
93
221
|
}
|
|
94
222
|
return response.data;
|
|
95
223
|
}
|
|
224
|
+
/**
|
|
225
|
+
* Load a workflow by ID
|
|
226
|
+
*/
|
|
96
227
|
async loadWorkflow(workflowId) {
|
|
97
|
-
const response = await this.request(
|
|
228
|
+
const response = await this.request("workflows.get", this.config.endpoints.workflows.get, { id: workflowId }, {}, "load workflow");
|
|
98
229
|
if (!response.success || !response.data) {
|
|
99
|
-
throw new Error(response.error
|
|
230
|
+
throw new Error(response.error ?? "Failed to load workflow");
|
|
100
231
|
}
|
|
101
232
|
return response.data;
|
|
102
233
|
}
|
|
234
|
+
/**
|
|
235
|
+
* List all workflows
|
|
236
|
+
*/
|
|
103
237
|
async listWorkflows() {
|
|
104
|
-
const response = await this.request(
|
|
238
|
+
const response = await this.request("workflows.list", this.config.endpoints.workflows.list, undefined, {}, "list workflows");
|
|
105
239
|
if (!response.success || !response.data) {
|
|
106
|
-
throw new Error(response.error
|
|
240
|
+
throw new Error(response.error ?? "Failed to list workflows");
|
|
107
241
|
}
|
|
108
242
|
return response.data;
|
|
109
243
|
}
|
|
244
|
+
/**
|
|
245
|
+
* Delete a workflow
|
|
246
|
+
*/
|
|
110
247
|
async deleteWorkflow(workflowId) {
|
|
111
|
-
const response = await this.request(
|
|
248
|
+
const response = await this.request("workflows.delete", this.config.endpoints.workflows.delete, { id: workflowId }, { method: "DELETE" }, "delete workflow");
|
|
112
249
|
if (!response.success) {
|
|
113
|
-
throw new Error(response.error
|
|
250
|
+
throw new Error(response.error ?? "Failed to delete workflow");
|
|
114
251
|
}
|
|
115
252
|
}
|
|
253
|
+
/**
|
|
254
|
+
* Validate a workflow
|
|
255
|
+
*/
|
|
116
256
|
async validateWorkflow(workflow) {
|
|
117
|
-
const response = await this.request(
|
|
118
|
-
method:
|
|
257
|
+
const response = await this.request("workflows.validate", this.config.endpoints.workflows.validate, undefined, {
|
|
258
|
+
method: "POST",
|
|
119
259
|
body: JSON.stringify(workflow)
|
|
120
|
-
});
|
|
260
|
+
}, "validate workflow");
|
|
121
261
|
if (!response.success || !response.data) {
|
|
122
|
-
throw new Error(response.error
|
|
262
|
+
throw new Error(response.error ?? "Failed to validate workflow");
|
|
123
263
|
}
|
|
124
264
|
return response.data;
|
|
125
265
|
}
|
|
266
|
+
/**
|
|
267
|
+
* Export a workflow as JSON string
|
|
268
|
+
*/
|
|
126
269
|
async exportWorkflow(workflowId) {
|
|
127
|
-
const response = await this.request(
|
|
270
|
+
const response = await this.request("workflows.export", this.config.endpoints.workflows.export, { id: workflowId }, {}, "export workflow");
|
|
128
271
|
if (!response.success || !response.data) {
|
|
129
|
-
throw new Error(response.error
|
|
272
|
+
throw new Error(response.error ?? "Failed to export workflow");
|
|
130
273
|
}
|
|
131
274
|
return response.data;
|
|
132
275
|
}
|
|
276
|
+
/**
|
|
277
|
+
* Import a workflow from JSON
|
|
278
|
+
*/
|
|
133
279
|
async importWorkflow(workflowJson) {
|
|
134
|
-
const response = await this.request(
|
|
135
|
-
method:
|
|
280
|
+
const response = await this.request("workflows.import", this.config.endpoints.workflows.import, undefined, {
|
|
281
|
+
method: "POST",
|
|
136
282
|
body: JSON.stringify({ workflow: workflowJson })
|
|
137
|
-
});
|
|
283
|
+
}, "import workflow");
|
|
138
284
|
if (!response.success || !response.data) {
|
|
139
|
-
throw new Error(response.error
|
|
285
|
+
throw new Error(response.error ?? "Failed to import workflow");
|
|
140
286
|
}
|
|
141
287
|
return response.data;
|
|
142
288
|
}
|
|
289
|
+
// =========================================================================
|
|
143
290
|
// Execution API Methods
|
|
291
|
+
// =========================================================================
|
|
292
|
+
/**
|
|
293
|
+
* Execute a workflow
|
|
294
|
+
*/
|
|
144
295
|
async executeWorkflow(workflowId, inputs) {
|
|
145
|
-
const response = await this.request(
|
|
146
|
-
method:
|
|
296
|
+
const response = await this.request("executions.execute", this.config.endpoints.executions.execute, { id: workflowId }, {
|
|
297
|
+
method: "POST",
|
|
147
298
|
body: JSON.stringify({ inputs })
|
|
148
|
-
});
|
|
299
|
+
}, "execute workflow");
|
|
149
300
|
if (!response.success || !response.data) {
|
|
150
|
-
throw new Error(response.error
|
|
301
|
+
throw new Error(response.error ?? "Failed to execute workflow");
|
|
151
302
|
}
|
|
152
303
|
return response.data;
|
|
153
304
|
}
|
|
305
|
+
/**
|
|
306
|
+
* Get execution status
|
|
307
|
+
*/
|
|
154
308
|
async getExecutionStatus(executionId) {
|
|
155
|
-
const response = await this.request(
|
|
309
|
+
const response = await this.request("executions.status", this.config.endpoints.executions.status, { id: executionId }, {}, "get execution status");
|
|
156
310
|
if (!response.success || !response.data) {
|
|
157
|
-
throw new Error(response.error
|
|
311
|
+
throw new Error(response.error ?? "Failed to get execution status");
|
|
158
312
|
}
|
|
159
313
|
return response.data;
|
|
160
314
|
}
|
|
315
|
+
/**
|
|
316
|
+
* Cancel a running execution
|
|
317
|
+
*/
|
|
161
318
|
async cancelExecution(executionId) {
|
|
162
|
-
const response = await this.request(
|
|
319
|
+
const response = await this.request("executions.cancel", this.config.endpoints.executions.cancel, { id: executionId }, { method: "POST" }, "cancel execution");
|
|
163
320
|
if (!response.success) {
|
|
164
|
-
throw new Error(response.error
|
|
321
|
+
throw new Error(response.error ?? "Failed to cancel execution");
|
|
165
322
|
}
|
|
166
323
|
}
|
|
324
|
+
/**
|
|
325
|
+
* Get execution logs
|
|
326
|
+
*/
|
|
167
327
|
async getExecutionLogs(executionId) {
|
|
168
|
-
const response = await this.request(
|
|
328
|
+
const response = await this.request("executions.logs", this.config.endpoints.executions.logs, { id: executionId }, {}, "get execution logs");
|
|
169
329
|
if (!response.success || !response.data) {
|
|
170
|
-
throw new Error(response.error
|
|
330
|
+
throw new Error(response.error ?? "Failed to get execution logs");
|
|
171
331
|
}
|
|
172
332
|
return response.data;
|
|
173
333
|
}
|
|
334
|
+
// =========================================================================
|
|
174
335
|
// Template API Methods
|
|
336
|
+
// =========================================================================
|
|
337
|
+
/**
|
|
338
|
+
* List available templates
|
|
339
|
+
*/
|
|
175
340
|
async listTemplates() {
|
|
176
|
-
const response = await this.request(
|
|
341
|
+
const response = await this.request("templates.list", this.config.endpoints.templates.list, undefined, {}, "list templates");
|
|
177
342
|
if (!response.success || !response.data) {
|
|
178
|
-
throw new Error(response.error
|
|
343
|
+
throw new Error(response.error ?? "Failed to list templates");
|
|
179
344
|
}
|
|
180
345
|
return response.data;
|
|
181
346
|
}
|
|
347
|
+
/**
|
|
348
|
+
* Get a template by ID
|
|
349
|
+
*/
|
|
182
350
|
async getTemplate(templateId) {
|
|
183
|
-
const response = await this.request(
|
|
351
|
+
const response = await this.request("templates.get", this.config.endpoints.templates.get, { id: templateId }, {}, "get template");
|
|
184
352
|
if (!response.success || !response.data) {
|
|
185
|
-
throw new Error(response.error
|
|
353
|
+
throw new Error(response.error ?? "Failed to get template");
|
|
186
354
|
}
|
|
187
355
|
return response.data;
|
|
188
356
|
}
|
|
357
|
+
// =========================================================================
|
|
189
358
|
// System API Methods
|
|
359
|
+
// =========================================================================
|
|
360
|
+
/**
|
|
361
|
+
* Get system health status
|
|
362
|
+
*/
|
|
190
363
|
async getSystemHealth() {
|
|
191
|
-
const response = await this.request(
|
|
364
|
+
const response = await this.request("system.health", this.config.endpoints.system.health, undefined, {}, "get system health");
|
|
192
365
|
if (!response.success || !response.data) {
|
|
193
|
-
throw new Error(response.error
|
|
366
|
+
throw new Error(response.error ?? "Failed to get system health");
|
|
194
367
|
}
|
|
195
368
|
return response.data;
|
|
196
369
|
}
|
|
370
|
+
/**
|
|
371
|
+
* Get system configuration
|
|
372
|
+
*/
|
|
197
373
|
async getSystemConfig() {
|
|
198
|
-
const response = await this.request(
|
|
374
|
+
const response = await this.request("system.config", this.config.endpoints.system.config, undefined, {}, "get system config");
|
|
199
375
|
if (!response.success || !response.data) {
|
|
200
|
-
throw new Error(response.error
|
|
376
|
+
throw new Error(response.error ?? "Failed to get system config");
|
|
201
377
|
}
|
|
202
378
|
return response.data;
|
|
203
379
|
}
|
|
380
|
+
/**
|
|
381
|
+
* Get system version information
|
|
382
|
+
*/
|
|
204
383
|
async getSystemVersion() {
|
|
205
|
-
const response = await this.request(
|
|
384
|
+
const response = await this.request("system.version", this.config.endpoints.system.version, undefined, {}, "get system version");
|
|
206
385
|
if (!response.success || !response.data) {
|
|
207
|
-
throw new Error(response.error
|
|
386
|
+
throw new Error(response.error ?? "Failed to get system version");
|
|
208
387
|
}
|
|
209
388
|
return response.data;
|
|
210
389
|
}
|