@wp-playground/cli 3.0.46 → 3.0.52

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.
@@ -1,64 +1,66 @@
1
- import { logger as y, LogSeverity as j, errorLogPath as re } from "@php-wasm/logger";
2
- import { PHPResponse as z, consumeAPI as U, SupportedPHPVersions as oe, printDebugDetails as ve, exposeAPI as Pe, exposeSyncAPI as Se } from "@php-wasm/universal";
3
- import { resolveRemoteBlueprint as xe, resolveRuntimeConfiguration as se, compileBlueprintV1 as ke, isBlueprintBundle as Ie, runBlueprintV1Steps as $e } from "@wp-playground/blueprints";
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 c, { existsSync as Z, rmdirSync as Te, mkdirSync as G, readdirSync as Be } from "fs";
6
- import { MessageChannel as Me, Worker as ie } from "worker_threads";
7
- import { createNodeFsMountHandler as Ce, FileLockManagerForNode as Le } from "@php-wasm/node";
8
- import p, { basename as A, join as ce } from "path";
9
- import We from "express";
10
- import N, { cpus as De } from "os";
11
- import { jspi as Q } from "wasm-feature-detect";
12
- import Re from "yargs";
13
- import { NodeJsFilesystem as Ae, OverlayFilesystem as Ue, InMemoryFilesystem as Fe, ZipFilesystem as Oe } from "@wp-playground/storage";
14
- import { EmscriptenDownloadMonitor as Ne, ProgressTracker as _e } from "@php-wasm/progress";
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 B from "fs-extra";
17
- import { startBridge as Ve } from "@php-wasm/xdebug-bridge";
18
- import { exec as je } from "child_process";
19
- import { dir as qe, setGracefulCleanup as Ye } from "tmp-promise";
20
- import ze from "ps-man";
21
- import { removeTempDirSymlink as Ge, createTempDirSymlink as Qe, clearXdebugIDEConfig as Xe, addXdebugIDEConfig as Ze } from "@php-wasm/cli-util";
22
- import { createHash as Je } from "crypto";
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 s = r.split(":");
27
- if (s.length !== 2)
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 [o, i] = s;
33
- if (!Z(o))
34
- throw new Error(`Host path does not exist: ${o}`);
35
- t.push({ hostPath: o, vfsPath: i });
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 ne(e) {
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 s = e[r], o = e[r + 1];
45
- if (!Z(s))
46
- throw new Error(`Host path does not exist: ${s}`);
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: p.resolve(process.cwd(), s),
49
- vfsPath: o
50
+ hostPath: u.resolve(process.cwd(), o),
51
+ vfsPath: i
50
52
  });
51
53
  }
52
54
  return t;
53
55
  }
54
- async function rr(e, t) {
56
+ async function lr(e, t) {
55
57
  for (const r of t)
56
58
  await e.mount(
57
59
  r.vfsPath,
58
- Ce(r.hostPath)
60
+ Le(r.hostPath)
59
61
  );
60
62
  }
61
- const ae = {
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 pe(e) {
81
- const t = e.autoMount, r = [...e.mount || []], s = [...e["mount-before-install"] || []], o = {
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": s,
86
+ "mount-before-install": o,
85
87
  "additional-blueprint-steps": [
86
88
  ...e["additional-blueprint-steps"] || []
87
89
  ]
88
90
  };
89
- if (rt(t)) {
90
- const n = `/wordpress/wp-content/plugins/${A(t)}`;
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
- }), o["additional-blueprint-steps"].push({
97
+ }), i["additional-blueprint-steps"].push({
96
98
  step: "activatePlugin",
97
- pluginPath: `/wordpress/wp-content/plugins/${A(t)}`
99
+ pluginPath: `/wordpress/wp-content/plugins/${D(t)}`
98
100
  });
99
- } else if (tt(t)) {
100
- const i = A(t), n = `/wordpress/wp-content/themes/${i}`;
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
- }), o["additional-blueprint-steps"].push(
107
+ }), i["additional-blueprint-steps"].push(
106
108
  e["experimental-blueprints-v2-runner"] ? {
107
109
  step: "activateTheme",
108
- themeDirectoryName: i
110
+ themeDirectoryName: s
109
111
  } : {
110
112
  step: "activateTheme",
111
- themeFolderName: i
113
+ themeFolderName: s
112
114
  }
113
115
  );
