@wp-playground/cli 3.0.18 → 3.0.19

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,27 +1,27 @@
1
- import { logger as h, LogSeverity as A, errorLogPath as q } from "@php-wasm/logger";
2
- import { PHPResponse as V, consumeAPI as j, SupportedPHPVersions as ue, printDebugDetails as de, exposeAPI as fe, exposeSyncAPI as me } from "@php-wasm/universal";
3
- import { resolveRemoteBlueprint as he, resolveRuntimeConfiguration as ge, compileBlueprintV1 as ye, isBlueprintBundle as we, runBlueprintV1Steps as be } from "@wp-playground/blueprints";
4
- import { zipDirectory as ve, RecommendedPHPVersion as G } from "@wp-playground/common";
5
- import u, { mkdirSync as z } from "fs";
6
- import { Worker as X, MessageChannel as Pe } from "worker_threads";
7
- import { p as J, a as Se, e as ke } from "./mounts-D1_eXSTw.js";
8
- import xe from "express";
1
+ import { logger as g, LogSeverity as U, errorLogPath as z } from "@php-wasm/logger";
2
+ import { PHPResponse as O, consumeAPI as B, SupportedPHPVersions as me, printDebugDetails as he, exposeAPI as ge, exposeSyncAPI as we } from "@php-wasm/universal";
3
+ import { resolveRemoteBlueprint as ye, resolveRuntimeConfiguration as X, compileBlueprintV1 as be, isBlueprintBundle as ve, runBlueprintV1Steps as Pe } from "@wp-playground/blueprints";
4
+ import { zipDirectory as Se, RecommendedPHPVersion as ee } from "@wp-playground/common";
5
+ import u, { mkdirSync as J } from "fs";
6
+ import { Worker as Z, MessageChannel as ke } from "worker_threads";
7
+ import { p as Y, a as G, e as xe } from "./mounts-D1_eXSTw.js";
8
+ import Ie from "express";
9
9
  import { FileLockManagerForNode as Ee } from "@php-wasm/node";
