flowscale 1.0.6 → 1.0.8

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/build/index.js ADDED
@@ -0,0 +1 @@
1
+ 'use strict';function a0_0x56ab(_0x304635,_0x30b74b){const _0x104788=a0_0x1047();return a0_0x56ab=function(_0x56ab12,_0x592549){_0x56ab12=_0x56ab12-0xf8;let _0x55655d=_0x104788[_0x56ab12];return _0x55655d;},a0_0x56ab(_0x304635,_0x30b74b);}const a0_0x242d13=a0_0x56ab;(function(_0x122b9d,_0x387eba){const _0x4e6e09=a0_0x56ab,_0x1a8675=_0x122b9d();while(!![]){try{const _0x3bfe44=parseInt(_0x4e6e09(0x12e))/0x1*(parseInt(_0x4e6e09(0x111))/0x2)+parseInt(_0x4e6e09(0x125))/0x3*(parseInt(_0x4e6e09(0x118))/0x4)+parseInt(_0x4e6e09(0x135))/0x5+parseInt(_0x4e6e09(0x112))/0x6+-parseInt(_0x4e6e09(0x117))/0x7*(parseInt(_0x4e6e09(0x12a))/0x8)+parseInt(_0x4e6e09(0x105))/0x9*(parseInt(_0x4e6e09(0x116))/0xa)+parseInt(_0x4e6e09(0x13a))/0xb*(-parseInt(_0x4e6e09(0x11b))/0xc);if(_0x3bfe44===_0x387eba)break;else _0x1a8675['push'](_0x1a8675['shift']());}catch(_0x2e868a){_0x1a8675['push'](_0x1a8675['shift']());}}}(a0_0x1047,0x49bb8));var __importDefault=this&&this['__importDefault']||function(_0xb12f49){return _0xb12f49&&_0xb12f49['__esModule']?_0xb12f49:{'default':_0xb12f49};};function a0_0x1047(){const _0x1b7ecc=['61332cvXYTF','2530068fWSvPl','checkHealth','/api/v1/runs/','__esModule','130oPgpIg','7XPsHOG','2041404XigVzt','stringify','PlAHY','422124xEaGen','string','isArray','baseUrl','X-API-KEY','hasOwnProperty','ReadStream','apiKey','status','data','3tGBHSl','getRuns','Run\x20Timeout','No\x20response\x20received\x20from\x20API\x20server','isAxiosError','3087128cSszaz','/api/v1/runs','Error:\x20','use','9IizKzG','basename','YjsZt','executeWorkflow','error','defineProperty','/cancel','1545935ksmQMH','appendFormData','\x20-\x20','FlowscaleAPI','statusText','407lCGVsk','cancelRun','handleError','eMCkA','OWvdA','create','axios','form-data','/api/v1/runs?workflow_id=','/api/v1/runs/output','isBuffer','/api/v1/comfy/health','interceptors','client','osFIt','aJOiB','326934JZKdua','get','API\x20Error:\x20','getRun','append','post','path','request','headers','createReadStream','default','response'];a0_0x1047=function(){return _0x1b7ecc;};return a0_0x1047();}Object[a0_0x242d13(0x133)](exports,a0_0x242d13(0x115),{'value':!![]}),exports[a0_0x242d13(0x138)]=void 0x0;const axios_1=__importDefault(require(a0_0x242d13(0xfb))),form_data_1=__importDefault(require(a0_0x242d13(0xfc))),fs_1=__importDefault(require('fs')),path_1=__importDefault(require(a0_0x242d13(0x10b)));class FlowscaleAPI{constructor(_0x4619f1,_0x44c752){const _0x335b9e=a0_0x242d13;this[_0x335b9e(0x122)]=_0x4619f1,this[_0x335b9e(0x11e)]=_0x44c752,this['client']=axios_1[_0x335b9e(0x10f)][_0x335b9e(0xfa)]({'baseURL':this[_0x335b9e(0x11e)]}),this['client'][_0x335b9e(0x101)]['request'][_0x335b9e(0x12d)](_0x3673d7=>{const _0x1e4c1a=_0x335b9e;return!_0x3673d7[_0x1e4c1a(0x10d)]&&(_0x3673d7[_0x1e4c1a(0x10d)]={}),_0x3673d7['headers'][_0x1e4c1a(0x11f)]=this['apiKey'],_0x3673d7;});}async[a0_0x242d13(0x113)](){const _0x2cda0a=a0_0x242d13,_0x102c76={'OWvdA':_0x2cda0a(0x100)};try{const _0x14fc8a=await this[_0x2cda0a(0x102)][_0x2cda0a(0x106)](_0x102c76[_0x2cda0a(0xf9)]);return _0x14fc8a[_0x2cda0a(0x124)];}catch(_0x2a5311){this[_0x2cda0a(0x13c)](_0x2a5311);}}async['getQueue'](){const _0x33547b=a0_0x242d13;try{const _0x4a4655=await this[_0x33547b(0x102)][_0x33547b(0x106)]('/api/v1/comfy/queue');return _0x4a4655[_0x33547b(0x124)];}catch(_0x168926){this[_0x33547b(0x13c)](_0x168926);}}async[a0_0x242d13(0x131)](_0x3cf925,_0x4b789e,_0x3b185b){const _0x2841e1=a0_0x242d13,_0x118067={'aJOiB':function(_0x24b137,_0x5efa1f){return _0x24b137(_0x5efa1f);}};try{const _0x1e6155=new form_data_1[(_0x2841e1(0x10f))]();for(const _0x4abe5f in _0x4b789e){if(_0x4b789e[_0x2841e1(0x120)](_0x4abe5f)){const _0x2596cb=_0x4b789e[_0x4abe5f];Array[_0x2841e1(0x11d)](_0x2596cb)?_0x2596cb['forEach'](_0x3f5d21=>{const _0x1cd027=_0x2841e1;this[_0x1cd027(0x136)](_0x1e6155,_0x4abe5f,_0x3f5d21);}):this['appendFormData'](_0x1e6155,_0x4abe5f,_0x2596cb);}}const _0x157d7b={..._0x1e6155['getHeaders'](),'X-API-KEY':this[_0x2841e1(0x122)]},_0x343417=_0x2841e1(0xfd)+encodeURIComponent(_0x3cf925)+(_0x3b185b?'&group_id='+_0x118067[_0x2841e1(0x104)](encodeURIComponent,_0x3b185b):''),_0x56aec9=await this[_0x2841e1(0x102)][_0x2841e1(0x10a)](_0x343417,_0x1e6155,{'headers':_0x157d7b});return _0x56aec9[_0x2841e1(0x124)];}catch(_0x25cd3b){this[_0x2841e1(0x13c)](_0x25cd3b);}}async['getOutput'](_0x543277){const _0x238629=a0_0x242d13,_0x45b407={'PlAHY':_0x238629(0xfe),'osFIt':function(_0x31fc31,_0x4c591d){return _0x31fc31===_0x4c591d;},'GKVTK':function(_0x588459,_0x7a21c8){return _0x588459===_0x7a21c8;},'YjsZt':_0x238629(0x127)};try{const _0x1f80ca=await this['client'][_0x238629(0x106)](_0x45b407[_0x238629(0x11a)],{'params':{'filename':_0x543277}});if(_0x1f80ca['status']===0xcc)return null;return _0x1f80ca[_0x238629(0x124)];}catch(_0x3d0228){const _0xca8dda=_0x3d0228;if(_0xca8dda[_0x238629(0x110)]&&_0x45b407[_0x238629(0x103)](_0xca8dda['response']['status'],0xcc))return null;else{if(_0xca8dda[_0x238629(0x110)]&&_0x45b407['GKVTK'](_0xca8dda[_0x238629(0x110)][_0x238629(0x123)],0x198))throw new Error(_0x45b407[_0x238629(0x130)]);else this[_0x238629(0x13c)](_0x3d0228);}}}async[a0_0x242d13(0x13b)](_0x1ee2ad){const _0x2cea4a=a0_0x242d13;try{const _0x2d4d52=await this[_0x2cea4a(0x102)][_0x2cea4a(0x10a)]('/api/v1/runs/'+encodeURIComponent(_0x1ee2ad)+_0x2cea4a(0x134));return _0x2d4d52[_0x2cea4a(0x124)];}catch(_0x567812){this[_0x2cea4a(0x13c)](_0x567812);}}async[a0_0x242d13(0x108)](_0x2b0b5e){const _0x537c78=a0_0x242d13;try{const _0x57d741=await this[_0x537c78(0x102)]['get'](_0x537c78(0x114)+encodeURIComponent(_0x2b0b5e));return _0x57d741[_0x537c78(0x124)];}catch(_0xded411){this['handleError'](_0xded411);}}async[a0_0x242d13(0x126)](_0x2b600e){const _0x553e90=a0_0x242d13,_0x3fe654={'Pvalo':_0x553e90(0x12b)};try{const _0x26570c=await this['client'][_0x553e90(0x106)](_0x3fe654['Pvalo'],{'params':{'group_id':_0x2b600e}});return _0x26570c[_0x553e90(0x124)];}catch(_0x3fe2e0){this[_0x553e90(0x13c)](_0x3fe2e0);}}['appendFormData'](_0x394a5c,_0x48e6df,_0x3851e2){const _0x5bf3a4=a0_0x242d13,_0x450cc3={'nWIsq':function(_0x504022,_0x32b2f5){return _0x504022 instanceof _0x32b2f5;},'eMCkA':function(_0xa49107,_0x2b0274){return _0xa49107===_0x2b0274;}};if(_0x450cc3['nWIsq'](_0x3851e2,fs_1[_0x5bf3a4(0x10f)][_0x5bf3a4(0x121)]))_0x394a5c[_0x5bf3a4(0x109)](_0x48e6df,_0x3851e2);else{if(Buffer[_0x5bf3a4(0xff)](_0x3851e2))_0x394a5c['append'](_0x48e6df,_0x3851e2,{'filename':_0x48e6df+'.dat'});else{if(_0x450cc3[_0x5bf3a4(0xf8)](typeof _0x3851e2,_0x5bf3a4(0x11c))&&fs_1[_0x5bf3a4(0x10f)]['existsSync'](_0x3851e2)){const _0x407b5b=path_1[_0x5bf3a4(0x10f)][_0x5bf3a4(0x12f)](_0x3851e2);_0x394a5c[_0x5bf3a4(0x109)](_0x48e6df,fs_1[_0x5bf3a4(0x10f)][_0x5bf3a4(0x10e)](_0x3851e2),_0x407b5b);}else _0x394a5c['append'](_0x48e6df,_0x3851e2);}}}['handleError'](_0x3fce25){const _0x36f292=a0_0x242d13;if(axios_1[_0x36f292(0x10f)][_0x36f292(0x129)](_0x3fce25)){if(_0x3fce25[_0x36f292(0x110)])throw new Error(_0x36f292(0x107)+_0x3fce25['response']['status']+'\x20'+_0x3fce25['response'][_0x36f292(0x139)]+_0x36f292(0x137)+JSON[_0x36f292(0x119)](_0x3fce25[_0x36f292(0x110)][_0x36f292(0x124)]));else{if(_0x3fce25[_0x36f292(0x10c)])throw new Error(_0x36f292(0x128));}}console[_0x36f292(0x132)](_0x3fce25);throw new Error(_0x36f292(0x12c)+_0x3fce25['message']);}}exports[a0_0x242d13(0x138)]=FlowscaleAPI;
package/build/types.js ADDED
@@ -0,0 +1 @@
1
+ 'use strict';function a1_0x5948(_0x17cd04,_0x391904){var _0xdbbfe1=a1_0xdbbf();return a1_0x5948=function(_0x5948eb,_0x1a6e86){_0x5948eb=_0x5948eb-0x12b;var _0x26d497=_0xdbbfe1[_0x5948eb];return _0x26d497;},a1_0x5948(_0x17cd04,_0x391904);}var a1_0x3ff81b=a1_0x5948;(function(_0x529f50,_0x3e50cc){var _0x3c8042=a1_0x5948,_0xf376ef=_0x529f50();while(!![]){try{var _0x59c2de=parseInt(_0x3c8042(0x131))/0x1+parseInt(_0x3c8042(0x137))/0x2*(-parseInt(_0x3c8042(0x12c))/0x3)+-parseInt(_0x3c8042(0x133))/0x4*(parseInt(_0x3c8042(0x136))/0x5)+parseInt(_0x3c8042(0x132))/0x6*(-parseInt(_0x3c8042(0x130))/0x7)+-parseInt(_0x3c8042(0x12d))/0x8*(parseInt(_0x3c8042(0x12f))/0x9)+parseInt(_0x3c8042(0x135))/0xa+parseInt(_0x3c8042(0x134))/0xb*(parseInt(_0x3c8042(0x12e))/0xc);if(_0x59c2de===_0x3e50cc)break;else _0xf376ef['push'](_0xf376ef['shift']());}catch(_0x4fdd5f){_0xf376ef['push'](_0xf376ef['shift']());}}}(a1_0xdbbf,0xa11ea));Object['defineProperty'](exports,a1_0x3ff81b(0x12b),{'value':!![]});function a1_0xdbbf(){var _0xa7a013=['5604rGyFye','270GeGuNM','6650vzQXJy','985933vCqgqD','3918aCWCiO','24ZPRVNq','46937aoNFXy','5565990llDvqh','485065Qtcbin','2242054bMYDOJ','__esModule','3hboQKI','147152JWfvTF'];a1_0xdbbf=function(){return _0xa7a013;};return a1_0xdbbf();}
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "flowscale",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "An NPM library for communicating with the Flowscale APIs",
5
- "main": "dist/index.js",
5
+ "main": "build/index.js",
6
+ "files": ["build/**/*"],
6
7
  "types": "dist/index.d.ts",
