@stubber/virtual-worker 1.3.0 → 1.4.0

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.
@@ -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,9 +98,16 @@ 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
+ }
106
+
101
107
  return create_success({
102
108
  message: "Files uploaded successfully",
103
109
  payload,
110
+ attachments,
104
111
  });
105
112
  } catch (error) {
106
113
  return create_error_technical(error);
@@ -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 };
@@ -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: params?.slow_mo || 0,
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, "with params:", task.params);
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stubber/virtual-worker",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Template to easily create a node app and keep development standards",
5
5
  "main": "app.js",
6
6
  "directories": {