10
- import K, { cpus as Ie } from "os";
11
- import { jspi as Ce } from "wasm-feature-detect";
12
- import Le from "yargs";
13
- import g, { basename as $e } from "path";
14
- import { NodeJsFilesystem as We, OverlayFilesystem as Te, InMemoryFilesystem as Be, ZipFilesystem as je } from "@wp-playground/storage";
15
- import { EmscriptenDownloadMonitor as Re, ProgressTracker as Fe } from "@php-wasm/progress";
16
- import { resolveWordPressRelease as Me } from "@wp-playground/wordpress";
17
- import $ from "fs-extra";
18
- import { startBridge as De } from "@php-wasm/xdebug-bridge";
19
- import { dir as Ae, setGracefulCleanup as Ue } from "tmp-promise";
20
- import Ne from "ps-man";
21
- import { XMLParser as Q, XMLBuilder as ee } from "fast-xml-parser";
22
- import P from "jsonc-parser";
23
- async function Ve(e) {
24
- const o = xe(), t = await new Promise((n, r) => {
10
+ import te, { cpus as Ce } from "os";
11
+ import { jspi as Le } from "wasm-feature-detect";
12
+ import $e from "yargs";
13
+ import m, { basename as Te } from "path";
14
+ import { NodeJsFilesystem as We, OverlayFilesystem as je, InMemoryFilesystem as Be, ZipFilesystem as Re } from "@wp-playground/storage";
15
+ import { EmscriptenDownloadMonitor as Fe, ProgressTracker as Me } from "@php-wasm/progress";
16
+ import { resolveWordPressRelease as De } from "@wp-playground/wordpress";
17
+ import T from "fs-extra";
18
+ import { startBridge as Ae } from "@php-wasm/xdebug-bridge";
19
+ import { dir as Ue, setGracefulCleanup as Ne } from "tmp-promise";
20
+ import Ve from "ps-man";
21
+ import { XMLParser as oe, XMLBuilder as re } from "fast-xml-parser";
22
+ import v from "jsonc-parser";
23
+ async function Oe(e) {
24
+ const o = Ie(), t = await new Promise((n, r) => {
25
25
  const a = o.listen(e.port, () => {
26
26
  const l = a.address();
27
27
  l === null || typeof l == "string" ? r(new Error("Server address is not available")) : n(a);
@@ -32,12 +32,12 @@ async function Ve(e) {
32
32
  try {
33
33
  a = await e.handleRequest({
34
34
  url: n.url,
35
- headers: _e(n),
35
+ headers: He(n),
36
36
  method: n.method,
37
- body: await Oe(n)
37
+ body: await _e(n)
38
38
  });
39
39
  } catch (l) {
40
- h.error(l), a = V.forHttpCode(500);
40
+ g.error(l), a = O.forHttpCode(500);
41
41
  }
42
42
  r.statusCode = a.httpStatusCode;
43
43
  for (const l in a.headers)
@@ -47,21 +47,21 @@ async function Ve(e) {
47
47
  const s = t.address().port;
48
48
  return await e.onBind(t, s);
49
49
  }
50
- const Oe = async (e) => await new Promise((o) => {
50
+ const _e = async (e) => await new Promise((o) => {
51
51
  const t = [];
52
52
  e.on("data", (i) => {
53
53
  t.push(i);
54
54
  }), e.on("end", () => {
55
55
  o(new Uint8Array(Buffer.concat(t)));
56
56
  });
57
- }), _e = (e) => {
57
+ }), He = (e) => {
58
58
  const o = {};
59
59
  if (e.rawHeaders && e.rawHeaders.length)
60
60
  for (let t = 0; t < e.rawHeaders.length; t += 2)
61
61
  o[e.rawHeaders[t].toLowerCase()] = e.rawHeaders[t + 1];
62
62
  return o;
63
63
  };
64
- class He {
64
+ class qe {
65
65
  constructor(o) {
66
66
  this.workerLoads = [], this.addWorker(o);
67
67
  }
@@ -71,6 +71,15 @@ class He {
71
71
  activeRequests: /* @__PURE__ */ new Set()
72
72
  });
73
73
  }
74
+ async removeWorker(o) {
75
+ const t = this.workerLoads.findIndex(
76
+ (s) => s.worker === o
77
+ );
78
+ if (t === -1)
79
+ return;
80
+ const [i] = this.workerLoads.splice(t, 1);
81
+ await Promise.allSettled(i.activeRequests);
82
+ }
74
83
  async handleRequest(o) {
75
84
  let t = this.workerLoads[0];
76
85
  for (let s = 1; s < this.workerLoads.length; s++) {
@@ -83,29 +92,29 @@ class He {
83
92
  });
84
93
  }
85
94
  }
86
- function qe(e) {
95
+ function ze(e) {
87
96
  return /^latest$|^trunk$|^nightly$|^(?:(\d+)\.(\d+)(?:\.(\d+))?)((?:-beta(?:\d+)?)|(?:-RC(?:\d+)?))?$/.test(e);
88
97
  }
89
- async function ze({
98
+ async function Xe({
90
99
  sourceString: e,
91
100
  blueprintMayReadAdjacentFiles: o
92
101
  }) {
93
102
  if (!e)
94
103
  return;
95
104
  if (e.startsWith("http://") || e.startsWith("https://"))
96
- return await he(e);
97
- let t = g.resolve(process.cwd(), e);
105
+ return await ye(e);
106
+ let t = m.resolve(process.cwd(), e);
98
107
  if (!u.existsSync(t))
99
108
  throw new Error(`Blueprint file does not exist: ${t}`);
100
109
  const i = u.statSync(t);
101
- if (i.isDirectory() && (t = g.join(t, "blueprint.json")), !i.isFile() && i.isSymbolicLink())
110
+ if (i.isDirectory() && (t = m.join(t, "blueprint.json")), !i.isFile() && i.isSymbolicLink())
102
111
  throw new Error(
103
112
  `Blueprint path is neither a file nor a directory: ${t}`
104
113
  );
105
- const s = g.extname(t);
114
+ const s = m.extname(t);
106
115
  switch (s) {
107
116
  case ".zip":
108
- return je.fromArrayBuffer(
117
+ return Re.fromArrayBuffer(
109
118
  u.readFileSync(t).buffer
110
119
  );
111
120
  case ".json": {
@@ -117,8 +126,8 @@ async function ze({
117
126
  `Blueprint file at ${t} is not a valid JSON file`
118
127
  );
119
128
  }
120
- const r = g.dirname(t), a = new We(r);
121
- return new Te([
129
+ const r = m.dirname(t), a = new We(r);
130
+ return new je([
122
131
  new Be({
123
132
  "blueprint.json": n
124
133
  }),
@@ -145,15 +154,15 @@ You can allow this Blueprint to read files from the same parent directory by exp
145
154
  );
146
155
  }
147
156
  }
148
- class Xe {
157
+ class Je {
149
158
  constructor(o, t) {
150
159
  this.lastProgressMessage = "", this.args = o, this.siteUrl = t.siteUrl, this.processIdSpaceLength = t.processIdSpaceLength, this.phpVersion = o.php;
151
160
  }
152
161
  getWorkerType() {
153
162
  return "v2";
154
163
  }
155
- async bootPrimaryWorker(o, t, i) {
156
- const s = j(o);
164
+ async bootAndSetUpInitialPlayground(o, t, i) {
165
+ const s = B(o);
157
166
  await s.useFileLockManager(t);
158
167
  const n = {
159
168
  ...this.args,
@@ -163,19 +172,23 @@ class Xe {
163
172
  processIdSpaceLength: this.processIdSpaceLength,
164
173
  trace: this.args.debug || !1,
165
174
  blueprint: this.args.blueprint,
166
- withXdebug: !!this.args.xdebug,
167
- xdebug: typeof this.args.xdebug == "object" ? this.args.xdebug : void 0,
175
+ // We do not enable Xdebug by default for the initial worker
176
+ // because we do not imagine users expect to hit breakpoints
177
+ // until Playground has fully booted.
178
+ // TODO: Consider supporting Xdebug for the initial worker via a dedicated flag.
179
+ withXdebug: !1,
180
+ xdebug: void 0,
168
181
  nativeInternalDirPath: i
169
182
  };
170
- return await s.bootAsPrimaryWorker(n), s;
183
+ return await s.bootAndSetUpInitialWorker(n), s;
171
184
  }
172
- async bootSecondaryWorker({
185
+ async bootPlayground({
173
186
  worker: o,
174
187
  fileLockManagerPort: t,
175
188
  firstProcessId: i,
176
189
  nativeInternalDirPath: s
177
190
  }) {
178
- const n = j(o.phpPort);
191
+ const n = B(o.phpPort);
179
192
  await n.useFileLockManager(t);
180
193
  const r = {
181
194
  ...this.args,
@@ -189,7 +202,7 @@ class Xe {
189
202
  mountsBeforeWpInstall: this.args["mount-before-install"] || [],
190
203
  mountsAfterWpInstall: this.args.mount || []
191
204
  };
192
- return await n.bootAsSecondaryWorker(r), n;
205
+ return await n.bootWorker(r), n;
193
206
  }
194
207
  writeProgressUpdate(o, t, i) {
195
208
  t !== this.lastProgressMessage && (this.lastProgressMessage = t, o.isTTY ? (o.cursorTo(0), o.write(t), o.clearLine(1), i && o.write(`
@@ -197,20 +210,20 @@ class Xe {
197
210
  `));
198
211
  }
199
212
  }
200
- const O = g.join(K.homedir(), ".wordpress-playground");
201
- async function Je(e) {
202
- return await te(
213
+ const _ = m.join(te.homedir(), ".wordpress-playground");
214
+ async function Ze(e) {
215
+ return await ne(
203
216
  "https://github.com/WordPress/sqlite-database-integration/archive/refs/heads/develop.zip",
204
217
  "sqlite.zip",
205
218
  e
206
219
  );
207
220
  }
208
- async function te(e, o, t) {
209
- const i = g.join(O, o);
210
- return $.existsSync(i) || ($.ensureDirSync(O), await Ze(e, i, t)), oe(i);
221
+ async function ne(e, o, t) {
222
+ const i = m.join(_, o);
223
+ return T.existsSync(i) || (T.ensureDirSync(_), await Ye(e, i, t)), ie(i);
211
224
  }
212
- async function Ze(e, o, t) {
213
- const s = (await t.monitorFetch(fetch(e))).body.getReader(), n = `${o}.partial`, r = $.createWriteStream(n);
225
+ async function Ye(e, o, t) {
226
+ const s = (await t.monitorFetch(fetch(e))).body.getReader(), n = `${o}.partial`, r = T.createWriteStream(n);
214
227
  for (; ; ) {
215
228
  const { done: a, value: l } = await s.read();
216
229
  if (l && r.write(l), a)
@@ -218,62 +231,62 @@ async function Ze(e, o, t) {
218
231
  }
219
232
  r.close(), r.closed || await new Promise((a, l) => {
220
233
  r.on("finish", () => {
221
- $.renameSync(n, o), a(null);
234
+ T.renameSync(n, o), a(null);
222
235
  }), r.on("error", (p) => {
223
- $.removeSync(n), l(p);
236
+ T.removeSync(n), l(p);
224
237
  });
225
238
  });
226
239
  }
227
- function oe(e, o) {
228
- return new File([$.readFileSync(e)], $e(e));
240
+ function ie(e, o) {
241
+ return new File([T.readFileSync(e)], Te(e));
229
242
  }
230
- class Ye {
243
+ class Ge {
231
244
  constructor(o, t) {
232
245
  this.lastProgressMessage = "", this.args = o, this.siteUrl = t.siteUrl, this.processIdSpaceLength = t.processIdSpaceLength;
233
246
  }
234
247
  getWorkerType() {
235
248
  return "v1";
236
249
  }
237
- async bootPrimaryWorker(o, t, i) {
250
+ async bootAndSetUpInitialPlayground(o, t, i) {
238
251
  let s;
239
- const n = new Re();
252
+ const n = new Fe();
240
253
  if (!this.args.skipWordPressSetup) {
241
- let I = !1;
242
- n.addEventListener("progress", (k) => {
243
- if (I)
254
+ let x = !1;
255
+ n.addEventListener("progress", (W) => {
256
+ if (x)
244
257
  return;
245
- const { loaded: x, total: f } = k.detail, W = Math.floor(
246
- Math.min(100, 100 * x / f)
258
+ const { loaded: k, total: f } = W.detail, j = Math.floor(
259
+ Math.min(100, 100 * k / f)
247
260
  );
248
- I = W === 100, this.writeProgressUpdate(
261
+ x = j === 100, this.writeProgressUpdate(
249
262
  process.stdout,
250
- `Downloading WordPress ${W}%...`,
251
- I
263
+ `Downloading WordPress ${j}%...`,
264
+ x
252
265
  );
253
- }), s = await Me(this.args.wp), h.log(
266
+ }), s = await De(this.args.wp), g.log(
254
267
  `Resolved WordPress release URL: ${s?.releaseUrl}`
255
268
  );
256
269
  }
257
- const r = s && g.join(
258
- O,
270
+ const r = s && m.join(
271
+ _,
259
272
  `prebuilt-wp-content-for-wp-${s.version}.zip`
260
- ), a = s ? u.existsSync(r) ? oe(r) : await te(
273
+ ), a = s ? u.existsSync(r) ? ie(r) : await ne(
261
274
  s.releaseUrl,
262
275
  `${s.version}.zip`,
263
276
  n
264
277
  ) : void 0;
265
- h.log("Fetching SQLite integration plugin...");
266
- const l = this.args.skipSqliteSetup ? void 0 : await Je(n), p = this.args.followSymlinks === !0, c = this.args.experimentalTrace === !0, d = this.args["mount-before-install"] || [], m = this.args.mount || [], b = j(o);
267
- await b.isConnected(), h.log("Booting WordPress...");
268
- const v = await ge(
278
+ g.log("Fetching SQLite integration plugin...");
279
+ const l = this.args.skipSqliteSetup ? void 0 : await Ze(n), p = this.args.followSymlinks === !0, c = this.args.experimentalTrace === !0, d = this.args["mount-before-install"] || [], h = this.args.mount || [], b = B(o);
280
+ await b.isConnected(), g.log("Booting WordPress...");
281
+ const S = await X(
269
282
  this.getEffectiveBlueprint()
270
283
  );
271
- return await b.useFileLockManager(t), await b.bootAsPrimaryWorker({
272
- phpVersion: v.phpVersion,
273
- wpVersion: v.wpVersion,
284
+ return await b.useFileLockManager(t), await b.bootAndSetUpInitialWorker({
285
+ phpVersion: S.phpVersion,
286
+ wpVersion: S.wpVersion,
274
287
  siteUrl: this.siteUrl,
275
288
  mountsBeforeWpInstall: d,
276
- mountsAfterWpInstall: m,
289
+ mountsAfterWpInstall: h,
277
290
  wordPressZip: a && await a.arrayBuffer(),
278
291
  sqliteIntegrationPluginZip: await l?.arrayBuffer(),
279
292
  firstProcessId: 0,
@@ -281,24 +294,32 @@ class Ye {
281
294
  followSymlinks: p,
282
295
  trace: c,
283
296
  internalCookieStore: this.args.internalCookieStore,
284
- withXdebug: !!this.args.xdebug,
297
+ // We do not enable Xdebug by default for the initial worker
298
+ // because we do not imagine users expect to hit breakpoints
299
+ // until Playground has fully booted.
300
+ // TODO: Consider supporting Xdebug for the initial worker via a dedicated flag.
301
+ withXdebug: !1,
285
302
  nativeInternalDirPath: i
286
- }), s && !this.args["mount-before-install"] && !u.existsSync(r) && (h.log("Caching preinstalled WordPress for the next boot..."), u.writeFileSync(
303
+ }), s && !this.args["mount-before-install"] && !u.existsSync(r) && (g.log("Caching preinstalled WordPress for the next boot..."), u.writeFileSync(
287
304
  r,
288
- await ve(b, "/wordpress")
289
- ), h.log("Cached!")), b;
305
+ await Se(b, "/wordpress")
306
+ ), g.log("Cached!")), b;
290
307
  }
291
- async bootSecondaryWorker({
308
+ async bootPlayground({
292
309
  worker: o,
293
310
  fileLockManagerPort: t,
294
311
  firstProcessId: i,
295
312
  nativeInternalDirPath: s
296
313
  }) {
297
- const n = j(
314
+ const n = B(
298
315
  o.phpPort
299
316
  );
300
- return await n.isConnected(), await n.useFileLockManager(t), await n.bootAsSecondaryWorker({
301
- phpVersion: this.phpVersion,
317
+ await n.isConnected();
318
+ const r = await X(
319
+ this.getEffectiveBlueprint()
320
+ );
321
+ return await n.useFileLockManager(t), await n.bootWorker({
322
+ phpVersion: r.phpVersion,
302
323
  siteUrl: this.siteUrl,
303
324
  mountsBeforeWpInstall: this.args["mount-before-install"] || [],
304
325
  mountsAfterWpInstall: this.args.mount || [],
@@ -314,7 +335,7 @@ class Ye {
314
335
  }), await n.isReady(), n;
315
336
  }
316
337
  async compileInputBlueprint(o) {
317
- const t = this.getEffectiveBlueprint(), i = new Fe();
338
+ const t = this.getEffectiveBlueprint(), i = new Me();
318
339
  let s = "", n = !1;
319
340
  return i.addEventListener("progress", (r) => {
320
341
  if (n)
@@ -328,31 +349,31 @@ class Ye {
328
349
  l,
329
350
  n
330
351
  );
331
- }), await ye(t, {
352
+ }), await be(t, {
332
353
  progress: i,
333
354
  additionalSteps: o
334
355
  });
335
356
  }
336
357
  getEffectiveBlueprint() {
337
358
  const o = this.args.blueprint;
338
- return we(o) ? o : {
359
+ return ve(o) ? o : {
339
360
  login: this.args.login,
340
361
  ...o || {},
341
362
  preferredVersions: {
342
- php: this.args.php ?? o?.preferredVersions?.php ?? G,
363
+ php: this.args.php ?? o?.preferredVersions?.php ?? ee,
343
364
  wp: this.args.wp ?? o?.preferredVersions?.wp ?? "latest",
344
365
  ...o?.preferredVersions || {}
345
366
  }
346
367
  };
347
368
  }
348
369
  writeProgressUpdate(o, t, i) {
349
- this.args.verbosity !== _.Quiet.name && t !== this.lastProgressMessage && (this.lastProgressMessage = t, o.isTTY ? (o.cursorTo(0), o.write(t), o.clearLine(1), i && o.write(`
370
+ this.args.verbosity !== H.Quiet.name && t !== this.lastProgressMessage && (this.lastProgressMessage = t, o.isTTY ? (o.cursorTo(0), o.write(t), o.clearLine(1), i && o.write(`
350
371
  `)) : o.write(`${t}
351
372
  `));
352
373
  }
353
374
  }
354
- async function Ge(e, o = !0) {
355
- const i = `${g.basename(process.argv0)}${e}${process.pid}-`, s = await Ae({
375
+ async function Ke(e, o = !0) {
376
+ const i = `${m.basename(process.argv0)}${e}${process.pid}-`, s = await Ue({
356
377
  prefix: i,
357
378
  /*
358
379
  * Allow recursive cleanup on process exit.
@@ -364,20 +385,20 @@ async function Ge(e, o = !0) {
364
385
  */
365
386
  unsafeCleanup: !0
366
387
  });
367
- return o && Ue(), s;
388
+ return o && Ne(), s;
368
389
  }
369
- async function Ke(e, o, t) {
370
- const s = (await Qe(
390
+ async function Qe(e, o, t) {
391
+ const s = (await et(
371
392
  e,
372
393
  o,
373
394
  t
374
395
  )).map(
375
396
  (n) => new Promise((r) => {
376
397
  u.rm(n, { recursive: !0 }, (a) => {
377
- a ? h.warn(
398
+ a ? g.warn(
378
399
  `Failed to delete stale Playground temp dir: ${n}`,
379
400
  a
380
- ) : h.info(
401
+ ) : g.info(
381
402
  `Deleted stale Playground temp dir: ${n}`
382
403
  ), r();
383
404
  });
@@ -385,24 +406,24 @@ async function Ke(e, o, t) {
385
406
  );
386
407
  await Promise.all(s);
387
408
  }
388
- async function Qe(e, o, t) {
409
+ async function et(e, o, t) {
389
410
  try {
390
- const i = u.readdirSync(t).map((n) => g.join(t, n)), s = [];
411
+ const i = u.readdirSync(t).map((n) => m.join(t, n)), s = [];
391
412
  for (const n of i)
392
- await et(
413
+ await tt(
393
414
  e,
394
415
  o,
395
416
  n
396
417
  ) && s.push(n);
397
418
  return s;
398
419
  } catch (i) {
399
- return h.warn(`Failed to find stale Playground temp dirs: ${i}`), [];
420
+ return g.warn(`Failed to find stale Playground temp dirs: ${i}`), [];
400
421
  }
401
422
  }
402
- async function et(e, o, t) {
423
+ async function tt(e, o, t) {
403
424
  if (!u.lstatSync(t).isDirectory())
404
425
  return !1;
405
- const s = g.basename(t);
426
+ const s = m.basename(t);
406
427
  if (!s.includes(e))
407
428
  return !1;
408
429
  const n = s.match(
@@ -414,15 +435,15 @@ async function et(e, o, t) {
414
435
  executableName: n[1],
415
436
  pid: n[2]
416
437
  };
417
- if (await tt(r.pid, r.executableName))
438
+ if (await ot(r.pid, r.executableName))
418
439
  return !1;
419
440
  const a = Date.now() - o;
420
441
  return u.statSync(t).mtime.getTime() < a;
421
442
  }
422
- async function tt(e, o) {
443
+ async function ot(e, o) {
423
444
  const [t] = await new Promise(
424
445
  (i, s) => {
425
- Ne.list(
446
+ Ve.list(
426
447
  {
427
448
  pid: e,
428
449
  name: o,
@@ -437,7 +458,7 @@ async function tt(e, o) {
437
458
  );
438
459
  return !!t && t.pid === e && t.command === o;
439
460
  }
440
- async function ot(e, o, t) {
461
+ async function rt(e, o, t) {
441
462
  const i = t === "win32" ? (
442
463
  // On Windows, creating a 'dir' symlink can require elevated permissions.
443
464
  // In this case, let's make junction points because they function like
@@ -446,15 +467,15 @@ async function ot(e, o, t) {
446
467
  ) : "dir";
447
468
  u.symlinkSync(e, o, i);
448
469
  }
449
- async function rt(e) {
470
+ async function nt(e) {
450
471
  try {
451
472
  u.lstatSync(e).isSymbolicLink() && u.unlinkSync(e);
452
473
  } catch {
453
474
  }
454
475
  }
455
- function nt(e, o) {
476
+ function it(e, o) {
456
477
  return o.filter((t) => {
457
- const i = g.resolve(t.hostPath), s = g.join(e, g.sep);
478
+ const i = m.resolve(t.hostPath), s = m.join(e, m.sep);
458
479
  return (
459
480
  // If auto-mounting from the current directory,
460
481
  // the entire project directory can be mapped.
@@ -470,7 +491,7 @@ const E = {
470
491
  commentPropName: "__xmlComment",
471
492
  allowBooleanAttributes: !0,
472
493
  trimValues: !0
473
- }, re = {
494
+ }, se = {
474
495
  ignoreAttributes: E.ignoreAttributes,
475
496
  attributeNamePrefix: E.attributeNamePrefix,
476
497
  preserveOrder: E.preserveOrder,
@@ -483,8 +504,8 @@ const E = {
483
504
  allowEmptyContent: !0,
484
505
  allowTrailingComma: !0
485
506
  };
486
- function it(e, o) {
487
- const { name: t, host: i, port: s, mappings: n, ideKey: r } = o, a = new Q(E), l = (() => {
507
+ function st(e, o) {
508
+ const { name: t, host: i, port: s, mappings: n, ideKey: r } = o, a = new oe(E), l = (() => {
488
509
  try {
489
510
  return a.parse(e, !0);
490
511
  } catch {
@@ -496,9 +517,8 @@ function it(e, o) {
496
517
  path_mappings: n.map((f) => ({
497
518
  mapping: [],
498
519
  ":@": {
499
- "local-root": `$PROJECT_DIR$/${f.hostPath.replace(
500
- /^\.\/?/,
501
- ""
520
+ "local-root": `$PROJECT_DIR$/${le(
521
+ m.relative(o.projectDir, f.hostPath)
502
522
  )}`,
503
523
  "remote-root": f.vfsPath
504
524
  }
@@ -537,21 +557,21 @@ function it(e, o) {
537
557
  component: [],
538
558
  ":@": { name: "PhpServers" }
539
559
  }, c.project === void 0 && (c.project = []), c.project.push(d));
540
- let m = d.component?.find(
560
+ let h = d.component?.find(
541
561
  (f) => !!f?.servers
542
562
  );
543
- m === void 0 && (m = { servers: [] }, d.component === void 0 && (d.component = []), d.component.push(m));
544
- const b = m.servers?.findIndex(
563
+ h === void 0 && (h = { servers: [] }, d.component === void 0 && (d.component = []), d.component.push(h));
564
+ const b = h.servers?.findIndex(
545
565
  (f) => !!f?.server && f?.[":@"]?.name === t
546
566
  );
547
- (b === void 0 || b < 0) && (m.servers === void 0 && (m.servers = []), m.servers.push(p));
548
- let v = c.project?.find(
567
+ (b === void 0 || b < 0) && (h.servers === void 0 && (h.servers = []), h.servers.push(p));
568
+ let S = c.project?.find(
549
569
  (f) => !!f?.component && f?.[":@"]?.name === "RunManager"
550
570
  );
551
- if (v === void 0 && (v = {
571
+ if (S === void 0 && (S = {
552
572
  component: [],
553
573
  ":@": { name: "RunManager" }
554
- }, c.project === void 0 && (c.project = []), c.project.push(v)), (v.component?.findIndex(
574
+ }, c.project === void 0 && (c.project = []), c.project.push(S)), (S.component?.findIndex(
555
575
  (f) => !!f?.configuration && f?.[":@"]?.name === t
556
576
  ) ?? -1) < 0) {
557
577
  const f = {
@@ -570,32 +590,32 @@ function it(e, o) {
570
590
  session_id: r
571
591
  }
572
592
  };
573
- v.component === void 0 && (v.component = []), v.component.push(f);
593
+ S.component === void 0 && (S.component = []), S.component.push(f);
574
594
  }
575
- const x = new ee(re).build(l);
595
+ const k = new re(se).build(l);
576
596
  try {
577
- a.parse(x, !0);
597
+ a.parse(k, !0);
578
598
  } catch {
579
599
  throw new Error(
580
600
  "The resulting PhpStorm configuration file is not valid XML."
581
601
  );
582
602
  }
583
- return x;
603
+ return k;
584
604
  }
585
- function st(e, o) {
605
+ function at(e, o) {
586
606
  const { name: t, mappings: i } = o, s = [];
587
- let n = e, r = P.parseTree(n, s, R);
607
+ let n = e, r = v.parseTree(n, s, R);
588
608
  if (r === void 0 || s.length)
589
609
  throw new Error("VS Code configuration file is not valid JSON.");
590
- let a = P.findNodeAtLocation(r, ["configurations"]);
610
+ let a = v.findNodeAtLocation(r, ["configurations"]);
591
611
  if (a === void 0 || a.children === void 0) {
592
- const p = P.modify(n, ["configurations"], [], {});
593
- n = P.applyEdits(n, p), r = P.parseTree(n, [], R), a = P.findNodeAtLocation(r, [
612
+ const p = v.modify(n, ["configurations"], [], {});
613
+ n = v.applyEdits(n, p), r = v.parseTree(n, [], R), a = v.findNodeAtLocation(r, [
594
614
  "configurations"
595
615
  ]);
596
616
  }
597
617
  const l = a?.children?.findIndex(
598
- (p) => P.findNodeAtLocation(p, ["name"])?.value === t
618
+ (p) => v.findNodeAtLocation(p, ["name"])?.value === t
599
619
  );
600
620
  if (l === void 0 || l < 0) {
601
621
  const p = {
@@ -603,11 +623,10 @@ function st(e, o) {
603
623
  type: "php",
604
624
  request: "launch",
605
625
  port: 9003,
606
- pathMappings: i.reduce((m, b) => (m[b.vfsPath] = `\${workspaceFolder}/${b.hostPath.replace(
607
- /^\.\/?/,
608
- ""
609
- )}`, m), {})
610
- }, c = a?.children?.length || 0, d = P.modify(
626
+ pathMappings: i.reduce((h, b) => (h[b.vfsPath] = `\${workspaceFolder}/${le(
627
+ m.relative(o.workspaceDir, b.hostPath)
628
+ )}`, h), {})
629
+ }, c = a?.children?.length || 0, d = v.modify(
611
630
  n,
612
631
  ["configurations", c],
613
632
  p,
@@ -620,11 +639,11 @@ function st(e, o) {
620
639
  }
621
640
  }
622
641
  );
623
- n = ne(n, d);
642
+ n = ae(n, d);
624
643
  }
625
644
  return n;
626
645
  }
627
- async function at({
646
+ async function lt({
628
647
  name: e,
629
648
  ides: o,
630
649
  host: t,
@@ -633,14 +652,14 @@ async function at({
633
652
  mounts: n,
634
653
  ideKey: r = "PLAYGROUNDCLI"
635
654
  }) {
636
- const a = nt(s, n), l = [];
655
+ const a = it(s, n), l = [];
637
656
  if (o.includes("phpstorm")) {
638
- const p = ".idea/workspace.xml", c = g.join(
657
+ const p = ".idea/workspace.xml", c = m.join(
639
658
  s,
640
659
  p
641
660
  );
642
661
  if (!u.existsSync(c)) {
643
- if (u.existsSync(g.dirname(c)))
662
+ if (u.existsSync(m.dirname(c)))
644
663
  u.writeFileSync(
645
664
  c,
646
665
  `<?xml version="1.0" encoding="UTF-8"?>
@@ -653,24 +672,25 @@ async function at({
653
672
  );
654
673
  }
655
674
  if (u.existsSync(c)) {
656
- const d = u.readFileSync(c, "utf8"), m = it(d, {
675
+ const d = u.readFileSync(c, "utf8"), h = st(d, {
657
676
  name: e,
658
677
  host: t,
659
678
  port: i,
679
+ projectDir: s,
660
680
  mappings: a,
661
681
  ideKey: r
662
682
  });
663
- u.writeFileSync(c, m);
683
+ u.writeFileSync(c, h);
664
684
  }
665
685
  l.push(p);
666
686
  }
667
687
  if (o.includes("vscode")) {
668
- const p = ".vscode/launch.json", c = g.join(
688
+ const p = ".vscode/launch.json", c = m.join(
669
689
  s,
670
690
  p
671
691
  );
672
692
  if (!u.existsSync(c)) {
673
- if (u.existsSync(g.dirname(c)))
693
+ if (u.existsSync(m.dirname(c)))
674
694
  u.writeFileSync(
675
695
  c,
676
696
  `{
@@ -683,19 +703,20 @@ async function at({
683
703
  );
684
704
  }
685
705
  if (u.existsSync(c)) {
686
- const d = u.readFileSync(c, "utf-8"), m = st(d, {
706
+ const d = u.readFileSync(c, "utf-8"), h = at(d, {
687
707
  name: e,
708
+ workspaceDir: s,
688
709
  mappings: a
689
710
  });
690
- m !== d && (u.writeFileSync(c, m), l.push(p));
711
+ h !== d && (u.writeFileSync(c, h), l.push(p));
691
712
  }
692
713
  }
693
714
  return l;
694
715
  }
695
- async function lt(e, o) {
696
- const t = g.join(o, ".idea/workspace.xml");
716
+ async function ct(e, o) {
717
+ const t = m.join(o, ".idea/workspace.xml");
697
718
  if (u.existsSync(t)) {
698
- const s = u.readFileSync(t, "utf8"), n = new Q(E), r = (() => {
719
+ const s = u.readFileSync(t, "utf8"), n = new oe(E), r = (() => {
699
720
  try {
700
721
  return n.parse(s, !0);
701
722
  } catch {
@@ -714,34 +735,34 @@ async function lt(e, o) {
714
735
  );
715
736
  if (c !== void 0 && c >= 0) {
716
737
  p.servers.splice(c, 1);
717
- const m = new ee(re).build(r);
738
+ const h = new re(se).build(r);
718
739
  try {
719
- n.parse(m, !0);
740
+ n.parse(h, !0);
720
741
  } catch {
721
742
  throw new Error(
722
743
  "The resulting PhpStorm configuration file is not valid XML."
723
744
  );
724
745
  }
725
- m === `<?xml version="1.0" encoding="UTF-8"?>
746
+ h === `<?xml version="1.0" encoding="UTF-8"?>
726
747
  <project version="4">
727
748
  <component name="PhpServers">
728
749
  <servers></servers>
729
750
  </component>
730
- </project>` ? u.unlinkSync(t) : u.writeFileSync(t, m);
751
+ </project>` ? u.unlinkSync(t) : u.writeFileSync(t, h);
731
752
  }
732
753
  }
733
- const i = g.join(o, ".vscode/launch.json");
754
+ const i = m.join(o, ".vscode/launch.json");
734
755
  if (u.existsSync(i)) {
735
- const s = [], n = u.readFileSync(i, "utf-8"), r = P.parseTree(n, s, R);
756
+ const s = [], n = u.readFileSync(i, "utf-8"), r = v.parseTree(n, s, R);
736
757
  if (r === void 0 || s.length)
737
758
  throw new Error("VS Code configuration file is not valid JSON.");
738
- const l = P.findNodeAtLocation(r, [
759
+ const l = v.findNodeAtLocation(r, [
739
760
  "configurations"
740
761
  ])?.children?.findIndex(
741
- (p) => P.findNodeAtLocation(p, ["name"])?.value === e
762
+ (p) => v.findNodeAtLocation(p, ["name"])?.value === e
742
763
  );
743
764
  if (l !== void 0 && l >= 0) {
744
- const p = P.modify(
765
+ const p = v.modify(
745
766
  n,
746
767
  ["configurations", l],
747
768
  void 0,
@@ -753,18 +774,18 @@ async function lt(e, o) {
753
774
  `
754
775
  }
755
776
  }
756
- ), c = ne(n, p);
777
+ ), c = ae(n, p);
757
778
  c === `{
758
779
  "configurations": []
759
780
  }` ? u.unlinkSync(i) : u.writeFileSync(i, c);
760
781
  }
761
782
  }
762
783
  }
763
- function ne(e, o) {
764
- const t = [], i = P.applyEdits(e, o);
765
- if (t.length = 0, P.parseTree(i, t, R), t.length) {
784
+ function ae(e, o) {
785
+ const t = [], i = v.applyEdits(e, o);
786
+ if (t.length = 0, v.parseTree(i, t, R), t.length) {
766
787
  const s = t.map((r) => ({
767
- message: P.printParseErrorCode(r.error),
788
+ message: v.printParseErrorCode(r.error),
768
789
  offset: r.offset,
769
790
  length: r.length,
770
791
  fragment: i.slice(
@@ -790,14 +811,17 @@ function ne(e, o) {
790
811
  }
791
812
  return i;
792
813
  }
793
- const _ = {
794
- Quiet: { name: "quiet", severity: A.Fatal },
795
- Normal: { name: "normal", severity: A.Info },
796
- Debug: { name: "debug", severity: A.Debug }
814
+ function le(e) {
815
+ return e.replaceAll(m.sep, m.posix.sep);
816
+ }
817
+ const H = {
818
+ Quiet: { name: "quiet", severity: U.Fatal },
819
+ Normal: { name: "normal", severity: U.Info },
820
+ Debug: { name: "debug", severity: U.Debug }
797
821
  };
798
- async function Dt() {
822
+ async function At() {
799
823
  try {
800
- const e = Le(process.argv.slice(2)).usage("Usage: wp-playground <command> [options]").positional("command", {
824
+ const e = $e(process.argv.slice(2)).usage("Usage: wp-playground <command> [options]").positional("command", {
801
825
  describe: "Command to run",
802
826
  choices: ["server", "run-blueprint", "build-snapshot"],
803
827
  demandOption: !0
@@ -815,8 +839,8 @@ async function Dt() {
815
839
  }).option("php", {
816
840
  describe: "PHP version to use.",
817
841
  type: "string",
818
- default: G,
819
- choices: ue
842
+ default: ee,
843
+ choices: me
820
844
  }).option("wp", {
821
845
  describe: "WordPress version to use.",
822
846
  type: "string",
@@ -825,24 +849,24 @@ async function Dt() {
825
849
  describe: "Mount a directory to the PHP runtime (can be used multiple times). Format: /host/path:/vfs/path",
826
850
  type: "array",
827
851
  string: !0,
828
- coerce: J
852
+ coerce: Y
829
853
  }).option("mount-before-install", {
830
854
  describe: "Mount a directory to the PHP runtime before WordPress installation (can be used multiple times). Format: /host/path:/vfs/path",
831
855
  type: "array",
832
856
  string: !0,
833
- coerce: J
857
+ coerce: Y
834
858
  }).option("mount-dir", {
835
859
  describe: 'Mount a directory to the PHP runtime (can be used multiple times). Format: "/host/path" "/vfs/path"',
836
860
  type: "array",
837
861
  nargs: 2,
838
- array: !0
839
- // coerce: parseMountDirArguments,
862
+ array: !0,
863
+ coerce: G
840
864
  }).option("mount-dir-before-install", {
841
865
  describe: 'Mount a directory before WordPress installation (can be used multiple times). Format: "/host/path" "/vfs/path"',
842
866
  type: "string",
843
867
  nargs: 2,
844
868
  array: !0,
845
- coerce: Se
869
+ coerce: G
846
870
  }).option("login", {
847
871
  describe: "Should log the user in",
848
872
  type: "boolean",
@@ -870,7 +894,7 @@ async function Dt() {
870
894
  }).option("verbosity", {
871
895
  describe: "Output logs and progress messages.",
872
896
  type: "string",
873
- choices: Object.values(_).map(
897
+ choices: Object.values(H).map(
874
898
  (r) => r.name
875
899
  ),
876
900
  default: "normal"
@@ -917,7 +941,7 @@ Warning: Following symlinks will expose files outside mounted directories to Pla
917
941
  ).option("experimental-multi-worker", {
918
942
  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.",
919
943
  type: "number",
920
- coerce: (r) => r ?? Ie().length - 1
944
+ coerce: (r) => r ?? Ce().length - 1
921
945
  }).option("experimental-blueprints-v2-runner", {
922
946
  describe: "Use the experimental Blueprint V2 runner.",
923
947
  type: "boolean",
@@ -931,7 +955,7 @@ Warning: Following symlinks will expose files outside mounted directories to Pla
931
955
  // Remove the "hidden" flag once Blueprint V2 is fully supported
932
956
  hidden: !0
933
957
  }).showHelpOnFail(!1).strictOptions().check(async (r) => {
934
- if ((r["skip-wordpress-setup"] || r.skipWordpressSetup) && (r.skipWordPressSetup = !0), r.wp !== void 0 && !qe(r.wp))
958
+ if ((r["skip-wordpress-setup"] || r.skipWordpressSetup) && (r.skipWordPressSetup = !0), r.wp !== void 0 && !ze(r.wp))
935
959
  try {
936
960
  new URL(r.wp);
937
961
  } catch {
@@ -998,7 +1022,7 @@ Warning: Following symlinks will expose files outside mounted directories to Pla
998
1022
  ...o["mount-before-install"] || [],
999
1023
  ...o["mount-dir-before-install"] || []
1000
1024
  ]
1001
- }, s = await pt(i);
1025
+ }, s = await ut(i);
1002
1026
  s === void 0 && process.exit(0);
1003
1027
  const n = /* @__PURE__ */ (() => {
1004
1028
  let r;
@@ -1011,7 +1035,7 @@ Warning: Following symlinks will expose files outside mounted directories to Pla
1011
1035
  if (!(e instanceof Error))
1012
1036
  throw e;
1013
1037
  if (process.argv.includes("--debug"))
1014
- de(e);
1038
+ he(e);
1015
1039
  else {
1016
1040
  const t = [];
1017
1041
  let i = e;
@@ -1025,102 +1049,102 @@ Warning: Following symlinks will expose files outside mounted directories to Pla
1025
1049
  process.exit(1);
1026
1050
  }
1027
1051
  }
1028
- const U = (e) => process.stdout.isTTY ? "\x1B[1m" + e + "\x1B[0m" : e, ct = (e) => process.stdout.isTTY ? `\x1B[2m${e}\x1B[0m` : e, N = (e) => process.stdout.isTTY ? `\x1B[3m${e}\x1B[0m` : e, Z = (e) => process.stdout.isTTY ? `\x1B[33m${e}\x1B[0m` : e;
1029
- async function pt(e) {
1052
+ const N = (e) => process.stdout.isTTY ? "\x1B[1m" + e + "\x1B[0m" : e, pt = (e) => process.stdout.isTTY ? `\x1B[2m${e}\x1B[0m` : e, V = (e) => process.stdout.isTTY ? `\x1B[3m${e}\x1B[0m` : e, K = (e) => process.stdout.isTTY ? `\x1B[33m${e}\x1B[0m` : e;
1053
+ async function ut(e) {
1030
1054
  let o, t;
1031
1055
  const i = [];
1032
- if (e.autoMount !== void 0 && (e.autoMount === "" && (e = { ...e, autoMount: process.cwd() }), e = ke(e)), e.quiet && (e.verbosity = "quiet", delete e.quiet), e.debug ? e.verbosity = "debug" : e.verbosity === "debug" && (e.debug = !0), e.verbosity) {
1033
- const l = Object.values(_).find(
1056
+ if (e.autoMount !== void 0 && (e.autoMount === "" && (e = { ...e, autoMount: process.cwd() }), e = xe(e)), e.quiet && (e.verbosity = "quiet", delete e.quiet), e.debug ? e.verbosity = "debug" : e.verbosity === "debug" && (e.debug = !0), e.verbosity) {
1057
+ const l = Object.values(H).find(
1034
1058
  (p) => p.name === e.verbosity
1035
1059
  ).severity;
1036
- h.setSeverityFilterLevel(l);
1060
+ g.setSeverityFilterLevel(l);
1037
1061
  }
1038
- const s = K.platform() === "win32" ? (
1062
+ const s = te.platform() === "win32" ? (
1039
1063
  // @TODO: Enable fs-ext here when it works with Windows.
1040
1064
  void 0
1041
1065
  ) : await import("fs-ext").then((l) => l.flockSync).catch(() => {
1042
- h.warn(
1066
+ g.warn(
1043
1067
  "The fs-ext package is not installed. Internal file locking will not be integrated with host OS file locking."
1044
1068
  );
1045
1069
  }), n = new Ee(s);
1046
1070
  let r = !1, a = !0;
1047
- return h.log("Starting a PHP server..."), Ve({
1071
+ return g.log("Starting a PHP server..."), Oe({
1048
1072
  port: e.port,
1049
1073
  onBind: async (l, p) => {
1050
- const c = "127.0.0.1", d = `http://${c}:${p}`, m = e["site-url"] || d, b = e.experimentalMultiWorker ?? 1, v = Math.floor(
1051
- Number.MAX_SAFE_INTEGER / b
1052
- ), I = "-playground-cli-site-", k = await Ge(
1053
- I
1074
+ const c = "127.0.0.1", d = `http://${c}:${p}`, h = e["site-url"] || d, b = e.experimentalMultiWorker ?? 1, S = b + 1, x = Math.floor(
1075
+ Number.MAX_SAFE_INTEGER / S
1076
+ ), W = "-playground-cli-site-", k = await Ke(
1077
+ W
1054
1078
  );
1055
- h.debug(`Native temp dir for VFS root: ${k.path}`);
1056
- const x = "WP Playground CLI - Listen for Xdebug", f = ".playground-xdebug-root", W = g.join(process.cwd(), f);
1057
- if (await rt(W), e.xdebug && e.experimentalUnsafeIdeIntegration) {
1058
- await ot(
1079
+ g.debug(`Native temp dir for VFS root: ${k.path}`);
1080
+ const f = "WP Playground CLI - Listen for Xdebug", j = ".playground-xdebug-root", q = m.join(process.cwd(), j);
1081
+ if (await nt(q), e.xdebug && e.experimentalUnsafeIdeIntegration) {
1082
+ await rt(
1059
1083
  k.path,
1060
- W,
1084
+ q,
1061
1085
  process.platform
1062
1086
  );
1063
- const y = {
1064
- hostPath: `./${f}`,
1087
+ const w = {
1088
+ hostPath: m.join(".", m.sep, j),
1065
1089
  vfsPath: "/"
1066
1090
  };
1067
1091
  try {
1068
- await lt(x, process.cwd());
1069
- const w = typeof e.xdebug == "object" ? e.xdebug : void 0, L = await at({
1070
- name: x,
1092
+ await ct(f, process.cwd());
1093
+ const y = typeof e.xdebug == "object" ? e.xdebug : void 0, $ = await lt({
1094
+ name: f,
1071
1095
  host: c,
1072
1096
  port: p,
1073
1097
  ides: e.experimentalUnsafeIdeIntegration,
1074
1098
  cwd: process.cwd(),
1075
1099
  mounts: [
1076
- y,
1100
+ w,
1077
1101
  ...e["mount-before-install"] || [],
1078
1102
  ...e.mount || []
1079
1103
  ],
1080
- ideKey: w?.ideKey
1081
- }), S = e.experimentalUnsafeIdeIntegration, T = S.includes("vscode"), B = S.includes("phpstorm");
1082
- console.log(""), console.log(U("Xdebug configured successfully")), console.log(
1083
- Z("Updated IDE config: ") + L.join(" ")
1104
+ ideKey: y?.ideKey
1105
+ }), P = e.experimentalUnsafeIdeIntegration, I = P.includes("vscode"), C = P.includes("phpstorm");
1106
+ console.log(""), console.log(N("Xdebug configured successfully")), console.log(
1107
+ K("Updated IDE config: ") + $.join(" ")
1084
1108
  ), console.log(
1085
- Z("Playground source root: ") + ".playground-xdebug-root" + N(
1086
- ct(
1109
+ K("Playground source root: ") + ".playground-xdebug-root" + V(
1110
+ pt(
1087
1111
  " – you can set breakpoints and preview Playground's VFS structure in there."
1088
1112
  )
1089
1113
  )
1090
- ), console.log(""), T && (console.log(U("VS Code / Cursor instructions:")), console.log(
1114
+ ), console.log(""), I && (console.log(N("VS Code / Cursor instructions:")), console.log(
1091
1115
  " 1. Open the Run and Debug panel on the left sidebar"
1092
1116
  ), console.log(
1093
- ` 2. Select "${N(
1094
- x
1117
+ ` 2. Select "${V(
1118
+ f
1095
1119
  )}" from the dropdown`
1096
1120
  ), console.log(' 3. Click "start debugging"'), console.log(
1097
1121
  " 4. Set a breakpoint. For example, in .playground-xdebug-root/wordpress/index.php"
1098
1122
  ), console.log(
1099
1123
  " 5. Visit Playground in your browser to hit the breakpoint"
1100
- ), B && console.log("")), B && (console.log(U("PhpStorm instructions:")), console.log(
1101
- ` 1. Choose "${N(
1102
- x
1124
+ ), C && console.log("")), C && (console.log(N("PhpStorm instructions:")), console.log(
1125
+ ` 1. Choose "${V(
1126
+ f
1103
1127
  )}" debug configuration in the toolbar`
1104
1128
  ), console.log(" 2. Click the debug button (bug icon)`"), console.log(
1105
1129
  " 3. Set a breakpoint. For example, in .playground-xdebug-root/wordpress/index.php"
1106
1130
  ), console.log(
1107
1131
  " 4. Visit Playground in your browser to hit the breakpoint"
1108
1132
  )), console.log("");
1109
- } catch (w) {
1133
+ } catch (y) {
1110
1134
  throw new Error("Could not configure Xdebug", {
1111
- cause: w
1135
+ cause: y
1112
1136
  });
1113
1137
  }
1114
1138
  }
1115
- const ie = g.dirname(k.path), se = 2 * 24 * 60 * 60 * 1e3;
1116
- Ke(
1117
- I,
1118
- se,
1119
- ie
1139
+ const ce = m.dirname(k.path), pe = 2 * 24 * 60 * 60 * 1e3;
1140
+ Qe(
1141
+ W,
1142
+ pe,
1143
+ ce
1120
1144
  );
1121
- const F = g.join(k.path, "internal");
1122
- z(F);
1123
- const ae = [
1145
+ const F = m.join(k.path, "internal");
1146
+ J(F);
1147
+ const ue = [
1124
1148
  "wordpress",
1125
1149
  // Note: These dirs are from Emscripten's "default dirs" list:
1126
1150
  // https://github.com/emscripten-core/emscripten/blob/f431ec220e472e1f8d3db6b52fe23fb377facf30/src/lib/libfs.js#L1400-L1402
@@ -1131,106 +1155,106 @@ async function pt(e) {
1131
1155
  "tmp",
1132
1156
  "home"
1133
1157
  ];
1134
- for (const y of ae) {
1135
- const w = (S) => S.vfsPath === `/${y}`;
1136
- if (!(e["mount-before-install"]?.some(w) || e.mount?.some(w))) {
1137
- const S = g.join(
1158
+ for (const w of ue) {
1159
+ const y = (P) => P.vfsPath === `/${w}`;
1160
+ if (!(e["mount-before-install"]?.some(y) || e.mount?.some(y))) {
1161
+ const P = m.join(
1138
1162
  k.path,
1139
- y
1163
+ w
1140
1164
  );
1141
- z(S), e["mount-before-install"] === void 0 && (e["mount-before-install"] = []), e["mount-before-install"].unshift({
1142
- vfsPath: `/${y}`,
1143
- hostPath: S
1165
+ J(P), e["mount-before-install"] === void 0 && (e["mount-before-install"] = []), e["mount-before-install"].unshift({
1166
+ vfsPath: `/${w}`,
1167
+ hostPath: P
1144
1168
  });
1145
1169
  }
1146
1170
  }
1147
1171
  if (e["mount-before-install"])
1148
- for (const y of e["mount-before-install"])
1149
- h.debug(
1150
- `Mount before WP install: ${y.vfsPath} -> ${y.hostPath}`
1172
+ for (const w of e["mount-before-install"])
1173
+ g.debug(
1174
+ `Mount before WP install: ${w.vfsPath} -> ${w.hostPath}`
1151
1175
  );
1152
1176
  if (e.mount)
1153
- for (const y of e.mount)
1154
- h.debug(
1155
- `Mount after WP install: ${y.vfsPath} -> ${y.hostPath}`
1177
+ for (const w of e.mount)
1178
+ g.debug(
1179
+ `Mount after WP install: ${w.vfsPath} -> ${w.hostPath}`
1156
1180
  );
1157
- let C;
1158
- e["experimental-blueprints-v2-runner"] ? C = new Xe(e, {
1159
- siteUrl: m,
1160
- processIdSpaceLength: v
1161
- }) : (C = new Ye(e, {
1162
- siteUrl: m,
1163
- processIdSpaceLength: v
1164
- }), typeof e.blueprint == "string" && (e.blueprint = await ze({
1181
+ let L;
1182
+ e["experimental-blueprints-v2-runner"] ? L = new Je(e, {
1183
+ siteUrl: h,
1184
+ processIdSpaceLength: x
1185
+ }) : (L = new Ge(e, {
1186
+ siteUrl: h,
1187
+ processIdSpaceLength: x
1188
+ }), typeof e.blueprint == "string" && (e.blueprint = await Xe({
1165
1189
  sourceString: e.blueprint,
1166
1190
  blueprintMayReadAdjacentFiles: e["blueprint-may-read-adjacent-files"] === !0
1167
1191
  })));
1168
1192
  let M = !1;
1169
1193
  const D = async function() {
1170
1194
  M || (M = !0, await Promise.all(
1171
- i.map(async ({ playground: w, worker: L }) => {
1172
- await w.dispose(), await L.terminate();
1195
+ i.map(async ({ playground: y, worker: $ }) => {
1196
+ await y.dispose(), await $.terminate();
1173
1197
  })
1174
- ), l && await new Promise((w) => l.close(w)), await k.cleanup());
1175
- }, le = ut(
1176
- b,
1177
- C.getWorkerType(),
1178
- ({ exitCode: y, workerIndex: w }) => {
1179
- M || y === 0 && h.error(
1180
- `Worker ${w} exited with code ${y}
1198
+ ), l && await new Promise((y) => l.close(y)), await k.cleanup());
1199
+ }, de = dt(
1200
+ S,
1201
+ L.getWorkerType(),
1202
+ ({ exitCode: w, workerIndex: y }) => {
1203
+ M || w === 0 && g.error(
1204
+ `Worker ${y} exited with code ${w}
1181
1205
  `
1182
1206
  );
1183
1207
  }
1184
1208
  );
1185
- h.log(`Setting up WordPress ${e.wp}`);
1209
+ g.log(`Setting up WordPress ${e.wp}`);
1186
1210
  try {
1187
- const [y, ...w] = await le, L = await Y(
1211
+ const w = await de, y = await Q(
1188
1212
  n
1189
1213
  );
1190
- if (t = await C.bootPrimaryWorker(
1191
- y.phpPort,
1192
- L,
1193
- F
1194
- ), i.push({
1195
- playground: t,
1196
- worker: y.worker
1197
- }), await t.isReady(), r = !0, h.log("Booted!"), o = new He(t), !e["experimental-blueprints-v2-runner"]) {
1198
- const S = await C.compileInputBlueprint(
1199
- e["additional-blueprint-steps"] || []
1200
- );
1201
- S && (h.log("Running the Blueprint..."), await be(
1202
- S,
1203
- t
1204
- ), h.log("Finished running the blueprint"));
1205
- }
1206
- if (e.command === "build-snapshot") {
1207
- await ft(t, e.outfile), h.log(`WordPress exported to ${e.outfile}`), await D();
1208
- return;
1209
- } else if (e.command === "run-blueprint") {
1210
- h.log("Blueprint executed"), await D();
1211
- return;
1212
- }
1213
- if (e.experimentalMultiWorker && e.experimentalMultiWorker > 1) {
1214
- h.log("Preparing additional workers...");
1215
- const S = v;
1216
- await Promise.all(
1217
- w.map(async (T, B) => {
1218
- const ce = S + B * v, pe = await Y(n), H = await C.bootSecondaryWorker({
1219
- worker: T,
1220
- fileLockManagerPort: pe,
1221
- firstProcessId: ce,
1222
- nativeInternalDirPath: F
1223
- });
1224
- i.push({
1225
- playground: H,
1226
- worker: T.worker
1227
- }), o.addWorker(H);
1228
- })
1214
+ {
1215
+ const P = w.shift(), I = await L.bootAndSetUpInitialPlayground(
1216
+ P.phpPort,
1217
+ y,
1218
+ F
1229
1219
  );
1220
+ if (await I.isReady(), r = !0, g.log("Booted!"), o = new qe(I), !e["experimental-blueprints-v2-runner"]) {
1221
+ const C = await L.compileInputBlueprint(
1222
+ e["additional-blueprint-steps"] || []
1223
+ );
1224
+ C && (g.log("Running the Blueprint..."), await Pe(
1225
+ C,
1226
+ I
1227
+ ), g.log("Finished running the blueprint"));
1228
+ }
1229
+ if (e.command === "build-snapshot") {
1230
+ await mt(t, e.outfile), g.log(`WordPress exported to ${e.outfile}`), await D();
1231
+ return;
1232
+ } else if (e.command === "run-blueprint") {
1233
+ g.log("Blueprint executed"), await D();
1234
+ return;
1235
+ }
1236
+ await o.removeWorker(I), await I.dispose(), await P.worker.terminate();
1230
1237
  }
1231
- return h.log(
1238
+ g.log("Preparing workers...");
1239
+ const $ = x;
1240
+ return [t] = await Promise.all(
1241
+ w.map(async (P, I) => {
1242
+ const C = $ + I * x, fe = await Q(
1243
+ n
1244
+ ), A = await L.bootPlayground({
1245
+ worker: P,
1246
+ fileLockManagerPort: fe,
1247
+ firstProcessId: C,
1248
+ nativeInternalDirPath: F
1249
+ });
1250
+ return i.push({
1251
+ playground: A,
1252
+ worker: P.worker
1253
+ }), o.addWorker(A), A;
1254
+ })
1255
+ ), g.log(
1232
1256
  `WordPress is running on ${d} with ${b} worker(s)`
1233
- ), e.xdebug && e.experimentalDevtools && (await De({
1257
+ ), e.xdebug && e.experimentalDevtools && (await Ae({
1234
1258
  phpInstance: t,
1235
1259
  phpRoot: "/wordpress"
1236
1260
  })).start(), {
@@ -1240,16 +1264,16 @@ async function pt(e) {
1240
1264
  [Symbol.asyncDispose]: D,
1241
1265
  workerThreadCount: b
1242
1266
  };
1243
- } catch (y) {
1267
+ } catch (w) {
1244
1268
  if (!e.debug)
1245
- throw y;
1246
- let w = "";
1247
- throw await t?.fileExists(q) && (w = await t.readFileAsText(q)), new Error(w, { cause: y });
1269
+ throw w;
1270
+ let y = "";
1271
+ throw await t?.fileExists(z) && (y = await t.readFileAsText(z)), new Error(y, { cause: w });
1248
1272
  }
1249
1273
  },
1250
1274
  async handleRequest(l) {
1251
1275
  if (!r)
1252
- return V.forHttpCode(
1276
+ return O.forHttpCode(
1253
1277
  502,
1254
1278
  "WordPress is not ready yet"
1255
1279
  );
@@ -1264,16 +1288,16 @@ async function pt(e) {
1264
1288
  "playground_auto_login_already_happened"
1265
1289
  ) && (p["Set-Cookie"] = [
1266
1290
  "playground_auto_login_already_happened=1; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Path=/"
1267
- ]), new V(302, p, new Uint8Array());
1291
+ ]), new O(302, p, new Uint8Array());
1268
1292
  }
1269
1293
  return await o.handleRequest(l);
1270
1294
  }
1271
1295
  });
1272
1296
  }
1273
- async function ut(e, o, t) {
1297
+ async function dt(e, o, t) {
1274
1298
  const i = [];
1275
1299
  for (let s = 0; s < e; s++) {
1276
- const n = await dt(o), r = (a) => {
1300
+ const n = await ft(o), r = (a) => {
1277
1301
  t({
1278
1302
  exitCode: a,
1279
1303
  workerIndex: s
@@ -1297,14 +1321,14 @@ async function ut(e, o, t) {
1297
1321
  }
1298
1322
  return Promise.all(i);
1299
1323
  }
1300
- async function dt(e) {
1301
- return e === "v1" ? new X(new URL("./worker-thread-v1.js", import.meta.url)) : new X(new URL("./worker-thread-v2.js", import.meta.url));
1324
+ async function ft(e) {
1325
+ return e === "v1" ? new Z(new URL("./worker-thread-v1.js", import.meta.url)) : new Z(new URL("./worker-thread-v2.js", import.meta.url));
1302
1326
  }
1303
- async function Y(e) {
1304
- const { port1: o, port2: t } = new Pe();
1305
- return await Ce() ? fe(e, null, o) : await me(e, o), t;
1327
+ async function Q(e) {
1328
+ const { port1: o, port2: t } = new ke();
1329
+ return await Le() ? ge(e, null, o) : await we(e, o), t;
1306
1330
  }
1307
- async function ft(e, o) {
1331
+ async function mt(e, o) {
1308
1332
  await e.run({
1309
1333
  code: `<?php
1310
1334
  $zip = new ZipArchive();
@@ -1329,8 +1353,8 @@ async function ft(e, o) {
1329
1353
  u.writeFileSync(o, t);
1330
1354
  }
1331
1355
  export {
1332
- _ as L,
1333
- Dt as p,
1334
- pt as r
1356
+ H as L,
1357
+ At as p,
1358
+ ut as r
1335
1359
  };
1336
- //# sourceMappingURL=run-cli-BBfr5tmj.js.map
1360
+ //# sourceMappingURL=run-cli-fhMEvo2X.js.map