@stubber/virtual-worker 1.3.0 → 1.4.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/app/commands/api_proxy/api_proxy.js +74 -0
- package/app/commands/browser/browser_screenshot.js +1 -1
- package/app/commands/file-server/upload_files.js +7 -0
- package/app/commands/index.js +4 -0
- package/app/commands/run_commands.js +11 -0
- package/app/helpers/get_chromium_page.js +5 -1
- package/lib/interfaces/http/routers/task_gateway.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { create_success } from "#app/functions/create_success.js";
|
|
2
|
+
import * as z from "zod";
|
|
3
|
+
|
|
4
|
+
const return_data_schema = z.object({
|
|
5
|
+
// eslint-disable-next-line id-match
|
|
6
|
+
contentType: z.string(),
|
|
7
|
+
body: z.any(),
|
|
8
|
+
status: z.number(),
|
|
9
|
+
// eslint-disable-next-line id-match
|
|
10
|
+
statusText: z.string(),
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const params_schema = z.looseObject({
|
|
14
|
+
apiurl: z.string(),
|
|
15
|
+
options: z.looseObject({}).optional(),
|
|
16
|
+
timeout_seconds: z.number().optional(),
|
|
17
|
+
__apicall_params: z
|
|
18
|
+
.looseObject({})
|
|
19
|
+
.optional()
|
|
20
|
+
.describe("apicall params as originally passed to the apicall task on core"),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Run an arbitrary CLI command and return stdout/stderr.
|
|
25
|
+
* @param {z.infer<typeof params_schema>} params
|
|
26
|
+
*/
|
|
27
|
+
export const api_proxy = async (params, _stubber) => {
|
|
28
|
+
let { apiurl, options, timeout_seconds, __apicall_params } = params || {};
|
|
29
|
+
|
|
30
|
+
const timeout = (timeout_seconds || __apicall_params?.timeout_seconds || 15) * 1000;
|
|
31
|
+
|
|
32
|
+
if (!options) {
|
|
33
|
+
options = {};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// console.log("timeout", timeout);
|
|
37
|
+
|
|
38
|
+
options.signal = AbortSignal.timeout(timeout);
|
|
39
|
+
|
|
40
|
+
const response = await fetch(apiurl, options);
|
|
41
|
+
|
|
42
|
+
const content_type = response.headers.get("content-type") || "";
|
|
43
|
+
let body;
|
|
44
|
+
if (content_type.includes("application/json")) {
|
|
45
|
+
body = await response.json();
|
|
46
|
+
} else if (content_type.includes("multipart/form-data")) {
|
|
47
|
+
body = await response.formData();
|
|
48
|
+
} else if (content_type.includes("application/octet-stream")) {
|
|
49
|
+
body = await response.blob();
|
|
50
|
+
} else {
|
|
51
|
+
body = await response.text();
|
|
52
|
+
}
|
|
53
|
+
const status = response.status;
|
|
54
|
+
const status_text = response.statusText;
|
|
55
|
+
|
|
56
|
+
/** @type {z.infer<typeof return_data_schema>} */
|
|
57
|
+
const result = {
|
|
58
|
+
// eslint-disable-next-line id-match
|
|
59
|
+
contentType: content_type,
|
|
60
|
+
body: body || undefined,
|
|
61
|
+
status,
|
|
62
|
+
// eslint-disable-next-line id-match
|
|
63
|
+
statusText: status_text,
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const success = response.ok;
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
success,
|
|
70
|
+
payload: {
|
|
71
|
+
apiresult: result,
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
};
|
|
@@ -53,7 +53,7 @@ export const browser_screenshot = async (params, stubber_context) => {
|
|
|
53
53
|
|
|
54
54
|
return create_success({
|
|
55
55
|
message: "Screenshot captured successfully",
|
|
56
|
-
payload: { screenshot: { path: screenshot_options.path, file_info } },
|
|
56
|
+
payload: { screenshot: { path: screenshot_options.path, file_info }, attachments: file_info ? [file_info] : [] },
|
|
57
57
|
});
|
|
58
58
|
} catch (error) {
|
|
59
59
|
return create_error_technical(error);
|
|
@@ -98,6 +98,13 @@ export const upload_files = async (params, _stubber) => {
|
|
|
98
98
|
};
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
let attachments = [];
|
|
102
|
+
|
|
103
|
+
if (payload.uploaded_files) {
|
|
104
|
+
attachments = payload.uploaded_files;
|
|
105
|
+
payload.attachments = attachments;
|
|
106
|
+
}
|
|
107
|
+
|
|
101
108
|
return create_success({
|
|
102
109
|
message: "Files uploaded successfully",
|
|
103
110
|
payload,
|
package/app/commands/index.js
CHANGED
|
@@ -12,6 +12,8 @@ import { cli_run } from "./cli/cli_run.js";
|
|
|
12
12
|
import { upload_files } from "./file-server/upload_files.js";
|
|
13
13
|
import { download_files } from "./file-server/download_files.js";
|
|
14
14
|
|
|
15
|
+
import { api_proxy } from "./api_proxy/api_proxy.js";
|
|
16
|
+
|
|
15
17
|
const all_commands = {
|
|
16
18
|
browser_click,
|
|
17
19
|
browser_extract_data,
|
|
@@ -27,6 +29,8 @@ const all_commands = {
|
|
|
27
29
|
|
|
28
30
|
upload_files,
|
|
29
31
|
download_files,
|
|
32
|
+
|
|
33
|
+
api_proxy,
|
|
30
34
|
};
|
|
31
35
|
|
|
32
36
|
export { all_commands };
|
|
@@ -71,6 +71,17 @@ export const run_commands = async (task, _stubber) => {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
// move command attachments to the task level
|
|
75
|
+
const command_attachments = payload.commands[command_name]?.payload?.attachments;
|
|
76
|
+
if (command_attachments && Array.isArray(command_attachments)) {
|
|
77
|
+
if (!payload.attachments) {
|
|
78
|
+
payload.attachments = [];
|
|
79
|
+
}
|
|
80
|
+
payload.attachments.push(...command_attachments);
|
|
81
|
+
// remove attachments from command payload
|
|
82
|
+
delete payload.commands[command_name].payload.attachments;
|
|
83
|
+
}
|
|
84
|
+
|
|
74
85
|
if (!payload.commands[command_name].success && !command.continue_on_error) {
|
|
75
86
|
important_command_failed = true;
|
|
76
87
|
break; // Stop execution if continue_on_error is falsy
|
|
@@ -22,12 +22,16 @@ export const get_chromium_page = async (params, stubber_context) => {
|
|
|
22
22
|
return create_error_conceptual({ message: "session_id is required to get a Chromium page." });
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
const slow_mo = params?.slow_mo || process.env.SLOW_MO || 0;
|
|
26
|
+
|
|
27
|
+
// console.log(`get_chromium_page: session_id=${session_id}, slow_mo=${slow_mo}`);
|
|
28
|
+
|
|
25
29
|
// Launch the browser once and reuse it
|
|
26
30
|
if (!browser) {
|
|
27
31
|
browser = await chromium.launch({
|
|
28
32
|
headless: false,
|
|
29
33
|
// eslint-disable-next-line id-match
|
|
30
|
-
slowMo:
|
|
34
|
+
slowMo: slow_mo,
|
|
31
35
|
});
|
|
32
36
|
}
|
|
33
37
|
|
|
@@ -15,7 +15,7 @@ router.post(["/virtual_worker_task", "/virtual_worker_send_commands"], async (re
|
|
|
15
15
|
const payload = task_payload_schema.parse(req.body);
|
|
16
16
|
const task = payload.task;
|
|
17
17
|
|
|
18
|
-
console.log("Received task:", task.task_name, "of type:", task.tasktype
|
|
18
|
+
console.log("Received task:", task.task_name, "of type:", task.tasktype);
|
|
19
19
|
|
|
20
20
|
const result = await virtual_worker_task(task);
|
|
21
21
|
|