wp-studio 1.7.7-alpha1

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.
Files changed (48) hide show
  1. package/LICENSE.md +257 -0
  2. package/README.md +87 -0
  3. package/dist/cli/_events-BeOo0LuG.js +116 -0
  4. package/dist/cli/appdata-07CF2rhg.js +21090 -0
  5. package/dist/cli/archive-xDmkN4wb.js +15942 -0
  6. package/dist/cli/browser-CgWK-yoe.js +44 -0
  7. package/dist/cli/certificate-manager-DdBumKZp.js +250 -0
  8. package/dist/cli/create-BHVhkvTx.js +80 -0
  9. package/dist/cli/create-ZS29BDDi.js +40999 -0
  10. package/dist/cli/delete-BgQn-elT.js +56 -0
  11. package/dist/cli/delete-g8pgaLna.js +132 -0
  12. package/dist/cli/get-wordpress-version-BwSCJujO.js +18 -0
  13. package/dist/cli/index-7pbG_s_U.js +434 -0
  14. package/dist/cli/index-BXRYeCYG.js +1393 -0
  15. package/dist/cli/index-T3F1GwxX.js +2668 -0
  16. package/dist/cli/is-errno-exception-t38xF2pB.js +6 -0
  17. package/dist/cli/list-BE_UBjL5.js +105 -0
  18. package/dist/cli/list-DKz0XxM7.js +1032 -0
  19. package/dist/cli/logger-actions-OaIvl-ai.js +45 -0
  20. package/dist/cli/login-B4PkfKOu.js +82 -0
  21. package/dist/cli/logout-BC9gKlTj.js +48 -0
  22. package/dist/cli/main.js +5 -0
  23. package/dist/cli/mu-plugins-GEfKsl5U.js +530 -0
  24. package/dist/cli/passwords-DyzWd9Xi.js +80 -0
  25. package/dist/cli/process-manager-daemon.js +327 -0
  26. package/dist/cli/process-manager-ipc-AUZeYYDT.js +454 -0
  27. package/dist/cli/proxy-daemon.js +197 -0
  28. package/dist/cli/run-wp-cli-command-BctnMDWG.js +88 -0
  29. package/dist/cli/sequential-BQFuixXz.js +46 -0
  30. package/dist/cli/server-files-C_oy-mnI.js +26 -0
  31. package/dist/cli/set-DknhAZpw.js +327 -0
  32. package/dist/cli/site-utils-CfsabjUn.js +243 -0
  33. package/dist/cli/snapshots-6XE53y_F.js +874 -0
  34. package/dist/cli/sqlite-integration-H4OwSlwR.js +83 -0
  35. package/dist/cli/start-CRJqm09_.js +90 -0
  36. package/dist/cli/status-CWNHIOaY.js +44 -0
  37. package/dist/cli/status-CWWx9jYF.js +110 -0
  38. package/dist/cli/stop-CQosmjqA.js +117 -0
  39. package/dist/cli/update-BgL2HKHW.js +101 -0
  40. package/dist/cli/validation-error-DqLxqQuA.js +40 -0
  41. package/dist/cli/wordpress-server-child.js +514 -0
  42. package/dist/cli/wordpress-server-ipc-Dwsg9jSb.js +140 -0
  43. package/dist/cli/wordpress-server-manager-CtiuJqEb.js +566 -0
  44. package/dist/cli/wordpress-version-utils-B6UVeTh_.js +51 -0
  45. package/dist/cli/wp-UGSnlkN0.js +103 -0
  46. package/package.json +73 -0
  47. package/patches/@wp-playground+wordpress+3.1.12.patch +28 -0
  48. package/scripts/postinstall-npm.mjs +38 -0
