@wp-playground/cli 3.1.19 → 3.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cli.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";const i=require("child_process");function t(){return!("Suspending"in WebAssembly||process.env.PLAYGROUND_NO_JSPI_RESPAWN||process.versions.bun||"Deno"in globalThis||process.execArgv.includes("--experimental-wasm-jspi")||parseInt(process.versions.node.split(".")[0],10)<23)}function o(){const r=process.argv.slice(2);Promise.resolve().then(()=>require("./run-cli-DGeb628T.cjs")).then(e=>e.runCli).then(({parseOptionsAndRunCLI:e})=>{e(r)})}if(t()){const r=Date.now(),e=i.spawn(process.execPath,["--experimental-wasm-jspi",...process.execArgv,...process.argv.slice(1)],{stdio:"inherit"});for(const s of["SIGINT","SIGTERM"])process.on(s,()=>e.kill(s));e.on("error",()=>{o()}),e.on("close",(s,n)=>{if(s!==0&&!n&&Date.now()-r<1e3){o();return}n?process.kill(process.pid,n):process.exit(s)})}else o();
1
+ "use strict";const i=require("child_process");function t(){return!("Suspending"in WebAssembly||process.env.PLAYGROUND_NO_JSPI_RESPAWN||process.versions.bun||"Deno"in globalThis||process.execArgv.includes("--experimental-wasm-jspi")||parseInt(process.versions.node.split(".")[0],10)<23)}function o(){const r=process.argv.slice(2);Promise.resolve().then(()=>require("./run-cli-B6Dm34vQ.cjs")).then(e=>e.runCli).then(({parseOptionsAndRunCLI:e})=>{e(r)})}if(t()){const r=Date.now(),e=i.spawn(process.execPath,["--experimental-wasm-jspi",...process.execArgv,...process.argv.slice(1)],{stdio:"inherit"});for(const s of["SIGINT","SIGTERM"])process.on(s,()=>e.kill(s));e.on("error",()=>{o()}),e.on("close",(s,n)=>{if(s!==0&&!n&&Date.now()-r<1e3){o();return}n?process.kill(process.pid,n):process.exit(s)})}else o();
2
2
  //# sourceMappingURL=cli.cjs.map
package/cli.js CHANGED
@@ -4,7 +4,7 @@ function t() {
4
4
  }
5
5
  function o() {
6
6
  const r = process.argv.slice(2);
7
- import("./run-cli-D1CmUFoL.js").then((e) => e.c).then(({ parseOptionsAndRunCLI: e }) => {
7
+ import("./run-cli-B9kBDU12.js").then((e) => e.c).then(({ parseOptionsAndRunCLI: e }) => {
8
8
  e(r);
9
9
  });
10
10
  }
package/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./run-cli-DGeb628T.cjs");exports.LogVerbosity=e.LogVerbosity;exports.internalsKeyForTesting=e.internalsKeyForTesting;exports.mergeDefinedConstants=e.mergeDefinedConstants;exports.parseOptionsAndRunCLI=e.parseOptionsAndRunCLI;exports.runCLI=e.runCLI;exports.spawnWorkerThread=e.spawnWorkerThread;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./run-cli-B6Dm34vQ.cjs");exports.LogVerbosity=e.LogVerbosity;exports.internalsKeyForTesting=e.internalsKeyForTesting;exports.mergeDefinedConstants=e.mergeDefinedConstants;exports.parseOptionsAndRunCLI=e.parseOptionsAndRunCLI;exports.runCLI=e.runCLI;exports.spawnWorkerThread=e.spawnWorkerThread;
2
2
  //# sourceMappingURL=index.cjs.map
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { L as r, i as a, m as n, p as o, r as t, s as i } from "./run-cli-D1CmUFoL.js";
1
+ import { L as r, i as a, m as n, p as o, r as t, s as i } from "./run-cli-B9kBDU12.js";
2
2
  export {
3
3
  r as LogVerbosity,
4
4
  a as internalsKeyForTesting,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wp-playground/cli",
3
- "version": "3.1.19",
3
+ "version": "3.1.20",
4
4
  "description": "WordPress Playground CLI",
5
5
  "repository": {
6
6
  "type": "git",
@@ -34,7 +34,7 @@
34
34
  "bin": {
35
35
  "wp-playground-cli": "wp-playground.js"
36
36
  },
37
- "gitHead": "be542ee28a5966eeb28154cd8e3723db5ff9df07",
37
+ "gitHead": "98cfca0a050ef1dacce25710d6ebdf816e80b764",
38
38
  "dependencies": {
39
39
  "@zip.js/zip.js": "2.7.57",
40
40
  "ajv": "8.12.0",
@@ -58,21 +58,21 @@
58
58
  "simple-get": "4.0.1",
59
59
  "tmp-promise": "3.0.3",
60
60
  "wasm-feature-detect": "1.8.0",
61
- "ws": "8.18.3",
61
+ "ws": "8.18.0",
62
62
  "xml2js": "0.6.2",
63
63
  "yargs": "17.7.2",
64
- "@wp-playground/common": "3.1.19",
65
- "@php-wasm/logger": "3.1.19",
66
- "@php-wasm/progress": "3.1.19",
67
- "@php-wasm/universal": "3.1.19",
68
- "@wp-playground/blueprints": "3.1.19",
69
- "@wp-playground/wordpress": "3.1.19",
70
- "@php-wasm/node": "3.1.19",
71
- "@php-wasm/util": "3.1.19",
72
- "@php-wasm/cli-util": "3.1.19",
73
- "@wp-playground/storage": "3.1.19",
74
- "@php-wasm/xdebug-bridge": "3.1.19",
75
- "@wp-playground/tools": "3.1.19"
64
+ "@wp-playground/common": "3.1.20",
65
+ "@php-wasm/logger": "3.1.20",
66
+ "@php-wasm/progress": "3.1.20",
67
+ "@php-wasm/universal": "3.1.20",
68
+ "@wp-playground/blueprints": "3.1.20",
69
+ "@wp-playground/wordpress": "3.1.20",
70
+ "@php-wasm/node": "3.1.20",
71
+ "@php-wasm/util": "3.1.20",
72
+ "@php-wasm/cli-util": "3.1.20",
73
+ "@wp-playground/storage": "3.1.20",
74
+ "@php-wasm/xdebug-bridge": "3.1.20",
75
+ "@wp-playground/tools": "3.1.20"
76
76
  },
77
77
  "packageManager": "npm@10.9.2",
78
78
  "overrides": {
@@ -84,6 +84,7 @@
84
84
  "tmp": "0.2.5",
85
85
  "form-data": "^4.0.4",
86
86
  "lodash": "^4.17.23",
87
- "glob": "^9.3.0"
87
+ "glob": "^9.3.0",
88
+ "webpackbar": "^7.0.0"
88
89
  }
89
90
  }
@@ -12,9 +12,9 @@
12
12
  switch_theme($themeName);
13
13
  }
14
14
  }
