@wp-playground/cli 3.0.45 → 3.0.51
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/README.md +1 -0
- package/blueprints-v1/download.d.ts +1 -1
- package/blueprints-v1/worker-thread-v1.d.ts +7 -1
- package/blueprints-v2/worker-thread-v2.d.ts +3 -2
- package/cli-output.d.ts +4 -0
- package/cli.cjs +1 -1
- package/cli.js +1 -1
- package/index.cjs +1 -1
- package/index.js +1 -1
- package/package.json +19 -16
- package/{run-cli-BK0MGgcU.js → run-cli-Cxpf7CoX.js} +535 -475
- package/run-cli-Cxpf7CoX.js.map +1 -0
- package/run-cli-DHqpmO6s.cjs +66 -0
- package/run-cli-DHqpmO6s.cjs.map +1 -0
- package/run-cli.d.ts +3 -1
- package/{sqlite-database-integration-develop.zip → sqlite-database-integration.zip} +0 -0
- package/worker-thread-v1.cjs +2 -2
- package/worker-thread-v1.cjs.map +1 -1
- package/worker-thread-v1.js +26 -24
- package/worker-thread-v1.js.map +1 -1
- package/worker-thread-v2.cjs +5 -5
- package/worker-thread-v2.cjs.map +1 -1
- package/worker-thread-v2.js +63 -61
- package/worker-thread-v2.js.map +1 -1
- package/run-cli-BK0MGgcU.js.map +0 -1
- package/run-cli-BUDz-Yr3.cjs +0 -64
- package/run-cli-BUDz-Yr3.cjs.map +0 -1
|
@@ -1,64 +1,66 @@
|
|
|
1
|
-
import { logger as
|
|
2
|
-
import { PHPResponse as z, consumeAPI as U, SupportedPHPVersions as oe, printDebugDetails as
|
|
3
|
-
import { resolveRemoteBlueprint as
|
|
1
|
+
import { logger as g, LogSeverity as j, errorLogPath as re } from "@php-wasm/logger";
|
|
2
|
+
import { PHPResponse as z, consumeAPI as U, SupportedPHPVersions as oe, printDebugDetails as Se, exposeAPI as xe, exposeSyncAPI as ke } from "@php-wasm/universal";
|
|
3
|
+
import { resolveRemoteBlueprint as Ie, resolveRuntimeConfiguration as ie, compileBlueprintV1 as me, isBlueprintBundle as $e, runBlueprintV1Steps as se } from "@wp-playground/blueprints";
|
|
4
4
|
import { zipDirectory as Ee, RecommendedPHPVersion as F } from "@wp-playground/common";
|
|
5
|
-
import
|
|
6
|
-
import { MessageChannel as
|
|
7
|
-
import { createNodeFsMountHandler as
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import N, { cpus as
|
|
11
|
-
import { jspi as
|
|
12
|
-
import
|
|
13
|
-
import { NodeJsFilesystem as
|
|
14
|
-
import { EmscriptenDownloadMonitor as Ne, ProgressTracker as
|
|
5
|
+
import m, { existsSync as Z, rmdirSync as Te, mkdirSync as Q, readdirSync as Me } from "fs";
|
|
6
|
+
import { MessageChannel as Be, Worker as ne } from "worker_threads";
|
|
7
|
+
import { createNodeFsMountHandler as Le, FileLockManagerForNode as Ae } from "@php-wasm/node";
|
|
8
|
+
import u, { basename as D, join as he } from "path";
|
|
9
|
+
import Ce from "express";
|
|
10
|
+
import N, { cpus as Re } from "os";
|
|
11
|
+
import { jspi as G } from "wasm-feature-detect";
|
|
12
|
+
import We from "yargs";
|
|
13
|
+
import { NodeJsFilesystem as De, OverlayFilesystem as Ue, InMemoryFilesystem as Fe, ZipFilesystem as _e } from "@wp-playground/storage";
|
|
14
|
+
import { EmscriptenDownloadMonitor as Ne, ProgressTracker as Oe } from "@php-wasm/progress";
|
|
15
15
|
import { resolveWordPressRelease as He } from "@wp-playground/wordpress";
|
|
16
|
-
import
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import ze from "
|
|
21
|
-
import
|
|
22
|
-
import {
|
|
16
|
+
import k from "fs-extra";
|
|
17
|
+
import { createRequire as Ve } from "module";
|
|
18
|
+
import { startBridge as je } from "@php-wasm/xdebug-bridge";
|
|
19
|
+
import { exec as qe } from "child_process";
|
|
20
|
+
import { dir as Ye, setGracefulCleanup as ze } from "tmp-promise";
|
|
21
|
+
import Qe from "ps-man";
|
|
22
|
+
import { removeTempDirSymlink as Ge, createTempDirSymlink as Xe, clearXdebugIDEConfig as Ze, addXdebugIDEConfig as Je } from "@php-wasm/cli-util";
|
|
23
|
+
import { createHash as Ke } from "crypto";
|
|
24
|
+
import { PHPMYADMIN_INSTALL_PATH as ae, getPhpMyAdminInstallSteps as et, PHPMYADMIN_ENTRY_PATH as tt } from "@wp-playground/tools";
|
|
23
25
|
function q(e) {
|
|
24
26
|
const t = [];
|
|
25
27
|
for (const r of e) {
|
|
26
|
-
const
|
|
27
|
-
if (
|
|
28
|
+
const o = r.split(":");
|
|
29
|
+
if (o.length !== 2)
|
|
28
30
|
throw new Error(`Invalid mount format: ${r}.
|
|
29
31
|
Expected format: /host/path:/vfs/path.
|
|
30
32
|
If your path contains a colon, e.g. C:\\myplugin, use the --mount-dir option instead.
|
|
31
33
|
Example: --mount-dir C:\\my-plugin /wordpress/wp-content/plugins/my-plugin`);
|
|
32
|
-
const [
|
|
33
|
-
if (!Z(
|
|
34
|
-
throw new Error(`Host path does not exist: ${
|
|
35
|
-
t.push({ hostPath:
|
|
34
|
+
const [i, s] = o;
|
|
35
|
+
if (!Z(i))
|
|
36
|
+
throw new Error(`Host path does not exist: ${i}`);
|
|
37
|
+
t.push({ hostPath: i, vfsPath: s });
|
|
36
38
|
}
|
|
37
39
|
return t;
|
|
38
40
|
}
|
|
39
|
-
function
|
|
41
|
+
function le(e) {
|
|
40
42
|
if (e.length % 2 !== 0)
|
|
41
43
|
throw new Error("Invalid mount format. Expected: /host/path /vfs/path");
|
|
42
44
|
const t = [];
|
|
43
45
|
for (let r = 0; r < e.length; r += 2) {
|
|
44
|
-
const
|
|
45
|
-
if (!Z(
|
|
46
|
-
throw new Error(`Host path does not exist: ${
|
|
46
|
+
const o = e[r], i = e[r + 1];
|
|
47
|
+
if (!Z(o))
|
|
48
|
+
throw new Error(`Host path does not exist: ${o}`);
|
|
47
49
|
t.push({
|
|
48
|
-
hostPath:
|
|
49
|
-
vfsPath:
|
|
50
|
+
hostPath: u.resolve(process.cwd(), o),
|
|
51
|
+
vfsPath: i
|
|
50
52
|
});
|
|
51
53
|
}
|
|
52
54
|
return t;
|
|
53
55
|
}
|
|
54
|
-
async function
|
|
56
|
+
async function lr(e, t) {
|
|
55
57
|
for (const r of t)
|
|
56
58
|
await e.mount(
|
|
57
59
|
r.vfsPath,
|
|
58
|
-
|
|
60
|
+
Le(r.hostPath)
|
|
59
61
|
);
|
|
60
62
|
}
|
|
61
|
-
const
|
|
63
|
+
const de = {
|
|
62
64
|
step: "runPHP",
|
|
63
65
|
code: {
|
|
64
66
|
filename: "activate-theme.php",
|
|
@@ -77,192 +79,192 @@ const ae = {
|
|
|
77
79
|
`
|
|
78
80
|
}
|
|
79
81
|
};
|
|
80
|
-
function
|
|
81
|
-
const t = e.autoMount, r = [...e.mount || []],
|
|
82
|
+
function fe(e) {
|
|
83
|
+
const t = e.autoMount, r = [...e.mount || []], o = [...e["mount-before-install"] || []], i = {
|
|
82
84
|
...e,
|
|
83
85
|
mount: r,
|
|
84
|
-
"mount-before-install":
|
|
86
|
+
"mount-before-install": o,
|
|
85
87
|
"additional-blueprint-steps": [
|
|
86
88
|
...e["additional-blueprint-steps"] || []
|
|
87
89
|
]
|
|
88
90
|
};
|
|
89
|
-
if (
|
|
90
|
-
const n = `/wordpress/wp-content/plugins/${
|
|
91
|
+
if (st(t)) {
|
|
92
|
+
const n = `/wordpress/wp-content/plugins/${D(t)}`;
|
|
91
93
|
r.push({
|
|
92
94
|
hostPath: t,
|
|
93
95
|
vfsPath: n,
|
|
94
96
|
autoMounted: !0
|
|
95
|
-
}),
|
|
97
|
+
}), i["additional-blueprint-steps"].push({
|
|
96
98
|
step: "activatePlugin",
|
|
97
|
-
pluginPath: `/wordpress/wp-content/plugins/${
|
|
99
|
+
pluginPath: `/wordpress/wp-content/plugins/${D(t)}`
|
|
98
100
|
});
|
|
99
|
-
} else if (
|
|
100
|
-
const
|
|
101
|
+
} else if (it(t)) {
|
|
102
|
+
const s = D(t), n = `/wordpress/wp-content/themes/${s}`;
|
|
101
103
|
r.push({
|
|
102
104
|
hostPath: t,
|
|
103
105
|
vfsPath: n,
|
|
104
106
|
autoMounted: !0
|
|
105
|
-
}),
|
|
107
|
+
}), i["additional-blueprint-steps"].push(
|
|
106
108
|
e["experimental-blueprints-v2-runner"] ? {
|
|
107
109
|
step: "activateTheme",
|
|
108
|
-
themeDirectoryName:
|
|
110
|
+
themeDirectoryName: s
|
|
109
111
|
} : {
|
|
110
112
|
step: "activateTheme",
|
|
111
|
-
themeFolderName:
|
|
113
|
+
themeFolderName: s
|
|
112
114
|
}
|
|
113
115
|
);
|
|
114
|
-
} else if (
|
|
115
|
-
const
|
|
116
|
-
for (const n of
|
|
116
|
+
} else if (ot(t)) {
|
|
117
|
+
const s = m.readdirSync(t);
|
|
118
|
+
for (const n of s)
|
|
117
119
|
n !== "index.php" && r.push({
|
|
118
120
|
hostPath: `${t}/${n}`,
|
|
119
121
|
vfsPath: `/wordpress/wp-content/${n}`,
|
|
120
122
|
autoMounted: !0
|
|
121
123
|
});
|
|
122
|
-
|
|
123
|
-
} else
|
|
124
|
+
i["additional-blueprint-steps"].push(de);
|
|
125
|
+
} else rt(t) && (o.push({
|
|
124
126
|
hostPath: t,
|
|
125
127
|
vfsPath: "/wordpress",
|
|
126
128
|
autoMounted: !0
|
|
127
|
-
}),
|
|
128
|
-
return
|
|
129
|
+
}), i.mode = "apply-to-existing-site", i["additional-blueprint-steps"].push(de), i.wordpressInstallMode || (i.wordpressInstallMode = "install-from-existing-files-if-needed"));
|
|
130
|
+
return i;
|
|
129
131
|
}
|
|
130
|
-
function
|
|
131
|
-
const t =
|
|
132
|
+
function rt(e) {
|
|
133
|
+
const t = m.readdirSync(e);
|
|
132
134
|
return t.includes("wp-admin") && t.includes("wp-includes") && t.includes("wp-content");
|
|
133
135
|
}
|
|
134
|
-
function
|
|
135
|
-
const t =
|
|
136
|
+
function ot(e) {
|
|
137
|
+
const t = m.readdirSync(e);
|
|
136
138
|
return t.includes("themes") || t.includes("plugins") || t.includes("mu-plugins") || t.includes("uploads");
|
|
137
139
|
}
|
|
138
|
-
function
|
|
139
|
-
if (!
|
|
140
|
+
function it(e) {
|
|
141
|
+
if (!m.readdirSync(e).includes("style.css"))
|
|
140
142
|
return !1;
|
|
141
|
-
const r =
|
|
143
|
+
const r = m.readFileSync(he(e, "style.css"), "utf8");
|
|
142
144
|
return !!/^(?:[ \t]*<\?php)?[ \t/*#@]*Theme Name:(.*)$/im.exec(r);
|
|
143
145
|
}
|
|
144
|
-
function
|
|
145
|
-
const t =
|
|
146
|
-
return !!t.filter((
|
|
147
|
-
const
|
|
148
|
-
return !!r.exec(
|
|
146
|
+
function st(e) {
|
|
147
|
+
const t = m.readdirSync(e), r = /^(?:[ \t]*<\?php)?[ \t/*#@]*Plugin Name:(.*)$/im;
|
|
148
|
+
return !!t.filter((i) => i.endsWith(".php")).find((i) => {
|
|
149
|
+
const s = m.readFileSync(he(e, i), "utf8");
|
|
150
|
+
return !!r.exec(s);
|
|
149
151
|
});
|
|
150
152
|
}
|
|
151
|
-
function
|
|
153
|
+
function nt(e) {
|
|
152
154
|
if (e.length % 2 !== 0)
|
|
153
155
|
throw new Error(
|
|
154
156
|
"Invalid constant definition format. Expected pairs of NAME value"
|
|
155
157
|
);
|
|
156
158
|
const t = {};
|
|
157
159
|
for (let r = 0; r < e.length; r += 2) {
|
|
158
|
-
const
|
|
159
|
-
if (!
|
|
160
|
+
const o = e[r], i = e[r + 1];
|
|
161
|
+
if (!o || !o.trim())
|
|
160
162
|
throw new Error("Constant name cannot be empty");
|
|
161
|
-
t[
|
|
163
|
+
t[o.trim()] = i;
|
|
162
164
|
}
|
|
163
165
|
return t;
|
|
164
166
|
}
|
|
165
|
-
function
|
|
167
|
+
function at(e) {
|
|
166
168
|
if (e.length % 2 !== 0)
|
|
167
169
|
throw new Error(
|
|
168
170
|
"Invalid boolean constant definition format. Expected pairs of NAME value"
|
|
169
171
|
);
|
|
170
172
|
const t = {};
|
|
171
173
|
for (let r = 0; r < e.length; r += 2) {
|
|
172
|
-
const
|
|
173
|
-
if (!
|
|
174
|
+
const o = e[r], i = e[r + 1].trim().toLowerCase();
|
|
175
|
+
if (!o || !o.trim())
|
|
174
176
|
throw new Error("Constant name cannot be empty");
|
|
175
|
-
if (
|
|
176
|
-
t[
|
|
177
|
-
else if (
|
|
178
|
-
t[
|
|
177
|
+
if (i === "true" || i === "1")
|
|
178
|
+
t[o.trim()] = !0;
|
|
179
|
+
else if (i === "false" || i === "0")
|
|
180
|
+
t[o.trim()] = !1;
|
|
179
181
|
else
|
|
180
182
|
throw new Error(
|
|
181
|
-
`Invalid boolean value for constant "${
|
|
183
|
+
`Invalid boolean value for constant "${o}": "${i}". Must be "true", "false", "1", or "0".`
|
|
182
184
|
);
|
|
183
185
|
}
|
|
184
186
|
return t;
|
|
185
187
|
}
|
|
186
|
-
function
|
|
188
|
+
function lt(e) {
|
|
187
189
|
if (e.length % 2 !== 0)
|
|
188
190
|
throw new Error(
|
|
189
191
|
"Invalid number constant definition format. Expected pairs of NAME value"
|
|
190
192
|
);
|
|
191
193
|
const t = {};
|
|
192
194
|
for (let r = 0; r < e.length; r += 2) {
|
|
193
|
-
const
|
|
194
|
-
if (!
|
|
195
|
+
const o = e[r], i = e[r + 1].trim();
|
|
196
|
+
if (!o || !o.trim())
|
|
195
197
|
throw new Error("Constant name cannot be empty");
|
|
196
|
-
const
|
|
197
|
-
if (isNaN(
|
|
198
|
+
const s = Number(i);
|
|
199
|
+
if (isNaN(s))
|
|
198
200
|
throw new Error(
|
|
199
|
-
`Invalid number value for constant "${
|
|
201
|
+
`Invalid number value for constant "${o}": "${i}". Must be a valid number.`
|
|
200
202
|
);
|
|
201
|
-
t[
|
|
203
|
+
t[o.trim()] = s;
|
|
202
204
|
}
|
|
203
205
|
return t;
|
|
204
206
|
}
|
|
205
|
-
function
|
|
206
|
-
const
|
|
207
|
-
for (const
|
|
208
|
-
if (
|
|
207
|
+
function dt(e = {}, t = {}, r = {}) {
|
|
208
|
+
const o = {}, i = /* @__PURE__ */ new Set(), s = (n, l) => {
|
|
209
|
+
for (const d in n) {
|
|
210
|
+
if (i.has(d))
|
|
209
211
|
throw new Error(
|
|
210
|
-
`Constant "${
|
|
212
|
+
`Constant "${d}" is defined multiple times across different --define-${l} flags`
|
|
211
213
|
);
|
|
212
|
-
|
|
214
|
+
i.add(d), o[d] = n[d];
|
|
213
215
|
}
|
|
214
216
|
};
|
|
215
|
-
return
|
|
217
|
+
return s(e, "string"), s(t, "bool"), s(r, "number"), o;
|
|
216
218
|
}
|
|
217
|
-
function
|
|
218
|
-
return
|
|
219
|
+
function _(e) {
|
|
220
|
+
return dt(
|
|
219
221
|
e.define,
|
|
220
222
|
e["define-bool"],
|
|
221
223
|
e["define-number"]
|
|
222
224
|
);
|
|
223
225
|
}
|
|
224
|
-
async function
|
|
225
|
-
const t =
|
|
226
|
+
async function ut(e) {
|
|
227
|
+
const t = Ce(), r = await new Promise((s, n) => {
|
|
226
228
|
const l = t.listen(e.port, () => {
|
|
227
|
-
const
|
|
228
|
-
|
|
229
|
+
const d = l.address();
|
|
230
|
+
d === null || typeof d == "string" ? n(new Error("Server address is not available")) : s(l);
|
|
229
231
|
});
|
|
230
232
|
});
|
|
231
|
-
t.use("/", async (
|
|
233
|
+
t.use("/", async (s, n) => {
|
|
232
234
|
let l;
|
|
233
235
|
try {
|
|
234
236
|
l = await e.handleRequest({
|
|
235
|
-
url:
|
|
236
|
-
headers:
|
|
237
|
-
method:
|
|
238
|
-
body: await
|
|
237
|
+
url: s.url,
|
|
238
|
+
headers: ct(s),
|
|
239
|
+
method: s.method,
|
|
240
|
+
body: await pt(s)
|
|
239
241
|
});
|
|
240
|
-
} catch (
|
|
241
|
-
|
|
242
|
+
} catch (d) {
|
|
243
|
+
g.error(d), l = z.forHttpCode(500);
|
|
242
244
|
}
|
|
243
245
|
n.statusCode = l.httpStatusCode;
|
|
244
|
-
for (const
|
|
245
|
-
n.setHeader(
|
|
246
|
+
for (const d in l.headers)
|
|
247
|
+
n.setHeader(d, l.headers[d]);
|
|
246
248
|
n.end(l.bytes);
|
|
247
249
|
});
|
|
248
|
-
const
|
|
249
|
-
return await e.onBind(r,
|
|
250
|
+
const i = r.address().port;
|
|
251
|
+
return await e.onBind(r, i);
|
|
250
252
|
}
|
|
251
|
-
const
|
|
253
|
+
const pt = async (e) => await new Promise((t) => {
|
|
252
254
|
const r = [];
|
|
253
|
-
e.on("data", (
|
|
254
|
-
r.push(
|
|
255
|
+
e.on("data", (o) => {
|
|
256
|
+
r.push(o);
|
|
255
257
|
}), e.on("end", () => {
|
|
256
258
|
t(new Uint8Array(Buffer.concat(r)));
|
|
257
259
|
});
|
|
258
|
-
}),
|
|
260
|
+
}), ct = (e) => {
|
|
259
261
|
const t = {};
|
|
260
262
|
if (e.rawHeaders && e.rawHeaders.length)
|
|
261
263
|
for (let r = 0; r < e.rawHeaders.length; r += 2)
|
|
262
264
|
t[e.rawHeaders[r].toLowerCase()] = e.rawHeaders[r + 1];
|
|
263
265
|
return t;
|
|
264
266
|
};
|
|
265
|
-
class
|
|
267
|
+
class mt {
|
|
266
268
|
constructor(t) {
|
|
267
269
|
this.workerLoads = [], this.addWorker(t);
|
|
268
270
|
}
|
|
@@ -274,98 +276,98 @@ class dt {
|
|
|
274
276
|
}
|
|
275
277
|
async removeWorker(t) {
|
|
276
278
|
const r = this.workerLoads.findIndex(
|
|
277
|
-
(
|
|
279
|
+
(i) => i.worker === t
|
|
278
280
|
);
|
|
279
281
|
if (r === -1)
|
|
280
282
|
return;
|
|
281
|
-
const [
|
|
282
|
-
await Promise.allSettled(
|
|
283
|
+
const [o] = this.workerLoads.splice(r, 1);
|
|
284
|
+
await Promise.allSettled(o.activeRequests);
|
|
283
285
|
}
|
|
284
286
|
async handleRequest(t) {
|
|
285
287
|
let r = this.workerLoads[0];
|
|
286
|
-
for (let
|
|
287
|
-
const
|
|
288
|
-
|
|
288
|
+
for (let i = 1; i < this.workerLoads.length; i++) {
|
|
289
|
+
const s = this.workerLoads[i];
|
|
290
|
+
s.activeRequests.size < r.activeRequests.size && (r = s);
|
|
289
291
|
}
|
|
290
|
-
const
|
|
291
|
-
return r.activeRequests.add(
|
|
292
|
-
r.activeRequests.delete(
|
|
292
|
+
const o = r.worker.request(t);
|
|
293
|
+
return r.activeRequests.add(o), o.url = t.url, o.finally(() => {
|
|
294
|
+
r.activeRequests.delete(o);
|
|
293
295
|
});
|
|
294
296
|
}
|
|
295
297
|
}
|
|
296
|
-
function
|
|
298
|
+
function ht(e) {
|
|
297
299
|
return /^latest$|^trunk$|^nightly$|^(?:(\d+)\.(\d+)(?:\.(\d+))?)((?:-beta(?:\d+)?)|(?:-RC(?:\d+)?))?$/.test(e);
|
|
298
300
|
}
|
|
299
|
-
async function
|
|
301
|
+
async function ft({
|
|
300
302
|
sourceString: e,
|
|
301
303
|
blueprintMayReadAdjacentFiles: t
|
|
302
304
|
}) {
|
|
303
305
|
if (!e)
|
|
304
306
|
return;
|
|
305
307
|
if (e.startsWith("http://") || e.startsWith("https://"))
|
|
306
|
-
return await
|
|
307
|
-
let r =
|
|
308
|
-
if (!
|
|
308
|
+
return await Ie(e);
|
|
309
|
+
let r = u.resolve(process.cwd(), e);
|
|
310
|
+
if (!m.existsSync(r))
|
|
309
311
|
throw new Error(`Blueprint file does not exist: ${r}`);
|
|
310
|
-
const
|
|
311
|
-
if (
|
|
312
|
+
const o = m.statSync(r);
|
|
313
|
+
if (o.isDirectory() && (r = u.join(r, "blueprint.json")), !o.isFile() && o.isSymbolicLink())
|
|
312
314
|
throw new Error(
|
|
313
315
|
`Blueprint path is neither a file nor a directory: ${r}`
|
|
314
316
|
);
|
|
315
|
-
const
|
|
316
|
-
switch (
|
|
317
|
+
const i = u.extname(r);
|
|
318
|
+
switch (i) {
|
|
317
319
|
case ".zip":
|
|
318
|
-
return
|
|
319
|
-
|
|
320
|
+
return _e.fromArrayBuffer(
|
|
321
|
+
m.readFileSync(r).buffer
|
|
320
322
|
);
|
|
321
323
|
case ".json": {
|
|
322
|
-
const
|
|
324
|
+
const s = m.readFileSync(r, "utf-8");
|
|
323
325
|
try {
|
|
324
|
-
JSON.parse(
|
|
326
|
+
JSON.parse(s);
|
|
325
327
|
} catch {
|
|
326
328
|
throw new Error(
|
|
327
329
|
`Blueprint file at ${r} is not a valid JSON file`
|
|
328
330
|
);
|
|
329
331
|
}
|
|
330
|
-
const n =
|
|
332
|
+
const n = u.dirname(r), l = new De(n);
|
|
331
333
|
return new Ue([
|
|
332
334
|
new Fe({
|
|
333
|
-
"blueprint.json":
|
|
335
|
+
"blueprint.json": s
|
|
334
336
|
}),
|
|
335
337
|
/**
|
|
336
338
|
* Wrap the NodeJS filesystem to prevent access to local files
|
|
337
339
|
* unless the user explicitly allowed it.
|
|
338
340
|
*/
|
|
339
341
|
{
|
|
340
|
-
read(
|
|
342
|
+
read(d) {
|
|
341
343
|
if (!t)
|
|
342
344
|
throw new Error(
|
|
343
|
-
`Error: Blueprint contained tried to read a local file at path "${
|
|
345
|
+
`Error: Blueprint contained tried to read a local file at path "${d}" (via a resource of type "bundled"). Playground restricts access to local resources by default as a security measure.
|
|
344
346
|
|
|
345
347
|
You can allow this Blueprint to read files from the same parent directory by explicitly adding the --blueprint-may-read-adjacent-files option to your command.`
|
|
346
348
|
);
|
|
347
|
-
return l.read(
|
|
349
|
+
return l.read(d);
|
|
348
350
|
}
|
|
349
351
|
}
|
|
350
352
|
]);
|
|
351
353
|
}
|
|
352
354
|
default:
|
|
353
355
|
throw new Error(
|
|
354
|
-
`Unsupported blueprint file extension: ${
|
|
356
|
+
`Unsupported blueprint file extension: ${i}. Only .zip and .json files are supported.`
|
|
355
357
|
);
|
|
356
358
|
}
|
|
357
359
|
}
|
|
358
|
-
class
|
|
360
|
+
class wt {
|
|
359
361
|
constructor(t, r) {
|
|
360
362
|
this.args = t, this.siteUrl = r.siteUrl, this.processIdSpaceLength = r.processIdSpaceLength, this.phpVersion = t.php, this.cliOutput = r.cliOutput;
|
|
361
363
|
}
|
|
362
364
|
getWorkerType() {
|
|
363
365
|
return "v2";
|
|
364
366
|
}
|
|
365
|
-
async bootAndSetUpInitialPlayground(t, r,
|
|
366
|
-
const
|
|
367
|
-
await
|
|
368
|
-
const
|
|
367
|
+
async bootAndSetUpInitialPlayground(t, r, o) {
|
|
368
|
+
const i = U(t);
|
|
369
|
+
await i.useFileLockManager(r);
|
|
370
|
+
const s = {
|
|
369
371
|
...this.args,
|
|
370
372
|
phpVersion: this.phpVersion,
|
|
371
373
|
siteUrl: this.siteUrl,
|
|
@@ -382,123 +384,132 @@ class mt {
|
|
|
382
384
|
// TODO: Consider supporting Xdebug for the initial worker via a dedicated flag.
|
|
383
385
|
withXdebug: !1,
|
|
384
386
|
xdebug: void 0,
|
|
385
|
-
nativeInternalDirPath:
|
|
387
|
+
nativeInternalDirPath: o,
|
|
386
388
|
mountsBeforeWpInstall: this.args["mount-before-install"] || [],
|
|
387
389
|
mountsAfterWpInstall: this.args.mount || [],
|
|
388
|
-
constants:
|
|
390
|
+
constants: _(this.args)
|
|
389
391
|
};
|
|
390
|
-
return await
|
|
392
|
+
return await i.bootAndSetUpInitialWorker(s), i;
|
|
391
393
|
}
|
|
392
394
|
async bootPlayground({
|
|
393
395
|
worker: t,
|
|
394
396
|
fileLockManagerPort: r,
|
|
395
|
-
firstProcessId:
|
|
396
|
-
nativeInternalDirPath:
|
|
397
|
+
firstProcessId: o,
|
|
398
|
+
nativeInternalDirPath: i
|
|
397
399
|
}) {
|
|
398
|
-
const
|
|
399
|
-
await
|
|
400
|
+
const s = U(t.phpPort);
|
|
401
|
+
await s.useFileLockManager(r);
|
|
400
402
|
const n = {
|
|
401
403
|
...this.args,
|
|
402
404
|
phpVersion: this.phpVersion,
|
|
403
405
|
siteUrl: this.siteUrl,
|
|
404
|
-
firstProcessId:
|
|
406
|
+
firstProcessId: o,
|
|
405
407
|
processIdSpaceLength: this.processIdSpaceLength,
|
|
406
408
|
trace: this.args.verbosity === "debug",
|
|
407
409
|
withIntl: this.args.intl,
|
|
408
410
|
withRedis: this.args.redis,
|
|
409
411
|
withMemcached: this.args.memcached,
|
|
410
412
|
withXdebug: !!this.args.xdebug,
|
|
411
|
-
nativeInternalDirPath:
|
|
413
|
+
nativeInternalDirPath: i,
|
|
412
414
|
mountsBeforeWpInstall: this.args["mount-before-install"] || [],
|
|
413
415
|
mountsAfterWpInstall: this.args.mount || [],
|
|
414
|
-
constants:
|
|
416
|
+
constants: _(this.args)
|
|
415
417
|
};
|
|
416
|
-
return await
|
|
418
|
+
return await s.bootWorker(n), s;
|
|
417
419
|
}
|
|
418
420
|
}
|
|
419
|
-
const X =
|
|
420
|
-
async function
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
421
|
+
const X = u.join(N.homedir(), ".wordpress-playground");
|
|
422
|
+
async function yt() {
|
|
423
|
+
const e = typeof __dirname < "u" ? __dirname : import.meta.dirname;
|
|
424
|
+
let t = u.join(e, "sqlite-database-integration.zip");
|
|
425
|
+
if (!k.existsSync(t)) {
|
|
426
|
+
const r = Ve(import.meta.url), o = u.dirname(
|
|
427
|
+
r.resolve("@wp-playground/wordpress-builds/package.json")
|
|
428
|
+
);
|
|
429
|
+
t = u.join(
|
|
430
|
+
o,
|
|
431
|
+
"src",
|
|
432
|
+
"sqlite-database-integration",
|
|
433
|
+
"sqlite-database-integration-trunk.zip"
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
return new File([await k.readFile(t)], u.basename(t));
|
|
426
437
|
}
|
|
427
|
-
async function
|
|
428
|
-
const
|
|
429
|
-
return
|
|
438
|
+
async function gt(e, t, r) {
|
|
439
|
+
const o = u.join(X, t);
|
|
440
|
+
return k.existsSync(o) || (k.ensureDirSync(X), await bt(e, o, r)), we(o);
|
|
430
441
|
}
|
|
431
|
-
async function
|
|
432
|
-
const
|
|
442
|
+
async function bt(e, t, r) {
|
|
443
|
+
const i = (await r.monitorFetch(fetch(e))).body.getReader(), s = `${t}.partial`, n = k.createWriteStream(s);
|
|
433
444
|
for (; ; ) {
|
|
434
|
-
const { done: l, value:
|
|
435
|
-
if (
|
|
445
|
+
const { done: l, value: d } = await i.read();
|
|
446
|
+
if (d && n.write(d), l)
|
|
436
447
|
break;
|
|
437
448
|
}
|
|
438
|
-
n.close(), n.closed || await new Promise((l,
|
|
449
|
+
n.close(), n.closed || await new Promise((l, d) => {
|
|
439
450
|
n.on("finish", () => {
|
|
440
|
-
|
|
451
|
+
k.renameSync(s, t), l(null);
|
|
441
452
|
}), n.on("error", (v) => {
|
|
442
|
-
|
|
453
|
+
k.removeSync(s), d(v);
|
|
443
454
|
});
|
|
444
455
|
});
|
|
445
456
|
}
|
|
446
|
-
function
|
|
447
|
-
return new File([
|
|
457
|
+
function we(e, t) {
|
|
458
|
+
return new File([k.readFileSync(e)], D(e));
|
|
448
459
|
}
|
|
449
|
-
class
|
|
460
|
+
class Pt {
|
|
450
461
|
constructor(t, r) {
|
|
451
462
|
this.args = t, this.siteUrl = r.siteUrl, this.processIdSpaceLength = r.processIdSpaceLength, this.cliOutput = r.cliOutput;
|
|
452
463
|
}
|
|
453
464
|
getWorkerType() {
|
|
454
465
|
return "v1";
|
|
455
466
|
}
|
|
456
|
-
async bootAndSetUpInitialPlayground(t, r,
|
|
457
|
-
let
|
|
467
|
+
async bootAndSetUpInitialPlayground(t, r, o) {
|
|
468
|
+
let i, s, n;
|
|
458
469
|
const l = new Ne();
|
|
459
470
|
if (this.args.wordpressInstallMode === "download-and-install") {
|
|
460
|
-
let
|
|
461
|
-
l.addEventListener("progress", (
|
|
462
|
-
if (
|
|
471
|
+
let I = !1;
|
|
472
|
+
l.addEventListener("progress", ($) => {
|
|
473
|
+
if (I)
|
|
463
474
|
return;
|
|
464
|
-
const { loaded:
|
|
465
|
-
Math.min(100, 100 *
|
|
475
|
+
const { loaded: A, total: J } = $.detail, C = Math.floor(
|
|
476
|
+
Math.min(100, 100 * A / J)
|
|
466
477
|
);
|
|
467
|
-
|
|
478
|
+
I = C === 100, this.cliOutput.updateProgress(
|
|
468
479
|
"Downloading WordPress",
|
|
469
|
-
|
|
480
|
+
C
|
|
470
481
|
);
|
|
471
|
-
}),
|
|
482
|
+
}), i = await He(this.args.wp), n = u.join(
|
|
472
483
|
X,
|
|
473
|
-
`prebuilt-wp-content-for-wp-${
|
|
474
|
-
),
|
|
475
|
-
|
|
476
|
-
`${
|
|
484
|
+
`prebuilt-wp-content-for-wp-${i.version}.zip`
|
|
485
|
+
), s = m.existsSync(n) ? we(n) : await gt(
|
|
486
|
+
i.releaseUrl,
|
|
487
|
+
`${i.version}.zip`,
|
|
477
488
|
l
|
|
478
|
-
),
|
|
479
|
-
`Resolved WordPress release URL: ${
|
|
489
|
+
), g.debug(
|
|
490
|
+
`Resolved WordPress release URL: ${i?.releaseUrl}`
|
|
480
491
|
);
|
|
481
492
|
}
|
|
482
|
-
let
|
|
483
|
-
this.args.skipSqliteSetup ? (
|
|
484
|
-
const v = this.args.followSymlinks === !0,
|
|
485
|
-
await
|
|
486
|
-
const h = await
|
|
493
|
+
let d;
|
|
494
|
+
this.args.skipSqliteSetup ? (g.debug("Skipping SQLite integration plugin setup..."), d = void 0) : (this.cliOutput.updateProgress("Preparing SQLite database"), d = await yt());
|
|
495
|
+
const v = this.args.followSymlinks === !0, S = this.args.experimentalTrace === !0, w = this.args["mount-before-install"] || [], a = this.args.mount || [], y = U(t);
|
|
496
|
+
await y.isConnected(), this.cliOutput.updateProgress("Booting WordPress");
|
|
497
|
+
const h = await ie(
|
|
487
498
|
this.getEffectiveBlueprint()
|
|
488
499
|
);
|
|
489
|
-
return await
|
|
500
|
+
return await y.useFileLockManager(r), await y.bootAndSetUpInitialWorker({
|
|
490
501
|
phpVersion: h.phpVersion,
|
|
491
502
|
wpVersion: h.wpVersion,
|
|
492
503
|
siteUrl: this.siteUrl,
|
|
493
504
|
mountsBeforeWpInstall: w,
|
|
494
505
|
mountsAfterWpInstall: a,
|
|
495
506
|
wordpressInstallMode: this.args.wordpressInstallMode || "download-and-install",
|
|
496
|
-
wordPressZip:
|
|
497
|
-
sqliteIntegrationPluginZip: await
|
|
507
|
+
wordPressZip: s && await s.arrayBuffer(),
|
|
508
|
+
sqliteIntegrationPluginZip: await d?.arrayBuffer(),
|
|
498
509
|
firstProcessId: 0,
|
|
499
510
|
processIdSpaceLength: this.processIdSpaceLength,
|
|
500
511
|
followSymlinks: v,
|
|
501
|
-
trace:
|
|
512
|
+
trace: S,
|
|
502
513
|
internalCookieStore: this.args.internalCookieStore,
|
|
503
514
|
withIntl: this.args.intl,
|
|
504
515
|
withRedis: this.args.redis,
|
|
@@ -508,32 +519,33 @@ class wt {
|
|
|
508
519
|
// until Playground has fully booted.
|
|
509
520
|
// TODO: Consider supporting Xdebug for the initial worker via a dedicated flag.
|
|
510
521
|
withXdebug: !1,
|
|
511
|
-
nativeInternalDirPath:
|
|
512
|
-
constants:
|
|
513
|
-
|
|
522
|
+
nativeInternalDirPath: o,
|
|
523
|
+
constants: _(this.args),
|
|
524
|
+
pathAliases: this.args.pathAliases
|
|
525
|
+
}), n && !this.args["mount-before-install"] && !m.existsSync(n) && (this.cliOutput.updateProgress("Caching WordPress for next boot"), m.writeFileSync(
|
|
514
526
|
n,
|
|
515
|
-
await Ee(
|
|
516
|
-
)),
|
|
527
|
+
await Ee(y, "/wordpress")
|
|
528
|
+
)), y;
|
|
517
529
|
}
|
|
518
530
|
async bootPlayground({
|
|
519
531
|
worker: t,
|
|
520
532
|
fileLockManagerPort: r,
|
|
521
|
-
firstProcessId:
|
|
522
|
-
nativeInternalDirPath:
|
|
533
|
+
firstProcessId: o,
|
|
534
|
+
nativeInternalDirPath: i
|
|
523
535
|
}) {
|
|
524
|
-
const
|
|
536
|
+
const s = U(
|
|
525
537
|
t.phpPort
|
|
526
538
|
);
|
|
527
|
-
await
|
|
528
|
-
const n = await
|
|
539
|
+
await s.isConnected();
|
|
540
|
+
const n = await ie(
|
|
529
541
|
this.getEffectiveBlueprint()
|
|
530
542
|
);
|
|
531
|
-
return await
|
|
543
|
+
return await s.useFileLockManager(r), await s.bootWorker({
|
|
532
544
|
phpVersion: n.phpVersion,
|
|
533
545
|
siteUrl: this.siteUrl,
|
|
534
546
|
mountsBeforeWpInstall: this.args["mount-before-install"] || [],
|
|
535
547
|
mountsAfterWpInstall: this.args.mount || [],
|
|
536
|
-
firstProcessId:
|
|
548
|
+
firstProcessId: o,
|
|
537
549
|
processIdSpaceLength: this.processIdSpaceLength,
|
|
538
550
|
followSymlinks: this.args.followSymlinks === !0,
|
|
539
551
|
trace: this.args.experimentalTrace === !0,
|
|
@@ -544,27 +556,28 @@ class wt {
|
|
|
544
556
|
withRedis: this.args.redis,
|
|
545
557
|
withMemcached: this.args.memcached,
|
|
546
558
|
withXdebug: !!this.args.xdebug,
|
|
547
|
-
nativeInternalDirPath:
|
|
548
|
-
constants:
|
|
549
|
-
|
|
559
|
+
nativeInternalDirPath: i,
|
|
560
|
+
constants: _(this.args),
|
|
561
|
+
pathAliases: this.args.pathAliases
|
|
562
|
+
}), await s.isReady(), s;
|
|
550
563
|
}
|
|
551
564
|
async compileInputBlueprint(t) {
|
|
552
|
-
const r = this.getEffectiveBlueprint(),
|
|
553
|
-
let
|
|
554
|
-
return
|
|
555
|
-
if (
|
|
565
|
+
const r = this.getEffectiveBlueprint(), o = new Oe();
|
|
566
|
+
let i = "", s = !1;
|
|
567
|
+
return o.addEventListener("progress", (n) => {
|
|
568
|
+
if (s)
|
|
556
569
|
return;
|
|
557
|
-
|
|
570
|
+
s = n.detail.progress === 100;
|
|
558
571
|
const l = Math.floor(n.detail.progress);
|
|
559
|
-
|
|
560
|
-
}), await
|
|
561
|
-
progress:
|
|
572
|
+
i = n.detail.caption || i || "Running Blueprint", this.cliOutput.updateProgress(i.trim(), l);
|
|
573
|
+
}), await me(r, {
|
|
574
|
+
progress: o,
|
|
562
575
|
additionalSteps: t
|
|
563
576
|
});
|
|
564
577
|
}
|
|
565
578
|
getEffectiveBlueprint() {
|
|
566
579
|
const t = this.args.blueprint;
|
|
567
|
-
return
|
|
580
|
+
return $e(t) ? t : {
|
|
568
581
|
login: this.args.login,
|
|
569
582
|
...t || {},
|
|
570
583
|
preferredVersions: {
|
|
@@ -575,9 +588,9 @@ class wt {
|
|
|
575
588
|
};
|
|
576
589
|
}
|
|
577
590
|
}
|
|
578
|
-
async function
|
|
579
|
-
const
|
|
580
|
-
prefix:
|
|
591
|
+
async function vt(e, t = !0) {
|
|
592
|
+
const o = `${u.basename(process.argv0)}${e}${process.pid}-`, i = await Ye({
|
|
593
|
+
prefix: o,
|
|
581
594
|
/*
|
|
582
595
|
* Allow recursive cleanup on process exit.
|
|
583
596
|
*
|
|
@@ -588,83 +601,83 @@ async function gt(e, t = !0) {
|
|
|
588
601
|
*/
|
|
589
602
|
unsafeCleanup: !0
|
|
590
603
|
});
|
|
591
|
-
return t &&
|
|
604
|
+
return t && ze(), i;
|
|
592
605
|
}
|
|
593
|
-
async function
|
|
594
|
-
const
|
|
606
|
+
async function St(e, t, r) {
|
|
607
|
+
const i = (await xt(
|
|
595
608
|
e,
|
|
596
609
|
t,
|
|
597
610
|
r
|
|
598
611
|
)).map(
|
|
599
|
-
(
|
|
600
|
-
|
|
601
|
-
l ?
|
|
602
|
-
`Failed to delete stale Playground temp dir: ${
|
|
612
|
+
(s) => new Promise((n) => {
|
|
613
|
+
m.rm(s, { recursive: !0 }, (l) => {
|
|
614
|
+
l ? g.warn(
|
|
615
|
+
`Failed to delete stale Playground temp dir: ${s}`,
|
|
603
616
|
l
|
|
604
|
-
) :
|
|
605
|
-
`Deleted stale Playground temp dir: ${
|
|
617
|
+
) : g.info(
|
|
618
|
+
`Deleted stale Playground temp dir: ${s}`
|
|
606
619
|
), n();
|
|
607
620
|
});
|
|
608
621
|
})
|
|
609
622
|
);
|
|
610
|
-
await Promise.all(
|
|
623
|
+
await Promise.all(i);
|
|
611
624
|
}
|
|
612
|
-
async function
|
|
625
|
+
async function xt(e, t, r) {
|
|
613
626
|
try {
|
|
614
|
-
const
|
|
615
|
-
for (const
|
|
616
|
-
await
|
|
627
|
+
const o = m.readdirSync(r).map((s) => u.join(r, s)), i = [];
|
|
628
|
+
for (const s of o)
|
|
629
|
+
await kt(
|
|
617
630
|
e,
|
|
618
631
|
t,
|
|
619
|
-
|
|
620
|
-
) &&
|
|
621
|
-
return
|
|
622
|
-
} catch (
|
|
623
|
-
return
|
|
632
|
+
s
|
|
633
|
+
) && i.push(s);
|
|
634
|
+
return i;
|
|
635
|
+
} catch (o) {
|
|
636
|
+
return g.warn(`Failed to find stale Playground temp dirs: ${o}`), [];
|
|
624
637
|
}
|
|
625
638
|
}
|
|
626
|
-
async function
|
|
627
|
-
if (!
|
|
639
|
+
async function kt(e, t, r) {
|
|
640
|
+
if (!m.lstatSync(r).isDirectory())
|
|
628
641
|
return !1;
|
|
629
|
-
const
|
|
630
|
-
if (!
|
|
642
|
+
const i = u.basename(r);
|
|
643
|
+
if (!i.includes(e))
|
|
631
644
|
return !1;
|
|
632
|
-
const
|
|
645
|
+
const s = i.match(
|
|
633
646
|
new RegExp(`^(.+)${e}(\\d+)-`)
|
|
634
647
|
);
|
|
635
|
-
if (!
|
|
648
|
+
if (!s)
|
|
636
649
|
return !1;
|
|
637
650
|
const n = {
|
|
638
|
-
executableName:
|
|
639
|
-
pid:
|
|
651
|
+
executableName: s[1],
|
|
652
|
+
pid: s[2]
|
|
640
653
|
};
|
|
641
|
-
if (await
|
|
654
|
+
if (await It(n.pid, n.executableName))
|
|
642
655
|
return !1;
|
|
643
656
|
const l = Date.now() - t;
|
|
644
|
-
return
|
|
657
|
+
return m.statSync(r).mtime.getTime() < l;
|
|
645
658
|
}
|
|
646
|
-
async function
|
|
659
|
+
async function It(e, t) {
|
|
647
660
|
const [r] = await new Promise(
|
|
648
|
-
(
|
|
649
|
-
|
|
661
|
+
(o, i) => {
|
|
662
|
+
Qe.list(
|
|
650
663
|
{
|
|
651
664
|
pid: e,
|
|
652
665
|
name: t,
|
|
653
666
|
// Remove path from executable name in the results.
|
|
654
667
|
clean: !0
|
|
655
668
|
},
|
|
656
|
-
(
|
|
657
|
-
|
|
669
|
+
(s, n) => {
|
|
670
|
+
s ? i(s) : o(n);
|
|
658
671
|
}
|
|
659
672
|
);
|
|
660
673
|
}
|
|
661
674
|
);
|
|
662
675
|
return !!r && r.pid === e && r.command === t;
|
|
663
676
|
}
|
|
664
|
-
function
|
|
677
|
+
function $t(e) {
|
|
665
678
|
return process.env.CI === "true" || process.env.CI === "1" || process.env.GITHUB_ACTIONS === "true" || process.env.GITHUB_ACTIONS === "1" || (process.env.TERM || "").toLowerCase() === "dumb" ? !1 : e ? !!e.isTTY : process.stdout.isTTY;
|
|
666
679
|
}
|
|
667
|
-
class
|
|
680
|
+
class Et {
|
|
668
681
|
constructor(t) {
|
|
669
682
|
this.lastProgressLine = "", this.progressActive = !1, this.verbosity = t.verbosity, this.writeStream = t.writeStream || process.stdout;
|
|
670
683
|
}
|
|
@@ -678,7 +691,7 @@ class xt {
|
|
|
678
691
|
* This prevents progress spam in logs - users only see the final outcome.
|
|
679
692
|
*/
|
|
680
693
|
get shouldRender() {
|
|
681
|
-
return
|
|
694
|
+
return $t(this.writeStream);
|
|
682
695
|
}
|
|
683
696
|
get isQuiet() {
|
|
684
697
|
return this.verbosity === "quiet";
|
|
@@ -729,12 +742,12 @@ ${t}
|
|
|
729
742
|
r.push(
|
|
730
743
|
`${this.dim("PHP")} ${this.cyan(t.phpVersion)} ${this.dim("WordPress")} ${this.cyan(t.wpVersion)}`
|
|
731
744
|
);
|
|
732
|
-
const
|
|
733
|
-
if (t.intl &&
|
|
734
|
-
for (const
|
|
735
|
-
const
|
|
745
|
+
const o = [];
|
|
746
|
+
if (t.intl && o.push("intl"), t.redis && o.push("redis"), t.memcached && o.push("memcached"), t.xdebug && o.push(this.yellow("xdebug")), o.length > 0 && r.push(`${this.dim("Extensions")} ${o.join(", ")}`), t.mounts.length > 0)
|
|
747
|
+
for (const i of t.mounts) {
|
|
748
|
+
const s = i.autoMounted ? ` ${this.dim("(auto-mount)")}` : "";
|
|
736
749
|
r.push(
|
|
737
|
-
`${this.dim("Mount")} ${
|
|
750
|
+
`${this.dim("Mount")} ${i.hostPath} ${this.dim("→")} ${i.vfsPath}${s}`
|
|
738
751
|
);
|
|
739
752
|
}
|
|
740
753
|
t.blueprint && r.push(`${this.dim("Blueprint")} ${t.blueprint}`), this.writeStream.write(r.join(`
|
|
@@ -761,8 +774,8 @@ ${t}
|
|
|
761
774
|
updateProgress(t, r) {
|
|
762
775
|
if (this.isQuiet || !this.shouldRender) return;
|
|
763
776
|
this.progressActive || (this.progressActive = !0);
|
|
764
|
-
let
|
|
765
|
-
r !== void 0 && (
|
|
777
|
+
let o = `${t}`;
|
|
778
|
+
r !== void 0 && (o = `${t} ${this.dim(`${r}%`)}`), o !== this.lastProgressLine && (this.lastProgressLine = o, this.isTTY ? (this.writeStream.cursorTo(0), this.writeStream.write(o), this.writeStream.clearLine(1)) : this.writeStream.write(`${o}
|
|
766
779
|
`));
|
|
767
780
|
}
|
|
768
781
|
/**
|
|
@@ -804,10 +817,10 @@ ${t}
|
|
|
804
817
|
*/
|
|
805
818
|
printReady(t, r) {
|
|
806
819
|
if (this.isQuiet) return;
|
|
807
|
-
const
|
|
820
|
+
const o = r === 1 ? "worker" : "workers";
|
|
808
821
|
this.writeStream.write(
|
|
809
822
|
`
|
|
810
|
-
${this.green("Ready!")} WordPress is running on ${this.bold(t)} ${this.dim(`(${r} ${
|
|
823
|
+
${this.green("Ready!")} WordPress is running on ${this.bold(t)} ${this.dim(`(${r} ${o})`)}
|
|
811
824
|
|
|
812
825
|
`
|
|
813
826
|
);
|
|
@@ -816,13 +829,23 @@ ${this.green("Ready!")} WordPress is running on ${this.bold(t)} ${this.dim(`(${r
|
|
|
816
829
|
this.isQuiet || this.writeStream.write(`${this.yellow("Warning:")} ${t}
|
|
817
830
|
`);
|
|
818
831
|
}
|
|
832
|
+
/**
|
|
833
|
+
* Prints the phpMyAdmin URL when the --phpmyadmin flag is enabled.
|
|
834
|
+
*/
|
|
835
|
+
printPhpMyAdminUrl(t) {
|
|
836
|
+
this.isQuiet || this.writeStream.write(
|
|
837
|
+
`${this.cyan("phpMyAdmin")} available at ${this.bold(t)}
|
|
838
|
+
|
|
839
|
+
`
|
|
840
|
+
);
|
|
841
|
+
}
|
|
819
842
|
}
|
|
820
|
-
const
|
|
843
|
+
const ye = {
|
|
821
844
|
Quiet: { name: "quiet", severity: j.Fatal },
|
|
822
845
|
Normal: { name: "normal", severity: j.Info },
|
|
823
846
|
Debug: { name: "debug", severity: j.Debug }
|
|
824
847
|
};
|
|
825
|
-
async function
|
|
848
|
+
async function dr(e) {
|
|
826
849
|
try {
|
|
827
850
|
const t = {
|
|
828
851
|
"site-url": {
|
|
@@ -845,21 +868,21 @@ async function or(e) {
|
|
|
845
868
|
type: "string",
|
|
846
869
|
nargs: 2,
|
|
847
870
|
array: !0,
|
|
848
|
-
coerce:
|
|
871
|
+
coerce: nt
|
|
849
872
|
},
|
|
850
873
|
"define-bool": {
|
|
851
874
|
describe: 'Define PHP boolean constants (can be used multiple times). Format: NAME value. Value must be "true", "false", "1", or "0". Examples: --define-bool WP_DEBUG true --define-bool MY_FEATURE false',
|
|
852
875
|
type: "string",
|
|
853
876
|
nargs: 2,
|
|
854
877
|
array: !0,
|
|
855
|
-
coerce:
|
|
878
|
+
coerce: at
|
|
856
879
|
},
|
|
857
880
|
"define-number": {
|
|
858
881
|
describe: "Define PHP number constants (can be used multiple times). Format: NAME value. Examples: --define-number LIMIT 100 --define-number RATE 45.67",
|
|
859
882
|
type: "string",
|
|
860
883
|
nargs: 2,
|
|
861
884
|
array: !0,
|
|
862
|
-
coerce:
|
|
885
|
+
coerce: lt
|
|
863
886
|
},
|
|
864
887
|
// @TODO: Support read-only mounts, e.g. via WORKERFS, a custom
|
|
865
888
|
// ReadOnlyNODEFS, or by copying the files into MEMFS
|
|
@@ -880,14 +903,14 @@ async function or(e) {
|
|
|
880
903
|
type: "array",
|
|
881
904
|
nargs: 2,
|
|
882
905
|
array: !0,
|
|
883
|
-
coerce:
|
|
906
|
+
coerce: le
|
|
884
907
|
},
|
|
885
908
|
"mount-dir-before-install": {
|
|
886
909
|
describe: 'Mount a directory before WordPress installation (can be used multiple times). Format: "/host/path" "/vfs/path"',
|
|
887
910
|
type: "string",
|
|
888
911
|
nargs: 2,
|
|
889
912
|
array: !0,
|
|
890
|
-
coerce:
|
|
913
|
+
coerce: le
|
|
891
914
|
},
|
|
892
915
|
login: {
|
|
893
916
|
describe: "Should log the user in",
|
|
@@ -934,7 +957,7 @@ async function or(e) {
|
|
|
934
957
|
verbosity: {
|
|
935
958
|
describe: "Output logs and progress messages.",
|
|
936
959
|
type: "string",
|
|
937
|
-
choices: Object.values(
|
|
960
|
+
choices: Object.values(ye).map(
|
|
938
961
|
(a) => a.name
|
|
939
962
|
),
|
|
940
963
|
default: "normal"
|
|
@@ -1010,6 +1033,11 @@ Warning: Following symlinks will expose files outside mounted directories to Pla
|
|
|
1010
1033
|
choices: ["create-new-site", "apply-to-existing-site"],
|
|
1011
1034
|
// Remove the "hidden" flag once Blueprint V2 is fully supported
|
|
1012
1035
|
hidden: !0
|
|
1036
|
+
},
|
|
1037
|
+
phpmyadmin: {
|
|
1038
|
+
describe: "Install phpMyAdmin for database management. The phpMyAdmin URL will be printed after boot. Optionally specify a custom URL path (default: /phpmyadmin).",
|
|
1039
|
+
type: "string",
|
|
1040
|
+
coerce: (a) => a === "" ? "/phpmyadmin" : a
|
|
1013
1041
|
}
|
|
1014
1042
|
}, r = {
|
|
1015
1043
|
port: {
|
|
@@ -1020,13 +1048,13 @@ Warning: Following symlinks will expose files outside mounted directories to Pla
|
|
|
1020
1048
|
"experimental-multi-worker": {
|
|
1021
1049
|
describe: "Enable experimental multi-worker support which requires a /wordpress directory backed by a real filesystem. Pass a positive number to specify the number of workers to use. Otherwise, default to the number of CPUs minus 1.",
|
|
1022
1050
|
type: "number",
|
|
1023
|
-
coerce: (a) => a ??
|
|
1051
|
+
coerce: (a) => a ?? Re().length - 1
|
|
1024
1052
|
},
|
|
1025
1053
|
"experimental-devtools": {
|
|
1026
1054
|
describe: "Enable experimental browser development tools.",
|
|
1027
1055
|
type: "boolean"
|
|
1028
1056
|
}
|
|
1029
|
-
},
|
|
1057
|
+
}, o = {
|
|
1030
1058
|
path: {
|
|
1031
1059
|
describe: "Path to the project directory. Playground will auto-detect if this is a plugin, theme, wp-content, or WordPress directory.",
|
|
1032
1060
|
type: "string",
|
|
@@ -1097,14 +1125,16 @@ Warning: Following symlinks will expose files outside mounted directories to Pla
|
|
|
1097
1125
|
// Define constants
|
|
1098
1126
|
define: t.define,
|
|
1099
1127
|
"define-bool": t["define-bool"],
|
|
1100
|
-
"define-number": t["define-number"]
|
|
1101
|
-
|
|
1128
|
+
"define-number": t["define-number"],
|
|
1129
|
+
// Tools
|
|
1130
|
+
phpmyadmin: t.phpmyadmin
|
|
1131
|
+
}, i = {
|
|
1102
1132
|
outfile: {
|
|
1103
1133
|
describe: "When building, write to this output file.",
|
|
1104
1134
|
type: "string",
|
|
1105
1135
|
default: "wordpress.zip"
|
|
1106
1136
|
}
|
|
1107
|
-
},
|
|
1137
|
+
}, s = We(e).usage("Usage: wp-playground <command> [options]").command(
|
|
1108
1138
|
"start",
|
|
1109
1139
|
"Start a local WordPress server with automatic project detection (recommended)",
|
|
1110
1140
|
(a) => a.usage(
|
|
@@ -1120,7 +1150,7 @@ Examples:
|
|
|
1120
1150
|
wp-playground start --wp=6.7 --php=8.3 # Use specific versions
|
|
1121
1151
|
wp-playground start --skip-browser # Skip opening browser
|
|
1122
1152
|
wp-playground start --no-auto-mount # Disable auto-detection`
|
|
1123
|
-
).options(
|
|
1153
|
+
).options(o)
|
|
1124
1154
|
).command(
|
|
1125
1155
|
"server",
|
|
1126
1156
|
"Start a local WordPress server (advanced, low-level)",
|
|
@@ -1137,18 +1167,18 @@ Examples:
|
|
|
1137
1167
|
"Build a ZIP snapshot of a WordPress site based on a Blueprint",
|
|
1138
1168
|
(a) => a.options({
|
|
1139
1169
|
...t,
|
|
1140
|
-
...
|
|
1170
|
+
...i
|
|
1141
1171
|
})
|
|
1142
1172
|
).demandCommand(1, "Please specify a command").strictCommands().conflicts(
|
|
1143
1173
|
"experimental-unsafe-ide-integration",
|
|
1144
1174
|
"experimental-devtools"
|
|
1145
|
-
).showHelpOnFail(!1).fail((a,
|
|
1146
|
-
if (
|
|
1147
|
-
throw
|
|
1175
|
+
).showHelpOnFail(!1).fail((a, y, h) => {
|
|
1176
|
+
if (y)
|
|
1177
|
+
throw y;
|
|
1148
1178
|
a && a.includes("Please specify a command") && (h.showHelp(), console.error(`
|
|
1149
1179
|
` + a), process.exit(1)), console.error(a), process.exit(1);
|
|
1150
1180
|
}).strictOptions().check(async (a) => {
|
|
1151
|
-
if (a["skip-wordpress-install"] === !0 && (a["wordpress-install-mode"] = "do-not-attempt-installing", a.wordpressInstallMode = "do-not-attempt-installing"), a.wp !== void 0 && typeof a.wp == "string" && !
|
|
1181
|
+
if (a["skip-wordpress-install"] === !0 && (a["wordpress-install-mode"] = "do-not-attempt-installing", a.wordpressInstallMode = "do-not-attempt-installing"), a.wp !== void 0 && typeof a.wp == "string" && !ht(a.wp))
|
|
1152
1182
|
try {
|
|
1153
1183
|
new URL(a.wp);
|
|
1154
1184
|
} catch {
|
|
@@ -1156,19 +1186,19 @@ Examples:
|
|
|
1156
1186
|
'Unrecognized WordPress version. Please use "latest", a URL, or a numeric version such as "6.2", "6.0.1", "6.2-beta1", or "6.2-RC1"'
|
|
1157
1187
|
);
|
|
1158
1188
|
}
|
|
1159
|
-
const
|
|
1160
|
-
if (typeof
|
|
1189
|
+
const y = a["site-url"];
|
|
1190
|
+
if (typeof y == "string" && y.trim() !== "")
|
|
1161
1191
|
try {
|
|
1162
|
-
new URL(
|
|
1192
|
+
new URL(y);
|
|
1163
1193
|
} catch {
|
|
1164
1194
|
throw new Error(
|
|
1165
|
-
`Invalid site-url "${
|
|
1195
|
+
`Invalid site-url "${y}". Please provide a valid URL (e.g., http://localhost:8080 or https://example.com)`
|
|
1166
1196
|
);
|
|
1167
1197
|
}
|
|
1168
1198
|
if (a["auto-mount"]) {
|
|
1169
1199
|
let h = !1;
|
|
1170
1200
|
try {
|
|
1171
|
-
h =
|
|
1201
|
+
h = m.statSync(
|
|
1172
1202
|
a["auto-mount"]
|
|
1173
1203
|
).isDirectory();
|
|
1174
1204
|
} catch {
|
|
@@ -1213,16 +1243,16 @@ Examples:
|
|
|
1213
1243
|
);
|
|
1214
1244
|
return !0;
|
|
1215
1245
|
});
|
|
1216
|
-
|
|
1217
|
-
const n = await
|
|
1246
|
+
s.wrap(s.terminalWidth());
|
|
1247
|
+
const n = await s.argv, l = n._[0];
|
|
1218
1248
|
["start", "run-blueprint", "server", "build-snapshot"].includes(
|
|
1219
1249
|
l
|
|
1220
|
-
) || (
|
|
1221
|
-
const
|
|
1222
|
-
!("WP_DEBUG" in
|
|
1250
|
+
) || (s.showHelp(), process.exit(1));
|
|
1251
|
+
const d = n.define || {};
|
|
1252
|
+
!("WP_DEBUG" in d) && !("WP_DEBUG_LOG" in d) && !("WP_DEBUG_DISPLAY" in d) && (d.WP_DEBUG = "true", d.WP_DEBUG_LOG = "true", d.WP_DEBUG_DISPLAY = "true");
|
|
1223
1253
|
const v = {
|
|
1224
1254
|
...n,
|
|
1225
|
-
define:
|
|
1255
|
+
define: d,
|
|
1226
1256
|
command: l,
|
|
1227
1257
|
mount: [
|
|
1228
1258
|
...n.mount || [],
|
|
@@ -1232,12 +1262,12 @@ Examples:
|
|
|
1232
1262
|
...n["mount-before-install"] || [],
|
|
1233
1263
|
...n["mount-dir-before-install"] || []
|
|
1234
1264
|
]
|
|
1235
|
-
},
|
|
1236
|
-
|
|
1265
|
+
}, S = await Lt(v);
|
|
1266
|
+
S === void 0 && process.exit(0);
|
|
1237
1267
|
const w = /* @__PURE__ */ (() => {
|
|
1238
1268
|
let a;
|
|
1239
1269
|
return async () => {
|
|
1240
|
-
a !== void 0 && (a =
|
|
1270
|
+
a !== void 0 && (a = S[Symbol.asyncDispose]()), await a, process.exit(0);
|
|
1241
1271
|
};
|
|
1242
1272
|
})();
|
|
1243
1273
|
process.on("SIGINT", w), process.on("SIGTERM", w);
|
|
@@ -1245,40 +1275,51 @@ Examples:
|
|
|
1245
1275
|
if (console.error(t), !(t instanceof Error))
|
|
1246
1276
|
throw t;
|
|
1247
1277
|
if (process.argv.includes("--debug"))
|
|
1248
|
-
|
|
1278
|
+
Se(t);
|
|
1249
1279
|
else {
|
|
1250
|
-
const
|
|
1251
|
-
let
|
|
1280
|
+
const o = [];
|
|
1281
|
+
let i = t;
|
|
1252
1282
|
do
|
|
1253
|
-
|
|
1254
|
-
while (
|
|
1283
|
+
o.push(i.message), i = i.cause;
|
|
1284
|
+
while (i instanceof Error);
|
|
1255
1285
|
console.error(
|
|
1256
|
-
"\x1B[1m" +
|
|
1286
|
+
"\x1B[1m" + o.join(" caused by: ") + "\x1B[0m"
|
|
1257
1287
|
);
|
|
1258
1288
|
}
|
|
1259
1289
|
process.exit(1);
|
|
1260
1290
|
}
|
|
1261
1291
|
}
|
|
1262
|
-
function
|
|
1292
|
+
function ue(e, t) {
|
|
1263
1293
|
return e.find(
|
|
1264
1294
|
(r) => r.vfsPath.replace(/\/$/, "") === t.replace(/\/$/, "")
|
|
1265
1295
|
);
|
|
1266
1296
|
}
|
|
1267
|
-
const
|
|
1268
|
-
async function
|
|
1297
|
+
const Tt = Symbol("playground-cli-testing"), B = (e) => process.stdout.isTTY ? "\x1B[1m" + e + "\x1B[0m" : e, Mt = (e) => process.stdout.isTTY ? "\x1B[31m" + e + "\x1B[0m" : e, Bt = (e) => process.stdout.isTTY ? `\x1B[2m${e}\x1B[0m` : e, Y = (e) => process.stdout.isTTY ? `\x1B[3m${e}\x1B[0m` : e, pe = (e) => process.stdout.isTTY ? `\x1B[33m${e}\x1B[0m` : e;
|
|
1298
|
+
async function Lt(e) {
|
|
1269
1299
|
let t, r;
|
|
1270
|
-
const
|
|
1271
|
-
if (e.command === "start" && (e =
|
|
1272
|
-
const w = Object.values(
|
|
1300
|
+
const o = /* @__PURE__ */ new Map();
|
|
1301
|
+
if (e.command === "start" && (e = At(e)), e.autoMount !== void 0 && (e.autoMount === "" && (e = { ...e, autoMount: process.cwd() }), e = fe(e)), e.wordpressInstallMode === void 0 && (e.wordpressInstallMode = "download-and-install"), e.quiet && (e.verbosity = "quiet", delete e.quiet), e.debug && (e.verbosity = "debug", delete e.debug), e.verbosity) {
|
|
1302
|
+
const w = Object.values(ye).find(
|
|
1273
1303
|
(a) => a.name === e.verbosity
|
|
1274
1304
|
).severity;
|
|
1275
|
-
|
|
1305
|
+
g.setSeverityFilterLevel(w);
|
|
1306
|
+
}
|
|
1307
|
+
if (e.intl || (e.intl = !0), e.redis === void 0 && (e.redis = await G()), e.memcached === void 0 && (e.memcached = await G()), e.phpmyadmin) {
|
|
1308
|
+
if (e.phpmyadmin === !0 && (e.phpmyadmin = "/phpmyadmin"), e.skipSqliteSetup)
|
|
1309
|
+
throw new Error(
|
|
1310
|
+
"--phpmyadmin requires SQLite. Cannot be used with --skip-sqlite-setup."
|
|
1311
|
+
);
|
|
1312
|
+
e.pathAliases = [
|
|
1313
|
+
{
|
|
1314
|
+
urlPrefix: e.phpmyadmin,
|
|
1315
|
+
fsPath: ae
|
|
1316
|
+
}
|
|
1317
|
+
];
|
|
1276
1318
|
}
|
|
1277
|
-
|
|
1278
|
-
const o = new xt({
|
|
1319
|
+
const i = new Et({
|
|
1279
1320
|
verbosity: e.verbosity || "normal"
|
|
1280
1321
|
});
|
|
1281
|
-
e.command === "server" && (
|
|
1322
|
+
e.command === "server" && (i.printBanner(), i.printConfig({
|
|
1282
1323
|
phpVersion: e.php || F,
|
|
1283
1324
|
wpVersion: e.wp || "latest",
|
|
1284
1325
|
port: e.port || 9400,
|
|
@@ -1292,80 +1333,80 @@ async function Et(e) {
|
|
|
1292
1333
|
],
|
|
1293
1334
|
blueprint: typeof e.blueprint == "string" ? e.blueprint : void 0
|
|
1294
1335
|
}));
|
|
1295
|
-
const
|
|
1336
|
+
const s = e.command === "server" ? e.port ?? 9400 : 0, n = N.platform() === "win32" ? (
|
|
1296
1337
|
// @TODO: Enable fs-ext here when it works with Windows.
|
|
1297
1338
|
void 0
|
|
1298
1339
|
) : await import("fs-ext").then((w) => w.flockSync).catch(() => {
|
|
1299
|
-
|
|
1340
|
+
g.debug(
|
|
1300
1341
|
"The fs-ext package is not installed. Internal file locking will not be integrated with host OS file locking."
|
|
1301
1342
|
);
|
|
1302
|
-
}), l = new
|
|
1303
|
-
let
|
|
1304
|
-
const
|
|
1305
|
-
port:
|
|
1343
|
+
}), l = new Ae(n);
|
|
1344
|
+
let d = !1, v = !0;
|
|
1345
|
+
const S = await ut({
|
|
1346
|
+
port: s,
|
|
1306
1347
|
onBind: async (w, a) => {
|
|
1307
|
-
const
|
|
1348
|
+
const y = "127.0.0.1", h = `http://${y}:${a}`, I = e["site-url"] || h, $ = e.command === "server" ? e.experimentalMultiWorker ?? 1 : 1, A = e.command === "server" ? (
|
|
1308
1349
|
// Account for the initial worker which is discarded by the server after setup.
|
|
1309
|
-
|
|
1310
|
-
) :
|
|
1311
|
-
|
|
1312
|
-
), K = "-playground-cli-site-",
|
|
1313
|
-
|
|
1314
|
-
const
|
|
1350
|
+
$ + 1
|
|
1351
|
+
) : $, C = 2 ** 31 - 1, L = Math.floor(
|
|
1352
|
+
C / A
|
|
1353
|
+
), K = "-playground-cli-site-", E = await vt(K);
|
|
1354
|
+
g.debug(`Native temp dir for VFS root: ${E.path}`);
|
|
1355
|
+
const R = "WP Playground CLI - Listen for Xdebug", ee = ".playground-xdebug-root", te = u.join(process.cwd(), ee);
|
|
1315
1356
|
if (await Ge(te), e.xdebug && e.experimentalUnsafeIdeIntegration) {
|
|
1316
|
-
await
|
|
1317
|
-
|
|
1357
|
+
await Xe(
|
|
1358
|
+
E.path,
|
|
1318
1359
|
te,
|
|
1319
1360
|
process.platform
|
|
1320
1361
|
);
|
|
1321
|
-
const
|
|
1322
|
-
hostPath:
|
|
1362
|
+
const p = {
|
|
1363
|
+
hostPath: u.join(".", u.sep, ee),
|
|
1323
1364
|
vfsPath: "/"
|
|
1324
1365
|
};
|
|
1325
1366
|
try {
|
|
1326
|
-
await
|
|
1327
|
-
const f = typeof e.xdebug == "object" ? e.xdebug : void 0,
|
|
1328
|
-
name:
|
|
1329
|
-
host:
|
|
1367
|
+
await Ze(R, process.cwd());
|
|
1368
|
+
const f = typeof e.xdebug == "object" ? e.xdebug : void 0, x = await Je({
|
|
1369
|
+
name: R,
|
|
1370
|
+
host: y,
|
|
1330
1371
|
port: a,
|
|
1331
1372
|
ides: e.experimentalUnsafeIdeIntegration,
|
|
1332
1373
|
cwd: process.cwd(),
|
|
1333
1374
|
mounts: [
|
|
1334
|
-
|
|
1375
|
+
p,
|
|
1335
1376
|
...e["mount-before-install"] || [],
|
|
1336
1377
|
...e.mount || []
|
|
1337
1378
|
],
|
|
1338
1379
|
ideKey: f?.ideKey
|
|
1339
|
-
}),
|
|
1340
|
-
console.log(""),
|
|
1341
|
-
|
|
1380
|
+
}), c = e.experimentalUnsafeIdeIntegration, b = c.includes("vscode"), P = c.includes("phpstorm"), M = Object.values(x);
|
|
1381
|
+
console.log(""), M.length > 0 ? (console.log(B("Xdebug configured successfully")), console.log(
|
|
1382
|
+
pe("Updated IDE config: ") + M.join(" ")
|
|
1342
1383
|
), console.log(
|
|
1343
|
-
|
|
1344
|
-
|
|
1384
|
+
pe("Playground source root: ") + ".playground-xdebug-root" + Y(
|
|
1385
|
+
Bt(
|
|
1345
1386
|
" – you can set breakpoints and preview Playground's VFS structure in there."
|
|
1346
1387
|
)
|
|
1347
1388
|
)
|
|
1348
|
-
)) : (console.log(
|
|
1389
|
+
)) : (console.log(B("Xdebug configuration failed.")), console.log(
|
|
1349
1390
|
"No IDE-specific project settings directory was found in the current working directory."
|
|
1350
|
-
)), console.log(""), b &&
|
|
1391
|
+
)), console.log(""), b && x.vscode && (console.log(B("VS Code / Cursor instructions:")), console.log(
|
|
1351
1392
|
" 1. Ensure you have installed an IDE extension for PHP Debugging"
|
|
1352
1393
|
), console.log(
|
|
1353
|
-
` (The ${
|
|
1394
|
+
` (The ${B("PHP Debug")} extension by ${B(
|
|
1354
1395
|
"Xdebug"
|
|
1355
1396
|
)} has been a solid option)`
|
|
1356
1397
|
), console.log(
|
|
1357
1398
|
" 2. Open the Run and Debug panel on the left sidebar"
|
|
1358
1399
|
), console.log(
|
|
1359
1400
|
` 3. Select "${Y(
|
|
1360
|
-
|
|
1401
|
+
R
|
|
1361
1402
|
)}" from the dropdown`
|
|
1362
1403
|
), console.log(' 3. Click "start debugging"'), console.log(
|
|
1363
1404
|
" 5. Set a breakpoint. For example, in .playground-xdebug-root/wordpress/index.php"
|
|
1364
1405
|
), console.log(
|
|
1365
1406
|
" 6. Visit Playground in your browser to hit the breakpoint"
|
|
1366
|
-
),
|
|
1407
|
+
), P && console.log("")), P && x.phpstorm && (console.log(B("PhpStorm instructions:")), console.log(
|
|
1367
1408
|
` 1. Choose "${Y(
|
|
1368
|
-
|
|
1409
|
+
R
|
|
1369
1410
|
)}" debug configuration in the toolbar`
|
|
1370
1411
|
), console.log(" 2. Click the debug button (bug icon)`"), console.log(
|
|
1371
1412
|
" 3. Set a breakpoint. For example, in .playground-xdebug-root/wordpress/index.php"
|
|
@@ -1378,16 +1419,17 @@ async function Et(e) {
|
|
|
1378
1419
|
});
|
|
1379
1420
|
}
|
|
1380
1421
|
}
|
|
1381
|
-
const
|
|
1382
|
-
|
|
1422
|
+
const ge = u.dirname(E.path), be = 2 * 24 * 60 * 60 * 1e3;
|
|
1423
|
+
St(
|
|
1383
1424
|
K,
|
|
1384
|
-
|
|
1385
|
-
|
|
1425
|
+
be,
|
|
1426
|
+
ge
|
|
1386
1427
|
);
|
|
1387
|
-
const
|
|
1388
|
-
|
|
1389
|
-
const
|
|
1428
|
+
const O = u.join(E.path, "internal");
|
|
1429
|
+
Q(O);
|
|
1430
|
+
const Pe = [
|
|
1390
1431
|
"wordpress",
|
|
1432
|
+
"tools",
|
|
1391
1433
|
// Note: These dirs are from Emscripten's "default dirs" list:
|
|
1392
1434
|
// https://github.com/emscripten-core/emscripten/blob/f431ec220e472e1f8d3db6b52fe23fb377facf30/src/lib/libfs.js#L1400-L1402
|
|
1393
1435
|
//
|
|
@@ -1397,127 +1439,145 @@ async function Et(e) {
|
|
|
1397
1439
|
"tmp",
|
|
1398
1440
|
"home"
|
|
1399
1441
|
];
|
|
1400
|
-
for (const
|
|
1401
|
-
const f = (
|
|
1442
|
+
for (const p of Pe) {
|
|
1443
|
+
const f = (c) => c.vfsPath === `/${p}`;
|
|
1402
1444
|
if (!(e["mount-before-install"]?.some(f) || e.mount?.some(f))) {
|
|
1403
|
-
const
|
|
1404
|
-
|
|
1405
|
-
|
|
1445
|
+
const c = u.join(
|
|
1446
|
+
E.path,
|
|
1447
|
+
p
|
|
1406
1448
|
);
|
|
1407
|
-
|
|
1408
|
-
vfsPath: `/${
|
|
1409
|
-
hostPath:
|
|
1449
|
+
Q(c), e["mount-before-install"] === void 0 && (e["mount-before-install"] = []), e["mount-before-install"].unshift({
|
|
1450
|
+
vfsPath: `/${p}`,
|
|
1451
|
+
hostPath: c
|
|
1410
1452
|
});
|
|
1411
1453
|
}
|
|
1412
1454
|
}
|
|
1413
1455
|
if (e["mount-before-install"])
|
|
1414
|
-
for (const
|
|
1415
|
-
|
|
1416
|
-
`Mount before WP install: ${
|
|
1456
|
+
for (const p of e["mount-before-install"])
|
|
1457
|
+
g.debug(
|
|
1458
|
+
`Mount before WP install: ${p.vfsPath} -> ${p.hostPath}`
|
|
1417
1459
|
);
|
|
1418
1460
|
if (e.mount)
|
|
1419
|
-
for (const
|
|
1420
|
-
|
|
1421
|
-
`Mount after WP install: ${
|
|
1461
|
+
for (const p of e.mount)
|
|
1462
|
+
g.debug(
|
|
1463
|
+
`Mount after WP install: ${p.vfsPath} -> ${p.hostPath}`
|
|
1422
1464
|
);
|
|
1423
|
-
let
|
|
1424
|
-
e["experimental-blueprints-v2-runner"] ?
|
|
1425
|
-
siteUrl:
|
|
1426
|
-
processIdSpaceLength:
|
|
1427
|
-
cliOutput:
|
|
1428
|
-
}) : (
|
|
1429
|
-
siteUrl:
|
|
1430
|
-
processIdSpaceLength:
|
|
1431
|
-
cliOutput:
|
|
1432
|
-
}), typeof e.blueprint == "string" && (e.blueprint = await
|
|
1465
|
+
let T;
|
|
1466
|
+
e["experimental-blueprints-v2-runner"] ? T = new wt(e, {
|
|
1467
|
+
siteUrl: I,
|
|
1468
|
+
processIdSpaceLength: L,
|
|
1469
|
+
cliOutput: i
|
|
1470
|
+
}) : (T = new Pt(e, {
|
|
1471
|
+
siteUrl: I,
|
|
1472
|
+
processIdSpaceLength: L,
|
|
1473
|
+
cliOutput: i
|
|
1474
|
+
}), typeof e.blueprint == "string" && (e.blueprint = await ft({
|
|
1433
1475
|
sourceString: e.blueprint,
|
|
1434
1476
|
blueprintMayReadAdjacentFiles: e["blueprint-may-read-adjacent-files"] === !0
|
|
1435
1477
|
})));
|
|
1436
1478
|
let H = !1;
|
|
1437
|
-
const
|
|
1479
|
+
const W = async function() {
|
|
1438
1480
|
H || (H = !0, await Promise.all(
|
|
1439
|
-
[...
|
|
1440
|
-
async ([f,
|
|
1441
|
-
await
|
|
1481
|
+
[...o].map(
|
|
1482
|
+
async ([f, x]) => {
|
|
1483
|
+
await x.dispose(), await f.terminate();
|
|
1442
1484
|
}
|
|
1443
1485
|
)
|
|
1444
|
-
), w && await new Promise((f) => w.close(f)), await
|
|
1445
|
-
},
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
({ exitCode:
|
|
1449
|
-
H ||
|
|
1450
|
-
`Worker ${f} exited with code ${
|
|
1486
|
+
), w && await new Promise((f) => w.close(f)), await E.cleanup());
|
|
1487
|
+
}, ve = Ct(
|
|
1488
|
+
A,
|
|
1489
|
+
T.getWorkerType(),
|
|
1490
|
+
({ exitCode: p, workerIndex: f }) => {
|
|
1491
|
+
H || p === 0 && g.error(
|
|
1492
|
+
`Worker ${f} exited with code ${p}
|
|
1451
1493
|
`
|
|
1452
1494
|
);
|
|
1453
1495
|
}
|
|
1454
1496
|
);
|
|
1455
|
-
|
|
1497
|
+
i.startProgress("Starting...");
|
|
1456
1498
|
try {
|
|
1457
|
-
const
|
|
1499
|
+
const p = await ve, f = await ce(l);
|
|
1458
1500
|
{
|
|
1459
|
-
const
|
|
1460
|
-
|
|
1501
|
+
const c = p.shift(), b = await T.bootAndSetUpInitialPlayground(
|
|
1502
|
+
c.phpPort,
|
|
1461
1503
|
f,
|
|
1462
|
-
|
|
1504
|
+
O
|
|
1463
1505
|
);
|
|
1464
|
-
if (
|
|
1465
|
-
|
|
1506
|
+
if (o.set(
|
|
1507
|
+
c.worker,
|
|
1466
1508
|
b
|
|
1467
|
-
), await b.isReady(),
|
|
1468
|
-
const
|
|
1509
|
+
), await b.isReady(), d = !0, t = new mt(b), !e["experimental-blueprints-v2-runner"]) {
|
|
1510
|
+
const P = await T.compileInputBlueprint(
|
|
1469
1511
|
e["additional-blueprint-steps"] || []
|
|
1470
1512
|
);
|
|
1471
|
-
|
|
1472
|
-
|
|
1513
|
+
P && await se(
|
|
1514
|
+
P,
|
|
1515
|
+
b
|
|
1516
|
+
);
|
|
1517
|
+
}
|
|
1518
|
+
if (e.phpmyadmin && !await b.fileExists(
|
|
1519
|
+
`${ae}/index.php`
|
|
1520
|
+
)) {
|
|
1521
|
+
const P = await et(), M = await me({ steps: P });
|
|
1522
|
+
await se(
|
|
1523
|
+
M,
|
|
1473
1524
|
b
|
|
1474
1525
|
);
|
|
1475
1526
|
}
|
|
1476
1527
|
if (e.command === "build-snapshot") {
|
|
1477
|
-
await
|
|
1528
|
+
await Dt(r, e.outfile), i.printStatus(`Exported to ${e.outfile}`), await W();
|
|
1478
1529
|
return;
|
|
1479
1530
|
} else if (e.command === "run-blueprint") {
|
|
1480
|
-
|
|
1531
|
+
i.finishProgress("Done"), await W();
|
|
1481
1532
|
return;
|
|
1482
1533
|
}
|
|
1483
|
-
await t.removeWorker(b), await b.dispose(), await
|
|
1534
|
+
await t.removeWorker(b), await b.dispose(), await c.worker.terminate(), o.delete(c.worker);
|
|
1484
1535
|
}
|
|
1485
|
-
const
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
const
|
|
1489
|
-
worker:
|
|
1490
|
-
fileLockManagerPort:
|
|
1491
|
-
firstProcessId:
|
|
1492
|
-
nativeInternalDirPath:
|
|
1536
|
+
const x = L;
|
|
1537
|
+
if ([r] = await Promise.all(
|
|
1538
|
+
p.map(async (c, b) => {
|
|
1539
|
+
const P = x + b * L, M = await ce(l), V = await T.bootPlayground({
|
|
1540
|
+
worker: c,
|
|
1541
|
+
fileLockManagerPort: M,
|
|
1542
|
+
firstProcessId: P,
|
|
1543
|
+
nativeInternalDirPath: O
|
|
1493
1544
|
});
|
|
1494
|
-
return
|
|
1495
|
-
|
|
1545
|
+
return o.set(
|
|
1546
|
+
c.worker,
|
|
1496
1547
|
V
|
|
1497
1548
|
), t.addWorker(V), V;
|
|
1498
1549
|
})
|
|
1499
|
-
),
|
|
1550
|
+
), i.finishProgress(), i.printReady(h, $), e.phpmyadmin) {
|
|
1551
|
+
const c = u.join(
|
|
1552
|
+
e.phpmyadmin,
|
|
1553
|
+
tt
|
|
1554
|
+
);
|
|
1555
|
+
i.printPhpMyAdminUrl(
|
|
1556
|
+
new URL(c, h).toString()
|
|
1557
|
+
);
|
|
1558
|
+
}
|
|
1559
|
+
return e.xdebug && e.experimentalDevtools && (await je({
|
|
1500
1560
|
phpInstance: r,
|
|
1501
1561
|
phpRoot: "/wordpress"
|
|
1502
1562
|
})).start(), {
|
|
1503
1563
|
playground: r,
|
|
1504
1564
|
server: w,
|
|
1505
1565
|
serverUrl: h,
|
|
1506
|
-
[Symbol.asyncDispose]:
|
|
1507
|
-
[
|
|
1508
|
-
workerThreadCount:
|
|
1509
|
-
getWorkerNumberFromProcessId: (
|
|
1566
|
+
[Symbol.asyncDispose]: W,
|
|
1567
|
+
[Tt]: {
|
|
1568
|
+
workerThreadCount: $,
|
|
1569
|
+
getWorkerNumberFromProcessId: (c) => Math.floor(c / L)
|
|
1510
1570
|
}
|
|
1511
1571
|
};
|
|
1512
|
-
} catch (
|
|
1572
|
+
} catch (p) {
|
|
1513
1573
|
if (e.verbosity !== "debug")
|
|
1514
|
-
throw
|
|
1574
|
+
throw p;
|
|
1515
1575
|
let f = "";
|
|
1516
|
-
throw await r?.fileExists(re) && (f = await r.readFileAsText(re)), await
|
|
1576
|
+
throw await r?.fileExists(re) && (f = await r.readFileAsText(re)), await W(), new Error(f, { cause: p });
|
|
1517
1577
|
}
|
|
1518
1578
|
},
|
|
1519
1579
|
async handleRequest(w) {
|
|
1520
|
-
if (!
|
|
1580
|
+
if (!d)
|
|
1521
1581
|
return z.forHttpCode(
|
|
1522
1582
|
502,
|
|
1523
1583
|
"WordPress is not ready yet"
|
|
@@ -1538,18 +1598,18 @@ async function Et(e) {
|
|
|
1538
1598
|
return await t.handleRequest(w);
|
|
1539
1599
|
}
|
|
1540
1600
|
});
|
|
1541
|
-
return
|
|
1601
|
+
return S && e.command === "start" && !e.skipBrowser && Wt(S.serverUrl), S;
|
|
1542
1602
|
}
|
|
1543
|
-
function
|
|
1603
|
+
function At(e) {
|
|
1544
1604
|
let t = { ...e, command: "server" };
|
|
1545
|
-
e.noAutoMount || (t.autoMount =
|
|
1546
|
-
const r =
|
|
1605
|
+
e.noAutoMount || (t.autoMount = u.resolve(process.cwd(), t.path ?? ""), t = fe(t), delete t.autoMount);
|
|
1606
|
+
const r = ue(
|
|
1547
1607
|
t["mount-before-install"] || [],
|
|
1548
1608
|
"/wordpress"
|
|
1549
|
-
) ||
|
|
1609
|
+
) || ue(t.mount || [], "/wordpress");
|
|
1550
1610
|
if (r)
|
|
1551
1611
|
console.log("Site files stored at:", r?.hostPath), e.reset && (console.log(""), console.log(
|
|
1552
|
-
|
|
1612
|
+
Mt(
|
|
1553
1613
|
"This site is not managed by Playground CLI and cannot be reset."
|
|
1554
1614
|
)
|
|
1555
1615
|
), console.log(
|
|
@@ -1558,15 +1618,15 @@ function Tt(e) {
|
|
|
1558
1618
|
"You may still remove the site's directory manually if you wish."
|
|
1559
1619
|
), process.exit(1));
|
|
1560
1620
|
else {
|
|
1561
|
-
const
|
|
1562
|
-
|
|
1621
|
+
const o = t.autoMount || process.cwd(), i = Ke("sha256").update(o).digest("hex"), s = N.homedir(), n = u.join(
|
|
1622
|
+
s,
|
|
1563
1623
|
".wordpress-playground/sites",
|
|
1564
|
-
|
|
1624
|
+
i
|
|
1565
1625
|
);
|
|
1566
|
-
console.log("Site files stored at:", n), Z(n) && e.reset && (console.log("Resetting site..."), Te(n, { recursive: !0 })),
|
|
1626
|
+
console.log("Site files stored at:", n), Z(n) && e.reset && (console.log("Resetting site..."), Te(n, { recursive: !0 })), Q(n, { recursive: !0 }), t["mount-before-install"] = [
|
|
1567
1627
|
...t["mount-before-install"] || [],
|
|
1568
1628
|
{ vfsPath: "/wordpress", hostPath: n }
|
|
1569
|
-
], t.wordpressInstallMode =
|
|
1629
|
+
], t.wordpressInstallMode = Me(n).length === 0 ? (
|
|
1570
1630
|
// Only download WordPress on the first run when the site directory is still
|
|
1571
1631
|
// empty.
|
|
1572
1632
|
"download-and-install"
|
|
@@ -1577,44 +1637,44 @@ function Tt(e) {
|
|
|
1577
1637
|
}
|
|
1578
1638
|
return t;
|
|
1579
1639
|
}
|
|
1580
|
-
async function
|
|
1581
|
-
const
|
|
1582
|
-
for (let
|
|
1583
|
-
const n =
|
|
1640
|
+
async function Ct(e, t, r) {
|
|
1641
|
+
const o = [];
|
|
1642
|
+
for (let i = 0; i < e; i++) {
|
|
1643
|
+
const n = Rt(t, { onExit: (l) => {
|
|
1584
1644
|
r({
|
|
1585
1645
|
exitCode: l,
|
|
1586
|
-
workerIndex:
|
|
1646
|
+
workerIndex: i
|
|
1587
1647
|
});
|
|
1588
1648
|
} });
|
|
1589
|
-
|
|
1649
|
+
o.push(n);
|
|
1590
1650
|
}
|
|
1591
|
-
return Promise.all(
|
|
1651
|
+
return Promise.all(o);
|
|
1592
1652
|
}
|
|
1593
|
-
function
|
|
1653
|
+
function Rt(e, { onExit: t } = {}) {
|
|
1594
1654
|
let r;
|
|
1595
|
-
return e === "v1" ? r = new
|
|
1655
|
+
return e === "v1" ? r = new ne(new URL("./worker-thread-v1.js", import.meta.url)) : r = new ne(new URL("./worker-thread-v2.js", import.meta.url)), new Promise((o, i) => {
|
|
1596
1656
|
r.once("message", function(n) {
|
|
1597
|
-
n.command === "worker-script-initialized" &&
|
|
1657
|
+
n.command === "worker-script-initialized" && o({ worker: r, phpPort: n.phpPort });
|
|
1598
1658
|
}), r.once("error", function(n) {
|
|
1599
1659
|
console.error(n);
|
|
1600
1660
|
const l = new Error(
|
|
1601
1661
|
`Worker failed to load worker. ${n.message ? `Original error: ${n.message}` : ""}`
|
|
1602
1662
|
);
|
|
1603
|
-
|
|
1663
|
+
i(l);
|
|
1604
1664
|
});
|
|
1605
|
-
let
|
|
1665
|
+
let s = !1;
|
|
1606
1666
|
r.once("spawn", () => {
|
|
1607
|
-
|
|
1667
|
+
s = !0;
|
|
1608
1668
|
}), r.once("exit", (n) => {
|
|
1609
|
-
|
|
1669
|
+
s || i(new Error(`Worker exited before spawning: ${n}`)), t?.(n);
|
|
1610
1670
|
});
|
|
1611
1671
|
});
|
|
1612
1672
|
}
|
|
1613
|
-
async function
|
|
1614
|
-
const { port1: t, port2: r } = new
|
|
1615
|
-
return await
|
|
1673
|
+
async function ce(e) {
|
|
1674
|
+
const { port1: t, port2: r } = new Be();
|
|
1675
|
+
return await G() ? xe(e, null, t) : await ke(e, t), r;
|
|
1616
1676
|
}
|
|
1617
|
-
function
|
|
1677
|
+
function Wt(e) {
|
|
1618
1678
|
const t = N.platform();
|
|
1619
1679
|
let r;
|
|
1620
1680
|
switch (t) {
|
|
@@ -1628,11 +1688,11 @@ function Ct(e) {
|
|
|
1628
1688
|
r = `xdg-open "${e}"`;
|
|
1629
1689
|
break;
|
|
1630
1690
|
}
|
|
1631
|
-
|
|
1632
|
-
|
|
1691
|
+
qe(r, (o) => {
|
|
1692
|
+
o && g.debug(`Could not open browser: ${o.message}`);
|
|
1633
1693
|
});
|
|
1634
1694
|
}
|
|
1635
|
-
async function
|
|
1695
|
+
async function Dt(e, t) {
|
|
1636
1696
|
await e.run({
|
|
1637
1697
|
code: `<?php
|
|
1638
1698
|
$zip = new ZipArchive();
|
|
@@ -1654,16 +1714,16 @@ async function Lt(e, t) {
|
|
|
1654
1714
|
`
|
|
1655
1715
|
});
|
|
1656
1716
|
const r = await e.readFileAsBuffer("/tmp/build.zip");
|
|
1657
|
-
|
|
1717
|
+
m.writeFileSync(t, r);
|
|
1658
1718
|
}
|
|
1659
1719
|
export {
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1720
|
+
ye as L,
|
|
1721
|
+
lr as a,
|
|
1722
|
+
$t as b,
|
|
1723
|
+
Tt as i,
|
|
1724
|
+
_ as m,
|
|
1725
|
+
dr as p,
|
|
1726
|
+
Lt as r,
|
|
1727
|
+
Rt as s
|
|
1668
1728
|
};
|
|
1669
|
-
//# sourceMappingURL=run-cli-
|
|
1729
|
+
//# sourceMappingURL=run-cli-Cxpf7CoX.js.map
|