@@ -0,0 +1,327 @@
1
+ import { spawn } from "child_process";
2
+ import fs, { createWriteStream } from "fs";
3
+ import path from "path";
4
+ import readline from "readline";
5
+ import semver from "semver";
6
+ import { S as SocketServer, P as PROCESS_MANAGER_CONTROL_SOCKET_PATH, a as PROCESS_MANAGER_EVENTS_SOCKET_PATH, b as PROCESS_MANAGER_LOGS_DIR, d as daemonRequestSchema, c as daemonEventSchema } from "./process-manager-ipc-AUZeYYDT.js";
7
+ const SOCKET_TIMEOUT_MS = 2500;
8
+ const STOP_TIMEOUT_MS = 5e3;
9
+ function getProcessLogPaths(processName) {
10
+ return {
11
+ stdoutLogPath: path.join(PROCESS_MANAGER_LOGS_DIR, `${processName}-out.log`),
12
+ stderrLogPath: path.join(PROCESS_MANAGER_LOGS_DIR, `${processName}-error.log`)
13
+ };
14
+ }
15
+ function timestampLogLine(line) {
16
+ return `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
17
+ `;
18
+ }
19
+ function writeTimestampedLines(target, content) {
20
+ const normalizedContent = content.split("\r\n").join("\n");
21
+ const lines = normalizedContent.trimEnd().split("\n");
22
+ lines.forEach((line) => {
23
+ target.write(timestampLogLine(line));
24
+ });
25
+ }
26
+ class ProcessManagerDaemon {
27
+ constructor() {
28
+ this.controlServer = new SocketServer(
29
+ PROCESS_MANAGER_CONTROL_SOCKET_PATH,
30
+ SOCKET_TIMEOUT_MS
31
+ );
32
+ this.eventsServer = new SocketServer(
33
+ PROCESS_MANAGER_EVENTS_SOCKET_PATH,
34
+ SOCKET_TIMEOUT_MS
35
+ );
36
+ this.managedProcesses = /* @__PURE__ */ new Map();
37
+ this.nextPmId = 1;
38
+ this.shuttingDown = false;
39
+ }
40
+ async start() {
41
+ fs.mkdirSync(PROCESS_MANAGER_LOGS_DIR, { recursive: true });
42
+ this.controlServer.on("message", ({ message, socket }) => {
43
+ void this.handleDecodedRequest(socket, message);
44
+ });
45
+ await this.eventsServer.listen();
46
+ await this.controlServer.listen();
47
+ process.on("SIGINT", () => void this.shutdown("signal"));
48
+ process.on("SIGTERM", () => void this.shutdown("signal"));
49
+ process.on("exit", () => {
50
+ this.forceCleanupChildren();
51
+ });
52
+ }
53
+ async handleDecodedRequest(socket, payload) {
54
+ const parsed = daemonRequestSchema.safeParse(payload);
55
+ if (!parsed.success) {
56
+ this.controlServer.sendAndClose(socket, {
57
+ type: "error",
58
+ error: { message: parsed.error.message }
59
+ });
60
+ return;
61
+ }
62
+ const request = parsed.data;
63
+ try {
64
+ const response = await this.handleRequest(request);
65
+ this.controlServer.sendAndClose(socket, response);
66
+ if (request.type === "kill-daemon") {
67
+ setImmediate(() => {
68
+ void this.shutdown("kill-daemon");
69
+ });
70
+ }
71
+ } catch (error) {
72
+ const err = error instanceof Error ? error : new Error(String(error));
73
+ this.controlServer.sendAndClose(socket, {
74
+ type: "error",
75
+ error: { message: err.message, stack: err.stack }
76
+ });
77
+ }
78
+ }
79
+ async handleRequest(request) {
80
+ switch (request.type) {
81
+ case "ping":
82
+ return {
83
+ type: "result",
84
+ payload: {}
85
+ };
86
+ case "start-process": {
87
+ const processDesc = await this.startProcess(
88
+ request.processName,
89
+ request.scriptPath,
90
+ request.env ?? {},
91
+ request.args ?? []
92
+ );
93
+ return {
94
+ type: "result",
95
+ payload: { process: processDesc }
96
+ };
97
+ }
98
+ case "stop-process":
99
+ await this.stopProcess(request.processName);
100
+ return {
101
+ type: "result",
102
+ payload: {}
103
+ };
104
+ case "list-processes":
105
+ return {
106
+ type: "result",
107
+ payload: { processes: this.listProcesses() }
108
+ };
109
+ case "send-message-to-process":
110
+ await this.sendMessageToProcess(request.processId, request.message);
111
+ return {
112
+ type: "result",
113
+ payload: {}
114
+ };
115
+ case "kill-daemon":
116
+ return {
117
+ type: "result",
118
+ payload: {}
119
+ };
120
+ }
121
+ }
122
+ listProcesses() {
123
+ return Array.from(this.managedProcesses.values()).map(this.toProcessDescription);
124
+ }
125
+ getManagedProcessByName(processName) {
126
+ for (const managedProcess of this.managedProcesses.values()) {
127
+ if (managedProcess.name === processName) {
128
+ return managedProcess;
129
+ }
130
+ }
131
+ return void 0;
132
+ }
133
+ async startProcess(processName, scriptPath, env, args) {
134
+ const existing = this.getManagedProcessByName(processName);
135
+ if (existing && existing.status === "online") {
136
+ return this.toProcessDescription(existing);
137
+ }
138
+ const pmId = this.nextPmId++;
139
+ const { stdoutLogPath, stderrLogPath } = getProcessLogPaths(processName);
140
+ const stdoutStream = createWriteStream(stdoutLogPath, { flags: "a" });
141
+ const stderrStream = createWriteStream(stderrLogPath, { flags: "a" });
142
+ const doesCurrentNodeSupportJspi = semver.gte(process.version, "24.0.0");
143
+ const execArgv = doesCurrentNodeSupportJspi ? ["--experimental-wasm-jspi"] : [];
144
+ const child = spawn(process.execPath, [...execArgv, scriptPath, ...args], {
145
+ env: { ...process.env, ...env },
146
+ stdio: ["ignore", "pipe", "pipe", "ipc"],
147
+ windowsHide: true
148
+ });
149
+ const managedProcess = {
150
+ pmId,
151
+ name: processName,
152
+ scriptPath,
153
+ args,
154
+ env,
155
+ child,
156
+ // `child.pid` is only undefined if there's an error, in which case our error handler
157
+ // immediately changes the status and deletes the process from the map
158
+ pid: child.pid,
159
+ status: "online",
160
+ stdoutLogPath,
161
+ stderrLogPath,
162
+ stdoutStream,
163
+ stderrStream,
164
+ settled: false
165
+ };
166
+ this.managedProcesses.set(pmId, managedProcess);
167
+ this.pipeOutputWithTimestamp(child.stdout, stdoutStream);
168
+ this.pipeOutputWithTimestamp(child.stderr, stderrStream);
169
+ child.on("message", (raw) => {
170
+ const event = daemonEventSchema.safeParse({
171
+ type: "process-message",
172
+ payload: {
173
+ process: { name: processName, pm_id: pmId },
174
+ raw
175
+ }
176
+ });
177
+ if (event.success) {
178
+ void this.broadcastEvent(event.data);
179
+ }
180
+ });
181
+ child.on("error", (error) => {
182
+ writeTimestampedLines(stderrStream, error.stack ?? error.message);
183
+ void this.handleProcessExit(managedProcess);
184
+ });
185
+ child.on("exit", () => {
186
+ void this.handleProcessExit(managedProcess);
187
+ });
188
+ await this.broadcastEvent({
189
+ type: "process-event",
190
+ payload: {
191
+ process: { name: processName, pm_id: pmId },
192
+ event: "online"
193
+ }
194
+ });
195
+ return this.toProcessDescription(managedProcess);
196
+ }
197
+ async stopProcess(processName) {
198
+ const managedProcess = this.getManagedProcessByName(processName);
199
+ if (!managedProcess || managedProcess.settled) {
200
+ return;
201
+ }
202
+ await new Promise((resolve) => {
203
+ const timeoutId = setTimeout(() => {
204
+ managedProcess.child.kill("SIGKILL");
205
+ }, STOP_TIMEOUT_MS);
206
+ managedProcess.child.once("exit", () => {
207
+ clearTimeout(timeoutId);
208
+ void this.broadcastEvent({
209
+ type: "process-event",
210
+ payload: {
211
+ process: { name: managedProcess.name, pm_id: managedProcess.pmId },
212
+ event: "delete"
213
+ }
214
+ });
215
+ resolve();
216
+ });
217
+ managedProcess.child.kill("SIGTERM");
218
+ });
219
+ }
220
+ async handleProcessExit(managedProcess) {
221
+ if (managedProcess.settled) {
222
+ return;
223
+ }
224
+ managedProcess.settled = true;
225
+ managedProcess.status = "stopped";
226
+ this.managedProcesses.delete(managedProcess.pmId);
227
+ managedProcess.stdoutStream.end();
228
+ managedProcess.stderrStream.end();
229
+ await this.broadcastEvent({
230
+ type: "process-event",
231
+ payload: {
232
+ process: { name: managedProcess.name, pm_id: managedProcess.pmId },
233
+ event: "exit"
234
+ }
235
+ });
236
+ }
237
+ async sendMessageToProcess(processId, message) {
238
+ const managedProcess = this.managedProcesses.get(processId);
239
+ if (!managedProcess) {
240
+ throw new Error(`Process with id ${processId} not found`);
241
+ }
242
+ if (!managedProcess.child.connected) {
243
+ throw new Error(`Process with id ${processId} is not connected`);
244
+ }
245
+ await new Promise((resolve, reject) => {
246
+ managedProcess.child.send(message, (error) => {
247
+ if (error) {
248
+ reject(error);
249
+ return;
250
+ }
251
+ resolve();
252
+ });
253
+ });
254
+ }
255
+ async broadcastEvent(event) {
256
+ this.eventsServer.broadcast(event);
257
+ }
258
+ pipeOutputWithTimestamp(input, target) {
259
+ if (!input) {
260
+ return;
261
+ }
262
+ const lineReader = readline.createInterface({
263
+ input,
264
+ crlfDelay: Infinity
265
+ });
266
+ lineReader.on("line", (line) => {
267
+ void target.write(timestampLogLine(line));
268
+ });
269
+ }
270
+ toProcessDescription(managedProcess) {
271
+ if (managedProcess.status === "stopped") {
272
+ return {
273
+ name: managedProcess.name,
274
+ pmId: managedProcess.pmId,
275
+ status: managedProcess.status
276
+ };
277
+ }
278
+ return {
279
+ name: managedProcess.name,
280
+ pmId: managedProcess.pmId,
281
+ status: managedProcess.status,
282
+ pid: managedProcess.pid
283
+ };
284
+ }
285
+ forceCleanupChildren() {
286
+ for (const managedProcess of this.managedProcesses.values()) {
287
+ if (managedProcess.settled) {
288
+ continue;
289
+ }
290
+ try {
291
+ managedProcess.child.kill("SIGKILL");
292
+ } catch {
293
+ }
294
+ }
295
+ }
296
+ async shutdown(reason) {
297
+ if (this.shuttingDown) {
298
+ return;
299
+ }
300
+ this.shuttingDown = true;
301
+ await this.broadcastEvent({
302
+ type: "daemon-kill",
303
+ payload: { reason }
304
+ });
305
+ await Promise.allSettled(
306
+ Array.from(this.managedProcesses.values()).map(
307
+ (managedProcess) => this.stopProcess(managedProcess.name)
308
+ )
309
+ );
310
+ await new Promise((resolve) => {
311
+ void this.controlServer.close().then(() => resolve());
312
+ });
313
+ await this.eventsServer.close();
314
+ }
315
+ }
316
+ async function main() {
317
+ try {
318
+ const daemon = new ProcessManagerDaemon();
319
+ await daemon.start();
320
+ } catch (error) {
321
+ console.error(error);
322
+ }
323
+ }
324
+ void main();
325
+ export {
326
+ ProcessManagerDaemon
327
+ };