-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathscripts.js
More file actions
124 lines (107 loc) · 3.56 KB
/
Copy pathscripts.js
File metadata and controls
124 lines (107 loc) · 3.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Node imports
import child_process from "node:child_process";
import fs from "node:fs";
import { on } from "node:events";
import path from "node:path";
import readline from "node:readline";
import { appMode } from "./app_mode.js";
const BYTES_PER_KIBIBYTE = 1024;
const MAX_ERROR_BUFFER_KIBIBYTES = 64;
const MAX_ERROR_BUFFER_BYTES = MAX_ERROR_BUFFER_KIBIBYTES * BYTES_PER_KIBIBYTE;
function commandExistsSync(execName) {
const envPath = process.env.PATH || "";
return envPath.split(path.delimiter).some((directory) => {
const filePath = path.join(directory, execName);
return fs.existsSync(filePath) && fs.statSync(filePath).isFile();
});
}
function waitForReady(child, expectedResponse, signal) {
// oxlint-disable-next-line promise/avoid-new
return new Promise((resolve, reject) => {
const readlineStdout = readline.createInterface({ input: child.stdout });
const readlineStderr = readline.createInterface({ input: child.stderr });
let recentOutput = "";
function recordOutput(line) {
recentOutput = `${recentOutput} ${line} \n`.slice(-MAX_ERROR_BUFFER_BYTES);
}
function cleanup() {
readlineStdout.removeAllListeners();
readlineStdout.close();
readlineStderr.removeAllListeners();
readlineStderr.close();
child.removeListener("error", onError);
child.removeListener("close", onClose);
if (signal) {
signal.removeEventListener("abort", onAbort);
}
}
function onLine(line) {
console.log(`[${child.name}] ${line}`);
recordOutput(line);
if (line.includes(expectedResponse)) {
cleanup();
resolve(child);
}
}
function onErrLine(line) {
console.log(`[${child.name}] ${line}`);
recordOutput(line);
}
function onError(err) {
cleanup();
reject(err);
}
function onClose(code) {
console.log(`[${child.name}] exited with code ${code}`);
cleanup();
reject(
new Error(
`[${child.name}] exited with code ${code} before becoming ready.${
recentOutput ? `\nRecent output:\n${recentOutput}` : ""
}`,
),
);
}
function onAbort() {
cleanup();
reject(new Error(`[${child.name}] timed out waiting for "${expectedResponse}"`));
}
readlineStdout.on("line", onLine);
readlineStderr.on("line", onErrLine);
child.once("error", onError);
child.once("close", onClose);
if (signal) {
signal.addEventListener("abort", onAbort, { once: true });
}
});
}
async function waitNuxt(nuxtProcess) {
nuxtProcess.stderr.on("data", (data) => {
console.log("Nuxt STDERR:", data.toString().trim());
});
nuxtProcess.on("close", (code) => {
console.log(`Nuxt process closed with code ${code}`);
});
for await (const [data] of on(nuxtProcess.stdout, "data")) {
const output = data.toString();
console.log("Nuxt STDOUT:", output.trim());
const portMatch = output.match(/Listening on http:\/\/\[::\]:(?<port>\d+)/u);
if (portMatch) {
console.log("Nuxt listening on port", portMatch.groups.port);
nuxtProcess.stdout.on("data", (newData) => {
console.log("Nuxt STDOUT:", newData.toString().trim());
});
return portMatch.groups.port;
}
}
throw new Error("Nuxt process closed");
}
async function runBrowser(scriptName) {
process.env.MODE = appMode.BROWSER;
const nuxtProcess = child_process.spawn("npm", ["run", scriptName], {
shell: true,
FORCE_COLOR: true,
});
return await waitNuxt(nuxtProcess);
}
export { runBrowser, waitForReady, commandExistsSync };