15
- `}};function he(e){const t=e.autoMount,r=[...e.mount||[]],o=[...e["mount-before-install"]||[]],n={...e,mount:r,"mount-before-install":o,"additional-blueprint-steps":[...e["additional-blueprint-steps"]||[]]};if(Le(t)){const i=`/wordpress/wp-content/plugins/${d.basename(t)}`;r.push({hostPath:t,vfsPath:i,autoMounted:!0}),n["additional-blueprint-steps"].push({step:"activatePlugin",pluginPath:`/wordpress/wp-content/plugins/${d.basename(t)}`})}else if(De(t)){const s=d.basename(t),i=`/wordpress/wp-content/themes/${s}`;r.push({hostPath:t,vfsPath:i,autoMounted:!0}),n["additional-blueprint-steps"].push(e["experimental-blueprints-v2-runner"]?{step:"activateTheme",themeDirectoryName:s}:{step:"activateTheme",themeFolderName:s})}else if(Be(t)){const s=c.readdirSync(t);for(const i of s)i!=="index.php"&&r.push({hostPath:`${t}/${i}`,vfsPath:`/wordpress/wp-content/${i}`,autoMounted:!0});n["additional-blueprint-steps"].push(ue)}else Ae(t)&&(o.push({hostPath:t,vfsPath:"/wordpress",autoMounted:!0}),n.mode="apply-to-existing-site",n["additional-blueprint-steps"].push(ue),n.wordpressInstallMode||(n.wordpressInstallMode="install-from-existing-files-if-needed"));return n}function Ae(e){const t=c.readdirSync(e);return t.includes("wp-admin")&&t.includes("wp-includes")&&t.includes("wp-content")}function Be(e){const t=c.readdirSync(e);return t.includes("themes")||t.includes("plugins")||t.includes("mu-plugins")||t.includes("uploads")}function De(e){if(!c.readdirSync(e).includes("style.css"))return!1;const r=c.readFileSync(d.join(e,"style.css"),"utf8");return!!/^(?:[ \t]*<\?php)?[ \t/*#@]*Theme Name:(.*)$/im.exec(r)}function Le(e){const t=c.readdirSync(e),r=/^(?:[ \t]*<\?php)?[ \t/*#@]*Plugin Name:(.*)$/im;return!!t.filter(n=>n.endsWith(".php")).find(n=>{const s=c.readFileSync(d.join(e,n),"utf8");return!!r.exec(s)})}function _e(e){if(e.length%2!==0)throw new Error("Invalid constant definition format. Expected pairs of NAME value");const t={};for(let r=0;r<e.length;r+=2){const o=e[r],n=e[r+1];if(!o||!o.trim())throw new Error("Constant name cannot be empty");t[o.trim()]=n}return t}function Ue(e){if(e.length%2!==0)throw new Error("Invalid boolean constant definition format. Expected pairs of NAME value");const t={};for(let r=0;r<e.length;r+=2){const o=e[r],n=e[r+1].trim().toLowerCase();if(!o||!o.trim())throw new Error("Constant name cannot be empty");if(n==="true"||n==="1")t[o.trim()]=!0;else if(n==="false"||n==="0")t[o.trim()]=!1;else throw new Error(`Invalid boolean value for constant "${o}": "${n}". Must be "true", "false", "1", or "0".`)}return t}function We(e){if(e.length%2!==0)throw new Error("Invalid number constant definition format. Expected pairs of NAME value");const t={};for(let r=0;r<e.length;r+=2){const o=e[r],n=e[r+1].trim();if(!o||!o.trim())throw new Error("Constant name cannot be empty");const s=Number(n);if(isNaN(s))throw new Error(`Invalid number value for constant "${o}": "${n}". Must be a valid number.`);t[o.trim()]=s}return t}function He(e={},t={},r={}){const o={},n=new Set,s=(i,l)=>{for(const u in i){if(n.has(u))throw new Error(`Constant "${u}" is defined multiple times across different --define-${l} flags`);n.add(u),o[u]=i[u]}};return s(e,"string"),s(t,"bool"),s(r,"number"),o}function j(e){return He(e.define,e["define-bool"],e["define-number"])}const Ne=xe.promisify(pe.exec);function Fe(e){return new Promise(t=>{if(e===0)return t(!1);const r=me().listen(e);r.once("listening",()=>r.close(()=>t(!1))),r.once("error",o=>t(o.code==="EADDRINUSE"))})}async function Oe(e){const t=me(),r=await new Promise((i,l)=>{const u=t.listen(e.port,()=>{const w=u.address();w===null||typeof w=="string"?l(new Error("Server address is not available")):i(u)}).once("error",l)});t.use("/",async(i,l)=>{try{const u={url:i.url,headers:Ye(i),method:i.method,body:await je(i)},w=await e.handleRequest(u);await qe(w,l)}catch(u){m.logger.error(u),l.headersSent||(l.statusCode=500,l.end("Internal Server Error"))}});const n=r.address().port,s=process.env.CODESPACE_NAME;return s&&Ve(n,s),await e.onBind(r,n)}async function qe(e,t){const[r,o]=await Promise.all([e.headers,e.httpStatusCode]);t.statusCode=o;for(const s in r)t.setHeader(s,r[s]);const n=Ee.Readable.fromWeb(e.stdout);try{await Te.pipeline(n,t)}catch(s){if(s instanceof Error&&"code"in s&&(s.code==="ERR_STREAM_PREMATURE_CLOSE"||s.code==="ERR_STREAM_UNABLE_TO_PIPE"))return;throw s}}const je=async e=>await new Promise(t=>{const r=[];e.on("data",o=>{r.push(o)}),e.on("end",()=>{t(new Uint8Array(Buffer.concat(r)))})});async function Ve(e,t){m.logger.log(`Publishing port ${e}...`);const r=`gh codespace ports visibility ${e}:public -c ${t}`;for(let o=0;o<10;o++)try{await Ne(r);return}catch{await new Promise(n=>setTimeout(n,2e3))}}const Ye=e=>{const t={};if(e.rawHeaders&&e.rawHeaders.length)for(let r=0;r<e.rawHeaders.length;r+=2)t[e.rawHeaders[r].toLowerCase()]=e.rawHeaders[r+1];return t};function ze(e){return/^latest$|^beta$|^trunk$|^nightly$|^(?:(\d+)\.(\d+)(?:\.(\d+))?)((?:-beta(?:\d+)?)|(?:-RC(?:\d+)?))?$/.test(e)}async function Ge({sourceString:e,blueprintMayReadAdjacentFiles:t}){if(!e)return;if(e.startsWith("http://")||e.startsWith("https://"))return await M.resolveRemoteBlueprint(e);let r=d.resolve(process.cwd(),e);if(!c.existsSync(r))throw new Error(`Blueprint file does not exist: ${r}`);const o=c.statSync(r);if(o.isDirectory()&&(r=d.join(r,"blueprint.json")),!o.isFile()&&o.isSymbolicLink())throw new Error(`Blueprint path is neither a file nor a directory: ${r}`);const n=d.extname(r);switch(n){case".zip":return N.ZipFilesystem.fromArrayBuffer(c.readFileSync(r).buffer);case".json":{const s=c.readFileSync(r,"utf-8");try{JSON.parse(s)}catch{throw new Error(`Blueprint file at ${r} is not a valid JSON file`)}const i=d.dirname(r),l=new N.NodeJsFilesystem(i);return new N.OverlayFilesystem([new N.InMemoryFilesystem({"blueprint.json":s}),{read(u){if(!t)throw new Error(`Error: Blueprint contained tried to read a local file at path "${u}" (via a resource of type "bundled"). Playground restricts access to local resources by default as a security measure.
15
+ `}};function he(e){const t=e.autoMount,r=[...e.mount||[]],o=[...e["mount-before-install"]||[]],n={...e,mount:r,"mount-before-install":o,"additional-blueprint-steps":[...e["additional-blueprint-steps"]||[]]};if(Le(t)){const i=`/wordpress/wp-content/plugins/${d.basename(t)}`;r.push({hostPath:t,vfsPath:i,autoMounted:!0}),n["additional-blueprint-steps"].push({step:"activatePlugin",pluginPath:`/wordpress/wp-content/plugins/${d.basename(t)}`})}else if(De(t)){const s=d.basename(t),i=`/wordpress/wp-content/themes/${s}`;r.push({hostPath:t,vfsPath:i,autoMounted:!0}),n["additional-blueprint-steps"].push(e["experimental-blueprints-v2-runner"]?{step:"activateTheme",themeDirectoryName:s}:{step:"activateTheme",themeFolderName:s})}else if(Be(t)){const s=c.readdirSync(t);for(const i of s)i!=="index.php"&&r.push({hostPath:d.join(t,i),vfsPath:`/wordpress/wp-content/${i}`,autoMounted:!0});n["additional-blueprint-steps"].push(ue)}else Ae(t)&&(o.push({hostPath:t,vfsPath:"/wordpress",autoMounted:!0}),n.mode="apply-to-existing-site",n["additional-blueprint-steps"].push(ue),n.wordpressInstallMode||(n.wordpressInstallMode="install-from-existing-files-if-needed"));return n}function Ae(e){const t=c.readdirSync(e);return t.includes("wp-admin")&&t.includes("wp-includes")&&t.includes("wp-content")}function Be(e){const t=c.readdirSync(e);return t.includes("themes")||t.includes("plugins")||t.includes("mu-plugins")||t.includes("uploads")}function De(e){if(!c.readdirSync(e).includes("style.css"))return!1;const r=c.readFileSync(d.join(e,"style.css"),"utf8");return!!/^(?:[ \t]*<\?php)?[ \t/*#@]*Theme Name:(.*)$/im.exec(r)}function Le(e){const t=c.readdirSync(e),r=/^(?:[ \t]*<\?php)?[ \t/*#@]*Plugin Name:(.*)$/im;return!!t.filter(n=>n.endsWith(".php")).find(n=>{const s=c.readFileSync(d.join(e,n),"utf8");return!!r.exec(s)})}function _e(e){if(e.length%2!==0)throw new Error("Invalid constant definition format. Expected pairs of NAME value");const t={};for(let r=0;r<e.length;r+=2){const o=e[r],n=e[r+1];if(!o||!o.trim())throw new Error("Constant name cannot be empty");t[o.trim()]=n}return t}function Ue(e){if(e.length%2!==0)throw new Error("Invalid boolean constant definition format. Expected pairs of NAME value");const t={};for(let r=0;r<e.length;r+=2){const o=e[r],n=e[r+1].trim().toLowerCase();if(!o||!o.trim())throw new Error("Constant name cannot be empty");if(n==="true"||n==="1")t[o.trim()]=!0;else if(n==="false"||n==="0")t[o.trim()]=!1;else throw new Error(`Invalid boolean value for constant "${o}": "${n}". Must be "true", "false", "1", or "0".`)}return t}function We(e){if(e.length%2!==0)throw new Error("Invalid number constant definition format. Expected pairs of NAME value");const t={};for(let r=0;r<e.length;r+=2){const o=e[r],n=e[r+1].trim();if(!o||!o.trim())throw new Error("Constant name cannot be empty");const s=Number(n);if(isNaN(s))throw new Error(`Invalid number value for constant "${o}": "${n}". Must be a valid number.`);t[o.trim()]=s}return t}function He(e={},t={},r={}){const o={},n=new Set,s=(i,l)=>{for(const u in i){if(n.has(u))throw new Error(`Constant "${u}" is defined multiple times across different --define-${l} flags`);n.add(u),o[u]=i[u]}};return s(e,"string"),s(t,"bool"),s(r,"number"),o}function j(e){return He(e.define,e["define-bool"],e["define-number"])}const Ne=xe.promisify(pe.exec);function Fe(e){return new Promise(t=>{if(e===0)return t(!1);const r=me().listen(e);r.once("listening",()=>r.close(()=>t(!1))),r.once("error",o=>t(o.code==="EADDRINUSE"))})}async function Oe(e){const t=me(),r=await new Promise((i,l)=>{const u=t.listen(e.port,()=>{const w=u.address();w===null||typeof w=="string"?l(new Error("Server address is not available")):i(u)}).once("error",l)});t.use("/",async(i,l)=>{try{const u={url:i.url,headers:Ye(i),method:i.method,body:await je(i)},w=await e.handleRequest(u);await qe(w,l)}catch(u){m.logger.error(u),l.headersSent||(l.statusCode=500,l.end("Internal Server Error"))}});const n=r.address().port,s=process.env.CODESPACE_NAME;return s&&Ve(n,s),await e.onBind(r,n)}async function qe(e,t){const[r,o]=await Promise.all([e.headers,e.httpStatusCode]);t.statusCode=o;for(const s in r)t.setHeader(s,r[s]);const n=Ee.Readable.fromWeb(e.stdout);try{await Te.pipeline(n,t)}catch(s){if(s instanceof Error&&"code"in s&&(s.code==="ERR_STREAM_PREMATURE_CLOSE"||s.code==="ERR_STREAM_UNABLE_TO_PIPE"))return;throw s}}const je=async e=>await new Promise(t=>{const r=[];e.on("data",o=>{r.push(o)}),e.on("end",()=>{t(new Uint8Array(Buffer.concat(r)))})});async function Ve(e,t){m.logger.log(`Publishing port ${e}...`);const r=`gh codespace ports visibility ${e}:public -c ${t}`;for(let o=0;o<10;o++)try{await Ne(r);return}catch{await new Promise(n=>setTimeout(n,2e3))}}const Ye=e=>{const t={};if(e.rawHeaders&&e.rawHeaders.length)for(let r=0;r<e.rawHeaders.length;r+=2)t[e.rawHeaders[r].toLowerCase()]=e.rawHeaders[r+1];return t};function ze(e){return/^latest$|^beta$|^trunk$|^nightly$|^(?:(\d+)\.(\d+)(?:\.(\d+))?)((?:-beta(?:\d+)?)|(?:-RC(?:\d+)?))?$/.test(e)}async function Ge({sourceString:e,blueprintMayReadAdjacentFiles:t}){if(!e)return;if(e.startsWith("http://")||e.startsWith("https://"))return await M.resolveRemoteBlueprint(e);let r=d.resolve(process.cwd(),e);if(!c.existsSync(r))throw new Error(`Blueprint file does not exist: ${r}`);const o=c.statSync(r);if(o.isDirectory()&&(r=d.join(r,"blueprint.json")),!o.isFile()&&o.isSymbolicLink())throw new Error(`Blueprint path is neither a file nor a directory: ${r}`);const n=d.extname(r);switch(n){case".zip":return N.ZipFilesystem.fromArrayBuffer(c.readFileSync(r).buffer);case".json":{const s=c.readFileSync(r,"utf-8");try{JSON.parse(s)}catch{throw new Error(`Blueprint file at ${r} is not a valid JSON file`)}const i=d.dirname(r),l=new N.NodeJsFilesystem(i);return new N.OverlayFilesystem([new N.InMemoryFilesystem({"blueprint.json":s}),{read(u){if(!t)throw new Error(`Error: Blueprint contained tried to read a local file at path "${u}" (via a resource of type "bundled"). Playground restricts access to local resources by default as a security measure.
16
16
 