114
- } else if (et(t)) {
115
- const i = c.readdirSync(t);
116
- for (const n of i)
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
- o["additional-blueprint-steps"].push(ae);
123
- } else Ke(t) && (s.push({
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
- }), o.mode = "apply-to-existing-site", o["additional-blueprint-steps"].push(ae), o.wordpressInstallMode || (o.wordpressInstallMode = "install-from-existing-files-if-needed"));
128
- return o;
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 Ke(e) {
131
- const t = c.readdirSync(e);
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 et(e) {
135
- const t = c.readdirSync(e);
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 tt(e) {
139
- if (!c.readdirSync(e).includes("style.css"))
140
+ function it(e) {
141
+ if (!m.readdirSync(e).includes("style.css"))
140
142
  return !1;
141
- const r = c.readFileSync(ce(e, "style.css"), "utf8");
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 rt(e) {
145
- const t = c.readdirSync(e), r = /^(?:[ \t]*<\?php)?[ \t/*#@]*Plugin Name:(.*)$/im;
146
- return !!t.filter((o) => o.endsWith(".php")).find((o) => {
147
- const i = c.readFileSync(ce(e, o), "utf8");
148
- return !!r.exec(i);
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 ot(e) {
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 s = e[r], o = e[r + 1];
159
- if (!s || !s.trim())
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[s.trim()] = o;
163
+ t[o.trim()] = i;
162
164
  }
163
165
  return t;
164
166
  }
165
- function st(e) {
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 s = e[r], o = e[r + 1].trim().toLowerCase();
173
- if (!s || !s.trim())
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 (o === "true" || o === "1")
176
- t[s.trim()] = !0;
177
- else if (o === "false" || o === "0")
178
- t[s.trim()] = !1;
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 "${s}": "${o}". Must be "true", "false", "1", or "0".`
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 it(e) {
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 s = e[r], o = e[r + 1].trim();
194
- if (!s || !s.trim())
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 i = Number(o);
197
- if (isNaN(i))
198
+ const s = Number(i);
199
+ if (isNaN(s))
198
200
  throw new Error(
199
- `Invalid number value for constant "${s}": "${o}". Must be a valid number.`
201
+ `Invalid number value for constant "${o}": "${i}". Must be a valid number.`
200
202
  );
201
- t[s.trim()] = i;
203
+ t[o.trim()] = s;
202
204
  }
203
205
  return t;
204
206
  }
205
- function nt(e = {}, t = {}, r = {}) {
206
- const s = {}, o = /* @__PURE__ */ new Set(), i = (n, l) => {
207
- for (const u in n) {
208
- if (o.has(u))
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 "${u}" is defined multiple times across different --define-${l} flags`
212
+ `Constant "${d}" is defined multiple times across different --define-${l} flags`
211
213
  );
212
- o.add(u), s[u] = n[u];
214
+ i.add(d), o[d] = n[d];
213
215
  }
214
216
  };
215
- return i(e, "string"), i(t, "bool"), i(r, "number"), s;
217
+ return s(e, "string"), s(t, "bool"), s(r, "number"), o;
216
218
  }
217
- function O(e) {
218
- return nt(
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 at(e) {
225
- const t = We(), r = await new Promise((i, n) => {
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 u = l.address();
228
- u === null || typeof u == "string" ? n(new Error("Server address is not available")) : i(l);
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 (i, n) => {
233
+ t.use("/", async (s, n) => {
232
234
  let l;
233
235
  try {
234
236
  l = await e.handleRequest({
235
- url: i.url,
236
- headers: ut(i),
237
- method: i.method,
238
- body: await lt(i)
237
+ url: s.url,
238
+ headers: ct(s),
239
+ method: s.method,
240
+ body: await pt(s)
239
241
  });
240
- } catch (u) {
241
- y.error(u), l = z.forHttpCode(500);
242
+ } catch (d) {
243
+ g.error(d), l = z.forHttpCode(500);
242
244
  }
243
245
  n.statusCode = l.httpStatusCode;
244
- for (const u in l.headers)
245
- n.setHeader(u, l.headers[u]);
246
+ for (const d in l.headers)
247
+ n.setHeader(d, l.headers[d]);
246
248
  n.end(l.bytes);
247
249
  });
248
- const o = r.address().port;
249
- return await e.onBind(r, o);
250
+ const i = r.address().port;
251
+ return await e.onBind(r, i);
250
252
  }
251
- const lt = async (e) => await new Promise((t) => {
253
+ const pt = async (e) => await new Promise((t) => {
252
254
  const r = [];
253
- e.on("data", (s) => {
254
- r.push(s);
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
- }), ut = (e) => {
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 dt {
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
- (o) => o.worker === t
279
+ (i) => i.worker === t
278
280
  );
279
281
  if (r === -1)
280
282
  return;
281
- const [s] = this.workerLoads.splice(r, 1);
282
- await Promise.allSettled(s.activeRequests);
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 o = 1; o < this.workerLoads.length; o++) {
287
- const i = this.workerLoads[o];
288
- i.activeRequests.size < r.activeRequests.size && (r = i);
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 s = r.worker.request(t);
291
- return r.activeRequests.add(s), s.url = t.url, s.finally(() => {
292
- r.activeRequests.delete(s);
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 ct(e) {
298
+ function ht(e) {
297
299
  return /^latest$|^trunk$|^nightly$|^(?:(\d+)\.(\d+)(?:\.(\d+))?)((?:-beta(?:\d+)?)|(?:-RC(?:\d+)?))?$/.test(e);
298
300
  }
299
- async function pt({
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 xe(e);
307
- let r = p.resolve(process.cwd(), e);
308
- if (!c.existsSync(r))
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 s = c.statSync(r);
311
- if (s.isDirectory() && (r = p.join(r, "blueprint.json")), !s.isFile() && s.isSymbolicLink())
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 o = p.extname(r);
316
- switch (o) {
317
+ const i = u.extname(r);
318
+ switch (i) {
317
319
  case ".zip":
318
- return Oe.fromArrayBuffer(
319
- c.readFileSync(r).buffer
320
+ return _e.fromArrayBuffer(
321
+ m.readFileSync(r).buffer
320
322
  );
321
323
  case ".json": {
322
- const i = c.readFileSync(r, "utf-8");
324
+ const s = m.readFileSync(r, "utf-8");
323
325
  try {
324
- JSON.parse(i);
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 = p.dirname(r), l = new Ae(n);
332
+ const n = u.dirname(r), l = new De(n);
331
333
  return new Ue([
332
334
  new Fe({
333
- "blueprint.json": i
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(u) {
342
+ read(d) {
341
343
  if (!t)
342
344
  throw new Error(
343
- `Error: Blueprint contained tried to read a local file at path "${u}" (via a resource of type "bundled"). Playground restricts access to local resources by default as a security measure.
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(u);
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: ${o}. Only .zip and .json files are supported.`
356
+ `Unsupported blueprint file extension: ${i}. Only .zip and .json files are supported.`
355
357
  );
356
358
  }
357
359
  }
358
- class mt {
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, s) {
366
- const o = U(t);
367
- await o.useFileLockManager(r);
368
- const i = {
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: s,
387
+ nativeInternalDirPath: o,
386
388
  mountsBeforeWpInstall: this.args["mount-before-install"] || [],
387
389
  mountsAfterWpInstall: this.args.mount || [],
388
- constants: O(this.args)
390
+ constants: _(this.args)
389
391
  };
390
- return await o.bootAndSetUpInitialWorker(i), o;
392
+ return await i.bootAndSetUpInitialWorker(s), i;
391
393
  }
392
394
  async bootPlayground({
393
395
  worker: t,
394
396
  fileLockManagerPort: r,
395
- firstProcessId: s,
396
- nativeInternalDirPath: o
397
+ firstProcessId: o,
398
+ nativeInternalDirPath: i
397
399
  }) {
398
- const i = U(t.phpPort);
399
- await i.useFileLockManager(r);
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: s,
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: o,
413
+ nativeInternalDirPath: i,
412
414
  mountsBeforeWpInstall: this.args["mount-before-install"] || [],
413
415
  mountsAfterWpInstall: this.args.mount || [],
414
- constants: O(this.args)
416
+ constants: _(this.args)
415
417
  };
416
- return await i.bootWorker(n), i;
418
+ return await s.bootWorker(n), s;
417
419
  }
418
420
  }
419
- const X = p.join(N.homedir(), ".wordpress-playground");
420
- async function ht(e) {
421
- return await me(
422
- "https://github.com/WordPress/sqlite-database-integration/archive/refs/heads/develop.zip",
423
- "sqlite.zip",
424
- e
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 me(e, t, r) {
428
- const s = p.join(X, t);
429
- return B.existsSync(s) || (B.ensureDirSync(X), await ft(e, s, r)), he(s);
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 ft(e, t, r) {
432
- const o = (await r.monitorFetch(fetch(e))).body.getReader(), i = `${t}.partial`, n = B.createWriteStream(i);
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: u } = await o.read();
435
- if (u && n.write(u), l)
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, u) => {
449
+ n.close(), n.closed || await new Promise((l, d) => {
439
450
  n.on("finish", () => {
440
- B.renameSync(i, t), l(null);
451
+ k.renameSync(s, t), l(null);
441
452
  }), n.on("error", (v) => {
442
- B.removeSync(i), u(v);
453
+ k.removeSync(s), d(v);
443
454
  });
444
455
  });
445
456
  }
446
- function he(e, t) {
447
- return new File([B.readFileSync(e)], A(e));
457
+ function we(e, t) {
458
+ return new File([k.readFileSync(e)], D(e));
448
459
  }
449
- class wt {
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, s) {
457
- let o, i, n;
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 k = !1;
461
- l.addEventListener("progress", (I) => {
462
- if (k)
471
+ let I = !1;
472
+ l.addEventListener("progress", ($) => {
473
+ if (I)
463
474
  return;
464
- const { loaded: C, total: J } = I.detail, L = Math.floor(
465
- Math.min(100, 100 * C / J)
475
+ const { loaded: A, total: J } = $.detail, C = Math.floor(
476
+ Math.min(100, 100 * A / J)
466
477
  );
467
- k = L === 100, this.cliOutput.updateProgress(
478
+ I = C === 100, this.cliOutput.updateProgress(
468
479
  "Downloading WordPress",
469
- L
480
+ C
470
481
  );
471
- }), o = await He(this.args.wp), n = p.join(
482
+ }), i = await He(this.args.wp), n = u.join(
472
483
  X,
473
- `prebuilt-wp-content-for-wp-${o.version}.zip`
474
- ), i = c.existsSync(n) ? he(n) : await me(
475
- o.releaseUrl,
476
- `${o.version}.zip`,
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
- ), y.debug(
479
- `Resolved WordPress release URL: ${o?.releaseUrl}`
489
+ ), g.debug(
490
+ `Resolved WordPress release URL: ${i?.releaseUrl}`
480
491
  );
481
492
  }
482
- let u;
483
- this.args.skipSqliteSetup ? (y.debug("Skipping SQLite integration plugin setup..."), u = void 0) : (this.cliOutput.updateProgress("Preparing SQLite database"), u = await ht(l));
484
- const v = this.args.followSymlinks === !0, P = this.args.experimentalTrace === !0, w = this.args["mount-before-install"] || [], a = this.args.mount || [], g = U(t);
485
- await g.isConnected(), this.cliOutput.updateProgress("Booting WordPress");
486
- const h = await se(
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 g.useFileLockManager(r), await g.bootAndSetUpInitialWorker({
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: i && await i.arrayBuffer(),
497
- sqliteIntegrationPluginZip: await u?.arrayBuffer(),
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: P,
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: s,
512
- constants: O(this.args)
513
- }), n && !this.args["mount-before-install"] && !c.existsSync(n) && (this.cliOutput.updateProgress("Caching WordPress for next boot"), c.writeFileSync(
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(g, "/wordpress")
516
- )), g;
527
+ await Ee(y, "/wordpress")
528
+ )), y;
517
529
  }
518
530
  async bootPlayground({
519
531
  worker: t,
520
532
  fileLockManagerPort: r,
521
- firstProcessId: s,
522
- nativeInternalDirPath: o
533
+ firstProcessId: o,
534
+ nativeInternalDirPath: i
523
535
  }) {
524
- const i = U(
536
+ const s = U(
525
537
  t.phpPort
526
538
  );
527
- await i.isConnected();
528
- const n = await se(
539
+ await s.isConnected();
540
+ const n = await ie(
529
541
  this.getEffectiveBlueprint()
530
542
  );
531
- return await i.useFileLockManager(r), await i.bootWorker({
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: s,
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: o,
548
- constants: O(this.args)
549
- }), await i.isReady(), i;
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(), s = new _e();
553
- let o = "", i = !1;
554
- return s.addEventListener("progress", (n) => {
555
- if (i)
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
- i = n.detail.progress === 100;
570
+ s = n.detail.progress === 100;
558
571
  const l = Math.floor(n.detail.progress);
559
- o = n.detail.caption || o || "Running Blueprint", this.cliOutput.updateProgress(o.trim(), l);
560
- }), await ke(r, {
561
- progress: s,
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 Ie(t) ? t : {
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 gt(e, t = !0) {
579
- const s = `${p.basename(process.argv0)}${e}${process.pid}-`, o = await qe({
580
- prefix: s,
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 && Ye(), o;
604
+ return t && ze(), i;
592
605
  }
593
- async function yt(e, t, r) {
594
- const o = (await bt(
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
- (i) => new Promise((n) => {
600
- c.rm(i, { recursive: !0 }, (l) => {
601
- l ? y.warn(
602
- `Failed to delete stale Playground temp dir: ${i}`,
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
- ) : y.info(
605
- `Deleted stale Playground temp dir: ${i}`
617
+ ) : g.info(
618
+ `Deleted stale Playground temp dir: ${s}`
606
619
  ), n();
607
620
  });
608
621
  })
609
622
  );
610
- await Promise.all(o);
623
+ await Promise.all(i);
611
624
  }
612
- async function bt(e, t, r) {
625
+ async function xt(e, t, r) {
613
626
  try {
614
- const s = c.readdirSync(r).map((i) => p.join(r, i)), o = [];
615
- for (const i of s)
616
- await vt(
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
- i
620
- ) && o.push(i);
621
- return o;
622
- } catch (s) {
623
- return y.warn(`Failed to find stale Playground temp dirs: ${s}`), [];
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 vt(e, t, r) {
627
- if (!c.lstatSync(r).isDirectory())
639
+ async function kt(e, t, r) {
640
+ if (!m.lstatSync(r).isDirectory())
628
641
  return !1;
629
- const o = p.basename(r);
630
- if (!o.includes(e))
642
+ const i = u.basename(r);
643
+ if (!i.includes(e))
631
644
  return !1;
632
- const i = o.match(
645
+ const s = i.match(
633
646
  new RegExp(`^(.+)${e}(\\d+)-`)
634
647
  );
635
- if (!i)
648
+ if (!s)
636
649
  return !1;
637
650
  const n = {
638
- executableName: i[1],
639
- pid: i[2]
651
+ executableName: s[1],
652
+ pid: s[2]
640
653
  };
641
- if (await Pt(n.pid, n.executableName))
654
+ if (await It(n.pid, n.executableName))
642
655
  return !1;
643
656
  const l = Date.now() - t;
644
- return c.statSync(r).mtime.getTime() < l;
657
+ return m.statSync(r).mtime.getTime() < l;
645
658
  }
646
- async function Pt(e, t) {
659
+ async function It(e, t) {
647
660
  const [r] = await new Promise(
648
- (s, o) => {
649
- ze.list(
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
- (i, n) => {
657
- i ? o(i) : s(n);
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 St(e) {
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 xt {
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 St(this.writeStream);
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 s = [];
733
- if (t.intl && s.push("intl"), t.redis && s.push("redis"), t.memcached && s.push("memcached"), t.xdebug && s.push(this.yellow("xdebug")), s.length > 0 && r.push(`${this.dim("Extensions")} ${s.join(", ")}`), t.mounts.length > 0)
734
- for (const o of t.mounts) {
735
- const i = o.autoMounted ? ` ${this.dim("(auto-mount)")}` : "";
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")} ${o.hostPath} ${this.dim("→")} ${o.vfsPath}${i}`
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 s = `${t}`;
765
- r !== void 0 && (s = `${t} ${this.dim(`${r}%`)}`), s !== this.lastProgressLine && (this.lastProgressLine = s, this.isTTY ? (this.writeStream.cursorTo(0), this.writeStream.write(s), this.writeStream.clearLine(1)) : this.writeStream.write(`${s}
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 s = r === 1 ? "worker" : "workers";
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} ${s})`)}
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 fe = {
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 or(e) {
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: ot
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: st
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: it
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: ne
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: ne
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(fe).map(
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 ?? De().length - 1
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
- }, s = {
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
- }, o = {
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
- }, i = Re(e).usage("Usage: wp-playground <command> [options]").command(
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(s)
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
- ...o
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, g, h) => {
1146
- if (g)
1147
- throw g;
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" && !ct(a.wp))
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 g = a["site-url"];
1160
- if (typeof g == "string" && g.trim() !== "")
1189
+ const y = a["site-url"];
1190
+ if (typeof y == "string" && y.trim() !== "")
1161
1191
  try {
1162
- new URL(g);
1192
+ new URL(y);
1163
1193
  } catch {
1164
1194
  throw new Error(
1165
- `Invalid site-url "${g}". Please provide a valid URL (e.g., http://localhost:8080 or https://example.com)`
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 = c.statSync(
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
- i.wrap(i.terminalWidth());
1217
- const n = await i.argv, l = n._[0];
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
- ) || (i.showHelp(), process.exit(1));
1221
- const u = n.define || {};
1222
- !("WP_DEBUG" in u) && !("WP_DEBUG_LOG" in u) && !("WP_DEBUG_DISPLAY" in u) && (u.WP_DEBUG = "true", u.WP_DEBUG_LOG = "true", u.WP_DEBUG_DISPLAY = "true");
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: u,
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
- }, P = await Et(v);
1236
- P === void 0 && process.exit(0);
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 = P[Symbol.asyncDispose]()), await a, process.exit(0);
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
- ve(t);
1278
+ Se(t);
1249
1279
  else {
1250
- const s = [];
1251
- let o = t;
1280
+ const o = [];
1281
+ let i = t;
1252
1282
  do
1253
- s.push(o.message), o = o.cause;
1254
- while (o instanceof Error);
1283
+ o.push(i.message), i = i.cause;
1284
+ while (i instanceof Error);
1255
1285
  console.error(
1256
- "\x1B[1m" + s.join(" caused by: ") + "\x1B[0m"
1286
+ "\x1B[1m" + o.join(" caused by: ") + "\x1B[0m"
1257
1287
  );
1258
1288
  }
1259
1289
  process.exit(1);
1260
1290
  }
1261
1291
  }
1262
- function le(e, t) {
1292
+ function ue(e, t) {
1263
1293
  return e.find(
1264
1294
  (r) => r.vfsPath.replace(/\/$/, "") === t.replace(/\/$/, "")
1265
1295
  );
1266
1296
  }
1267
- const kt = Symbol("playground-cli-testing"), T = (e) => process.stdout.isTTY ? "\x1B[1m" + e + "\x1B[0m" : e, It = (e) => process.stdout.isTTY ? "\x1B[31m" + e + "\x1B[0m" : e, $t = (e) => process.stdout.isTTY ? `\x1B[2m${e}\x1B[0m` : e, Y = (e) => process.stdout.isTTY ? `\x1B[3m${e}\x1B[0m` : e, ue = (e) => process.stdout.isTTY ? `\x1B[33m${e}\x1B[0m` : e;
1268
- async function Et(e) {
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 s = /* @__PURE__ */ new Map();
1271
- if (e.command === "start" && (e = Tt(e)), e.autoMount !== void 0 && (e.autoMount === "" && (e = { ...e, autoMount: process.cwd() }), e = pe(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) {
1272
- const w = Object.values(fe).find(
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
- y.setSeverityFilterLevel(w);
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
- e.intl || (e.intl = !0), e.redis === void 0 && (e.redis = await Q()), e.memcached === void 0 && (e.memcached = await Q());
1278
- const o = new xt({
1319
+ const i = new Et({
1279
1320
  verbosity: e.verbosity || "normal"
1280
1321
  });
1281
- e.command === "server" && (o.printBanner(), o.printConfig({
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 i = e.command === "server" ? e.port ?? 9400 : 0, n = N.platform() === "win32" ? (
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
- y.debug(
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 Le(n);
1303
- let u = !1, v = !0;
1304
- const P = await at({
1305
- port: i,
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 g = "127.0.0.1", h = `http://${g}:${a}`, k = e["site-url"] || h, I = e.command === "server" ? e.experimentalMultiWorker ?? 1 : 1, C = e.command === "server" ? (
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
- I + 1
1310
- ) : I, L = 2 ** 31 - 1, M = Math.floor(
1311
- L / C
1312
- ), K = "-playground-cli-site-", $ = await gt(K);
1313
- y.debug(`Native temp dir for VFS root: ${$.path}`);
1314
- const W = "WP Playground CLI - Listen for Xdebug", ee = ".playground-xdebug-root", te = p.join(process.cwd(), ee);
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 Qe(
1317
- $.path,
1357
+ await Xe(
1358
+ E.path,
1318
1359
  te,
1319
1360
  process.platform
1320
1361
  );
1321
- const d = {
1322
- hostPath: p.join(".", p.sep, ee),
1362
+ const p = {
1363
+ hostPath: u.join(".", u.sep, ee),
1323
1364
  vfsPath: "/"
1324
1365
  };
1325
1366
  try {
1326
- await Xe(W, process.cwd());
1327
- const f = typeof e.xdebug == "object" ? e.xdebug : void 0, S = await Ze({
1328
- name: W,
1329
- host: g,
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
- d,
1375
+ p,
1335
1376
  ...e["mount-before-install"] || [],
1336
1377
  ...e.mount || []
1337
1378
  ],
1338
1379
  ideKey: f?.ideKey
1339
- }), m = e.experimentalUnsafeIdeIntegration, b = m.includes("vscode"), x = m.includes("phpstorm"), R = Object.values(S);
1340
- console.log(""), R.length > 0 ? (console.log(T("Xdebug configured successfully")), console.log(
1341
- ue("Updated IDE config: ") + R.join(" ")
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
- ue("Playground source root: ") + ".playground-xdebug-root" + Y(
1344
- $t(
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(T("Xdebug configuration failed.")), 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 && S.vscode && (console.log(T("VS Code / Cursor instructions:")), console.log(
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 ${T("PHP Debug")} extension by ${T(
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
- W
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
- ), x && console.log("")), x && S.phpstorm && (console.log(T("PhpStorm instructions:")), console.log(
1407
+ ), P && console.log("")), P && x.phpstorm && (console.log(B("PhpStorm instructions:")), console.log(
1367
1408
  ` 1. Choose "${Y(
1368
- W
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 we = p.dirname($.path), ge = 2 * 24 * 60 * 60 * 1e3;
1382
- yt(
1422
+ const ge = u.dirname(E.path), be = 2 * 24 * 60 * 60 * 1e3;
1423
+ St(
1383
1424
  K,
1384
- ge,
1385
- we
1425
+ be,
1426
+ ge
1386
1427
  );
1387
- const _ = p.join($.path, "internal");
1388
- G(_);
1389
- const ye = [
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 d of ye) {
1401
- const f = (m) => m.vfsPath === `/${d}`;
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 m = p.join(
1404
- $.path,
1405
- d
1445
+ const c = u.join(
1446
+ E.path,
1447
+ p
1406
1448
  );
1407
- G(m), e["mount-before-install"] === void 0 && (e["mount-before-install"] = []), e["mount-before-install"].unshift({
1408
- vfsPath: `/${d}`,
1409
- hostPath: m
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 d of e["mount-before-install"])
1415
- y.debug(
1416
- `Mount before WP install: ${d.vfsPath} -> ${d.hostPath}`
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 d of e.mount)
1420
- y.debug(
1421
- `Mount after WP install: ${d.vfsPath} -> ${d.hostPath}`
1461
+ for (const p of e.mount)
1462
+ g.debug(
1463
+ `Mount after WP install: ${p.vfsPath} -> ${p.hostPath}`
1422
1464
  );
1423
- let E;
1424
- e["experimental-blueprints-v2-runner"] ? E = new mt(e, {
1425
- siteUrl: k,
1426
- processIdSpaceLength: M,
1427
- cliOutput: o
1428
- }) : (E = new wt(e, {
1429
- siteUrl: k,
1430
- processIdSpaceLength: M,
1431
- cliOutput: o
1432
- }), typeof e.blueprint == "string" && (e.blueprint = await pt({
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 D = async function() {
1479
+ const W = async function() {
1438
1480
  H || (H = !0, await Promise.all(
1439
- [...s].map(
1440
- async ([f, S]) => {
1441
- await S.dispose(), await f.terminate();
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 $.cleanup());
1445
- }, be = Bt(
1446
- C,
1447
- E.getWorkerType(),
1448
- ({ exitCode: d, workerIndex: f }) => {
1449
- H || d === 0 && y.error(
1450
- `Worker ${f} exited with code ${d}
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
- o.startProgress("Starting...");
1497
+ i.startProgress("Starting...");
1456
1498
  try {
1457
- const d = await be, f = await de(l);
1499
+ const p = await ve, f = await ce(l);
1458
1500
  {
1459
- const m = d.shift(), b = await E.bootAndSetUpInitialPlayground(
1460
- m.phpPort,
1501
+ const c = p.shift(), b = await T.bootAndSetUpInitialPlayground(
1502
+ c.phpPort,
1461
1503
  f,
1462
- _
1504
+ O
1463
1505
  );
1464
- if (s.set(
1465
- m.worker,
1506
+ if (o.set(
1507
+ c.worker,
1466
1508
  b
1467
- ), await b.isReady(), u = !0, t = new dt(b), !e["experimental-blueprints-v2-runner"]) {
1468
- const x = await E.compileInputBlueprint(
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
- x && await $e(
1472
- x,
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 Lt(r, e.outfile), o.printStatus(`Exported to ${e.outfile}`), await D();
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
- o.finishProgress("Done"), await D();
1531
+ i.finishProgress("Done"), await W();
1481
1532
  return;
1482
1533
  }
1483
- await t.removeWorker(b), await b.dispose(), await m.worker.terminate(), s.delete(m.worker);
1534
+ await t.removeWorker(b), await b.dispose(), await c.worker.terminate(), o.delete(c.worker);
1484
1535
  }
1485
- const S = M;
1486
- return [r] = await Promise.all(
1487
- d.map(async (m, b) => {
1488
- const x = S + b * M, R = await de(l), V = await E.bootPlayground({
1489
- worker: m,
1490
- fileLockManagerPort: R,
1491
- firstProcessId: x,
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 s.set(
1495
- m.worker,
1545
+ return o.set(
1546
+ c.worker,
1496
1547
  V
1497
1548
  ), t.addWorker(V), V;
1498
1549
  })
1499
- ), o.finishProgress(), o.printReady(h, I), e.xdebug && e.experimentalDevtools && (await Ve({
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]: D,
1507
- [kt]: {
1508
- workerThreadCount: I,
1509
- getWorkerNumberFromProcessId: (m) => Math.floor(m / M)
1566
+ [Symbol.asyncDispose]: W,
1567
+ [Tt]: {
1568
+ workerThreadCount: $,
1569
+ getWorkerNumberFromProcessId: (c) => Math.floor(c / L)
1510
1570
  }
1511
1571
  };
1512
- } catch (d) {
1572
+ } catch (p) {
1513
1573
  if (e.verbosity !== "debug")
1514
- throw d;
1574
+ throw p;
1515
1575
  let f = "";
1516
- throw await r?.fileExists(re) && (f = await r.readFileAsText(re)), await D(), new Error(f, { cause: d });
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 (!u)
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 P && e.command === "start" && !e.skipBrowser && Ct(P.serverUrl), P;
1601
+ return S && e.command === "start" && !e.skipBrowser && Wt(S.serverUrl), S;
1542
1602
  }
1543
- function Tt(e) {
1603
+ function At(e) {
1544
1604
  let t = { ...e, command: "server" };
1545
- e.noAutoMount || (t.autoMount = p.resolve(process.cwd(), t.path ?? ""), t = pe(t), delete t.autoMount);
1546
- const r = le(
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
- ) || le(t.mount || [], "/wordpress");
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
- It(
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 s = t.autoMount || process.cwd(), o = Je("sha256").update(s).digest("hex"), i = N.homedir(), n = p.join(
1562
- i,
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
- o
1624
+ i
1565
1625
  );
1566
- console.log("Site files stored at:", n), Z(n) && e.reset && (console.log("Resetting site..."), Te(n, { recursive: !0 })), G(n, { recursive: !0 }), t["mount-before-install"] = [
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 = Be(n).length === 0 ? (
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 Bt(e, t, r) {
1581
- const s = [];
1582
- for (let o = 0; o < e; o++) {
1583
- const n = Mt(t, { onExit: (l) => {
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: o
1646
+ workerIndex: i
1587
1647
  });
1588
1648
  } });
1589
- s.push(n);
1649
+ o.push(n);
1590
1650
  }
1591
- return Promise.all(s);
1651
+ return Promise.all(o);
1592
1652
  }
1593
- function Mt(e, { onExit: t } = {}) {
1653
+ function Rt(e, { onExit: t } = {}) {
1594
1654
  let r;
1595
- return e === "v1" ? r = new ie(new URL("./worker-thread-v1.js", import.meta.url)) : r = new ie(new URL("./worker-thread-v2.js", import.meta.url)), new Promise((s, o) => {
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" && s({ worker: r, phpPort: n.phpPort });
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
- o(l);
1663
+ i(l);
1604
1664
  });
1605
- let i = !1;
1665
+ let s = !1;
1606
1666
  r.once("spawn", () => {
1607
- i = !0;
1667
+ s = !0;
1608
1668
  }), r.once("exit", (n) => {
1609
- i || o(new Error(`Worker exited before spawning: ${n}`)), t?.(n);
1669
+ s || i(new Error(`Worker exited before spawning: ${n}`)), t?.(n);
1610
1670
  });
1611
1671
  });
1612
1672
  }
1613
- async function de(e) {
1614
- const { port1: t, port2: r } = new Me();
1615
- return await Q() ? Pe(e, null, t) : await Se(e, t), r;
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 Ct(e) {
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
- je(r, (s) => {
1632
- s && y.debug(`Could not open browser: ${s.message}`);
1691
+ qe(r, (o) => {
1692
+ o && g.debug(`Could not open browser: ${o.message}`);
1633
1693
  });
1634
1694
  }
1635
- async function Lt(e, t) {
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
- c.writeFileSync(t, r);
1717
+ m.writeFileSync(t, r);
1658
1718
  }
1659
1719
  export {
1660
- fe as L,
1661
- rr as a,
1662
- St as b,
1663
- kt as i,
1664
- O as m,
1665
- or as p,
1666
- Et as r,
1667
- Mt as s
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-BK0MGgcU.js.map
1729
+ //# sourceMappingURL=run-cli-Cxpf7CoX.js.map