7
8
  "keywords": [
8
9
  "flowscale",
@@ -12,18 +13,20 @@
12
13
  ],
13
14
  "scripts": {
14
15
  "build": "tsc",
15
- "test": "echo \"No tests yet\""
16
+ "test": "echo \"No tests yet\"",
17
+ "obfuscate": "javascript-obfuscator dist --output build --compact true --control-flow-flattening true"
16
18
  },
17
19
  "author": "flowscale",
18
20
  "license": "MIT",
19
21
  "dependencies": {
20
22
  "axios": "^1.7.7",
21
- "form-data": "^4.0.1",
22
- "flowscale-test": "^1.0.1"
23
+ "flowscale-test": "^1.0.1",
24
+ "form-data": "^4.0.1"
23
25
  },
24
26
  "devDependencies": {
25
27
  "@types/form-data": "^2.5.2",
26
28
  "@types/node": "^22.9.1",
29
+ "javascript-obfuscator": "^4.1.1",
27
30
  "typescript": "^5.6.3"
28
31
  }
29
32
  }
package/dist/index.d.ts DELETED
@@ -1,52 +0,0 @@
1
- import { HealthCheckResponse, QueueResponse, ExecuteWorkflowResponse, GetOutputResponse, RunDetailResponse, RunListResponse, CancelRunResponse } from './types';
2
- export declare class FlowscaleAPI {
3
- private apiKey;
4
- private baseUrl;
5
- private client;
6
- constructor(apiKey: string, baseUrl: string);
7
- /**
8
- * Checks the health status of all ComfyUI instances within the specified cluster.
9
- */
10
- checkHealth(): Promise<HealthCheckResponse>;
11
- /**
12
- * Retrieves the queue data for all ComfyUI instances in the cluster.
13
- */
14
- getQueue(): Promise<QueueResponse>;
15
- /**
16
- * Executes a specified workflow by processing dynamic form data.
17
- * @param workflowId - The ID of the workflow to execute.
18
- * @param data - Form data including text fields and file uploads.
19
- * @param groupId - Optional group ID.
20
- */
21
- executeWorkflow(workflowId: string, data: {
22
- [key: string]: any;
23
- }, groupId?: string): Promise<ExecuteWorkflowResponse>;
24
- /**
25
- * Retrieves the output of a specific run by providing the filename.
26
- * @param filename - The filename of the output to retrieve.
27
- */
28
- getOutput(filename: string): Promise<GetOutputResponse | null>;
29
- /**
30
- * Cancels a specific run using its unique run ID.
31
- * @param runId - The ID of the run to cancel.
32
- */
33
- cancelRun(runId: string): Promise<CancelRunResponse>;
34
- /**
35
- * Retrieves detailed information about a specific run using its unique run ID.
36
- * @param runId - The ID of the run to retrieve.
37
- */
38
- getRun(runId: string): Promise<RunDetailResponse>;
39
- /**
40
- * Retrieves a list of all runs associated with a specific group ID.
41
- * @param groupId - The group ID to filter runs.
42
- */
43
- getRuns(groupId: string): Promise<RunListResponse>;
44
- /**
45
- * Helper method to append data to FormData.
46
- */
47
- private appendFormData;
48
- /**
49
- * Error handling helper.
50
- */
51
- private handleError;
52
- }
package/dist/index.js DELETED
@@ -1,197 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.FlowscaleAPI = void 0;
7
- const axios_1 = __importDefault(require("axios"));
8
- const form_data_1 = __importDefault(require("form-data"));
9
- const fs_1 = __importDefault(require("fs"));
10
- const path_1 = __importDefault(require("path"));
11
- class FlowscaleAPI {
12
- constructor(apiKey, baseUrl) {
13
- this.apiKey = apiKey;
14
- this.baseUrl = baseUrl;
15
- this.client = axios_1.default.create({
16
- baseURL: this.baseUrl,
17
- });
18
- // Add the API key to all requests
19
- this.client.interceptors.request.use((config) => {
20
- if (!config.headers) {
21
- config.headers = {};
22
- }
23
- config.headers['X-API-KEY'] = this.apiKey;
24
- return config;
25
- });
26
- }
27
- /**
28
- * Checks the health status of all ComfyUI instances within the specified cluster.
29
- */
30
- async checkHealth() {
31
- try {
32
- const response = await this.client.get('/api/v1/comfy/health');
33
- return response.data;
34
- }
35
- catch (error) {
36
- this.handleError(error);
37
- }
38
- }
39
- /**
40
- * Retrieves the queue data for all ComfyUI instances in the cluster.
41
- */
42
- async getQueue() {
43
- try {
44
- const response = await this.client.get('/api/v1/comfy/queue');
45
- return response.data;
46
- }
47
- catch (error) {
48
- this.handleError(error);
49
- }
50
- }
51
- /**
52
- * Executes a specified workflow by processing dynamic form data.
53
- * @param workflowId - The ID of the workflow to execute.
54
- * @param data - Form data including text fields and file uploads.
55
- * @param groupId - Optional group ID.
56
- */
57
- async executeWorkflow(workflowId, data, groupId) {
58
- try {
59
- const formData = new form_data_1.default();
60
- // Append data to formData
61
- for (const key in data) {
62
- if (data.hasOwnProperty(key)) {
63
- const value = data[key];
64
- if (Array.isArray(value)) {
65
- // Handle arrays (for multiple files)
66
- value.forEach((item) => {
67
- this.appendFormData(formData, key, item);
68
- });
69
- }
70
- else {
71
- this.appendFormData(formData, key, value);
72
- }
73
- }
74
- }
75
- const headers = {
76
- ...formData.getHeaders(),
77
- 'X-API-KEY': this.apiKey,
78
- };
79
- const url = `/api/v1/runs?workflow_id=${encodeURIComponent(workflowId)}${groupId ? `&group_id=${encodeURIComponent(groupId)}` : ''}`;
80
- const response = await this.client.post(url, formData, { headers });
81
- return response.data;
82
- }
83
- catch (error) {
84
- this.handleError(error);
85
- }
86
- }
87
- /**
88
- * Retrieves the output of a specific run by providing the filename.
89
- * @param filename - The filename of the output to retrieve.
90
- */
91
- async getOutput(filename) {
92
- try {
93
- const response = await this.client.get('/api/v1/runs/output', {
94
- params: { filename },
95
- });
96
- if (response.status === 204) {
97
- return null;
98
- }
99
- return response.data;
100
- }
101
- catch (error) {
102
- const axiosError = error;
103
- if (axiosError.response && axiosError.response.status === 204) {
104
- return null; // No output found
105
- }
106
- else if (axiosError.response &&
107
- axiosError.response.status === 408) {
108
- throw new Error('Run Timeout');
109
- }
110
- else {
111
- this.handleError(error);
112
- }
113
- }
114
- }
115
- /**
116
- * Cancels a specific run using its unique run ID.
117
- * @param runId - The ID of the run to cancel.
118
- */
119
- async cancelRun(runId) {
120
- try {
121
- const response = await this.client.post(`/api/v1/runs/${encodeURIComponent(runId)}/cancel`);
122
- return response.data;
123
- }
124
- catch (error) {
125
- this.handleError(error);
126
- }
127
- }
128
- /**
129
- * Retrieves detailed information about a specific run using its unique run ID.
130
- * @param runId - The ID of the run to retrieve.
131
- */
132
- async getRun(runId) {
133
- try {
134
- const response = await this.client.get(`/api/v1/runs/${encodeURIComponent(runId)}`);
135
- return response.data;
136
- }
137
- catch (error) {
138
- this.handleError(error);
139
- }
140
- }
141
- /**
142
- * Retrieves a list of all runs associated with a specific group ID.
143
- * @param groupId - The group ID to filter runs.
144
- */
145
- async getRuns(groupId) {
146
- try {
147
- const response = await this.client.get('/api/v1/runs', {
148
- params: { group_id: groupId },
149
- });
150
- return response.data;
151
- }
152
- catch (error) {
153
- this.handleError(error);
154
- }
155
- }
156
- /**
157
- * Helper method to append data to FormData.
158
- */
159
- appendFormData(formData, key, value) {
160
- if (value instanceof fs_1.default.ReadStream) {
161
- // It's a file stream
162
- formData.append(key, value);
163
- }
164
- else if (Buffer.isBuffer(value)) {
165
- // It's a Buffer
166
- formData.append(key, value, { filename: `${key}.dat` });
167
- }
168
- else if (typeof value === 'string' && fs_1.default.existsSync(value)) {
169
- // If the value is a file path
170
- const fileName = path_1.default.basename(value);
171
- formData.append(key, fs_1.default.createReadStream(value), fileName);
172
- }
173
- else {
174
- // Assume it's a string or other value
175
- formData.append(key, value);
176
- }
177
- }
178
- /**
179
- * Error handling helper.
180
- */
181
- handleError(error) {
182
- if (axios_1.default.isAxiosError(error)) {
183
- if (error.response) {
184
- // Server responded with a status code outside 2xx
185
- throw new Error(`API Error: ${error.response.status} ${error.response.statusText} - ${JSON.stringify(error.response.data)}`);
186
- }
187
- else if (error.request) {
188
- // Request was made but no response
189
- throw new Error('No response received from API server');
190
- }
191
- }
192
- console.error(error);
193
- // Something else happened
194
- throw new Error(`Error: ${error.message}`);
195
- }
196
- }
197
- exports.FlowscaleAPI = FlowscaleAPI;
package/dist/types.d.ts DELETED
@@ -1,72 +0,0 @@
1
- export interface HealthCheckResponse {
2
- status: string;
3
- data: Array<{
4
- container: string;
5
- status: string;
6
- }>;
7
- }
8
- export interface QueueResponse {
9
- status: string;
10
- data: Array<{
11
- container: string;
12
- queue: {
13
- queue_running: any[];
14
- queue_pending: any[];
15
- };
16
- }>;
17
- }
18
- export interface ExecuteWorkflowResponse {
19
- status: string;
20
- data: {
21
- output_names: string[];
22
- run_id: string;
23
- };
24
- }
25
- export interface GetOutputResponse {
26
- status: string;
27
- data: {
28
- download_url: string;
29
- generation_status: string;
30
- };
31
- }
32
- export interface RunDetail {
33
- _id: string;
34
- team_id: string;
35
- workflow_id: string;
36
- group_id?: string;
37
- status: string;
38
- inputs: Array<{
39
- path: string;
40
- value: string;
41
- s3_key?: string;
42
- url?: string;
43
- }>;
44
- outputs: Array<{
45
- filename: string;
46
- s3_key?: string;
47
- url?: string;
48
- }>;
49
- created_at: string;
50
- started_at?: string;
51
- completed_at?: string;
52
- }
53
- export interface RunDetailResponse {
54
- status: string;
55
- data: RunDetail;
56
- }
57
- export interface RunListResponse {
58
- status: string;
59
- data: {
60
- group_id: string;
61
- count: number;
62
- runs: RunDetail[];
63
- };
64
- }
65
- export interface CancelRunResponse {
66
- status: string;
67
- data: string;
68
- }
69
- export interface ErrorResponse {
70
- status: string;
71
- errors: string;
72
- }
package/dist/types.js DELETED
@@ -1,3 +0,0 @@
1
- "use strict";
2
- // src/types.ts
3
- Object.defineProperty(exports, "__esModule", { value: true });
package/src/index.ts DELETED
@@ -1,233 +0,0 @@
1
- import axios, { AxiosInstance, AxiosError, AxiosRequestHeaders } from 'axios';
2
- import FormData from 'form-data';
3
- import fs from 'fs';
4
- import path from 'path';
5
- import {
6
- HealthCheckResponse,
7
- QueueResponse,
8
- ExecuteWorkflowResponse,
9
- GetOutputResponse,
10
- RunDetailResponse,
11
- RunListResponse,
12
- CancelRunResponse,
13
- ErrorResponse,
14
- } from './types';
15
-
16
- export class FlowscaleAPI {
17
- private apiKey: string;
18
- private baseUrl: string;
19
- private client: AxiosInstance;
20
-
21
- constructor(apiKey: string, baseUrl: string) {
22
- this.apiKey = apiKey;
23
- this.baseUrl = baseUrl;
24
-
25
- this.client = axios.create({
26
- baseURL: this.baseUrl,
27
- });
28
-
29
- // Add the API key to all requests
30
- this.client.interceptors.request.use((config) => {
31
- if (!config.headers) {
32
- config.headers = {} as AxiosRequestHeaders
33
- }
34
- config.headers['X-API-KEY'] = this.apiKey;
35
- return config;
36
- });
37
- }
38
-
39
- /**
40
- * Checks the health status of all ComfyUI instances within the specified cluster.
41
- */
42
- public async checkHealth(): Promise<HealthCheckResponse> {
43
- try {
44
- const response = await this.client.get<HealthCheckResponse>(
45
- '/api/v1/comfy/health'
46
- );
47
- return response.data;
48
- } catch (error) {
49
- this.handleError(error);
50
- }
51
- }
52
-
53
- /**
54
- * Retrieves the queue data for all ComfyUI instances in the cluster.
55
- */
56
- public async getQueue(): Promise<QueueResponse> {
57
- try {
58
- const response = await this.client.get<QueueResponse>(
59
- '/api/v1/comfy/queue'
60
- );
61
- return response.data;
62
- } catch (error) {
63
- this.handleError(error);
64
- }
65
- }
66
-
67
- /**
68
- * Executes a specified workflow by processing dynamic form data.
69
- * @param workflowId - The ID of the workflow to execute.
70
- * @param data - Form data including text fields and file uploads.
71
- * @param groupId - Optional group ID.
72
- */
73
- public async executeWorkflow(
74
- workflowId: string,
75
- data: { [key: string]: any },
76
- groupId?: string
77
- ): Promise<ExecuteWorkflowResponse> {
78
- try {
79
- const formData = new FormData();
80
-
81
- // Append data to formData
82
- for (const key in data) {
83
- if (data.hasOwnProperty(key)) {
84
- const value = data[key];
85
- if (Array.isArray(value)) {
86
- // Handle arrays (for multiple files)
87
- value.forEach((item: any) => {
88
- this.appendFormData(formData, key, item);
89
- });
90
- } else {
91
- this.appendFormData(formData, key, value);
92
- }
93
- }
94
- }
95
-
96
- const headers = {
97
- ...formData.getHeaders(),
98
- 'X-API-KEY': this.apiKey,
99
- };
100
-
101
- const url = `/api/v1/runs?workflow_id=${encodeURIComponent(workflowId)}${
102
- groupId ? `&group_id=${encodeURIComponent(groupId)}` : ''
103
- }`;
104
-
105
- const response = await this.client.post<ExecuteWorkflowResponse>(
106
- url,
107
- formData,
108
- { headers }
109
- );
110
- return response.data;
111
- } catch (error) {
112
- this.handleError(error);
113
- }
114
- }
115
-
116
- /**
117
- * Retrieves the output of a specific run by providing the filename.
118
- * @param filename - The filename of the output to retrieve.
119
- */
120
- public async getOutput(filename: string): Promise<GetOutputResponse | null> {
121
- try {
122
- const response = await this.client.get<GetOutputResponse>(
123
- '/api/v1/runs/output',
124
- {
125
- params: { filename },
126
- }
127
- );
128
- if (response.status === 204) {
129
- return null;
130
- }
131
- return response.data;
132
- } catch (error) {
133
- const axiosError = error as AxiosError;
134
- if (axiosError.response && axiosError.response.status === 204) {
135
- return null; // No output found
136
- } else if (
137
- axiosError.response &&
138
- axiosError.response.status === 408
139
- ) {
140
- throw new Error('Run Timeout');
141
- } else {
142
- this.handleError(error);
143
- }
144
- }
145
- }
146
-
147
- /**
148
- * Cancels a specific run using its unique run ID.
149
- * @param runId - The ID of the run to cancel.
150
- */
151
- public async cancelRun(runId: string): Promise<CancelRunResponse> {
152
- try {
153
- const response = await this.client.post<CancelRunResponse>(
154
- `/api/v1/runs/${encodeURIComponent(runId)}/cancel`
155
- );
156
- return response.data;
157
- } catch (error) {
158
- this.handleError(error);
159
- }
160
- }
161
-
162
- /**
163
- * Retrieves detailed information about a specific run using its unique run ID.
164
- * @param runId - The ID of the run to retrieve.
165
- */
166
- public async getRun(runId: string): Promise<RunDetailResponse> {
167
- try {
168
- const response = await this.client.get<RunDetailResponse>(
169
- `/api/v1/runs/${encodeURIComponent(runId)}`
170
- );
171
- return response.data;
172
- } catch (error) {
173
- this.handleError(error);
174
- }
175
- }
176
-
177
- /**
178
- * Retrieves a list of all runs associated with a specific group ID.
179
- * @param groupId - The group ID to filter runs.
180
- */
181
- public async getRuns(groupId: string): Promise<RunListResponse> {
182
- try {
183
- const response = await this.client.get<RunListResponse>('/api/v1/runs', {
184
- params: { group_id: groupId },
185
- });
186
- return response.data;
187
- } catch (error) {
188
- this.handleError(error);
189
- }
190
- }
191
-
192
- /**
193
- * Helper method to append data to FormData.
194
- */
195
- private appendFormData(formData: FormData, key: string, value: any) {
196
- if (value instanceof fs.ReadStream) {
197
- // It's a file stream
198
- formData.append(key, value);
199
- } else if (Buffer.isBuffer(value)) {
200
- // It's a Buffer
201
- formData.append(key, value, { filename: `${key}.dat` });
202
- } else if (typeof value === 'string' && fs.existsSync(value)) {
203
- // If the value is a file path
204
- const fileName = path.basename(value);
205
- formData.append(key, fs.createReadStream(value), fileName);
206
- } else {
207
- // Assume it's a string or other value
208
- formData.append(key, value);
209
- }
210
- }
211
-
212
- /**
213
- * Error handling helper.
214
- */
215
- private handleError(error: any): never {
216
- if (axios.isAxiosError(error)) {
217
- if (error.response) {
218
- // Server responded with a status code outside 2xx
219
- throw new Error(
220
- `API Error: ${error.response.status} ${error.response.statusText} - ${JSON.stringify(
221
- error.response.data
222
- )}`
223
- );
224
- } else if (error.request) {
225
- // Request was made but no response
226
- throw new Error('No response received from API server');
227
- }
228
- }
229
- console.error(error);
230
- // Something else happened
231
- throw new Error(`Error: ${error.message}`);
232
- }
233
- }
package/src/types.ts DELETED
@@ -1,82 +0,0 @@
1
- // src/types.ts
2
-
3
- export interface HealthCheckResponse {
4
- status: string;
5
- data: Array<{
6
- container: string;
7
- status: string;
8
- }>;
9
- }
10
-
11
- export interface QueueResponse {
12
- status: string;
13
- data: Array<{
14
- container: string;
15
- queue: {
16
- queue_running: any[];
17
- queue_pending: any[];
18
- };
19
- }>;
20
- }
21
-
22
- export interface ExecuteWorkflowResponse {
23
- status: string;
24
- data: {
25
- output_names: string[];
26
- run_id: string;
27
- };
28
- }
29
-
30
- export interface GetOutputResponse {
31
- status: string;
32
- data: {
33
- download_url: string;
34
- generation_status: string;
35
- };
36
- }
37
-
38
- export interface RunDetail {
39
- _id: string;
40
- team_id: string;
41
- workflow_id: string;
42
- group_id?: string;
43
- status: string;
44
- inputs: Array<{
45
- path: string;
46
- value: string;
47
- s3_key?: string;
48
- url?: string;
49
- }>;
50
- outputs: Array<{
51
- filename: string;
52
- s3_key?: string;
53
- url?: string;
54
- }>;
55
- created_at: string;
56
- started_at?: string;
57
- completed_at?: string;
58
- }
59
-
60
- export interface RunDetailResponse {
61
- status: string;
62
- data: RunDetail;
63
- }
64
-
65
- export interface RunListResponse {
66
- status: string;
67
- data: {
68
- group_id: string;
69
- count: number;
70
- runs: RunDetail[];
71
- };
72
- }
73
-
74
- export interface CancelRunResponse {
75
- status: string;
76
- data: string;
77
- }
78
-
79
- export interface ErrorResponse {
80
- status: string;
81
- errors: string;
82
- }
package/tsconfig.json DELETED
@@ -1,11 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2019",
4
- "module": "CommonJS",
5
- "declaration": true,
6
- "outDir": "./dist",
7
- "strict": true,
8
- "esModuleInterop": true
9
- },
10
- "include": ["src/**/*"]
11
- }