17
- You can allow this Blueprint to read files from the same parent directory by explicitly adding the --blueprint-may-read-adjacent-files option to your command.`);return l.read(u)}}])}default:throw new Error(`Unsupported blueprint file extension: ${n}. Only .zip and .json files are supported.`)}}class Qe{constructor(t,r){this.args=t,this.siteUrl=r.siteUrl,this.phpVersion=t.php,this.cliOutput=r.cliOutput}getWorkerType(){return"v2"}async bootWordPress(t,r){const o={command:this.args.command,siteUrl:this.siteUrl,blueprint:this.args.blueprint,workerPostInstallMountsPort:r};return await t.bootWordPress(o,r),t}async bootRequestHandler({worker:t,fileLockManagerPort:r,nativeInternalDirPath:o}){const n=b.consumeAPI(t.phpPort);await n.useFileLockManager(r);const s={...this.args,phpVersion:this.phpVersion,siteUrl:this.siteUrl,processId:t.processId,trace:this.args.verbosity==="debug",withIntl:this.args.intl,withRedis:this.args.redis,withMemcached:this.args.memcached,withXdebug:!!this.args.xdebug,nativeInternalDirPath:o,mountsBeforeWpInstall:this.args["mount-before-install"]||[],mountsAfterWpInstall:this.args.mount||[],constants:j(this.args)};return await n.bootWorker(s),n}}const J=d.join(ee.homedir(),".wordpress-playground");async function Xe(){const e=typeof __dirname<"u"?__dirname:void 0;let t=d.join(e,"sqlite-database-integration.zip");if(!A.existsSync(t)){const r=ke.createRequire(typeof document>"u"?require("url").pathToFileURL(__filename).href:k&&k.tagName.toUpperCase()==="SCRIPT"&&k.src||new URL("run-cli-DGeb628T.cjs",document.baseURI).href),o=d.dirname(r.resolve("@wp-playground/wordpress-builds/package.json"));t=d.join(o,"src","sqlite-database-integration","sqlite-database-integration-trunk.zip")}return new File([await A.readFile(t)],d.basename(t))}async function Ze(e,t,r){const o=d.join(J,t);return A.existsSync(o)||(A.ensureDirSync(J),await Ke(e,o,r)),fe(o)}async function Ke(e,t,r){const n=(await r.monitorFetch(fetch(e))).body.getReader(),s=`${t}.partial`,i=A.createWriteStream(s);for(;;){const{done:l,value:u}=await n.read();if(u&&i.write(u),l)break}i.close(),i.closed||await new Promise((l,u)=>{i.on("finish",()=>{A.renameSync(s,t),l(null)}),i.on("error",w=>{A.removeSync(s),u(w)})})}function fe(e,t){return new File([A.readFileSync(e)],d.basename(e))}class Je{constructor(t,r){this.args=t,this.siteUrl=r.siteUrl,this.cliOutput=r.cliOutput}getWorkerType(){return"v1"}async bootWordPress(t,r){let o,n,s;const i=new se.EmscriptenDownloadMonitor;if(this.args.wordpressInstallMode==="download-and-install"){let w=!1;i.addEventListener("progress",B=>{if(w)return;const{loaded:p,total:E}=B.detail,y=Math.floor(Math.min(100,100*p/E));w=y===100,this.cliOutput.updateProgress("Downloading WordPress",y)}),o=await Ie.resolveWordPressRelease(this.args.wp),s=d.join(J,`prebuilt-wp-content-for-wp-${o.version}.zip`),n=c.existsSync(s)?fe(s):await Ze(o.releaseUrl,`${o.version}.zip`,i),m.logger.debug(`Resolved WordPress release URL: ${o?.releaseUrl}`)}let l;this.args.skipSqliteSetup?(m.logger.debug("Skipping SQLite integration plugin setup..."),l=void 0):(this.cliOutput.updateProgress("Preparing SQLite database"),l=await Xe()),this.cliOutput.updateProgress("Booting WordPress");const u=await M.resolveRuntimeConfiguration(this.getEffectiveBlueprint());return await t.bootWordPress({wpVersion:u.wpVersion,siteUrl:this.siteUrl,wordpressInstallMode:this.args.wordpressInstallMode||"download-and-install",wordPressZip:n&&await n.arrayBuffer(),sqliteIntegrationPluginZip:await l?.arrayBuffer(),constants:j(this.args)},r),s&&!this.args["mount-before-install"]&&!c.existsSync(s)&&(this.cliOutput.updateProgress("Caching WordPress for next boot"),c.writeFileSync(s,await _.zipDirectory(t,"/wordpress"))),t}async bootRequestHandler({worker:t,fileLockManagerPort:r,nativeInternalDirPath:o}){const n=b.consumeAPI(t.phpPort);await n.isConnected();const s=await M.resolveRuntimeConfiguration(this.getEffectiveBlueprint());return await n.useFileLockManager(r),await n.bootRequestHandler({phpVersion:s.phpVersion,siteUrl:this.siteUrl,mountsBeforeWpInstall:this.args["mount-before-install"]||[],mountsAfterWpInstall:this.args.mount||[],processId:t.processId,followSymlinks:this.args.followSymlinks===!0,trace:this.args.experimentalTrace===!0,withIntl:this.args.intl,withRedis:this.args.redis,withMemcached:this.args.memcached,withXdebug:!!this.args.xdebug,nativeInternalDirPath:o,pathAliases:this.args.pathAliases}),await n.isReady(),n}async compileInputBlueprint(t){const r=this.getEffectiveBlueprint(),o=new se.ProgressTracker;let n="",s=!1;return o.addEventListener("progress",i=>{if(s)return;s=i.detail.progress===100;const l=Math.floor(i.detail.progress);n=i.detail.caption||n||"Running Blueprint",this.cliOutput.updateProgress(n.trim(),l)}),await M.compileBlueprintV1(r,{progress:o,additionalSteps:t})}getEffectiveBlueprint(){const t=this.args.blueprint;return M.isBlueprintBundle(t)?t:{login:this.args.login,...t||{},preferredVersions:{php:this.args.php??t?.preferredVersions?.php??_.RecommendedPHPVersion,wp:this.args.wp??t?.preferredVersions?.wp??"latest",...t?.preferredVersions||{}}}}}async function et(e,t=!0){const o=`${d.basename(process.argv0)}${e}${process.pid}-`,n=await ie.dir({prefix:o,unsafeCleanup:!0});return t&&ie.setGracefulCleanup(),n}async function tt(e,t,r){const n=(await rt(e,t,r)).map(s=>new Promise(i=>{c.rm(s,{recursive:!0},l=>{l?m.logger.warn(`Failed to delete stale Playground temp dir: ${s}`,l):m.logger.info(`Deleted stale Playground temp dir: ${s}`),i()})}));await Promise.all(n)}async function rt(e,t,r){try{const o=c.readdirSync(r).map(s=>d.join(r,s)),n=[];for(const s of o)await ot(e,t,s)&&n.push(s);return n}catch(o){return m.logger.warn(`Failed to find stale Playground temp dirs: ${o}`),[]}}async function ot(e,t,r){if(!c.lstatSync(r).isDirectory())return!1;const n=d.basename(r);if(!n.includes(e))return!1;const s=n.match(new RegExp(`^(.+)${e}(\\d+)-`));if(!s)return!1;const i={executableName:s[1],pid:s[2]};if(nt(i.pid))return!1;const l=Date.now()-t;return c.statSync(r).mtime.getTime()<l}function nt(e,t){try{return process.kill(Number(e),0),!0}catch(r){const o=r,n=o&&typeof o.code=="string"?o.code:void 0;return n==="ESRCH"?!1:n==="EPERM"||n==="EACCES"?(m.logger.debug(`Permission denied while checking if process ${e} exists (code: ${n}).`,r),!0):(m.logger.warn(`Could not determine if process ${e} exists due to unexpected error${n?` (code: ${n})`:""}.`,r),!0)}}function we(e){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}class st{constructor(t){this.lastProgressLine="",this.progressActive=!1,this.verbosity=t.verbosity,this.writeStream=t.writeStream||process.stdout}get isTTY(){return!!this.writeStream.isTTY}get shouldRender(){return we(this.writeStream)}get isQuiet(){return this.verbosity==="quiet"}bold(t){return this.isTTY?`\x1B[1m${t}\x1B[0m`:t}dim(t){return this.isTTY?`\x1B[2m${t}\x1B[0m`:t}green(t){return this.isTTY?`\x1B[32m${t}\x1B[0m`:t}cyan(t){return this.isTTY?`\x1B[36m${t}\x1B[0m`:t}yellow(t){return this.isTTY?`\x1B[33m${t}\x1B[0m`:t}red(t){return this.isTTY?`\x1B[31m${t}\x1B[0m`:t}printBanner(){if(this.isQuiet)return;const t=this.bold("WordPress Playground CLI");this.writeStream.write(`
17
+ You can allow this Blueprint to read files from the same parent directory by explicitly adding the --blueprint-may-read-adjacent-files option to your command.`);return l.read(u)}}])}default:throw new Error(`Unsupported blueprint file extension: ${n}. Only .zip and .json files are supported.`)}}class Qe{constructor(t,r){this.args=t,this.siteUrl=r.siteUrl,this.phpVersion=t.php,this.cliOutput=r.cliOutput}getWorkerType(){return"v2"}async bootWordPress(t,r){const o={command:this.args.command,siteUrl:this.siteUrl,blueprint:this.args.blueprint,workerPostInstallMountsPort:r};return await t.bootWordPress(o,r),t}async bootRequestHandler({worker:t,fileLockManagerPort:r,nativeInternalDirPath:o}){const n=b.consumeAPI(t.phpPort);await n.useFileLockManager(r);const s={...this.args,phpVersion:this.phpVersion,siteUrl:this.siteUrl,processId:t.processId,trace:this.args.verbosity==="debug",withIntl:this.args.intl,withRedis:this.args.redis,withMemcached:this.args.memcached,withXdebug:!!this.args.xdebug,nativeInternalDirPath:o,mountsBeforeWpInstall:this.args["mount-before-install"]||[],mountsAfterWpInstall:this.args.mount||[],constants:j(this.args)};return await n.bootWorker(s),n}}const J=d.join(ee.homedir(),".wordpress-playground");async function Xe(){const e=typeof __dirname<"u"?__dirname:void 0;let t=d.join(e,"sqlite-database-integration.zip");if(!A.existsSync(t)){const r=ke.createRequire(typeof document>"u"?require("url").pathToFileURL(__filename).href:k&&k.tagName.toUpperCase()==="SCRIPT"&&k.src||new URL("run-cli-B6Dm34vQ.cjs",document.baseURI).href),o=d.dirname(r.resolve("@wp-playground/wordpress-builds/package.json"));t=d.join(o,"src","sqlite-database-integration","sqlite-database-integration-trunk.zip")}return new File([await A.readFile(t)],d.basename(t))}async function Ze(e,t,r){const o=d.join(J,t);return A.existsSync(o)||(A.ensureDirSync(J),await Ke(e,o,r)),fe(o)}async function Ke(e,t,r){const n=(await r.monitorFetch(fetch(e))).body.getReader(),s=`${t}.partial`,i=A.createWriteStream(s);for(;;){const{done:l,value:u}=await n.read();if(u&&i.write(u),l)break}i.close(),i.closed||await new Promise((l,u)=>{i.on("finish",()=>{A.renameSync(s,t),l(null)}),i.on("error",w=>{A.removeSync(s),u(w)})})}function fe(e,t){return new File([A.readFileSync(e)],d.basename(e))}class Je{constructor(t,r){this.args=t,this.siteUrl=r.siteUrl,this.cliOutput=r.cliOutput}getWorkerType(){return"v1"}async bootWordPress(t,r){let o,n,s;const i=new se.EmscriptenDownloadMonitor;if(this.args.wordpressInstallMode==="download-and-install"){let w=!1;i.addEventListener("progress",B=>{if(w)return;const{loaded:p,total:E}=B.detail,y=Math.floor(Math.min(100,100*p/E));w=y===100,this.cliOutput.updateProgress("Downloading WordPress",y)}),o=await Ie.resolveWordPressRelease(this.args.wp),s=d.join(J,`prebuilt-wp-content-for-wp-${o.version}.zip`),n=c.existsSync(s)?fe(s):await Ze(o.releaseUrl,`${o.version}.zip`,i),m.logger.debug(`Resolved WordPress release URL: ${o?.releaseUrl}`)}let l;this.args.skipSqliteSetup?(m.logger.debug("Skipping SQLite integration plugin setup..."),l=void 0):(this.cliOutput.updateProgress("Preparing SQLite database"),l=await Xe()),this.cliOutput.updateProgress("Booting WordPress");const u=await M.resolveRuntimeConfiguration(this.getEffectiveBlueprint());return await t.bootWordPress({wpVersion:u.wpVersion,siteUrl:this.siteUrl,wordpressInstallMode:this.args.wordpressInstallMode||"download-and-install",wordPressZip:n&&await n.arrayBuffer(),sqliteIntegrationPluginZip:await l?.arrayBuffer(),constants:j(this.args)},r),s&&!this.args["mount-before-install"]&&!c.existsSync(s)&&(this.cliOutput.updateProgress("Caching WordPress for next boot"),c.writeFileSync(s,await _.zipDirectory(t,"/wordpress"))),t}async bootRequestHandler({worker:t,fileLockManagerPort:r,nativeInternalDirPath:o}){const n=b.consumeAPI(t.phpPort);await n.isConnected();const s=await M.resolveRuntimeConfiguration(this.getEffectiveBlueprint());return await n.useFileLockManager(r),await n.bootRequestHandler({phpVersion:s.phpVersion,siteUrl:this.siteUrl,mountsBeforeWpInstall:this.args["mount-before-install"]||[],mountsAfterWpInstall:this.args.mount||[],processId:t.processId,followSymlinks:this.args.followSymlinks===!0,trace:this.args.experimentalTrace===!0,withIntl:this.args.intl,withRedis:this.args.redis,withMemcached:this.args.memcached,withXdebug:!!this.args.xdebug,nativeInternalDirPath:o,pathAliases:this.args.pathAliases}),await n.isReady(),n}async compileInputBlueprint(t){const r=this.getEffectiveBlueprint(),o=new se.ProgressTracker;let n="",s=!1;return o.addEventListener("progress",i=>{if(s)return;s=i.detail.progress===100;const l=Math.floor(i.detail.progress);n=i.detail.caption||n||"Running Blueprint",this.cliOutput.updateProgress(n.trim(),l)}),await M.compileBlueprintV1(r,{progress:o,additionalSteps:t})}getEffectiveBlueprint(){const t=this.args.blueprint;return M.isBlueprintBundle(t)?t:{login:this.args.login,...t||{},preferredVersions:{php:this.args.php??t?.preferredVersions?.php??_.RecommendedPHPVersion,wp:this.args.wp??t?.preferredVersions?.wp??"latest",...t?.preferredVersions||{}}}}}async function et(e,t=!0){const o=`${d.basename(process.argv0)}${e}${process.pid}-`,n=await ie.dir({prefix:o,unsafeCleanup:!0});return t&&ie.setGracefulCleanup(),n}async function tt(e,t,r){const n=(await rt(e,t,r)).map(s=>new Promise(i=>{c.rm(s,{recursive:!0},l=>{l?m.logger.warn(`Failed to delete stale Playground temp dir: ${s}`,l):m.logger.info(`Deleted stale Playground temp dir: ${s}`),i()})}));await Promise.all(n)}async function rt(e,t,r){try{const o=c.readdirSync(r).map(s=>d.join(r,s)),n=[];for(const s of o)await ot(e,t,s)&&n.push(s);return n}catch(o){return m.logger.warn(`Failed to find stale Playground temp dirs: ${o}`),[]}}async function ot(e,t,r){if(!c.lstatSync(r).isDirectory())return!1;const n=d.basename(r);if(!n.includes(e))return!1;const s=n.match(new RegExp(`^(.+)${e}(\\d+)-`));if(!s)return!1;const i={executableName:s[1],pid:s[2]};if(nt(i.pid))return!1;const l=Date.now()-t;return c.statSync(r).mtime.getTime()<l}function nt(e,t){try{return process.kill(Number(e),0),!0}catch(r){const o=r,n=o&&typeof o.code=="string"?o.code:void 0;return n==="ESRCH"?!1:n==="EPERM"||n==="EACCES"?(m.logger.debug(`Permission denied while checking if process ${e} exists (code: ${n}).`,r),!0):(m.logger.warn(`Could not determine if process ${e} exists due to unexpected error${n?` (code: ${n})`:""}.`,r),!0)}}function we(e){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}class st{constructor(t){this.lastProgressLine="",this.progressActive=!1,this.verbosity=t.verbosity,this.writeStream=t.writeStream||process.stdout}get isTTY(){return!!this.writeStream.isTTY}get shouldRender(){return we(this.writeStream)}get isQuiet(){return this.verbosity==="quiet"}bold(t){return this.isTTY?`\x1B[1m${t}\x1B[0m`:t}dim(t){return this.isTTY?`\x1B[2m${t}\x1B[0m`:t}green(t){return this.isTTY?`\x1B[32m${t}\x1B[0m`:t}cyan(t){return this.isTTY?`\x1B[36m${t}\x1B[0m`:t}yellow(t){return this.isTTY?`\x1B[33m${t}\x1B[0m`:t}red(t){return this.isTTY?`\x1B[31m${t}\x1B[0m`:t}printBanner(){if(this.isQuiet)return;const t=this.bold("WordPress Playground CLI");this.writeStream.write(`
18
18
  ${t}
19
19
 
20
20
  `)}printConfig(t){if(this.isQuiet)return;const r=[];r.push(`${this.dim("PHP")} ${this.cyan(t.phpVersion)} ${this.dim("WordPress")} ${this.cyan(t.wpVersion)}`);const o=[];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)for(const n of t.mounts){const s=n.autoMounted?` ${this.dim("(auto-mount)")}`:"";r.push(`${this.dim("Mount")} ${n.hostPath} ${this.dim("→")} ${n.vfsPath}${s}`)}t.blueprint&&r.push(`${this.dim("Blueprint")} ${t.blueprint}`),this.writeStream.write(r.join(`
@@ -45,7 +45,7 @@ Examples:
45
45
  wp-playground start --skip-browser # Skip opening browser
46
46
  wp-playground start --no-auto-mount # Disable auto-detection`).options(o)).command("server","Start a local WordPress server (advanced, low-level)",a=>a.options({...t,...r})).command("run-blueprint","Execute a Blueprint without starting a server",a=>a.options({...t})).command("build-snapshot","Build a ZIP snapshot of a WordPress site based on a Blueprint",a=>a.options({...t,...n})).command("php","Run a PHP script",a=>a.options({...t})).demandCommand(1,"Please specify a command").strictCommands().conflicts("experimental-unsafe-ide-integration","experimental-devtools").showHelpOnFail(!1).fail((a,T,v)=>{if(T)throw T;a&&a.includes("Please specify a command")&&(v.showHelp(),console.error(`
47
47
  `+a),process.exit(1)),console.error(a),process.exit(1)}).strictOptions().check(async a=>{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"&&!ze(a.wp))try{new URL(a.wp)}catch{throw new Error('Unrecognized WordPress version. Please use "latest", "beta", "trunk", "nightly", a URL, or a numeric version such as "6.2", "6.0.1", "6.2-beta1", or "6.2-RC1" (see --help for details).')}const T=a["site-url"];if(typeof T=="string"&&T.trim()!=="")try{new URL(T)}catch{throw new Error(`Invalid site-url "${T}". Please provide a valid URL (e.g., http://localhost:8080 or https://example.com)`)}if(a["auto-mount"]){let v=!1;try{v=c.statSync(a["auto-mount"]).isDirectory()}catch{v=!1}if(!v)throw new Error(`The specified --auto-mount path is not a directory: '${a["auto-mount"]}'.`)}if(a["experimental-blueprints-v2-runner"]===!0)throw new Error("Blueprints v2 are temporarily disabled while we rework their runtime implementation.");if(a.mode!==void 0)throw new Error("The --mode option requires the --experimentalBlueprintsV2Runner flag.");return!0});s.wrap(s.terminalWidth());const i=await s.argv,l=i._[0];["start","run-blueprint","server","build-snapshot","php"].includes(l)||(s.showHelp(),process.exit(1));const u=i.define||{},w=i["define-bool"]||{},B=i["define-number"]||{},p=a=>a in u||a in w||a in B;p("WP_DEBUG")||(u.WP_DEBUG="true"),p("WP_DEBUG_LOG")||(u.WP_DEBUG_LOG="true"),p("WP_DEBUG_DISPLAY")||(u.WP_DEBUG_DISPLAY="false");const E={...i,define:u,command:l,mount:[...i.mount||[],...i["mount-dir"]||[]],"mount-before-install":[...i["mount-before-install"]||[],...i["mount-dir-before-install"]||[]]},y=await te(E);y===void 0&&process.exit(0);const I=(()=>{let a;return async()=>{a===void 0&&(a=y[Symbol.asyncDispose]()),await a,process.exit(0)}})();return process.on("SIGINT",I),process.on("SIGTERM",I),{[Symbol.asyncDispose]:async()=>{process.off("SIGINT",I),process.off("SIGTERM",I),await y[Symbol.asyncDispose]()},[Y]:{cliServer:y}}}catch(t){console.error(t);const r=process.argv.includes("--debug");if(t instanceof Error)if(r)b.printDebugDetails(t);else{const o=[];let n=t;do o.push(n.message),n=n.cause;while(n instanceof Error);console.error("\x1B[1m"+o.join(" caused by: ")+"\x1B[0m")}else console.error("\x1B[1m"+be(t)+"\x1B[0m");process.exit(1)}}function be(e){if(e instanceof Error)return e.message;if(e&&typeof e=="object"){const t=[],r=e;if(r.name&&t.push(String(r.name)),r.message&&t.push(String(r.message)),r.errno!==void 0&&t.push(`errno: ${r.errno}`),t.length>0)return t.join(" — ");try{return JSON.stringify(e)}catch{return String(e)}}return String(e)}function de(e,t){return e.find(r=>r.vfsPath.replace(/\/$/,"")===t.replace(/\/$/,""))}const Y=Symbol("playground-cli-testing"),D=e=>process.stdout.isTTY?"\x1B[1m"+e+"\x1B[0m":e,it=e=>process.stdout.isTTY?"\x1B[31m"+e+"\x1B[0m":e,ce=e=>process.stdout.isTTY?`\x1B[2m${e}\x1B[0m`:e,O=e=>process.stdout.isTTY?`\x1B[3m${e}\x1B[0m`:e,Z=e=>process.stdout.isTTY?`\x1B[33m${e}\x1B[0m`:e;async function te(e){let t;const r=e.internalCookieStore?new b.HttpCookieStore:void 0,o=[],n=new Map;if(e.command==="start"&&(e=at(e)),e.autoMount!==void 0&&(e.autoMount===""&&(e={...e,autoMount:process.cwd()}),e=he(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){const p=Object.values(V).find(E=>E.name===e.verbosity).severity;m.logger.setSeverityFilterLevel(p)}e.intl||(e.intl=!0),e.redis===void 0&&(e.redis=await ae.jspi()),e.memcached===void 0&&(e.memcached=await ae.jspi()),e.phpmyadmin&&(e.phpmyadmin===!0&&(e.phpmyadmin="/phpmyadmin"),e.pathAliases=[{urlPrefix:e.phpmyadmin,fsPath:F.PHPMYADMIN_INSTALL_PATH}]);const s=new st({verbosity:e.verbosity||"normal"});e.command==="server"&&(s.printBanner(),s.printConfig({phpVersion:e.php||_.RecommendedPHPVersion,wpVersion:e.wp||"latest",port:e.port??9400,xdebug:!!e.xdebug,intl:!!e.intl,redis:!!e.redis,memcached:!!e.memcached,mounts:[...e.mount||[],...e["mount-before-install"]||[]],blueprint:typeof e.blueprint=="string"?e.blueprint:void 0}));const i=e.command==="server"?e.port??9400:0,l=new b.FileLockManagerInMemory;let u=!1,w=!0;const B=await Oe({port:e.port?e.port:await Fe(i)?0:i,onBind:async(p,E)=>{const y="127.0.0.1",I=`http://${y}:${E}`,a=e["site-url"]||I,T=6,v="-playground-cli-site-",C=await et(v);m.logger.debug(`Native temp dir for VFS root: ${C.path}`);const W="WP Playground CLI - Listen for Xdebug",oe=".playground-xdebug-root",z=d.join(process.cwd(),oe);if(await R.removeTempDirSymlink(z),e.xdebug){const h={hostPath:d.join(".",d.sep,oe),vfsPath:"/"};if(b.SupportedPHPVersions.indexOf(e.php||_.RecommendedPHPVersion)<=b.SupportedPHPVersions.indexOf("8.5"))await R.createTempDirSymlink(C.path,z,process.platform),e.xdebug=R.makeXdebugConfig({cwd:process.cwd(),mounts:[h,...e["mount-before-install"]||[],...e.mount||[]],pathSkippings:[...R.DEFAULT_PATH_SKIPPINGS]}),console.log(D("Xdebug configured successfully")),console.log(Z("Playground source root: ")+".playground-xdebug-root"+O(ce(" – you can set breakpoints and preview Playground's VFS structure in there.")));else if(e.experimentalUnsafeIdeIntegration){await R.createTempDirSymlink(C.path,z,process.platform);try{await R.clearXdebugIDEConfig(W,process.cwd());const f=typeof e.xdebug=="object"?e.xdebug:{},g=await R.addXdebugIDEConfig({name:W,host:y,port:E,ides:e.experimentalUnsafeIdeIntegration,cwd:process.cwd(),mounts:[h,...e["mount-before-install"]||[],...e.mount||[]],pathSkippings:[...R.DEFAULT_PATH_SKIPPINGS],ideKey:f.ideKey||"WPPLAYGROUNDCLI"}),S=e.experimentalUnsafeIdeIntegration,x=S.includes("vscode"),$=S.includes("phpstorm"),H=Object.values(g);console.log(""),H.length>0?(console.log(D("Xdebug configured successfully")),console.log(Z("Updated IDE config: ")+H.join(" ")),console.log(Z("Playground source root: ")+".playground-xdebug-root"+O(ce(" – you can set breakpoints and preview Playground's VFS structure in there.")))):(console.log(D("Xdebug configuration failed.")),console.log("No IDE-specific project settings directory was found in the current working directory.")),console.log(""),x&&g.vscode&&(console.log(D("VS Code / Cursor instructions:")),console.log(" 1. Ensure you have installed an IDE extension for PHP Debugging"),console.log(` (The ${D("PHP Debug")} extension by ${D("Xdebug")} has been a solid option)`),console.log(" 2. Open the Run and Debug panel on the left sidebar"),console.log(` 3. Select "${O(W)}" from the dropdown`),console.log(' 3. Click "start debugging"'),console.log(" 5. Set a breakpoint. For example, in .playground-xdebug-root/wordpress/index.php"),console.log(" 6. Visit Playground in your browser to hit the breakpoint"),$&&console.log("")),$&&g.phpstorm&&(console.log(D("PhpStorm instructions:")),console.log(` 1. Choose "${O(W)}" debug configuration in the toolbar`),console.log(" 2. Click the debug button (bug icon)`"),console.log(" 3. Set a breakpoint. For example, in .playground-xdebug-root/wordpress/index.php"),console.log(" 4. Visit Playground in your browser to hit the breakpoint")),console.log("")}catch(f){throw new Error("Could not configure Xdebug",{cause:f})}}}const ge=d.dirname(C.path),Pe=2*24*60*60*1e3;tt(v,Pe,ge);const ne=d.join(C.path,"internal");c.mkdirSync(ne);const ve=["wordpress","tools","tmp","home"];for(const h of ve){const P=g=>g.vfsPath===`/${h}`;if(!(e["mount-before-install"]?.some(P)||e.mount?.some(P))){const g=d.join(C.path,h);c.mkdirSync(g),e["mount-before-install"]===void 0&&(e["mount-before-install"]=[]),e["mount-before-install"].unshift({vfsPath:`/${h}`,hostPath:g})}}if(e["mount-before-install"])for(const h of e["mount-before-install"])m.logger.debug(`Mount before WP install: ${h.vfsPath} -> ${h.hostPath}`);if(e.mount)for(const h of e.mount)m.logger.debug(`Mount after WP install: ${h.vfsPath} -> ${h.hostPath}`);let L;e["experimental-blueprints-v2-runner"]?L=new Qe(e,{siteUrl:a,cliOutput:s}):(L=new Je(e,{siteUrl:a,cliOutput:s}),typeof e.blueprint=="string"&&(e.blueprint=await Ge({sourceString:e.blueprint,blueprintMayReadAdjacentFiles:e["blueprint-may-read-adjacent-files"]===!0})));let G=!1;const U=async function(){G||(G=!0,await Promise.all(o.map(async P=>{await n.get(P)?.dispose(),await P.worker.terminate()})),p&&await new Promise(P=>{p.close(P),p.closeAllConnections()}),await C.cleanup())};try{const h=[],P=L.getWorkerType();for(let f=0;f<T;f++){const g=re(P,{onExit:S=>{G||S!==0&&m.logger.error(`Worker ${f} exited with code ${S}
48
- `)}}).then(async S=>{o.push(S);const x=await lt(l),$=await L.bootRequestHandler({worker:S,fileLockManagerPort:x,nativeInternalDirPath:ne});return n.set(S,$),[S,$]});h.push(g),f===0&&await g}await Promise.all(h),t=b.createObjectPoolProxy(o.map(f=>n.get(f)));{const f=new q.MessageChannel,g=f.port1,S=f.port2;if(await b.exposeAPI({applyPostInstallMountsToAllWorkers:async()=>{for(const x of n.values())await x.mountAfterWordPressInstall(e.mount||[])}},void 0,g),await L.bootWordPress(t,S),g.close(),u=!0,!e["experimental-blueprints-v2-runner"]){const x=await L.compileInputBlueprint(e["additional-blueprint-steps"]||[]);x&&await M.runBlueprintV1Steps(x,t)}if(e.phpmyadmin&&!await t.fileExists(`${F.PHPMYADMIN_INSTALL_PATH}/index.php`)){const x=await F.getPhpMyAdminInstallSteps(),$=await M.compileBlueprintV1({steps:x});await M.runBlueprintV1Steps($,t)}if(e.command==="build-snapshot"){await dt(t,e.outfile),s.printStatus(`Exported to ${e.outfile}`),await U();return}else if(e.command==="run-blueprint"){s.finishProgress("Done"),await U();return}else if(e.command==="php"){const x=["/internal/shared/bin/php",...(e._||[]).slice(1)],$=await t.cli(x),[H]=await Promise.all([$.exitCode,$.stdout.pipeTo(new WritableStream({write(Q){process.stdout.write(Q)}})),$.stderr.pipeTo(new WritableStream({write(Q){process.stderr.write(Q)}}))]);await U(),process.exit(H)}}if(s.finishProgress(),s.printReady(I,T),e.phpmyadmin){const f=d.join(e.phpmyadmin,F.PHPMYADMIN_ENTRY_PATH);s.printPhpMyAdminUrl(new URL(f,I).toString())}return e.xdebug&&e.experimentalDevtools&&(await Ce.startBridge({phpInstance:t,phpRoot:"/wordpress"})).start(),{playground:t,server:p,serverUrl:I,[Symbol.asyncDispose]:U,[Y]:{workerThreadCount:T}}}catch(h){if(e.verbosity!=="debug")throw h;let P="";throw await t?.fileExists(m.errorLogPath)&&(P=await t.readFileAsText(m.errorLogPath)),await U(),new Error(P,{cause:h})}},async handleRequest(p){if(!u)return b.StreamedPHPResponse.forHttpCode(502,"WordPress is not ready yet");if(w){w=!1;const y={"Content-Type":["text/plain"],"Content-Length":["0"],Location:[p.url]};return p.headers?.cookie?.includes("playground_auto_login_already_happened")&&(y["Set-Cookie"]=["playground_auto_login_already_happened=1; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Path=/"]),b.StreamedPHPResponse.fromPHPResponse(new b.PHPResponse(302,y,new Uint8Array))}r&&(p={...p,headers:{...p.headers,cookie:r.getCookieRequestHeader()}});const E=await t.requestStreamed(p);if(r){const y=await E.headers;r.rememberCookiesFromResponseHeaders(y),delete y["set-cookie"]}return E}}).catch(p=>{s.printError(be(p)),process.exit(1)});return B&&e.command==="start"&&!e.skipBrowser&&ut(B.serverUrl),B}function at(e){let t={...e,command:"server"};e.noAutoMount||(t.autoMount=d.resolve(process.cwd(),t.path??""),t=he(t),delete t.autoMount);const r=de(t["mount-before-install"]||[],"/wordpress")||de(t.mount||[],"/wordpress");if(r)console.log("Site files stored at:",r?.hostPath),e.reset&&(console.log(""),console.log(it("This site is not managed by Playground CLI and cannot be reset.")),console.log("(It's not stored in the ~/.wordpress-playground/sites/<site-id> directory.)"),console.log(""),console.log("You may still remove the site's directory manually if you wish."),process.exit(1));else{const o=t.autoMount||process.cwd(),n=Re.createHash("sha256").update(o).digest("hex"),s=ee.homedir(),i=d.join(s,".wordpress-playground/sites",n);console.log("Site files stored at:",i),c.existsSync(i)&&e.reset&&(console.log("Resetting site..."),c.rmdirSync(i,{recursive:!0})),c.mkdirSync(i,{recursive:!0}),t["mount-before-install"]=[...t["mount-before-install"]||[],{vfsPath:"/wordpress",hostPath:i}],t.wordpressInstallMode=c.readdirSync(i).length===0?"download-and-install":"install-from-existing-files-if-needed"}return t}const K=new b.ProcessIdAllocator;function re(e,{onExit:t}={}){let r;return e==="v1"?r=new q.Worker(new URL("./worker-thread-v1.cjs",typeof document>"u"?require("url").pathToFileURL(__filename).href:k&&k.tagName.toUpperCase()==="SCRIPT"&&k.src||new URL("run-cli-DGeb628T.cjs",document.baseURI).href)):r=new q.Worker(new URL("./worker-thread-v2.cjs",typeof document>"u"?require("url").pathToFileURL(__filename).href:k&&k.tagName.toUpperCase()==="SCRIPT"&&k.src||new URL("run-cli-DGeb628T.cjs",document.baseURI).href)),new Promise((o,n)=>{const s=K.claim();r.once("message",function(l){l.command==="worker-script-initialized"&&o({processId:s,worker:r,phpPort:l.phpPort})}),r.once("error",function(l){K.release(s),console.error(l);const u=l?.message||(l?String(l):"unknown error"),w=new Error(`Worker failed to load. Original error: ${u}`,{cause:l});n(w)});let i=!1;r.once("spawn",()=>{i=!0}),r.once("exit",l=>{K.release(s),i||n(new Error(`Worker exited before spawning: ${l}`)),t?.(l)})})}async function lt(e){const{port1:t,port2:r}=new q.MessageChannel;return await b.exposeSyncAPI(e,t),r}function ut(e){const t=ee.platform();let r;switch(t){case"darwin":r=`open "${e}"`;break;case"win32":r=`start "" "${e}"`;break;default:r=`xdg-open "${e}"`;break}pe.exec(r,o=>{o&&m.logger.debug(`Could not open browser: ${o.message}`)})}async function dt(e,t){await e.run({code:`<?php
48
+ `)}}).then(async S=>{o.push(S);const x=await lt(l),$=await L.bootRequestHandler({worker:S,fileLockManagerPort:x,nativeInternalDirPath:ne});return n.set(S,$),[S,$]});h.push(g),f===0&&await g}await Promise.all(h),t=b.createObjectPoolProxy(o.map(f=>n.get(f)));{const f=new q.MessageChannel,g=f.port1,S=f.port2;if(await b.exposeAPI({applyPostInstallMountsToAllWorkers:async()=>{for(const x of n.values())await x.mountAfterWordPressInstall(e.mount||[])}},void 0,g),await L.bootWordPress(t,S),g.close(),u=!0,!e["experimental-blueprints-v2-runner"]){const x=await L.compileInputBlueprint(e["additional-blueprint-steps"]||[]);x&&await M.runBlueprintV1Steps(x,t)}if(e.phpmyadmin&&!await t.fileExists(`${F.PHPMYADMIN_INSTALL_PATH}/index.php`)){const x=await F.getPhpMyAdminInstallSteps(),$=await M.compileBlueprintV1({steps:x});await M.runBlueprintV1Steps($,t)}if(e.command==="build-snapshot"){await dt(t,e.outfile),s.printStatus(`Exported to ${e.outfile}`),await U();return}else if(e.command==="run-blueprint"){s.finishProgress("Done"),await U();return}else if(e.command==="php"){const x=["/internal/shared/bin/php",...(e._||[]).slice(1)],$=await t.cli(x),[H]=await Promise.all([$.exitCode,$.stdout.pipeTo(new WritableStream({write(Q){process.stdout.write(Q)}})),$.stderr.pipeTo(new WritableStream({write(Q){process.stderr.write(Q)}}))]);await U(),process.exit(H)}}if(s.finishProgress(),s.printReady(I,T),e.phpmyadmin){const f=d.join(e.phpmyadmin,F.PHPMYADMIN_ENTRY_PATH);s.printPhpMyAdminUrl(new URL(f,I).toString())}return e.xdebug&&e.experimentalDevtools&&(await Ce.startBridge({phpInstance:t,phpRoot:"/wordpress"})).start(),{playground:t,server:p,serverUrl:I,[Symbol.asyncDispose]:U,[Y]:{workerThreadCount:T}}}catch(h){if(e.verbosity!=="debug")throw h;let P="";throw await t?.fileExists(m.errorLogPath)&&(P=await t.readFileAsText(m.errorLogPath)),await U(),new Error(P,{cause:h})}},async handleRequest(p){if(!u)return b.StreamedPHPResponse.forHttpCode(502,"WordPress is not ready yet");if(w){w=!1;const y={"Content-Type":["text/plain"],"Content-Length":["0"],Location:[p.url]};return p.headers?.cookie?.includes("playground_auto_login_already_happened")&&(y["Set-Cookie"]=["playground_auto_login_already_happened=1; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Path=/"]),b.StreamedPHPResponse.fromPHPResponse(new b.PHPResponse(302,y,new Uint8Array))}r&&(p={...p,headers:{...p.headers,cookie:r.getCookieRequestHeader()}});const E=await t.requestStreamed(p);if(r){const y=await E.headers;r.rememberCookiesFromResponseHeaders(y),delete y["set-cookie"]}return E}}).catch(p=>{s.printError(be(p)),process.exit(1)});return B&&e.command==="start"&&!e.skipBrowser&&ut(B.serverUrl),B}function at(e){let t={...e,command:"server"};e.noAutoMount||(t.autoMount=d.resolve(process.cwd(),t.path??""),t=he(t),delete t.autoMount);const r=de(t["mount-before-install"]||[],"/wordpress")||de(t.mount||[],"/wordpress");if(r)console.log("Site files stored at:",r?.hostPath),e.reset&&(console.log(""),console.log(it("This site is not managed by Playground CLI and cannot be reset.")),console.log("(It's not stored in the ~/.wordpress-playground/sites/<site-id> directory.)"),console.log(""),console.log("You may still remove the site's directory manually if you wish."),process.exit(1));else{const o=t.autoMount||process.cwd(),n=Re.createHash("sha256").update(o).digest("hex"),s=ee.homedir(),i=d.join(s,".wordpress-playground/sites",n);console.log("Site files stored at:",i),c.existsSync(i)&&e.reset&&(console.log("Resetting site..."),c.rmdirSync(i,{recursive:!0})),c.mkdirSync(i,{recursive:!0}),t["mount-before-install"]=[...t["mount-before-install"]||[],{vfsPath:"/wordpress",hostPath:i}],t.wordpressInstallMode=c.readdirSync(i).length===0?"download-and-install":"install-from-existing-files-if-needed"}return t}const K=new b.ProcessIdAllocator;function re(e,{onExit:t}={}){let r;return e==="v1"?r=new q.Worker(new URL("./worker-thread-v1.cjs",typeof document>"u"?require("url").pathToFileURL(__filename).href:k&&k.tagName.toUpperCase()==="SCRIPT"&&k.src||new URL("run-cli-B6Dm34vQ.cjs",document.baseURI).href)):r=new q.Worker(new URL("./worker-thread-v2.cjs",typeof document>"u"?require("url").pathToFileURL(__filename).href:k&&k.tagName.toUpperCase()==="SCRIPT"&&k.src||new URL("run-cli-B6Dm34vQ.cjs",document.baseURI).href)),new Promise((o,n)=>{const s=K.claim();r.once("message",function(l){l.command==="worker-script-initialized"&&o({processId:s,worker:r,phpPort:l.phpPort})}),r.once("error",function(l){K.release(s),console.error(l);const u=l?.message||(l?String(l):"unknown error"),w=new Error(`Worker failed to load. Original error: ${u}`,{cause:l});n(w)});let i=!1;r.once("spawn",()=>{i=!0}),r.once("exit",l=>{K.release(s),i||n(new Error(`Worker exited before spawning: ${l}`)),t?.(l)})})}async function lt(e){const{port1:t,port2:r}=new q.MessageChannel;return await b.exposeSyncAPI(e,t),r}function ut(e){const t=ee.platform();let r;switch(t){case"darwin":r=`open "${e}"`;break;case"win32":r=`start "" "${e}"`;break;default:r=`xdg-open "${e}"`;break}pe.exec(r,o=>{o&&m.logger.debug(`Could not open browser: ${o.message}`)})}async function dt(e,t){await e.run({code:`<?php
49
49
  $zip = new ZipArchive();
50
50
  if(false === $zip->open('/tmp/build.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE)) {
51
51
  throw new Exception('Failed to create ZIP');
@@ -63,4 +63,4 @@ Examples:
63
63
  $zip->close();
64
64
 
65
65
  `});const r=await e.readFileAsBuffer("/tmp/build.zip");c.writeFileSync(t,r)}const ct=Object.freeze(Object.defineProperty({__proto__:null,LogVerbosity:V,internalsKeyForTesting:Y,mergeDefinedConstants:j,parseOptionsAndRunCLI:ye,runCLI:te,spawnWorkerThread:re},Symbol.toStringTag,{value:"Module"}));exports.LogVerbosity=V;exports.internalsKeyForTesting=Y;exports.mergeDefinedConstants=j;exports.mountResources=Me;exports.parseOptionsAndRunCLI=ye;exports.runCLI=te;exports.runCli=ct;exports.shouldRenderProgress=we;exports.spawnWorkerThread=re;
66
- //# sourceMappingURL=run-cli-DGeb628T.cjs.map
66
+ //# sourceMappingURL=run-cli-B6Dm34vQ.cjs.map