@wp-playground/cli 3.0.12 → 3.0.13

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 n=require("./run-cli-4qHq8whi.cjs");n.parseOptionsAndRunCLI();
1
+ "use strict";const n=require("./run-cli-Bb8U_jz3.cjs");n.parseOptionsAndRunCLI();
2
2
  //# sourceMappingURL=cli.cjs.map
package/cli.js CHANGED
@@ -1,3 +1,3 @@
1
- import { p } from "./run-cli-BRWTcRHa.js";
1
+ import { p } from "./run-cli-C0WqHEVM.js";
2
2
  p();
3
3
  //# sourceMappingURL=cli.js.map
package/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./run-cli-4qHq8whi.cjs");exports.LogVerbosity=e.LogVerbosity;exports.parseOptionsAndRunCLI=e.parseOptionsAndRunCLI;exports.runCLI=e.runCLI;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./run-cli-Bb8U_jz3.cjs");exports.LogVerbosity=e.LogVerbosity;exports.parseOptionsAndRunCLI=e.parseOptionsAndRunCLI;exports.runCLI=e.runCLI;
2
2
  //# sourceMappingURL=index.cjs.map
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { L as o, p as a, r as n } from "./run-cli-BRWTcRHa.js";
1
+ import { L as o, p as a, r as n } from "./run-cli-C0WqHEVM.js";
2
2
  export {
3
3
  o as LogVerbosity,
4
4
  a as parseOptionsAndRunCLI,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wp-playground/cli",
3
- "version": "3.0.12",
3
+ "version": "3.0.13",
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": "75715549fdb6064f4fa335e65bc5718e2177c229",
37
+ "gitHead": "26e75279df438946c3fc81c12a47fae483f0ff3a",
38
38
  "dependencies": {
39
39
  "@zip.js/zip.js": "2.7.57",
40
40
  "ajv": "8.12.0",
@@ -59,16 +59,16 @@
59
59
  "ws": "8.18.1",
60
60
  "xml2js": "0.6.2",
61
61
  "yargs": "17.7.2",
62
- "@php-wasm/logger": "3.0.12",
63
- "@php-wasm/progress": "3.0.12",
64
- "@php-wasm/universal": "3.0.12",
65
- "@wp-playground/blueprints": "3.0.12",
66
- "@wp-playground/common": "3.0.12",
67
- "@wp-playground/wordpress": "3.0.12",
68
- "@php-wasm/node": "3.0.12",
69
- "@php-wasm/util": "3.0.12",
70
- "@wp-playground/storage": "3.0.12",
71
- "@php-wasm/xdebug-bridge": "3.0.12"
62
+ "@php-wasm/logger": "3.0.13",
63
+ "@php-wasm/progress": "3.0.13",
64
+ "@php-wasm/universal": "3.0.13",
65
+ "@wp-playground/blueprints": "3.0.13",
66
+ "@wp-playground/common": "3.0.13",
67
+ "@wp-playground/wordpress": "3.0.13",
68
+ "@php-wasm/node": "3.0.13",
69
+ "@php-wasm/util": "3.0.13",
70
+ "@wp-playground/storage": "3.0.13",
71
+ "@php-wasm/xdebug-bridge": "3.0.13"
72
72
  },
73
73
  "packageManager": "npm@10.9.2",
74
74
  "overrides": {
@@ -1,12 +1,12 @@
1
- "use strict";var K=Object.create;var V=Object.defineProperty;var ee=Object.getOwnPropertyDescriptor;var te=Object.getOwnPropertyNames;var re=Object.getPrototypeOf,oe=Object.prototype.hasOwnProperty;var ie=(e,r,t,s)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of te(r))!oe.call(e,o)&&o!==t&&V(e,o,{get:()=>r[o],enumerable:!(s=ee(r,o))||s.enumerable});return e};var se=(e,r,t)=>(t=e!=null?K(re(e)):{},ie(r||!e||!e.__esModule?V(t,"default",{value:e,enumerable:!0}):t,e));const u=require("@php-wasm/logger"),m=require("@php-wasm/universal"),R=require("@wp-playground/blueprints"),F=require("@wp-playground/common"),p=require("fs"),A=require("worker_threads"),E=require("./mounts-BJFrPHGW.cjs"),ne=require("express"),ae=require("@php-wasm/node"),D=require("os"),le=require("wasm-feature-detect"),ue=require("yargs"),d=require("path"),M=require("@wp-playground/storage"),j=require("@php-wasm/progress"),ce=require("@wp-playground/wordpress"),W=require("fs-extra"),pe=require("@php-wasm/xdebug-bridge"),O=require("tmp-promise"),de=require("ps-man");var x=typeof document<"u"?document.currentScript:null;async function he(e){const r=ne(),t=await new Promise((i,n)=>{const l=r.listen(e.port,()=>{const a=l.address();a===null||typeof a=="string"?n(new Error("Server address is not available")):i(l)})});r.use("/",async(i,n)=>{let l;try{l=await e.handleRequest({url:i.url,headers:me(i),method:i.method,body:await fe(i)})}catch(a){u.logger.error(a),l=m.PHPResponse.forHttpCode(500)}n.statusCode=l.httpStatusCode;for(const a in l.headers)n.setHeader(a,l.headers[a]);n.end(l.bytes)});const o=t.address().port;return await e.onBind(t,o)}const fe=async e=>await new Promise(r=>{const t=[];e.on("data",s=>{t.push(s)}),e.on("end",()=>{r(new Uint8Array(Buffer.concat(t)))})}),me=e=>{const r={};if(e.rawHeaders&&e.rawHeaders.length)for(let t=0;t<e.rawHeaders.length;t+=2)r[e.rawHeaders[t].toLowerCase()]=e.rawHeaders[t+1];return r};class we{constructor(r){this.workerLoads=[],this.addWorker(r)}addWorker(r){this.workerLoads.push({worker:r,activeRequests:new Set})}async handleRequest(r){let t=this.workerLoads[0];for(let o=1;o<this.workerLoads.length;o++){const i=this.workerLoads[o];i.activeRequests.size<t.activeRequests.size&&(t=i)}const s=t.worker.request(r);return t.activeRequests.add(s),s.url=r.url,s.finally(()=>{t.activeRequests.delete(s)})}}function ge(e){return/^latest$|^trunk$|^nightly$|^(?:(\d+)\.(\d+)(?:\.(\d+))?)((?:-beta(?:\d+)?)|(?:-RC(?:\d+)?))?$/.test(e)}async function ye({sourceString:e,blueprintMayReadAdjacentFiles:r}){if(!e)return;if(e.startsWith("http://")||e.startsWith("https://"))return await R.resolveRemoteBlueprint(e);let t=d.resolve(process.cwd(),e);if(!p.existsSync(t))throw new Error(`Blueprint file does not exist: ${t}`);const s=p.statSync(t);if(s.isDirectory()&&(t=d.join(t,"blueprint.json")),!s.isFile()&&s.isSymbolicLink())throw new Error(`Blueprint path is neither a file nor a directory: ${t}`);const o=d.extname(t);switch(o){case".zip":return M.ZipFilesystem.fromArrayBuffer(p.readFileSync(t).buffer);case".json":{const i=p.readFileSync(t,"utf-8");try{JSON.parse(i)}catch{throw new Error(`Blueprint file at ${t} is not a valid JSON file`)}const n=d.dirname(t),l=new M.NodeJsFilesystem(n);return new M.OverlayFilesystem([new M.InMemoryFilesystem({"blueprint.json":i}),{read(a){if(!r)throw new Error(`Error: Blueprint contained tried to read a local file at path "${a}" (via a resource of type "bundled"). Playground restricts access to local resources by default as a security measure.
1
+ "use strict";var K=Object.create;var _=Object.defineProperty;var ee=Object.getOwnPropertyDescriptor;var te=Object.getOwnPropertyNames;var re=Object.getPrototypeOf,oe=Object.prototype.hasOwnProperty;var ie=(e,r,t,s)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of te(r))!oe.call(e,o)&&o!==t&&_(e,o,{get:()=>r[o],enumerable:!(s=ee(r,o))||s.enumerable});return e};var se=(e,r,t)=>(t=e!=null?K(re(e)):{},ie(r||!e||!e.__esModule?_(t,"default",{value:e,enumerable:!0}):t,e));const u=require("@php-wasm/logger"),m=require("@php-wasm/universal"),R=require("@wp-playground/blueprints"),F=require("@wp-playground/common"),d=require("fs"),A=require("worker_threads"),M=require("./mounts-BJFrPHGW.cjs"),ne=require("express"),ae=require("@php-wasm/node"),D=require("os"),le=require("wasm-feature-detect"),ue=require("yargs"),f=require("path"),B=require("@wp-playground/storage"),j=require("@php-wasm/progress"),ce=require("@wp-playground/wordpress"),x=require("fs-extra"),pe=require("@php-wasm/xdebug-bridge"),O=require("tmp-promise"),de=require("ps-man");var W=typeof document<"u"?document.currentScript:null;async function fe(e){const r=ne(),t=await new Promise((i,n)=>{const l=r.listen(e.port,()=>{const a=l.address();a===null||typeof a=="string"?n(new Error("Server address is not available")):i(l)})});r.use("/",async(i,n)=>{let l;try{l=await e.handleRequest({url:i.url,headers:me(i),method:i.method,body:await he(i)})}catch(a){u.logger.error(a),l=m.PHPResponse.forHttpCode(500)}n.statusCode=l.httpStatusCode;for(const a in l.headers)n.setHeader(a,l.headers[a]);n.end(l.bytes)});const o=t.address().port;return await e.onBind(t,o)}const he=async e=>await new Promise(r=>{const t=[];e.on("data",s=>{t.push(s)}),e.on("end",()=>{r(new Uint8Array(Buffer.concat(t)))})}),me=e=>{const r={};if(e.rawHeaders&&e.rawHeaders.length)for(let t=0;t<e.rawHeaders.length;t+=2)r[e.rawHeaders[t].toLowerCase()]=e.rawHeaders[t+1];return r};class we{constructor(r){this.workerLoads=[],this.addWorker(r)}addWorker(r){this.workerLoads.push({worker:r,activeRequests:new Set})}async handleRequest(r){let t=this.workerLoads[0];for(let o=1;o<this.workerLoads.length;o++){const i=this.workerLoads[o];i.activeRequests.size<t.activeRequests.size&&(t=i)}const s=t.worker.request(r);return t.activeRequests.add(s),s.url=r.url,s.finally(()=>{t.activeRequests.delete(s)})}}function ge(e){return/^latest$|^trunk$|^nightly$|^(?:(\d+)\.(\d+)(?:\.(\d+))?)((?:-beta(?:\d+)?)|(?:-RC(?:\d+)?))?$/.test(e)}async function ye({sourceString:e,blueprintMayReadAdjacentFiles:r}){if(!e)return;if(e.startsWith("http://")||e.startsWith("https://"))return await R.resolveRemoteBlueprint(e);let t=f.resolve(process.cwd(),e);if(!d.existsSync(t))throw new Error(`Blueprint file does not exist: ${t}`);const s=d.statSync(t);if(s.isDirectory()&&(t=f.join(t,"blueprint.json")),!s.isFile()&&s.isSymbolicLink())throw new Error(`Blueprint path is neither a file nor a directory: ${t}`);const o=f.extname(t);switch(o){case".zip":return B.ZipFilesystem.fromArrayBuffer(d.readFileSync(t).buffer);case".json":{const i=d.readFileSync(t,"utf-8");try{JSON.parse(i)}catch{throw new Error(`Blueprint file at ${t} is not a valid JSON file`)}const n=f.dirname(t),l=new B.NodeJsFilesystem(n);return new B.OverlayFilesystem([new B.InMemoryFilesystem({"blueprint.json":i}),{read(a){if(!r)throw new Error(`Error: Blueprint contained tried to read a local file at path "${a}" (via a resource of type "bundled"). Playground restricts access to local resources by default as a security measure.
2
2
 
3
3
  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(a)}}])}default:throw new Error(`Unsupported blueprint file extension: ${o}. Only .zip and .json files are supported.`)}}class be{constructor(r,t){this.lastProgressMessage="",this.args=r,this.siteUrl=t.siteUrl,this.processIdSpaceLength=t.processIdSpaceLength,this.phpVersion=r.php}getWorkerType(){return"v2"}async bootPrimaryWorker(r,t,s){const o=m.consumeAPI(r);await o.useFileLockManager(t);const i={...this.args,phpVersion:this.phpVersion,siteUrl:this.siteUrl,firstProcessId:1,processIdSpaceLength:this.processIdSpaceLength,trace:this.args.debug||!1,blueprint:this.args.blueprint,nativeInternalDirPath:s};return await o.bootAsPrimaryWorker(i),o}async bootSecondaryWorker({worker:r,fileLockManagerPort:t,firstProcessId:s,nativeInternalDirPath:o}){const i=m.consumeAPI(r.phpPort);await i.useFileLockManager(t);const n={...this.args,phpVersion:this.phpVersion,siteUrl:this.siteUrl,firstProcessId:s,processIdSpaceLength:this.processIdSpaceLength,trace:this.args.debug||!1,nativeInternalDirPath:o,mountsBeforeWpInstall:this.args["mount-before-install"]||[],mountsAfterWpInstall:this.args.mount||[]};return await i.bootAsSecondaryWorker(n),i}writeProgressUpdate(r,t,s){t!==this.lastProgressMessage&&(this.lastProgressMessage=t,r.isTTY?(r.cursorTo(0),r.write(t),r.clearLine(1),s&&r.write(`
4
4
  `)):r.write(`${t}
5
- `))}}const q=d.join(D.homedir(),".wordpress-playground");async function Pe(e){return await N("https://github.com/WordPress/sqlite-database-integration/archive/refs/heads/develop.zip","sqlite.zip",e)}async function N(e,r,t){const s=d.join(q,r);return W.existsSync(s)||(W.ensureDirSync(q),await ve(e,s,t)),Z(s)}async function ve(e,r,t){const o=(await t.monitorFetch(fetch(e))).body.getReader(),i=`${r}.partial`,n=W.createWriteStream(i);for(;;){const{done:l,value:a}=await o.read();if(a&&n.write(a),l)break}n.close(),n.closed||await new Promise((l,a)=>{n.on("finish",()=>{W.renameSync(i,r),l(null)}),n.on("error",c=>{W.removeSync(i),a(c)})})}function Z(e,r){return new File([W.readFileSync(e)],d.basename(e))}class ke{constructor(r,t){this.lastProgressMessage="",this.args=r,this.siteUrl=t.siteUrl,this.processIdSpaceLength=t.processIdSpaceLength}getWorkerType(){return"v1"}async bootPrimaryWorker(r,t,s){let o;const i=new j.EmscriptenDownloadMonitor;if(!this.args.skipWordPressSetup){let b=!1;i.addEventListener("progress",$=>{if(b)return;const{loaded:H,total:U}=$.detail,v=Math.floor(Math.min(100,100*H/U));b=v===100,this.writeProgressUpdate(process.stdout,`Downloading WordPress ${v}%...`,b)}),o=await ce.resolveWordPressRelease(this.args.wp),u.logger.log(`Resolved WordPress release URL: ${o?.releaseUrl}`)}const n=o&&d.join(q,`prebuilt-wp-content-for-wp-${o.version}.zip`),l=o?p.existsSync(n)?Z(n):await N(o.releaseUrl,`${o.version}.zip`,i):void 0;u.logger.log("Fetching SQLite integration plugin...");const a=this.args.skipSqliteSetup?void 0:await Pe(i),c=this.args.followSymlinks===!0,y=this.args.experimentalTrace===!0,I=this.args["mount-before-install"]||[],P=this.args.mount||[],w=m.consumeAPI(r);await w.isConnected(),u.logger.log("Booting WordPress...");const L=await R.resolveRuntimeConfiguration(this.getEffectiveBlueprint());return await w.useFileLockManager(t),await w.bootAsPrimaryWorker({phpVersion:L.phpVersion,wpVersion:L.wpVersion,siteUrl:this.siteUrl,mountsBeforeWpInstall:I,mountsAfterWpInstall:P,wordPressZip:l&&await l.arrayBuffer(),sqliteIntegrationPluginZip:await a?.arrayBuffer(),firstProcessId:0,processIdSpaceLength:this.processIdSpaceLength,followSymlinks:c,trace:y,internalCookieStore:this.args.internalCookieStore,withXdebug:this.args.xdebug,nativeInternalDirPath:s}),o&&!this.args["mount-before-install"]&&!p.existsSync(n)&&(u.logger.log("Caching preinstalled WordPress for the next boot..."),p.writeFileSync(n,await F.zipDirectory(w,"/wordpress")),u.logger.log("Cached!")),w}async bootSecondaryWorker({worker:r,fileLockManagerPort:t,firstProcessId:s,nativeInternalDirPath:o}){const i=m.consumeAPI(r.phpPort);return await i.isConnected(),await i.useFileLockManager(t),await i.bootAsSecondaryWorker({phpVersion:this.phpVersion,siteUrl:this.siteUrl,mountsBeforeWpInstall:this.args["mount-before-install"]||[],mountsAfterWpInstall:this.args.mount||[],firstProcessId:s,processIdSpaceLength:this.processIdSpaceLength,followSymlinks:this.args.followSymlinks===!0,trace:this.args.experimentalTrace===!0,internalCookieStore:this.args.internalCookieStore,withXdebug:this.args.xdebug,nativeInternalDirPath:o}),await i.isReady(),i}async compileInputBlueprint(r){const t=this.getEffectiveBlueprint(),s=new j.ProgressTracker;let o="",i=!1;return s.addEventListener("progress",n=>{if(i)return;i=n.detail.progress===100;const l=Math.floor(n.detail.progress);o=n.detail.caption||o||"Running the Blueprint";const a=`${o.trim()} – ${l}%`;this.writeProgressUpdate(process.stdout,a,i)}),await R.compileBlueprintV1(t,{progress:s,additionalSteps:r})}getEffectiveBlueprint(){const r=this.args.blueprint;return R.isBlueprintBundle(r)?r:{login:this.args.login,...r||{},preferredVersions:{php:this.args.php??r?.preferredVersions?.php??F.RecommendedPHPVersion,wp:this.args.wp??r?.preferredVersions?.wp??"latest",...r?.preferredVersions||{}}}}writeProgressUpdate(r,t,s){this.args.verbosity!==T.Quiet.name&&t!==this.lastProgressMessage&&(this.lastProgressMessage=t,r.isTTY?(r.cursorTo(0),r.write(t),r.clearLine(1),s&&r.write(`
5
+ `))}}const q=f.join(D.homedir(),".wordpress-playground");async function Pe(e){return await N("https://github.com/WordPress/sqlite-database-integration/archive/refs/heads/develop.zip","sqlite.zip",e)}async function N(e,r,t){const s=f.join(q,r);return x.existsSync(s)||(x.ensureDirSync(q),await ve(e,s,t)),Z(s)}async function ve(e,r,t){const o=(await t.monitorFetch(fetch(e))).body.getReader(),i=`${r}.partial`,n=x.createWriteStream(i);for(;;){const{done:l,value:a}=await o.read();if(a&&n.write(a),l)break}n.close(),n.closed||await new Promise((l,a)=>{n.on("finish",()=>{x.renameSync(i,r),l(null)}),n.on("error",p=>{x.removeSync(i),a(p)})})}function Z(e,r){return new File([x.readFileSync(e)],f.basename(e))}class ke{constructor(r,t){this.lastProgressMessage="",this.args=r,this.siteUrl=t.siteUrl,this.processIdSpaceLength=t.processIdSpaceLength}getWorkerType(){return"v1"}async bootPrimaryWorker(r,t,s){let o;const i=new j.EmscriptenDownloadMonitor;if(!this.args.skipWordPressSetup){let y=!1;i.addEventListener("progress",T=>{if(y)return;const{loaded:H,total:U}=T.detail,v=Math.floor(Math.min(100,100*H/U));y=v===100,this.writeProgressUpdate(process.stdout,`Downloading WordPress ${v}%...`,y)}),o=await ce.resolveWordPressRelease(this.args.wp),u.logger.log(`Resolved WordPress release URL: ${o?.releaseUrl}`)}const n=o&&f.join(q,`prebuilt-wp-content-for-wp-${o.version}.zip`),l=o?d.existsSync(n)?Z(n):await N(o.releaseUrl,`${o.version}.zip`,i):void 0;u.logger.log("Fetching SQLite integration plugin...");const a=this.args.skipSqliteSetup?void 0:await Pe(i),p=this.args.followSymlinks===!0,b=this.args.experimentalTrace===!0,I=this.args["mount-before-install"]||[],P=this.args.mount||[],w=m.consumeAPI(r);await w.isConnected(),u.logger.log("Booting WordPress...");const L=await R.resolveRuntimeConfiguration(this.getEffectiveBlueprint());return await w.useFileLockManager(t),await w.bootAsPrimaryWorker({phpVersion:L.phpVersion,wpVersion:L.wpVersion,siteUrl:this.siteUrl,mountsBeforeWpInstall:I,mountsAfterWpInstall:P,wordPressZip:l&&await l.arrayBuffer(),sqliteIntegrationPluginZip:await a?.arrayBuffer(),firstProcessId:0,processIdSpaceLength:this.processIdSpaceLength,followSymlinks:p,trace:b,internalCookieStore:this.args.internalCookieStore,withXdebug:this.args.xdebug,nativeInternalDirPath:s}),o&&!this.args["mount-before-install"]&&!d.existsSync(n)&&(u.logger.log("Caching preinstalled WordPress for the next boot..."),d.writeFileSync(n,await F.zipDirectory(w,"/wordpress")),u.logger.log("Cached!")),w}async bootSecondaryWorker({worker:r,fileLockManagerPort:t,firstProcessId:s,nativeInternalDirPath:o}){const i=m.consumeAPI(r.phpPort);return await i.isConnected(),await i.useFileLockManager(t),await i.bootAsSecondaryWorker({phpVersion:this.phpVersion,siteUrl:this.siteUrl,mountsBeforeWpInstall:this.args["mount-before-install"]||[],mountsAfterWpInstall:this.args.mount||[],firstProcessId:s,processIdSpaceLength:this.processIdSpaceLength,followSymlinks:this.args.followSymlinks===!0,trace:this.args.experimentalTrace===!0,internalCookieStore:this.args.internalCookieStore,withXdebug:this.args.xdebug,nativeInternalDirPath:o}),await i.isReady(),i}async compileInputBlueprint(r){const t=this.getEffectiveBlueprint(),s=new j.ProgressTracker;let o="",i=!1;return s.addEventListener("progress",n=>{if(i)return;i=n.detail.progress===100;const l=Math.floor(n.detail.progress);o=n.detail.caption||o||"Running the Blueprint";const a=`${o.trim()} – ${l}%`;this.writeProgressUpdate(process.stdout,a,i)}),await R.compileBlueprintV1(t,{progress:s,additionalSteps:r})}getEffectiveBlueprint(){const r=this.args.blueprint;return R.isBlueprintBundle(r)?r:{login:this.args.login,...r||{},preferredVersions:{php:this.args.php??r?.preferredVersions?.php??F.RecommendedPHPVersion,wp:this.args.wp??r?.preferredVersions?.wp??"latest",...r?.preferredVersions||{}}}}writeProgressUpdate(r,t,s){this.args.verbosity!==E.Quiet.name&&t!==this.lastProgressMessage&&(this.lastProgressMessage=t,r.isTTY?(r.cursorTo(0),r.write(t),r.clearLine(1),s&&r.write(`
6
6
  `)):r.write(`${t}
7
- `))}}async function Se(e,r=!0){const s=`${d.basename(process.argv0)}${e}${process.pid}-`,o=(await O.dir({prefix:s,unsafeCleanup:!0})).path;return r&&O.setGracefulCleanup(),o}async function xe(e,r,t){const o=(await We(e,r,t)).map(i=>new Promise(n=>{p.rm(i,{recursive:!0},l=>{l?u.logger.warn(`Failed to delete stale Playground temp dir: ${i}`,l):u.logger.info(`Deleted stale Playground temp dir: ${i}`),n()})}));await Promise.all(o)}async function We(e,r,t){try{const s=p.readdirSync(t).map(i=>d.join(t,i)),o=[];for(const i of s)await Le(e,r,i)&&o.push(i);return o}catch(s){return u.logger.warn(`Failed to find stale Playground temp dirs: ${s}`),[]}}async function Le(e,r,t){if(!p.lstatSync(t).isDirectory())return!1;const o=d.basename(t);if(!o.includes(e))return!1;const i=o.match(new RegExp(`^(.+)${e}(\\d+)-`));if(!i)return!1;const n={executableName:i[1],pid:i[2]};if(await Re(n.pid,n.executableName))return!1;const l=Date.now()-r;return p.statSync(t).mtime.getTime()<l}async function Re(e,r){const[t]=await new Promise((s,o)=>{de.list({pid:e,name:r,clean:!0},(i,n)=>{i?o(i):s(n)})});return!!t&&t.pid===e&&t.command===r}const T={Quiet:{name:"quiet",severity:u.LogSeverity.Fatal},Normal:{name:"normal",severity:u.LogSeverity.Info},Debug:{name:"debug",severity:u.LogSeverity.Debug}};async function Ie(){try{const e=ue(process.argv.slice(2)).usage("Usage: wp-playground <command> [options]").positional("command",{describe:"Command to run",choices:["server","run-blueprint","build-snapshot"],demandOption:!0}).option("outfile",{describe:"When building, write to this output file.",type:"string",default:"wordpress.zip"}).option("port",{describe:"Port to listen on when serving.",type:"number",default:9400}).option("site-url",{describe:"Site URL to use for WordPress. Defaults to http://127.0.0.1:{port}",type:"string"}).option("php",{describe:"PHP version to use.",type:"string",default:F.RecommendedPHPVersion,choices:m.SupportedPHPVersions}).option("wp",{describe:"WordPress version to use.",type:"string",default:"latest"}).option("mount",{describe:"Mount a directory to the PHP runtime (can be used multiple times). Format: /host/path:/vfs/path",type:"array",string:!0,coerce:E.parseMountWithDelimiterArguments}).option("mount-before-install",{describe:"Mount a directory to the PHP runtime before WordPress installation (can be used multiple times). Format: /host/path:/vfs/path",type:"array",string:!0,coerce:E.parseMountWithDelimiterArguments}).option("mount-dir",{describe:'Mount a directory to the PHP runtime (can be used multiple times). Format: "/host/path" "/vfs/path"',type:"array",nargs:2,array:!0}).option("mount-dir-before-install",{describe:'Mount a directory before WordPress installation (can be used multiple times). Format: "/host/path" "/vfs/path"',type:"string",nargs:2,array:!0,coerce:E.parseMountDirArguments}).option("login",{describe:"Should log the user in",type:"boolean",default:!1}).option("blueprint",{describe:"Blueprint to execute.",type:"string"}).option("blueprint-may-read-adjacent-files",{describe:'Consent flag: Allow "bundled" resources in a local blueprint to read files in the same directory as the blueprint file.',type:"boolean",default:!1}).option("skip-wordpress-setup",{describe:"Do not download, unzip, and install WordPress. Useful for mounting a pre-configured WordPress directory at /wordpress.",type:"boolean",default:!1}).option("skip-sqlite-setup",{describe:"Skip the SQLite integration plugin setup to allow the WordPress site to use MySQL.",type:"boolean",default:!1}).option("quiet",{describe:"Do not output logs and progress messages.",type:"boolean",default:!1,hidden:!0}).option("verbosity",{describe:"Output logs and progress messages.",type:"string",choices:Object.values(T).map(o=>o.name),default:"normal"}).option("debug",{describe:"Print PHP error log content if an error occurs during Playground boot.",type:"boolean",default:!1}).option("auto-mount",{describe:"Automatically mount the specified directory. If no path is provided, mount the current working directory. You can mount a WordPress directory, a plugin directory, a theme directory, a wp-content directory, or any directory containing PHP and HTML files.",type:"string"}).option("follow-symlinks",{describe:`Allow Playground to follow symlinks by automatically mounting symlinked directories and files encountered in mounted directories.
8
- Warning: Following symlinks will expose files outside mounted directories to Playground and could be a security risk.`,type:"boolean",default:!1}).option("experimental-trace",{describe:"Print detailed messages about system behavior to the console. Useful for troubleshooting.",type:"boolean",default:!1,hidden:!0}).option("internal-cookie-store",{describe:"Enable internal cookie handling. When enabled, Playground will manage cookies internally using an HttpCookieStore that persists cookies across requests. When disabled, cookies are handled externally (e.g., by a browser in Node.js environments).",type:"boolean",default:!1}).option("xdebug",{describe:"Enable Xdebug.",type:"boolean",default:!1}).option("experimental-devtools",{describe:"Enable experimental browser development tools.",type:"boolean",default:!1}).option("experimental-multi-worker",{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.",type:"number",coerce:o=>o??D.cpus().length-1}).option("experimental-blueprints-v2-runner",{describe:"Use the experimental Blueprint V2 runner.",type:"boolean",default:!1,hidden:!0}).option("mode",{describe:"Blueprints v2 runner mode to use. This option is required when using the --experimental-blueprints-v2-runner flag with a blueprint.",type:"string",choices:["create-new-site","apply-to-existing-site"],hidden:!0}).showHelpOnFail(!1).strictOptions().check(async o=>{if((o["skip-wordpress-setup"]||o.skipWordpressSetup)&&(o.skipWordPressSetup=!0),o.wp!==void 0&&!ge(o.wp))try{new URL(o.wp)}catch{throw new Error('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"')}if(o["site-url"]!==void 0&&o["site-url"]!=="")try{new URL(o["site-url"])}catch{throw new Error(`Invalid site-url "${o["site-url"]}". Please provide a valid URL (e.g., http://localhost:8080 or https://example.com)`)}if(o["auto-mount"]){let i=!1;try{i=p.statSync(o["auto-mount"]).isDirectory()}catch{i=!1}if(!i)throw new Error(`The specified --auto-mount path is not a directory: '${o["auto-mount"]}'.`)}if(o["experimental-multi-worker"]!==void 0&&o["experimental-multi-worker"]<=1)throw new Error("The --experimental-multi-worker flag must be a positive integer greater than 1.");if(o["experimental-blueprints-v2-runner"]===!0){if(o.mode!==void 0){if("skip-wordpress-setup"in o)throw new Error("The --skipWordPressSetup option cannot be used with the --mode option. Use one or the other.");if("skip-sqlite-setup"in o)throw new Error("The --skipSqliteSetup option is not supported in Blueprint V2 mode.");if(o["auto-mount"]!==void 0)throw new Error("The --mode option cannot be used with --auto-mount because --auto-mount automatically sets the mode.")}else o["skip-wordpress-setup"]===!0?o.mode="apply-to-existing-site":o.mode="create-new-site";const i=o.allow||[];o.followSymlinks===!0&&i.push("follow-symlinks"),o["blueprint-may-read-adjacent-files"]===!0&&i.push("read-local-fs"),o.allow=i}else if(o.mode!==void 0)throw new Error("The --mode option requires the --experimentalBlueprintsV2Runner flag.");return!0});e.wrap(e.terminalWidth());const r=await e.argv,t=r._[0];["run-blueprint","server","build-snapshot"].includes(t)||(e.showHelp(),process.exit(1));const s={...r,command:t,mount:[...r.mount||[],...r["mount-dir"]||[]],"mount-before-install":[...r["mount-before-install"]||[],...r["mount-dir-before-install"]||[]]};await J(s)}catch(e){if(!(e instanceof Error))throw e;if(process.argv.includes("--debug"))m.printDebugDetails(e);else{const t=[];let s=e;do t.push(s.message),s=s.cause;while(s instanceof Error);console.error("\x1B[1m"+t.join(" caused by ")+"\x1B[0m")}process.exit(1)}}async function J(e){let r,t;const s=[];if(e.autoMount!==void 0&&(e.autoMount===""&&(e={...e,autoMount:process.cwd()}),e=E.expandAutoMounts(e)),e.quiet&&(e.verbosity="quiet",delete e.quiet),e.debug?e.verbosity="debug":e.verbosity==="debug"&&(e.debug=!0),e.verbosity){const a=Object.values(T).find(c=>c.name===e.verbosity).severity;u.logger.setSeverityFilterLevel(a)}const o=D.platform()==="win32"?void 0:await import("fs-ext").then(a=>a.flockSync).catch(()=>{u.logger.warn("The fs-ext package is not installed. Internal file locking will not be integrated with host OS file locking.")}),i=new ae.FileLockManagerForNode(o);let n=!1,l=!0;return u.logger.log("Starting a PHP server..."),he({port:e.port,onBind:async(a,c)=>{const y=`http://127.0.0.1:${c}`,I=e["site-url"]||y,P=e.experimentalMultiWorker??1,w=Math.floor(Number.MAX_SAFE_INTEGER/P),L="-playground-cli-site-",b=await Se(L),$=d.dirname(b),U=2*24*60*60*1e3;xe(L,U,$);const v=d.join(b,"internal");p.mkdirSync(v);const Q=["wordpress","tmp","home"];for(const h of Q){const g=f=>f.vfsPath===`/${h}`;if(!(e["mount-before-install"]?.some(g)||e.mount?.some(g))){const f=d.join(b,h);p.mkdirSync(f),e["mount-before-install"]===void 0&&(e["mount-before-install"]=[]),e["mount-before-install"].unshift({vfsPath:`/${h}`,hostPath:f})}}let k;e["experimental-blueprints-v2-runner"]?k=new be(e,{siteUrl:I,processIdSpaceLength:w}):(k=new ke(e,{siteUrl:I,processIdSpaceLength:w}),typeof e.blueprint=="string"&&(e.blueprint=await ye({sourceString:e.blueprint,blueprintMayReadAdjacentFiles:e["blueprint-may-read-adjacent-files"]===!0})));const X=Be(P,k.getWorkerType(),({exitCode:h,isMain:g,workerIndex:B})=>{h!==0&&(u.logger.error(`Worker ${B} exited with code ${h}
9
- `),g&&e.exitOnPrimaryWorkerCrash&&process.exit(1))});u.logger.log(`Setting up WordPress ${e.wp}`);try{const[h,...g]=await X,B=await z(i);if(t=await k.bootPrimaryWorker(h.phpPort,B,v),s.push({playground:t,worker:h.worker}),await t.isReady(),n=!0,u.logger.log("Booted!"),r=new we(t),!e["experimental-blueprints-v2-runner"]){const f=await k.compileInputBlueprint(e["additional-blueprint-steps"]||[]);f&&(u.logger.log("Running the Blueprint..."),await R.runBlueprintV1Steps(f,t),u.logger.log("Finished running the blueprint"))}if(e.command==="build-snapshot"?(await Ee(t,e.outfile),u.logger.log(`WordPress exported to ${e.outfile}`),process.exit(0)):e.command==="run-blueprint"&&(u.logger.log("Blueprint executed"),process.exit(0)),e.experimentalMultiWorker&&e.experimentalMultiWorker>1){u.logger.log("Preparing additional workers...");const f=w;await Promise.all(g.map(async(S,C)=>{const Y=f+C*w,G=await z(i),_=await k.bootSecondaryWorker({worker:S,fileLockManagerPort:G,firstProcessId:Y,nativeInternalDirPath:v});s.push({playground:_,worker:S.worker}),r.addWorker(_)}))}return u.logger.log(`WordPress is running on ${y} with ${P} worker(s)`),e.experimentalDevtools&&e.xdebug&&(await pe.startBridge({phpInstance:t,phpRoot:"/wordpress"})).start(),{playground:t,server:a,serverUrl:y,[Symbol.asyncDispose]:async function(){await Promise.all(s.map(async({playground:S,worker:C})=>{await S.dispose(),await C.terminate()})),await new Promise(S=>a.close(S))},workerThreadCount:P}}catch(h){if(!e.debug)throw h;let g="";throw await t?.fileExists(u.errorLogPath)&&(g=await t.readFileAsText(u.errorLogPath)),new Error(g,{cause:h})}},async handleRequest(a){if(!n)return m.PHPResponse.forHttpCode(502,"WordPress is not ready yet");if(l){l=!1;const c={"Content-Type":["text/plain"],"Content-Length":["0"],Location:[a.url]};return a.headers?.cookie?.includes("playground_auto_login_already_happened")&&(c["Set-Cookie"]=["playground_auto_login_already_happened=1; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Path=/"]),new m.PHPResponse(302,c,new Uint8Array)}return await r.handleRequest(a)}})}async function Be(e,r,t){const s=[];for(let o=0;o<e;o++){const i=await Me(r),n=l=>{t({exitCode:l,isMain:o===0,workerIndex:o})};s.push(new Promise((l,a)=>{i.once("message",function(c){c.command==="worker-script-initialized"&&l({worker:i,phpPort:c.phpPort})}),i.once("error",function(c){console.error(c);const y=new Error(`Worker failed to load worker. ${c.message?`Original error: ${c.message}`:""}`);a(y)}),i.once("exit",n)}))}return Promise.all(s)}async function Me(e){return e==="v1"?new A.Worker(new URL("./worker-thread-v1.cjs",typeof document>"u"?require("url").pathToFileURL(__filename).href:x&&x.tagName.toUpperCase()==="SCRIPT"&&x.src||new URL("run-cli-4qHq8whi.cjs",document.baseURI).href)):new A.Worker(new URL("./worker-thread-v2.cjs",typeof document>"u"?require("url").pathToFileURL(__filename).href:x&&x.tagName.toUpperCase()==="SCRIPT"&&x.src||new URL("run-cli-4qHq8whi.cjs",document.baseURI).href))}async function z(e){const{port1:r,port2:t}=new A.MessageChannel;return await le.jspi()?m.exposeAPI(e,null,r):await m.exposeSyncAPI(e,r),t}async function Ee(e,r){await e.run({code:`<?php
7
+ `))}}async function Se(e,r=!0){const s=`${f.basename(process.argv0)}${e}${process.pid}-`,o=(await O.dir({prefix:s,unsafeCleanup:!0})).path;return r&&O.setGracefulCleanup(),o}async function We(e,r,t){const o=(await xe(e,r,t)).map(i=>new Promise(n=>{d.rm(i,{recursive:!0},l=>{l?u.logger.warn(`Failed to delete stale Playground temp dir: ${i}`,l):u.logger.info(`Deleted stale Playground temp dir: ${i}`),n()})}));await Promise.all(o)}async function xe(e,r,t){try{const s=d.readdirSync(t).map(i=>f.join(t,i)),o=[];for(const i of s)await Le(e,r,i)&&o.push(i);return o}catch(s){return u.logger.warn(`Failed to find stale Playground temp dirs: ${s}`),[]}}async function Le(e,r,t){if(!d.lstatSync(t).isDirectory())return!1;const o=f.basename(t);if(!o.includes(e))return!1;const i=o.match(new RegExp(`^(.+)${e}(\\d+)-`));if(!i)return!1;const n={executableName:i[1],pid:i[2]};if(await Re(n.pid,n.executableName))return!1;const l=Date.now()-r;return d.statSync(t).mtime.getTime()<l}async function Re(e,r){const[t]=await new Promise((s,o)=>{de.list({pid:e,name:r,clean:!0},(i,n)=>{i?o(i):s(n)})});return!!t&&t.pid===e&&t.command===r}const E={Quiet:{name:"quiet",severity:u.LogSeverity.Fatal},Normal:{name:"normal",severity:u.LogSeverity.Info},Debug:{name:"debug",severity:u.LogSeverity.Debug}};async function Ie(){try{const e=ue(process.argv.slice(2)).usage("Usage: wp-playground <command> [options]").positional("command",{describe:"Command to run",choices:["server","run-blueprint","build-snapshot"],demandOption:!0}).option("outfile",{describe:"When building, write to this output file.",type:"string",default:"wordpress.zip"}).option("port",{describe:"Port to listen on when serving.",type:"number",default:9400}).option("site-url",{describe:"Site URL to use for WordPress. Defaults to http://127.0.0.1:{port}",type:"string"}).option("php",{describe:"PHP version to use.",type:"string",default:F.RecommendedPHPVersion,choices:m.SupportedPHPVersions}).option("wp",{describe:"WordPress version to use.",type:"string",default:"latest"}).option("mount",{describe:"Mount a directory to the PHP runtime (can be used multiple times). Format: /host/path:/vfs/path",type:"array",string:!0,coerce:M.parseMountWithDelimiterArguments}).option("mount-before-install",{describe:"Mount a directory to the PHP runtime before WordPress installation (can be used multiple times). Format: /host/path:/vfs/path",type:"array",string:!0,coerce:M.parseMountWithDelimiterArguments}).option("mount-dir",{describe:'Mount a directory to the PHP runtime (can be used multiple times). Format: "/host/path" "/vfs/path"',type:"array",nargs:2,array:!0}).option("mount-dir-before-install",{describe:'Mount a directory before WordPress installation (can be used multiple times). Format: "/host/path" "/vfs/path"',type:"string",nargs:2,array:!0,coerce:M.parseMountDirArguments}).option("login",{describe:"Should log the user in",type:"boolean",default:!1}).option("blueprint",{describe:"Blueprint to execute.",type:"string"}).option("blueprint-may-read-adjacent-files",{describe:'Consent flag: Allow "bundled" resources in a local blueprint to read files in the same directory as the blueprint file.',type:"boolean",default:!1}).option("skip-wordpress-setup",{describe:"Do not download, unzip, and install WordPress. Useful for mounting a pre-configured WordPress directory at /wordpress.",type:"boolean",default:!1}).option("skip-sqlite-setup",{describe:"Skip the SQLite integration plugin setup to allow the WordPress site to use MySQL.",type:"boolean",default:!1}).option("quiet",{describe:"Do not output logs and progress messages.",type:"boolean",default:!1,hidden:!0}).option("verbosity",{describe:"Output logs and progress messages.",type:"string",choices:Object.values(E).map(o=>o.name),default:"normal"}).option("debug",{describe:"Print PHP error log content if an error occurs during Playground boot.",type:"boolean",default:!1}).option("auto-mount",{describe:"Automatically mount the specified directory. If no path is provided, mount the current working directory. You can mount a WordPress directory, a plugin directory, a theme directory, a wp-content directory, or any directory containing PHP and HTML files.",type:"string"}).option("follow-symlinks",{describe:`Allow Playground to follow symlinks by automatically mounting symlinked directories and files encountered in mounted directories.
8
+ Warning: Following symlinks will expose files outside mounted directories to Playground and could be a security risk.`,type:"boolean",default:!1}).option("experimental-trace",{describe:"Print detailed messages about system behavior to the console. Useful for troubleshooting.",type:"boolean",default:!1,hidden:!0}).option("internal-cookie-store",{describe:"Enable internal cookie handling. When enabled, Playground will manage cookies internally using an HttpCookieStore that persists cookies across requests. When disabled, cookies are handled externally (e.g., by a browser in Node.js environments).",type:"boolean",default:!1}).option("xdebug",{describe:"Enable Xdebug.",type:"boolean",default:!1}).option("experimental-devtools",{describe:"Enable experimental browser development tools.",type:"boolean",default:!1}).option("experimental-multi-worker",{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.",type:"number",coerce:o=>o??D.cpus().length-1}).option("experimental-blueprints-v2-runner",{describe:"Use the experimental Blueprint V2 runner.",type:"boolean",default:!1,hidden:!0}).option("mode",{describe:"Blueprints v2 runner mode to use. This option is required when using the --experimental-blueprints-v2-runner flag with a blueprint.",type:"string",choices:["create-new-site","apply-to-existing-site"],hidden:!0}).showHelpOnFail(!1).strictOptions().check(async o=>{if((o["skip-wordpress-setup"]||o.skipWordpressSetup)&&(o.skipWordPressSetup=!0),o.wp!==void 0&&!ge(o.wp))try{new URL(o.wp)}catch{throw new Error('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"')}if(o["site-url"]!==void 0&&o["site-url"]!=="")try{new URL(o["site-url"])}catch{throw new Error(`Invalid site-url "${o["site-url"]}". Please provide a valid URL (e.g., http://localhost:8080 or https://example.com)`)}if(o["auto-mount"]){let i=!1;try{i=d.statSync(o["auto-mount"]).isDirectory()}catch{i=!1}if(!i)throw new Error(`The specified --auto-mount path is not a directory: '${o["auto-mount"]}'.`)}if(o["experimental-multi-worker"]!==void 0&&o["experimental-multi-worker"]<=1)throw new Error("The --experimental-multi-worker flag must be a positive integer greater than 1.");if(o["experimental-blueprints-v2-runner"]===!0){if(o.mode!==void 0){if("skip-wordpress-setup"in o)throw new Error("The --skipWordPressSetup option cannot be used with the --mode option. Use one or the other.");if("skip-sqlite-setup"in o)throw new Error("The --skipSqliteSetup option is not supported in Blueprint V2 mode.");if(o["auto-mount"]!==void 0)throw new Error("The --mode option cannot be used with --auto-mount because --auto-mount automatically sets the mode.")}else o["skip-wordpress-setup"]===!0?o.mode="apply-to-existing-site":o.mode="create-new-site";const i=o.allow||[];o.followSymlinks===!0&&i.push("follow-symlinks"),o["blueprint-may-read-adjacent-files"]===!0&&i.push("read-local-fs"),o.allow=i}else if(o.mode!==void 0)throw new Error("The --mode option requires the --experimentalBlueprintsV2Runner flag.");return!0});e.wrap(e.terminalWidth());const r=await e.argv,t=r._[0];["run-blueprint","server","build-snapshot"].includes(t)||(e.showHelp(),process.exit(1));const s={...r,command:t,mount:[...r.mount||[],...r["mount-dir"]||[]],"mount-before-install":[...r["mount-before-install"]||[],...r["mount-dir-before-install"]||[]]};await J(s)}catch(e){if(!(e instanceof Error))throw e;if(process.argv.includes("--debug"))m.printDebugDetails(e);else{const t=[];let s=e;do t.push(s.message),s=s.cause;while(s instanceof Error);console.error("\x1B[1m"+t.join(" caused by ")+"\x1B[0m")}process.exit(1)}}async function J(e){let r,t;const s=[];if(e.autoMount!==void 0&&(e.autoMount===""&&(e={...e,autoMount:process.cwd()}),e=M.expandAutoMounts(e)),e.quiet&&(e.verbosity="quiet",delete e.quiet),e.debug?e.verbosity="debug":e.verbosity==="debug"&&(e.debug=!0),e.verbosity){const a=Object.values(E).find(p=>p.name===e.verbosity).severity;u.logger.setSeverityFilterLevel(a)}const o=D.platform()==="win32"?void 0:await import("fs-ext").then(a=>a.flockSync).catch(()=>{u.logger.warn("The fs-ext package is not installed. Internal file locking will not be integrated with host OS file locking.")}),i=new ae.FileLockManagerForNode(o);let n=!1,l=!0;return u.logger.log("Starting a PHP server..."),fe({port:e.port,onBind:async(a,p)=>{const b=`http://127.0.0.1:${p}`,I=e["site-url"]||b,P=e.experimentalMultiWorker??1,w=Math.floor(Number.MAX_SAFE_INTEGER/P),L="-playground-cli-site-",y=await Se(L);u.logger.debug(`Native temp dir for VFS root: ${y}`);const T=f.dirname(y),U=2*24*60*60*1e3;We(L,U,T);const v=f.join(y,"internal");d.mkdirSync(v);const Q=["wordpress","tmp","home"];for(const c of Q){const g=h=>h.vfsPath===`/${c}`;if(!(e["mount-before-install"]?.some(g)||e.mount?.some(g))){const h=f.join(y,c);d.mkdirSync(h),e["mount-before-install"]===void 0&&(e["mount-before-install"]=[]),e["mount-before-install"].unshift({vfsPath:`/${c}`,hostPath:h})}}if(e["mount-before-install"])for(const c of e["mount-before-install"])u.logger.debug(`Mount before WP install: ${c.vfsPath} -> ${c.hostPath}`);if(e.mount)for(const c of e.mount)u.logger.debug(`Mount after WP install: ${c.vfsPath} -> ${c.hostPath}`);let k;e["experimental-blueprints-v2-runner"]?k=new be(e,{siteUrl:I,processIdSpaceLength:w}):(k=new ke(e,{siteUrl:I,processIdSpaceLength:w}),typeof e.blueprint=="string"&&(e.blueprint=await ye({sourceString:e.blueprint,blueprintMayReadAdjacentFiles:e["blueprint-may-read-adjacent-files"]===!0})));const X=$e(P,k.getWorkerType(),({exitCode:c,isMain:g,workerIndex:$})=>{c!==0&&(u.logger.error(`Worker ${$} exited with code ${c}
9
+ `),g&&e.exitOnPrimaryWorkerCrash&&process.exit(1))});u.logger.log(`Setting up WordPress ${e.wp}`);try{const[c,...g]=await X,$=await z(i);if(t=await k.bootPrimaryWorker(c.phpPort,$,v),s.push({playground:t,worker:c.worker}),await t.isReady(),n=!0,u.logger.log("Booted!"),r=new we(t),!e["experimental-blueprints-v2-runner"]){const h=await k.compileInputBlueprint(e["additional-blueprint-steps"]||[]);h&&(u.logger.log("Running the Blueprint..."),await R.runBlueprintV1Steps(h,t),u.logger.log("Finished running the blueprint"))}if(e.command==="build-snapshot"?(await Me(t,e.outfile),u.logger.log(`WordPress exported to ${e.outfile}`),process.exit(0)):e.command==="run-blueprint"&&(u.logger.log("Blueprint executed"),process.exit(0)),e.experimentalMultiWorker&&e.experimentalMultiWorker>1){u.logger.log("Preparing additional workers...");const h=w;await Promise.all(g.map(async(S,C)=>{const Y=h+C*w,G=await z(i),V=await k.bootSecondaryWorker({worker:S,fileLockManagerPort:G,firstProcessId:Y,nativeInternalDirPath:v});s.push({playground:V,worker:S.worker}),r.addWorker(V)}))}return u.logger.log(`WordPress is running on ${b} with ${P} worker(s)`),e.experimentalDevtools&&e.xdebug&&(await pe.startBridge({phpInstance:t,phpRoot:"/wordpress"})).start(),{playground:t,server:a,serverUrl:b,[Symbol.asyncDispose]:async function(){await Promise.all(s.map(async({playground:S,worker:C})=>{await S.dispose(),await C.terminate()})),await new Promise(S=>a.close(S))},workerThreadCount:P}}catch(c){if(!e.debug)throw c;let g="";throw await t?.fileExists(u.errorLogPath)&&(g=await t.readFileAsText(u.errorLogPath)),new Error(g,{cause:c})}},async handleRequest(a){if(!n)return m.PHPResponse.forHttpCode(502,"WordPress is not ready yet");if(l){l=!1;const p={"Content-Type":["text/plain"],"Content-Length":["0"],Location:[a.url]};return a.headers?.cookie?.includes("playground_auto_login_already_happened")&&(p["Set-Cookie"]=["playground_auto_login_already_happened=1; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Path=/"]),new m.PHPResponse(302,p,new Uint8Array)}return await r.handleRequest(a)}})}async function $e(e,r,t){const s=[];for(let o=0;o<e;o++){const i=await Be(r),n=l=>{t({exitCode:l,isMain:o===0,workerIndex:o})};s.push(new Promise((l,a)=>{i.once("message",function(p){p.command==="worker-script-initialized"&&l({worker:i,phpPort:p.phpPort})}),i.once("error",function(p){console.error(p);const b=new Error(`Worker failed to load worker. ${p.message?`Original error: ${p.message}`:""}`);a(b)}),i.once("exit",n)}))}return Promise.all(s)}async function Be(e){return e==="v1"?new A.Worker(new URL("./worker-thread-v1.cjs",typeof document>"u"?require("url").pathToFileURL(__filename).href:W&&W.tagName.toUpperCase()==="SCRIPT"&&W.src||new URL("run-cli-Bb8U_jz3.cjs",document.baseURI).href)):new A.Worker(new URL("./worker-thread-v2.cjs",typeof document>"u"?require("url").pathToFileURL(__filename).href:W&&W.tagName.toUpperCase()==="SCRIPT"&&W.src||new URL("run-cli-Bb8U_jz3.cjs",document.baseURI).href))}async function z(e){const{port1:r,port2:t}=new A.MessageChannel;return await le.jspi()?m.exposeAPI(e,null,r):await m.exposeSyncAPI(e,r),t}async function Me(e,r){await e.run({code:`<?php
10
10
  $zip = new ZipArchive();
11
11
  if(false === $zip->open('/tmp/build.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE)) {
12
12
  throw new Exception('Failed to create ZIP');
@@ -23,5 +23,5 @@ Warning: Following symlinks will expose files outside mounted directories to Pla
23
23
  }
24
24
  $zip->close();
25
25
 
26
- `});const t=await e.readFileAsBuffer("/tmp/build.zip");p.writeFileSync(r,t)}exports.LogVerbosity=T;exports.parseOptionsAndRunCLI=Ie;exports.runCLI=J;
27
- //# sourceMappingURL=run-cli-4qHq8whi.cjs.map
26
+ `});const t=await e.readFileAsBuffer("/tmp/build.zip");d.writeFileSync(r,t)}exports.LogVerbosity=E;exports.parseOptionsAndRunCLI=Ie;exports.runCLI=J;
27
+ //# sourceMappingURL=run-cli-Bb8U_jz3.cjs.map