@wp-playground/cli 3.0.54 → 3.1.1

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