flowscale 1.0.17 → 1.0.18-beta.1
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/CLAUDE.md +73 -0
- package/README.md +130 -56
- package/dist/index.d.ts +26 -3
- package/dist/index.js +341 -136
- package/dist/types.d.ts +16 -4
- package/examples/backend-proxy-example.js +194 -0
- package/examples/node-websocket-example.js +59 -3
- package/examples/secure-frontend-example.html +113 -0
- package/package.json +1 -1
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Development Commands
|
|
6
|
+
|
|
7
|
+
- **Build**: `npm run build` or `tsc` - Compiles TypeScript to JavaScript in `/dist`
|
|
8
|
+
- **Test**: `echo "No tests yet"` - Currently no test framework is configured
|
|
9
|
+
- **Publish Beta**: `npm run publish:beta` - Publishes to npm with beta tag
|
|
10
|
+
- **Publish Latest**: `npm run publish:latest` - Publishes to npm as latest version
|
|
11
|
+
|
|
12
|
+
## Architecture Overview
|
|
13
|
+
|
|
14
|
+
This is a TypeScript SDK for interacting with the Flowscale ComfyUI API. The codebase is structured as follows:
|
|
15
|
+
|
|
16
|
+
### Core Components
|
|
17
|
+
|
|
18
|
+
- **FlowscaleAPI Class** (`src/index.ts`): The main SDK class that provides all API methods
|
|
19
|
+
- Uses Axios for HTTP requests with built-in retry logic and timeout handling
|
|
20
|
+
- Supports both Node.js and browser environments with security warnings for browser usage
|
|
21
|
+
- Includes WebSocket support for real-time communication (browser only)
|
|
22
|
+
- Has configurable logging with different levels (debug, info, warn, error)
|
|
23
|
+
|
|
24
|
+
- **Type Definitions** (`src/types.ts`): Comprehensive TypeScript interfaces for:
|
|
25
|
+
- API responses (HealthCheckResponse, WorkflowResponse, etc.)
|
|
26
|
+
- Configuration options (FlowscaleConfig)
|
|
27
|
+
- WebSocket-related types (WebSocketOptions, WebSocketMessage)
|
|
28
|
+
|
|
29
|
+
### Key Features
|
|
30
|
+
|
|
31
|
+
1. **Environment Detection**: Automatically detects Node.js vs browser environments
|
|
32
|
+
2. **Security**: Multiple security modes including secure proxy mode for frontend usage and API key protection
|
|
33
|
+
3. **Input Validation**: Comprehensive validation for all required parameters with helpful error messages
|
|
34
|
+
4. **File Upload Support**: Handles FormData for file uploads in workflow execution
|
|
35
|
+
5. **Async Workflow Execution**: `executeWorkflowAsync` method polls for all outputs and waits for completion automatically
|
|
36
|
+
6. **WebSocket Integration**: Real-time updates for workflow status (supports both browser and Node.js with WebSocket polyfill) with proper memory management
|
|
37
|
+
7. **Error Handling**: Consistent error handling with retry logic for timeouts and 504 errors
|
|
38
|
+
|
|
39
|
+
### API Methods Structure
|
|
40
|
+
|
|
41
|
+
All API methods follow this pattern:
|
|
42
|
+
- Make HTTP requests using the internal `makeRequest` method
|
|
43
|
+
- Return typed responses based on interfaces in `types.ts`
|
|
44
|
+
- Handle authentication via X-API-KEY header
|
|
45
|
+
- Support both individual operations and bulk operations where applicable
|
|
46
|
+
|
|
47
|
+
### Configuration
|
|
48
|
+
|
|
49
|
+
The SDK requires:
|
|
50
|
+
- `apiKey`: Flowscale API key (optional in proxy mode)
|
|
51
|
+
- `baseUrl`: API endpoint URL
|
|
52
|
+
- Optional: timeout, retry settings
|
|
53
|
+
- Optional: `proxyMode` - Enable secure frontend usage without exposing API key
|
|
54
|
+
- Optional: `customHeaders` - For JWT tokens, session cookies, etc.
|
|
55
|
+
- Optional: `WebSocketImpl` - For Node.js environments, pass the 'ws' WebSocket constructor to enable WebSocket functionality
|
|
56
|
+
|
|
57
|
+
### Build Configuration
|
|
58
|
+
|
|
59
|
+
- TypeScript compiler targets ES5 with CommonJS modules
|
|
60
|
+
- Outputs declaration files for TypeScript consumers
|
|
61
|
+
- Uses strict type checking
|
|
62
|
+
- Builds to `dist/` directory
|
|
63
|
+
|
|
64
|
+
## Important Notes
|
|
65
|
+
|
|
66
|
+
- No test framework is currently configured
|
|
67
|
+
- WebSocket functionality works in both browser and Node.js environments (Node.js requires passing `WebSocketImpl: require('ws')`)
|
|
68
|
+
- **Security**: Supports both direct API key usage and secure proxy mode for frontend applications
|
|
69
|
+
- **Proxy Mode**: Enables secure frontend usage by routing requests through a backend proxy that holds the API key
|
|
70
|
+
- All file uploads are handled through FormData with support for File/Blob objects
|
|
71
|
+
- The SDK has built-in retry logic for network timeouts and gateway errors
|
|
72
|
+
- Comprehensive input validation prevents common configuration errors
|
|
73
|
+
- Dynamic header management supports JWT token refresh and session management
|
package/README.md
CHANGED
|
@@ -4,20 +4,39 @@ A comprehensive SDK designed to simplify interaction with the FlowScale ComfyUI
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## 🔒 Secure Frontend Usage (Recommended)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
For secure frontend usage, use **Proxy Mode** to keep your API key safe on the backend:
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
```javascript
|
|
12
|
+
// ✅ SECURE: No API key exposed to frontend users
|
|
13
|
+
const flowscale = new FlowscaleAPI({
|
|
14
|
+
baseUrl: 'https://your-backend-proxy.com', // Your secure backend proxy
|
|
15
|
+
proxyMode: true, // Enable proxy mode
|
|
16
|
+
customHeaders: {
|
|
17
|
+
'Authorization': 'Bearer jwt-token-here' // Use JWT tokens instead
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Security Options:
|
|
13
23
|
|
|
14
|
-
|
|
24
|
+
1. **🔒 Backend-Only (MOST SECURE)**: Use SDK only on backend, frontend makes simple API calls to your server
|
|
25
|
+
2. **🔒 Proxy Mode**: Frontend SDK routes through your backend proxy (provides SDK convenience with security)
|
|
26
|
+
3. **⚠️ Direct Mode**: API key is exposed in browser (only for development/demos)
|
|
27
|
+
|
|
28
|
+
**Recommendation:** For production apps, use Backend-Only approach for maximum security and simplicity.
|
|
29
|
+
|
|
30
|
+
## ⚠️ Direct Browser Usage Warning
|
|
31
|
+
|
|
32
|
+
If you use the SDK directly in the browser with an API key, it will be exposed to end users. Only do this for development:
|
|
15
33
|
|
|
16
34
|
```javascript
|
|
35
|
+
// ⚠️ WARNING: API key will be visible to users
|
|
17
36
|
const flowscale = new FlowscaleAPI({
|
|
18
37
|
apiKey: 'your-api-key',
|
|
19
38
|
baseUrl: 'your-api-url',
|
|
20
|
-
allowDangerouslyExposeApiKey:
|
|
39
|
+
allowDangerouslyExposeApiKey: true // Required acknowledgment
|
|
21
40
|
});
|
|
22
41
|
```
|
|
23
42
|
|
|
@@ -240,14 +259,14 @@ console.log('Workflow Result:', result);
|
|
|
240
259
|
### 5 `executeWorkflowAsync(workflowId, data, groupId?, pollIntervalMs?, timeoutMs?)`
|
|
241
260
|
|
|
242
261
|
**Description:**
|
|
243
|
-
Execute a workflow and automatically wait for
|
|
262
|
+
Execute a workflow and automatically wait for all outputs by polling. This is a convenience method that combines `executeWorkflow` and `getOutput` with automatic polling for all workflow outputs.
|
|
244
263
|
|
|
245
264
|
**Parameters:**
|
|
246
265
|
- `workflowId` *(string)*: The unique ID of the workflow.
|
|
247
266
|
- `data` *(object)*: Input parameters for the workflow.
|
|
248
267
|
- `groupId` *(string, optional)*: A custom identifier for grouping runs.
|
|
249
|
-
- `pollIntervalMs` *(number, optional)*: Polling interval in milliseconds (default:
|
|
250
|
-
- `timeoutMs` *(number, optional)*: Maximum time to wait for results in milliseconds (default:
|
|
268
|
+
- `pollIntervalMs` *(number, optional)*: Polling interval in milliseconds (default: 2000).
|
|
269
|
+
- `timeoutMs` *(number, optional)*: Maximum time to wait for results in milliseconds (default: 600000 - 10 minutes).
|
|
251
270
|
|
|
252
271
|
**Usage:**
|
|
253
272
|
```javascript
|
|
@@ -273,10 +292,18 @@ try {
|
|
|
273
292
|
```json
|
|
274
293
|
{
|
|
275
294
|
"status": "success",
|
|
276
|
-
"data":
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
295
|
+
"data": [
|
|
296
|
+
{
|
|
297
|
+
"filename": "output_image_1.png",
|
|
298
|
+
"download_url": "https://runs.s3.amazonaws.com/generations/...",
|
|
299
|
+
"generation_status": "success"
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
"filename": "output_image_2.png",
|
|
303
|
+
"download_url": "https://runs.s3.amazonaws.com/generations/...",
|
|
304
|
+
"generation_status": "success"
|
|
305
|
+
}
|
|
306
|
+
]
|
|
280
307
|
}
|
|
281
308
|
```
|
|
282
309
|
|
|
@@ -421,47 +448,6 @@ console.log('All Runs:', allRuns);
|
|
|
421
448
|
- Always store sensitive information such as API keys in environment variables.
|
|
422
449
|
- Use `.env` files and libraries like `dotenv` for easy environment management.
|
|
423
450
|
|
|
424
|
-
### Logging Configuration
|
|
425
|
-
The SDK includes configurable logging to help with debugging and monitoring. By default, logging is enabled with the 'info' level.
|
|
426
|
-
|
|
427
|
-
#### Configuration Options
|
|
428
|
-
```javascript
|
|
429
|
-
const flowscale = new FlowscaleAPI({
|
|
430
|
-
apiKey: 'your-api-key',
|
|
431
|
-
baseUrl: 'https://your-api-url.pod.flowscale.ai',
|
|
432
|
-
enableLogging: true, // Enable/disable logging (default: true)
|
|
433
|
-
logLevel: 'info' // Set log level: 'debug', 'info', 'warn', 'error' (default: 'info')
|
|
434
|
-
});
|
|
435
|
-
```
|
|
436
|
-
|
|
437
|
-
#### Dynamic Logging Control
|
|
438
|
-
You can also change logging settings after initialization:
|
|
439
|
-
|
|
440
|
-
```javascript
|
|
441
|
-
// Enable debug logging
|
|
442
|
-
flowscale.setLoggingConfig(true, 'debug');
|
|
443
|
-
|
|
444
|
-
// Disable logging completely
|
|
445
|
-
flowscale.setLoggingConfig(false);
|
|
446
|
-
|
|
447
|
-
// Check current logging configuration
|
|
448
|
-
const loggingConfig = flowscale.getLoggingConfig();
|
|
449
|
-
console.log(loggingConfig); // { enabled: true, level: 'debug' }
|
|
450
|
-
```
|
|
451
|
-
|
|
452
|
-
#### Log Levels
|
|
453
|
-
- **debug**: Most verbose, includes detailed operation information
|
|
454
|
-
- **info**: General information about operations (default)
|
|
455
|
-
- **warn**: Warning messages for potential issues
|
|
456
|
-
- **error**: Only error messages
|
|
457
|
-
|
|
458
|
-
#### Log Format
|
|
459
|
-
All logs are prefixed with timestamp and level:
|
|
460
|
-
```
|
|
461
|
-
[Flowscale INFO] 2025-06-03T10:30:45.123Z: WebSocket connection established
|
|
462
|
-
[Flowscale DEBUG] 2025-06-03T10:30:46.456Z: Polling workflow output: {...}
|
|
463
|
-
```
|
|
464
|
-
|
|
465
451
|
### Error Handling
|
|
466
452
|
- Wrap API calls in try-catch blocks to handle errors gracefully.
|
|
467
453
|
- Log errors for debugging and improve resilience.
|
|
@@ -583,12 +569,100 @@ See `examples/websocket-example.html` for a complete browser example with a user
|
|
|
583
569
|
#### Node.js Example
|
|
584
570
|
Node.js requires a custom WebSocket implementation since the WebSocket API is not built-in. See `examples/node-websocket-example.js` for an example using the 'ws' library.
|
|
585
571
|
|
|
586
|
-
**Note:** To use WebSockets in Node.js, you'll need to install the 'ws' package:
|
|
572
|
+
**Note:** To use WebSockets in Node.js, you'll need to install the 'ws' package and pass it to the SDK:
|
|
587
573
|
```bash
|
|
588
574
|
npm install ws
|
|
589
575
|
```
|
|
590
576
|
|
|
591
|
-
|
|
577
|
+
```javascript
|
|
578
|
+
const WebSocket = require('ws');
|
|
579
|
+
const flowscale = new FlowscaleAPI({
|
|
580
|
+
apiKey: 'your-api-key',
|
|
581
|
+
baseUrl: 'https://your-api-url.pod.flowscale.ai',
|
|
582
|
+
WebSocketImpl: WebSocket // Pass the WebSocket implementation for Node.js
|
|
583
|
+
});
|
|
584
|
+
|
|
585
|
+
// Now you can use WebSocket methods directly in Node.js!
|
|
586
|
+
const disconnect = flowscale.connectWebSocket({
|
|
587
|
+
onOpen: () => console.log('Connected!'),
|
|
588
|
+
onMessage: (message) => console.log('Message:', message),
|
|
589
|
+
onClose: (event) => console.log('Closed:', event),
|
|
590
|
+
onError: (error) => console.error('Error:', error)
|
|
591
|
+
});
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
---
|
|
595
|
+
|
|
596
|
+
## 🔒 Advanced Security Features
|
|
597
|
+
|
|
598
|
+
### Proxy Mode Configuration
|
|
599
|
+
|
|
600
|
+
```javascript
|
|
601
|
+
const flowscale = new FlowscaleAPI({
|
|
602
|
+
baseUrl: 'https://your-backend-proxy.com',
|
|
603
|
+
proxyMode: true,
|
|
604
|
+
customHeaders: {
|
|
605
|
+
'Authorization': 'Bearer your-jwt-token',
|
|
606
|
+
'X-User-ID': 'user123' // Additional custom headers
|
|
607
|
+
}
|
|
608
|
+
});
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
### Dynamic Header Management
|
|
612
|
+
|
|
613
|
+
```javascript
|
|
614
|
+
// Update JWT token without recreating SDK instance
|
|
615
|
+
flowscale.updateCustomHeaders({
|
|
616
|
+
'Authorization': 'Bearer new-jwt-token'
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
// Get current headers
|
|
620
|
+
const headers = flowscale.getCustomHeaders();
|
|
621
|
+
|
|
622
|
+
// Clear all custom headers
|
|
623
|
+
flowscale.clearCustomHeaders();
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
### Architecture Options
|
|
627
|
+
|
|
628
|
+
#### Option 1: Backend-Only (Recommended)
|
|
629
|
+
```javascript
|
|
630
|
+
// Backend - Use Flowscale SDK
|
|
631
|
+
const flowscale = new FlowscaleAPI({
|
|
632
|
+
apiKey: process.env.FLOWSCALE_API_KEY,
|
|
633
|
+
baseUrl: process.env.FLOWSCALE_API_URL
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
app.post('/api/workflows/execute', async (req, res) => {
|
|
637
|
+
const result = await flowscale.executeWorkflowAsync(req.body.workflowId, req.body.data);
|
|
638
|
+
res.json(result);
|
|
639
|
+
});
|
|
640
|
+
|
|
641
|
+
// Frontend - Simple API calls
|
|
642
|
+
const result = await fetch('/api/workflows/execute', {
|
|
643
|
+
method: 'POST',
|
|
644
|
+
headers: { 'Authorization': 'Bearer ' + token },
|
|
645
|
+
body: JSON.stringify({ workflowId, data })
|
|
646
|
+
});
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
#### Option 2: Proxy Mode (SDK Convenience)
|
|
650
|
+
```javascript
|
|
651
|
+
// Backend - SDK + Proxy endpoints
|
|
652
|
+
const flowscale = new FlowscaleAPI({
|
|
653
|
+
apiKey: process.env.FLOWSCALE_API_KEY,
|
|
654
|
+
baseUrl: process.env.FLOWSCALE_API_URL
|
|
655
|
+
});
|
|
656
|
+
|
|
657
|
+
// Frontend - SDK through proxy
|
|
658
|
+
const flowscale = new FlowscaleAPI({
|
|
659
|
+
baseUrl: 'https://your-backend.com',
|
|
660
|
+
proxyMode: true,
|
|
661
|
+
customHeaders: { 'Authorization': 'Bearer jwt-token' }
|
|
662
|
+
});
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
See `examples/secure-frontend-example.html` and `examples/backend-proxy-example.js` for complete implementation examples.
|
|
592
666
|
|
|
593
667
|
---
|
|
594
668
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HealthCheckResponse, QueueResponse, ExecuteWorkflowResponse, GetOutputResponse, RunDetailResponse, RunListResponse, CancelRunResponse, FlowscaleConfig, WorkflowResponse, WebSocketOptions } from './types';
|
|
1
|
+
import { HealthCheckResponse, QueueResponse, ExecuteWorkflowResponse, GetOutputResponse, GetAllOutputsResponse, RunDetailResponse, RunListResponse, CancelRunResponse, FlowscaleConfig, WorkflowResponse, WebSocketOptions } from './types';
|
|
2
2
|
export declare class FlowscaleAPI {
|
|
3
3
|
private apiKey;
|
|
4
4
|
private baseUrl;
|
|
@@ -9,6 +9,10 @@ export declare class FlowscaleAPI {
|
|
|
9
9
|
private ws;
|
|
10
10
|
private wsConnected;
|
|
11
11
|
private reconnectAttempts;
|
|
12
|
+
private reconnectTimeout;
|
|
13
|
+
private WebSocketImpl;
|
|
14
|
+
private proxyMode;
|
|
15
|
+
private customHeaders;
|
|
12
16
|
constructor(config: FlowscaleConfig);
|
|
13
17
|
/**
|
|
14
18
|
* Checks the health status of all ComfyUI instances within the specified cluster.
|
|
@@ -32,7 +36,7 @@ export declare class FlowscaleAPI {
|
|
|
32
36
|
[key: string]: any;
|
|
33
37
|
}, groupId?: string): Promise<ExecuteWorkflowResponse>;
|
|
34
38
|
/**
|
|
35
|
-
* Executes a workflow and waits for
|
|
39
|
+
* Executes a workflow and waits for all outputs by polling.
|
|
36
40
|
* @param workflowId - The ID of the workflow to execute.
|
|
37
41
|
* @param data - Form data including text fields and file uploads.
|
|
38
42
|
* @param groupId - Optional group ID.
|
|
@@ -41,7 +45,7 @@ export declare class FlowscaleAPI {
|
|
|
41
45
|
*/
|
|
42
46
|
executeWorkflowAsync(workflowId: string, data: {
|
|
43
47
|
[key: string]: any;
|
|
44
|
-
}, groupId?: string, pollIntervalMs?: number, timeoutMs?: number): Promise<
|
|
48
|
+
}, groupId?: string, pollIntervalMs?: number, timeoutMs?: number): Promise<GetAllOutputsResponse>;
|
|
45
49
|
/**
|
|
46
50
|
* Retrieves the output of a specific run by providing the filename.
|
|
47
51
|
* @param filename - The filename of the output to retrieve.
|
|
@@ -99,9 +103,28 @@ export declare class FlowscaleAPI {
|
|
|
99
103
|
* @returns Whether the message was sent successfully
|
|
100
104
|
*/
|
|
101
105
|
sendWebSocketMessage(message: any): boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Updates custom headers for authentication (useful for refreshing JWT tokens)
|
|
108
|
+
* @param headers - Object containing header key-value pairs
|
|
109
|
+
*/
|
|
110
|
+
updateCustomHeaders(headers: {
|
|
111
|
+
[key: string]: string;
|
|
112
|
+
}): void;
|
|
113
|
+
/**
|
|
114
|
+
* Clears all custom headers
|
|
115
|
+
*/
|
|
116
|
+
clearCustomHeaders(): void;
|
|
117
|
+
/**
|
|
118
|
+
* Gets current custom headers
|
|
119
|
+
* @returns Copy of current custom headers
|
|
120
|
+
*/
|
|
121
|
+
getCustomHeaders(): {
|
|
122
|
+
[key: string]: string;
|
|
123
|
+
};
|
|
102
124
|
/**
|
|
103
125
|
* Checks if the WebSocket connection is currently open.
|
|
104
126
|
* @returns True if the WebSocket is connected, false otherwise
|
|
105
127
|
*/
|
|
106
128
|
isWebSocketConnected(): boolean;
|
|
107
129
|
}
|
|
130
|
+
export * from './types';
|