@wp-playground/client 0.1.51 → 0.1.58

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.
@@ -104,6 +104,9 @@
104
104
  },
105
105
  "pluginPath": {
106
106
  "type": "string"
107
+ },
108
+ "pluginName": {
109
+ "type": "string"
107
110
  }
108
111
  },
109
112
  "required": [
@@ -244,37 +247,11 @@
244
247
  "type": "object",
245
248
  "additionalProperties": {},
246
249
  "description": "The constants to define"
247
- }
248
- },
249
- "required": [
250
- "consts",
251
- "step"
252
- ]
253
- },
254
- {
255
- "type": "object",
256
- "additionalProperties": false,
257
- "properties": {
258
- "progress": {
259
- "type": "object",
260
- "properties": {
261
- "weight": {
262
- "type": "number"
263
- },
264
- "caption": {
265
- "type": "string"
266
- }
267
- },
268
- "additionalProperties": false
269
250
  },
270
- "step": {
271
- "type": "string",
272
- "const": "defineVirtualWpConfigConsts"
273
- },
274
- "consts": {
275
- "type": "object",
276
- "additionalProperties": {},
277
- "description": "The constants to define"
251
+ "virtualize": {
252
+ "type": "boolean",
253
+ "description": "Enables the virtualization of wp-config.php and playground-consts.json files, leaving the local system files untouched. The variables defined in the /vfs-blueprints/playground-consts.json file are loaded via the auto_prepend_file directive in the php.ini file.",
254
+ "default": false
278
255
  }
279
256
  },
280
257
  "required": [
package/index.cjs CHANGED
@@ -1,23 +1,36 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const me=async(t,{pluginPath:e},r)=>{r?.tracker.setCaption(`Activating ${e}`);const s=[`${t.documentRoot}/wp-load.php`,`${t.documentRoot}/wp-admin/includes/plugin.php`];if(!s.every(i=>t.fileExists(i)))throw new Error(`Required WordPress files do not exist: ${s.join(", ")}`);await t.run({code:`<?php
2
- ${s.map(i=>`require_once( '${i}' );`).join(`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const D=async(t,{pluginPath:e,pluginName:r},s)=>{s?.tracker.setCaption(`Activating ${r||e}`);const n=[`${await t.documentRoot}/wp-load.php`,`${await t.documentRoot}/wp-admin/includes/plugin.php`];if(!n.every(a=>t.fileExists(a)))throw new Error(`Required WordPress files do not exist: ${n.join(", ")}`);if((await t.run({code:`<?php
2
+ ${n.map(a=>`require_once( '${a}' );`).join(`
3
3
  `)}
4
- activate_plugin('${e}');
5
- `})},ge=async(t,{themeFolderName:e},r)=>{r?.tracker.setCaption(`Activating ${e}`);const s=`${t.documentRoot}/wp-load.php`;if(!t.fileExists(s))throw new Error(`Required WordPress file does not exist: ${s}`);await t.run({code:`<?php
4
+ $plugin_path = '${e}';
5
+ if (!is_dir($plugin_path)) {
6
+ activate_plugin($plugin_path);
7
+ return;
8
+ }
9
+ // Find plugin entry file
10
+ foreach ( ( glob( $plugin_path . '/*.php' ) ?: array() ) as $file ) {
11
+ $info = get_plugin_data( $file, false, false );
12
+ if ( ! empty( $info['Name'] ) ) {
13
+ activate_plugin( $file );
14
+ return;
15
+ }
16
+ }
17
+ echo 'NO_ENTRY_FILE';
18
+ `})).text.endsWith("NO_ENTRY_FILE"))throw new Error("Could not find plugin entry file.")},q=async(t,{themeFolderName:e},r)=>{r?.tracker.setCaption(`Activating ${e}`);const s=`${await t.documentRoot}/wp-load.php`;if(!t.fileExists(s))throw new Error(`Required WordPress file does not exist: ${s}`);await t.run({code:`<?php
6
19
  require_once( '${s}' );
7
20
  switch_theme( '${e}' );
8
- `})};function F(t){return new DOMParser().parseFromString(t.text,"text/html")}function A(t){const e=t.split(".").shift().replace("-"," ");return e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()}async function P(t,e,r){let s="";await t.fileExists(e)&&(s=await t.readFileAsText(e)),await t.writeFile(e,r(s))}async function it(t){return new Uint8Array(await t.arrayBuffer())}const Y="/vfs-blueprints",K="/vfs-blueprints/wp-config-consts.php",we=async(t,e)=>{const r=new ot(t,e.siteUrl,e.wordpressPath||"/wordpress");e.patchSqlitePlugin!==!1&&await r.patchSqlitePlugin(),e.addPhpInfo!==!1&&await r.addPhpInfo(),e.patchSiteUrl!==!1&&await r.patchSiteUrl(),e.disableSiteHealth!==!1&&await r.disableSiteHealth(),e.disableWpNewBlogNotification!==!1&&await r.disableWpNewBlogNotification()};class ot{constructor(e,r,s){this.php=e,this.scopedSiteUrl=r,this.wordpressPath=s}async patchSqlitePlugin(){await P(this.php,`${this.wordpressPath}/wp-content/plugins/sqlite-database-integration/wp-includes/sqlite/class-wp-sqlite-translator.php`,e=>e.replace("if ( false === strtotime( $value ) )",'if ( $value === "0000-00-00 00:00:00" || false === strtotime( $value ) )'))}async addPhpInfo(){await this.php.writeFile(`${this.wordpressPath}/phpinfo.php`,"<?php phpinfo(); ")}async patchSiteUrl(){await P(this.php,`${this.wordpressPath}/wp-config.php`,e=>`<?php
21
+ `})};function L(t){const e=t.split(".").shift().replace(/-/g," ");return e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()}async function S(t,e,r){let s="";await t.fileExists(e)&&(s=await t.readFileAsText(e)),await t.writeFile(e,r(s))}async function rt(t){return new Uint8Array(await t.arrayBuffer())}class st extends File{constructor(e,r){super(e,r),this.buffers=e}async arrayBuffer(){return this.buffers[0]}}const j=File.prototype.arrayBuffer instanceof Function?File:st,ge=async(t,e)=>{const r=new nt(t,e.siteUrl,e.wordpressPath||"/wordpress");e.patchSqlitePlugin!==!1&&await r.patchSqlitePlugin(),e.addPhpInfo!==!1&&await r.addPhpInfo(),e.patchSiteUrl!==!1&&await r.patchSiteUrl(),e.disableSiteHealth!==!1&&await r.disableSiteHealth(),e.disableWpNewBlogNotification!==!1&&await r.disableWpNewBlogNotification()};class nt{constructor(e,r,s){this.php=e,this.scopedSiteUrl=r,this.wordpressPath=s}async patchSqlitePlugin(){await S(this.php,`${this.wordpressPath}/wp-content/plugins/sqlite-database-integration/wp-includes/sqlite/class-wp-sqlite-translator.php`,e=>e.replace("if ( false === strtotime( $value ) )",'if ( $value === "0000-00-00 00:00:00" || false === strtotime( $value ) )'))}async addPhpInfo(){await this.php.writeFile(`${this.wordpressPath}/phpinfo.php`,"<?php phpinfo(); ")}async patchSiteUrl(){await S(this.php,`${this.wordpressPath}/wp-config.php`,e=>`<?php
9
22
  if(!defined('WP_HOME')) {
10
23
  define('WP_HOME', "${this.scopedSiteUrl}");
11
24
  define('WP_SITEURL', "${this.scopedSiteUrl}");
12
25
  }
13
- ?>${e}`)}async disableSiteHealth(){await P(this.php,`${this.wordpressPath}/wp-includes/default-filters.php`,e=>e.replace(/add_filter[^;]+wp_maybe_grant_site_health_caps[^;]+;/i,""))}async disableWpNewBlogNotification(){await P(this.php,`${this.wordpressPath}/wp-config.php`,e=>`${e} function wp_new_blog_notification(...$args){} `)}}const ye=async(t,{code:e})=>await t.run({code:e}),Pe=async(t,{options:e})=>await t.run(e),be=async(t,{key:e,value:r})=>{await t.setPhpIniEntry(e,r)},_e=async(t,{request:e})=>await t.request(e),$e=async(t,{fromPath:e,toPath:r})=>{await t.writeFile(r,await t.readFileAsBuffer(e))},Ee=async(t,{fromPath:e,toPath:r})=>{await t.mv(e,r)},Se=async(t,{path:e})=>{await t.mkdir(e)},ve=async(t,{path:e})=>{await t.unlink(e)},Re=async(t,{path:e})=>{await t.rmdir(e)},xe=async(t,{path:e,data:r})=>{r instanceof File&&(r=await it(r)),await t.writeFile(e,r)},D=async(t,{consts:e})=>{const r=await t.documentRoot;await P(t,`${r}/playground-consts.json`,s=>JSON.stringify({...JSON.parse(s||"{}"),...e})),await P(t,`${r}/wp-config.php`,s=>s.includes("playground-consts.json")?s:`<?php
14
- $consts = json_decode(file_get_contents('./playground-consts.json'), true);
26
+ ?>${e}`)}async disableSiteHealth(){await S(this.php,`${this.wordpressPath}/wp-includes/default-filters.php`,e=>e.replace(/add_filter[^;]+wp_maybe_grant_site_health_caps[^;]+;/i,""))}async disableWpNewBlogNotification(){await S(this.php,`${this.wordpressPath}/wp-config.php`,e=>`${e} function wp_new_blog_notification(...$args){} `)}}const ye=async(t,{code:e})=>await t.run({code:e}),Pe=async(t,{options:e})=>await t.run(e),be=async(t,{key:e,value:r})=>{await t.setPhpIniEntry(e,r)},_e=async(t,{request:e})=>await t.request(e),$e=async(t,{fromPath:e,toPath:r})=>{await t.writeFile(r,await t.readFileAsBuffer(e))},Ee=async(t,{fromPath:e,toPath:r})=>{await t.mv(e,r)},ve=async(t,{path:e})=>{await t.mkdir(e)},Se=async(t,{path:e})=>{await t.unlink(e)},Re=async(t,{path:e})=>{await t.rmdir(e)},B=async(t,{path:e,data:r})=>{r instanceof File&&(r=await rt(r)),await t.writeFile(e,r)},Q="/vfs-blueprints",V=async(t,{consts:e,virtualize:r=!1})=>{const s=await t.documentRoot,n=r?Q:s,i=`${n}/playground-consts.json`,o=`${n}/wp-config.php`;return r&&(t.mkdir(Q),t.setPhpIniEntry("auto_prepend_file",o)),await S(t,i,a=>JSON.stringify({...JSON.parse(a||"{}"),...e})),await S(t,o,a=>a.includes("playground-consts.json")?a:`<?php
27
+ $consts = json_decode(file_get_contents('${i}'), true);
15
28
  foreach ($consts as $const => $value) {
16
29
  if (!defined($const)) {
17
30
  define($const, $value);
18
31
  }
19
32
  }
20
- ?>${s}`)},Te=async(t,{siteUrl:e})=>await D(t,{consts:{WP_HOME:e,WP_SITEURL:e}});class Ce{constructor({concurrency:e}){this._running=0,this.concurrency=e,this.queue=[]}get running(){return this._running}async acquire(){for(;;)if(this._running>=this.concurrency)await new Promise(e=>this.queue.push(e));else return this._running++,()=>{this._running--,this.queue.length>0&&this.queue.shift()()}}async run(e){const r=await this.acquire();try{return await e()}finally{r()}}}const at=Symbol("literal");function $(t){if(typeof t=="string")return t.startsWith("$")?t:JSON.stringify(t);if(typeof t=="number")return t.toString();if(Array.isArray(t))return`array(${t.map($).join(", ")})`;if(t===null)return"null";if(typeof t=="object")return at in t?t.toString():`array(${Object.entries(t).map(([r,s])=>`${JSON.stringify(r)} => ${$(s)}`).join(", ")})`;if(typeof t=="function")return t();throw new Error(`Unsupported value: ${t}`)}function U(t){const e={};for(const r in t)e[r]=$(t[r]);return e}const Q=`<?php
33
+ ?>${a}`),o},xe=async(t,{siteUrl:e})=>await V(t,{consts:{WP_HOME:e,WP_SITEURL:e}});class Te{constructor({concurrency:e}){this._running=0,this.concurrency=e,this.queue=[]}get running(){return this._running}async acquire(){for(;;)if(this._running>=this.concurrency)await new Promise(e=>this.queue.push(e));else return this._running++,()=>{this._running--,this.queue.length>0&&this.queue.shift()()}}async run(e){const r=await this.acquire();try{return await e()}finally{r()}}}const it=Symbol("literal");function _(t){if(typeof t=="string")return t.startsWith("$")?t:JSON.stringify(t);if(typeof t=="number")return t.toString();if(Array.isArray(t))return`array(${t.map(_).join(", ")})`;if(t===null)return"null";if(typeof t=="object")return it in t?t.toString():`array(${Object.entries(t).map(([r,s])=>`${JSON.stringify(r)} => ${_(s)}`).join(", ")})`;if(typeof t=="function")return t();throw new Error(`Unsupported value: ${t}`)}function O(t){const e={};for(const r in t)e[r]=_(t[r]);return e}const X=`<?php
21
34
 
22
35
  function zipDir($dir, $output, $additionalFiles = array())
23
36
  {
@@ -79,39 +92,32 @@ function delTree($dir)
79
92
  }
80
93
  return rmdir($dir);
81
94
  }
82
- `;async function Fe(t){const e="wordpress-playground.zip",r=`/${e}`,s=U({zipPath:r,documentRoot:await t.documentRoot});await Le(t,`zipDir(${s.documentRoot}, ${s.zipPath});`);const n=await t.readFileAsBuffer(r);return t.unlink(r),new File([n],e)}const ke=async(t,{fullSiteZip:e})=>{const r="/import.zip";await t.writeFile(r,new Uint8Array(await e.arrayBuffer()));const s=await t.absoluteUrl,n=await t.documentRoot;await t.rmdir(n),await q(t,{zipPath:r,extractToPath:"/"});const i=U({absoluteUrl:s});await lt(t,`${n}/wp-config.php`,o=>`<?php
95
+ `;async function Fe(t){const e="wordpress-playground.zip",r=`/${e}`,s=O({zipPath:r,documentRoot:await t.documentRoot});await Ae(t,`zipDir(${s.documentRoot}, ${s.zipPath});`);const n=await t.readFileAsBuffer(r);return t.unlink(r),new File([n],e)}const Ce=async(t,{fullSiteZip:e})=>{const r="/import.zip";await t.writeFile(r,new Uint8Array(await e.arrayBuffer()));const s=await t.absoluteUrl,n=await t.documentRoot;await t.rmdir(n),await U(t,{zipPath:r,extractToPath:"/"});const i=O({absoluteUrl:s});await at(t,`${n}/wp-config.php`,o=>`<?php
83
96
  if(!defined('WP_HOME')) {
84
97
  define('WP_HOME', ${i.absoluteUrl});
85
98
  define('WP_SITEURL', ${i.absoluteUrl});
86
99
  }
87
- ?>${o}`)},q=async(t,{zipPath:e,extractToPath:r})=>{const s=U({zipPath:e,extractToPath:r});await Le(t,`unzip(${s.zipPath}, ${s.extractToPath});`)},Oe=async(t,{file:e})=>{const r=await t.request({url:"/wp-admin/admin.php?import=wordpress"}),s=X(r).getElementById("import-upload-form")?.getAttribute("action"),n=await t.request({url:`/wp-admin/${s}`,method:"POST",files:{import:e}}),i=X(n).querySelector("#wpbody-content form");if(!i)throw console.log(n.text),new Error("Could not find an importer form in response. See the response text above for details.");const o=ct(i);o.fetch_attachments="1";for(const a in o)if(a.startsWith("user_map[")){const l="user_new["+a.slice(9,-1)+"]";o[l]="1"}await t.request({url:i.action,method:"POST",formData:o})};function X(t){return new DOMParser().parseFromString(t.text,"text/html")}function ct(t){return Object.fromEntries(new FormData(t).entries())}async function lt(t,e,r){await t.writeFile(e,r(await t.readFileAsText(e)))}async function Le(t,e){const r=await t.run({code:Q+e});if(r.exitCode!==0)throw console.log(Q+e),console.log(e+""),console.log(r.errors),r.errors;return r}const Ae=async(t,{pluginZipFile:e,options:r={}},s)=>{s?.tracker.setCaption(`Installing the ${A(e?.name)} plugin`);try{const n="activate"in r?r.activate:!0,i=await t.request({url:"/wp-admin/plugin-install.php?tab=upload"}),o=F(i),a=new FormData(o.querySelector(".wp-upload-form")),{pluginzip:l,...c}=Object.fromEntries(a.entries()),u=await t.request({url:"/wp-admin/update.php?action=upload-plugin",method:"POST",formData:c,files:{pluginzip:e}});if(n){const p=F(u).querySelector("#wpbody-content .button.button-primary").attributes.getNamedItem("href").value,y=new URL(p,await t.pathToInternalUrl("/wp-admin/")).toString();await t.request({url:y})}await t.isDir("/wordpress/wp-content/plugins/gutenberg")&&!await t.fileExists("/wordpress/.gutenberg-patched")&&(await t.writeFile("/wordpress/.gutenberg-patched","1"),await Z(t,"/wordpress/wp-content/plugins/gutenberg/build/block-editor/index.js",d=>d.replace(/srcDoc:("[^"]+"|[^,]+)/g,'src:"/wp-includes/empty.html"')),await Z(t,"/wordpress/wp-content/plugins/gutenberg/build/block-editor/index.min.js",d=>d.replace(/srcDoc:("[^"]+"|[^,]+)/g,'src:"/wp-includes/empty.html"')))}catch(n){console.error(`Proceeding without the ${e.name} theme. Could not install it in wp-admin. The original error was: ${n}`),console.error(n)}};async function Z(t,e,r){return await t.writeFile(e,r(await t.readFileAsText(e)))}const Ue=async(t,{themeZipFile:e,options:r={}},s)=>{s?.tracker.setCaption(`Installing the ${A(e.name)} theme`);try{const n="activate"in r?r.activate:!0,i=await t.request({url:"/wp-admin/theme-install.php"}),o=F(i),a=new FormData(o.querySelector(".wp-upload-form")),{themezip:l,...c}=Object.fromEntries(a.entries()),u=await t.request({url:"/wp-admin/update.php?action=upload-theme",method:"POST",formData:c,files:{themezip:e}});if(n){const d=F(u),p=d.querySelector("#wpbody-content > .wrap");if(p?.textContent?.includes("Theme installation failed.")){console.error(p?.textContent);return}const y=d.querySelector("#wpbody-content .activatelink, .update-from-upload-actions .button.button-primary");if(!y){console.error('The "activate" button was not found.');return}const st=y.attributes.getNamedItem("href").value,nt=new URL(st,await t.pathToInternalUrl("/wp-admin/")).toString();await t.request({url:nt})}}catch(n){console.error(`Proceeding without the ${e.name} theme. Could not install it in wp-admin. The original error was: ${n}`),console.error(n)}},He=async(t,{username:e="admin",password:r="password"}={},s)=>{s?.tracker.setCaption(s?.initialCaption||"Logging in"),await t.request({url:"/wp-login.php"}),await t.request({url:"/wp-login.php",method:"POST",formData:{log:e,pwd:r,rememberme:"forever"}})},Ie=async(t,{options:e})=>{await t.request({url:"/wp-admin/install.php?step=2",method:"POST",formData:{language:"en",prefix:"wp_",weblog_title:"My WordPress Website",user_name:e.adminPassword||"admin",admin_password:e.adminPassword||"password",admin_password2:e.adminPassword||"password",Submit:"Install WordPress",pw_weak:"1",admin_email:"admin@localhost.com"}})},We=async(t,{options:e})=>{const r=`<?php
100
+ ?>${o}`)},U=async(t,{zipPath:e,extractToPath:r})=>{const s=O({zipPath:e,extractToPath:r});await Ae(t,`unzip(${s.zipPath}, ${s.extractToPath});`)},ke=async(t,{file:e})=>{const r=await t.request({url:"/wp-admin/admin.php?import=wordpress"}),s=ee(r).getElementById("import-upload-form")?.getAttribute("action"),n=await t.request({url:`/wp-admin/${s}`,method:"POST",files:{import:e}}),i=ee(n).querySelector("#wpbody-content form");if(!i)throw console.log(n.text),new Error("Could not find an importer form in response. See the response text above for details.");const o=ot(i);o.fetch_attachments="1";for(const a in o)if(a.startsWith("user_map[")){const l="user_new["+a.slice(9,-1)+"]";o[l]="1"}await t.request({url:i.action,method:"POST",formData:o})};function ee(t){return new DOMParser().parseFromString(t.text,"text/html")}function ot(t){return Object.fromEntries(new FormData(t).entries())}async function at(t,e,r){await t.writeFile(e,r(await t.readFileAsText(e)))}async function Ae(t,e){const r=await t.run({code:X+e});if(r.exitCode!==0)throw console.log(X+e),console.log(e+""),console.log(r.errors),r.errors;return r}async function Le(t,{targetPath:e,zipFile:r}){const s=r.name,n=s.replace(/\.zip$/,""),i=`/tmp/assets/${n}`,o=`/tmp/${s}`,a=()=>t.rmdir(i,{recursive:!0});await t.fileExists(i)&&await a(),await B(t,{path:o,data:r});const l=()=>Promise.all([a,()=>t.unlink(o)]);try{await U(t,{zipPath:o,extractToPath:i});const c=await t.listFiles(i,{prependPath:!0}),u=c.length===1&&await t.isDir(c[0]);let d,p="";u?(p=c[0],d=c[0].split("/").pop()):(p=i,d=n);const y=`${e}/${d}`;return await t.mv(p,y),await l(),{assetFolderPath:y,assetFolderName:d}}catch(c){throw await l(),c}}const Oe=async(t,{pluginZipFile:e,options:r={}},s)=>{const n=e.name.split("/").pop()||"plugin.zip",i=L(n);s?.tracker.setCaption(`Installing the ${i} plugin`);try{const{assetFolderPath:o}=await Le(t,{zipFile:e,targetPath:`${await t.documentRoot}/wp-content/plugins`});("activate"in r?r.activate:!0)&&await D(t,{pluginPath:o,pluginName:i},s),await ct(t)}catch(o){console.error(`Proceeding without the ${i} plugin. Could not install it in wp-admin. The original error was: ${o}`),console.error(o)}};async function ct(t){await t.isDir("/wordpress/wp-content/plugins/gutenberg")&&!await t.fileExists("/wordpress/.gutenberg-patched")&&(await t.writeFile("/wordpress/.gutenberg-patched","1"),await te(t,"/wordpress/wp-content/plugins/gutenberg/build/block-editor/index.js",e=>e.replace(/srcDoc:("[^"]+"|[^,]+)/g,'src:"/wp-includes/empty.html"')),await te(t,"/wordpress/wp-content/plugins/gutenberg/build/block-editor/index.min.js",e=>e.replace(/srcDoc:("[^"]+"|[^,]+)/g,'src:"/wp-includes/empty.html"')))}async function te(t,e,r){return await t.writeFile(e,r(await t.readFileAsText(e)))}const Ue=async(t,{themeZipFile:e,options:r={}},s)=>{const n=L(e.name);s?.tracker.setCaption(`Installing the ${n} theme`);try{const{assetFolderName:i}=await Le(t,{zipFile:e,targetPath:`${await t.documentRoot}/wp-content/themes`});("activate"in r?r.activate:!0)&&await q(t,{themeFolderName:i},s)}catch(i){console.error(`Proceeding without the ${n} theme. Could not install it in wp-admin. The original error was: ${i}`),console.error(i)}},He=async(t,{username:e="admin",password:r="password"}={},s)=>{s?.tracker.setCaption(s?.initialCaption||"Logging in"),await t.request({url:"/wp-login.php"}),await t.request({url:"/wp-login.php",method:"POST",formData:{log:e,pwd:r,rememberme:"forever"}})},Ne=async(t,{options:e})=>{await t.request({url:"/wp-admin/install.php?step=2",method:"POST",formData:{language:"en",prefix:"wp_",weblog_title:"My WordPress Website",user_name:e.adminPassword||"admin",admin_password:e.adminPassword||"password",admin_password2:e.adminPassword||"password",Submit:"Install WordPress",pw_weak:"1",admin_email:"admin@localhost.com"}})},We=async(t,{options:e})=>{const r=`<?php
88
101
  include 'wordpress/wp-load.php';
89
- $site_options = ${$(e)};
102
+ $site_options = ${_(e)};
90
103
  foreach($site_options as $name => $value) {
91
104
  update_option($name, $value);
92
105
  }
93
106
  echo "Success";
94
- `,s=await t.run({code:r});return Me(s),{code:r,result:s}},Ne=async(t,{meta:e,userId:r})=>{const s=`<?php
107
+ `,s=await t.run({code:r});return ze(s),{code:r,result:s}},Ie=async(t,{meta:e,userId:r})=>{const s=`<?php
95
108
  include 'wordpress/wp-load.php';
96
- $meta = ${$(e)};
109
+ $meta = ${_(e)};
97
110
  foreach($meta as $name => $value) {
98
- update_user_meta(${$(r)}, $name, $value);
111
+ update_user_meta(${_(r)}, $name, $value);
99
112
  }
100
113
  echo "Success";
101
- `,n=await t.run({code:s});return Me(n),{code:s,result:n}};async function Me(t){if(t.text!=="Success")throw console.log(t),new Error(`Failed to run code: ${t.text} ${t.errors}`)}const ze=async(t,{consts:e})=>{t.mkdir(Y);const r=`${Y}/playground-consts.json`;return await P(t,r,s=>JSON.stringify({...JSON.parse(s||"{}"),...e})),await P(t,K,s=>s.includes("playground-consts.json")?s:`<?php
102
- $consts = json_decode(file_get_contents('${r}'), true);
103
- foreach ($consts as $const => $value) {
104
- if (!defined($const)) {
105
- define($const, $value);
106
- }
107
- }
108
- ?>${s}`),K},ut=Object.freeze(Object.defineProperty({__proto__:null,activatePlugin:me,activateTheme:ge,applyWordPressPatches:we,cp:$e,defineSiteUrl:Te,defineVirtualWpConfigConsts:ze,defineWpConfigConsts:D,importFile:Oe,installPlugin:Ae,installTheme:Ue,login:He,mkdir:Se,mv:Ee,replaceSite:ke,request:_e,rm:ve,rmdir:Re,runPHP:ye,runPHPWithOptions:Pe,runWpInstallationWizard:Ie,setPhpIniEntry:be,setSiteOptions:We,unzip:q,updateUserMeta:Ne,writeFile:xe,zipEntireSite:Fe},Symbol.toStringTag,{value:"Module"})),ht=5*1024*1024;function dt(t,e){const r=t.headers.get("content-length")||"",s=parseInt(r,10)||ht;function n(i,o){e(new CustomEvent("progress",{detail:{loaded:i,total:o}}))}return new Response(new ReadableStream({async start(i){if(!t.body){i.close();return}const o=t.body.getReader();let a=0;for(;;)try{const{done:l,value:c}=await o.read();if(c&&(a+=c.byteLength),l){n(a,a),i.close();break}else n(a,s),i.enqueue(c)}catch(l){console.error({e:l}),i.error(l);break}}}),{status:t.status,statusText:t.statusText,headers:t.headers})}const W=1e-5;class H extends EventTarget{constructor({weight:e=1,caption:r="",fillTime:s=4}={}){super(),this._selfWeight=1,this._selfDone=!1,this._selfProgress=0,this._selfCaption="",this._isFilling=!1,this._subTrackers=[],this._weight=e,this._selfCaption=r,this._fillTime=s}stage(e,r=""){if(e||(e=this._selfWeight),this._selfWeight-e<-W)throw new Error(`Cannot add a stage with weight ${e} as the total weight of registered stages would exceed 1.`);this._selfWeight-=e;const s=new H({caption:r,weight:e,fillTime:this._fillTime});return this._subTrackers.push(s),s.addEventListener("progress",()=>this.notifyProgress()),s.addEventListener("done",()=>{this.done&&this.notifyDone()}),s}fillSlowly({stopBeforeFinishing:e=!0}={}){if(this._isFilling)return;this._isFilling=!0;const r=100,s=this._fillTime/r;this._fillInterval=setInterval(()=>{this.set(this._selfProgress+1),e&&this._selfProgress>=99&&clearInterval(this._fillInterval)},s)}set(e){this._selfProgress=Math.min(e,100),this.notifyProgress(),this._selfProgress+W>=100&&this.finish()}finish(){this._fillInterval&&clearInterval(this._fillInterval),this._selfDone=!0,this._selfProgress=100,this._isFilling=!1,this._fillInterval=void 0,this.notifyProgress(),this.notifyDone()}get caption(){for(let e=this._subTrackers.length-1;e>=0;e--)if(!this._subTrackers[e].done){const r=this._subTrackers[e].caption;if(r)return r}return this._selfCaption}setCaption(e){this._selfCaption=e,this.notifyProgress()}get done(){return this.progress+W>=100}get progress(){if(this._selfDone)return 100;const e=this._subTrackers.reduce((r,s)=>r+s.progress*s.weight,this._selfProgress*this._selfWeight);return Math.round(e*1e4)/1e4}get weight(){return this._weight}get observer(){return this._progressObserver||(this._progressObserver=e=>{this.set(e)}),this._progressObserver}get loadingListener(){return this._loadingListener||(this._loadingListener=e=>{this.set(e.detail.loaded/e.detail.total*100)}),this._loadingListener}pipe(e){e.setProgress({progress:this.progress,caption:this.caption}),this.addEventListener("progress",r=>{e.setProgress({progress:r.detail.progress,caption:r.detail.caption})}),this.addEventListener("done",()=>{e.setLoaded()})}addEventListener(e,r){super.addEventListener(e,r)}removeEventListener(e,r){super.removeEventListener(e,r)}notifyProgress(){const e=this;this.dispatchEvent(new CustomEvent("progress",{detail:{get progress(){return e.progress},get caption(){return e.caption}}}))}notifyDone(){this.dispatchEvent(new CustomEvent("done"))}}const ee=Symbol("error"),te=Symbol("message");class j extends Event{constructor(e,r={}){super(e),this[ee]=r.error===void 0?null:r.error,this[te]=r.message===void 0?"":r.message}get error(){return this[ee]}get message(){return this[te]}}Object.defineProperty(j.prototype,"error",{enumerable:!0});Object.defineProperty(j.prototype,"message",{enumerable:!0});const pt=typeof globalThis.ErrorEvent=="function"?globalThis.ErrorEvent:j;class ft extends EventTarget{constructor(){super(...arguments),this.listenersCount=0}addEventListener(e,r){++this.listenersCount,super.addEventListener(e,r)}removeEventListener(e,r){--this.listenersCount,super.removeEventListener(e,r)}hasListeners(){return this.listenersCount>0}}function mt(t){t.asm={...t.asm};const e=new ft;for(const r in t.asm)if(typeof t.asm[r]=="function"){const s=t.asm[r];t.asm[r]=function(...n){try{return s(...n)}catch(i){if(!(i instanceof Error))throw i;if("exitCode"in i&&i?.exitCode===0)return;const o=wt(i,t.lastAsyncifyStackSource?.stack);if(t.lastAsyncifyStackSource&&(i.cause=t.lastAsyncifyStackSource),!e.hasListeners())throw bt(o),i;e.dispatchEvent(new pt("error",{error:i,message:o}))}}}return e}let M=[];function gt(){return M}function wt(t,e){if(t.message==="unreachable"){let r=yt;e||(r+=`
114
+ `,n=await t.run({code:s});return ze(n),{code:s,result:n}};async function ze(t){if(t.text!=="Success")throw console.log(t),new Error(`Failed to run code: ${t.text} ${t.errors}`)}const lt=Object.freeze(Object.defineProperty({__proto__:null,activatePlugin:D,activateTheme:q,applyWordPressPatches:ge,cp:$e,defineSiteUrl:xe,defineWpConfigConsts:V,importFile:ke,installPlugin:Oe,installTheme:Ue,login:He,mkdir:ve,mv:Ee,replaceSite:Ce,request:_e,rm:Se,rmdir:Re,runPHP:ye,runPHPWithOptions:Pe,runWpInstallationWizard:Ne,setPhpIniEntry:be,setSiteOptions:We,unzip:U,updateUserMeta:Ie,writeFile:B,zipEntireSite:Fe},Symbol.toStringTag,{value:"Module"})),ut=5*1024*1024;function ht(t,e){const r=t.headers.get("content-length")||"",s=parseInt(r,10)||ut;function n(i,o){e(new CustomEvent("progress",{detail:{loaded:i,total:o}}))}return new Response(new ReadableStream({async start(i){if(!t.body){i.close();return}const o=t.body.getReader();let a=0;for(;;)try{const{done:l,value:c}=await o.read();if(c&&(a+=c.byteLength),l){n(a,a),i.close();break}else n(a,s),i.enqueue(c)}catch(l){console.error({e:l}),i.error(l);break}}}),{status:t.status,statusText:t.statusText,headers:t.headers})}const W=1e-5;class H extends EventTarget{constructor({weight:e=1,caption:r="",fillTime:s=4}={}){super(),this._selfWeight=1,this._selfDone=!1,this._selfProgress=0,this._selfCaption="",this._isFilling=!1,this._subTrackers=[],this._weight=e,this._selfCaption=r,this._fillTime=s}stage(e,r=""){if(e||(e=this._selfWeight),this._selfWeight-e<-W)throw new Error(`Cannot add a stage with weight ${e} as the total weight of registered stages would exceed 1.`);this._selfWeight-=e;const s=new H({caption:r,weight:e,fillTime:this._fillTime});return this._subTrackers.push(s),s.addEventListener("progress",()=>this.notifyProgress()),s.addEventListener("done",()=>{this.done&&this.notifyDone()}),s}fillSlowly({stopBeforeFinishing:e=!0}={}){if(this._isFilling)return;this._isFilling=!0;const r=100,s=this._fillTime/r;this._fillInterval=setInterval(()=>{this.set(this._selfProgress+1),e&&this._selfProgress>=99&&clearInterval(this._fillInterval)},s)}set(e){this._selfProgress=Math.min(e,100),this.notifyProgress(),this._selfProgress+W>=100&&this.finish()}finish(){this._fillInterval&&clearInterval(this._fillInterval),this._selfDone=!0,this._selfProgress=100,this._isFilling=!1,this._fillInterval=void 0,this.notifyProgress(),this.notifyDone()}get caption(){for(let e=this._subTrackers.length-1;e>=0;e--)if(!this._subTrackers[e].done){const r=this._subTrackers[e].caption;if(r)return r}return this._selfCaption}setCaption(e){this._selfCaption=e,this.notifyProgress()}get done(){return this.progress+W>=100}get progress(){if(this._selfDone)return 100;const e=this._subTrackers.reduce((r,s)=>r+s.progress*s.weight,this._selfProgress*this._selfWeight);return Math.round(e*1e4)/1e4}get weight(){return this._weight}get observer(){return this._progressObserver||(this._progressObserver=e=>{this.set(e)}),this._progressObserver}get loadingListener(){return this._loadingListener||(this._loadingListener=e=>{this.set(e.detail.loaded/e.detail.total*100)}),this._loadingListener}pipe(e){e.setProgress({progress:this.progress,caption:this.caption}),this.addEventListener("progress",r=>{e.setProgress({progress:r.detail.progress,caption:r.detail.caption})}),this.addEventListener("done",()=>{e.setLoaded()})}addEventListener(e,r){super.addEventListener(e,r)}removeEventListener(e,r){super.removeEventListener(e,r)}notifyProgress(){const e=this;this.dispatchEvent(new CustomEvent("progress",{detail:{get progress(){return e.progress},get caption(){return e.caption}}}))}notifyDone(){this.dispatchEvent(new CustomEvent("done"))}}const re=Symbol("error"),se=Symbol("message");class G extends Event{constructor(e,r={}){super(e),this[re]=r.error===void 0?null:r.error,this[se]=r.message===void 0?"":r.message}get error(){return this[re]}get message(){return this[se]}}Object.defineProperty(G.prototype,"error",{enumerable:!0});Object.defineProperty(G.prototype,"message",{enumerable:!0});const dt=typeof globalThis.ErrorEvent=="function"?globalThis.ErrorEvent:G;class pt extends EventTarget{constructor(){super(...arguments),this.listenersCount=0}addEventListener(e,r){++this.listenersCount,super.addEventListener(e,r)}removeEventListener(e,r){--this.listenersCount,super.removeEventListener(e,r)}hasListeners(){return this.listenersCount>0}}function ft(t){t.asm={...t.asm};const e=new pt;for(const r in t.asm)if(typeof t.asm[r]=="function"){const s=t.asm[r];t.asm[r]=function(...n){try{return s(...n)}catch(i){if(!(i instanceof Error))throw i;if("exitCode"in i&&i?.exitCode===0)return;const o=wt(i,t.lastAsyncifyStackSource?.stack);if(t.lastAsyncifyStackSource&&(i.cause=t.lastAsyncifyStackSource),!e.hasListeners())throw Pt(o),i;e.dispatchEvent(new dt("error",{error:i,message:o}))}}}return e}let z=[];function mt(){return z}function wt(t,e){if(t.message==="unreachable"){let r=gt;e||(r+=`
109
115
 
110
116
  This stack trace is lacking. For a better one initialize
111
117
  the PHP runtime with { debug: true }, e.g. PHPNode.load('8.1', { debug: true }).
112
118
 
113
- `),M=_t(e||t.stack||"");for(const s of M)r+=` * ${s}
114
- `;return r}return t.message}const yt=`
119
+ `),z=bt(e||t.stack||"");for(const s of z)r+=` * ${s}
120
+ `;return r}return t.message}const gt=`
115
121
  "unreachable" WASM instruction executed.
116
122
 
117
123
  The typical reason is a PHP function missing from the ASYNCIFY_ONLY
@@ -135,17 +141,17 @@ the Dockerfile, you'll need to trigger this error again with long stack
135
141
  traces enabled. In node.js, you can do it using the --stack-trace-limit=100
136
142
  CLI option:
137
143
 
138
- `,re="\x1B[41m",Pt="\x1B[1m",se="\x1B[0m",ne="\x1B[K";let ie=!1;function bt(t){if(!ie){ie=!0,console.log(`${re}
139
- ${ne}
140
- ${Pt} WASM ERROR${se}${re}`);for(const e of t.split(`
141
- `))console.log(`${ne} ${e} `);console.log(`${se}`)}}function _t(t){try{const e=t.split(`
142
- `).slice(1).map(r=>{const s=r.trim().substring(3).split(" ");return{fn:s.length>=2?s[0]:"<unknown>",isWasm:r.includes("wasm://")}}).filter(({fn:r,isWasm:s})=>s&&!r.startsWith("dynCall_")&&!r.startsWith("invoke_")).map(({fn:r})=>r);return Array.from(new Set(e))}catch{return[]}}class _{constructor(e,r,s,n="",i=0){this.httpStatusCode=e,this.headers=r,this.bytes=s,this.exitCode=i,this.errors=n}static fromRawData(e){return new _(e.httpStatusCode,e.headers,e.bytes,e.errors,e.exitCode)}toRawData(){return{headers:this.headers,bytes:this.bytes,errors:this.errors,exitCode:this.exitCode,httpStatusCode:this.httpStatusCode}}get json(){return JSON.parse(this.text)}get text(){return new TextDecoder().decode(this.bytes)}}const I=["8.2","8.1","8.0","7.4","7.3","7.2","7.1","7.0","5.6"],De=I[0],$t=I;class Et{#e;#t;constructor(e,r={}){this.requestHandler=e,this.#e={},this.#t={handleRedirects:!1,maxRedirects:4,...r}}async request(e,r=0){const s=await this.requestHandler.request({...e,headers:{...e.headers,cookie:this.#r()}});if(s.headers["set-cookie"]&&this.#s(s.headers["set-cookie"]),this.#t.handleRedirects&&s.headers.location&&r<this.#t.maxRedirects){const n=new URL(s.headers.location[0],this.requestHandler.absoluteUrl);return this.request({url:n.toString(),method:"GET",headers:{}},r+1)}return s}pathToInternalUrl(e){return this.requestHandler.pathToInternalUrl(e)}internalUrlToPath(e){return this.requestHandler.internalUrlToPath(e)}get absoluteUrl(){return this.requestHandler.absoluteUrl}get documentRoot(){return this.requestHandler.documentRoot}#s(e){for(const r of e)try{if(!r.includes("="))continue;const s=r.indexOf("="),n=r.substring(0,s),i=r.substring(s+1).split(";")[0];this.#e[n]=i}catch(s){console.error(s)}}#r(){const e=[];for(const r in this.#e)e.push(`${r}=${this.#e[r]}`);return e.join("; ")}}const St="http://example.com";function oe(t){return t.toString().substring(t.origin.length)}function ae(t,e){return!e||!t.startsWith(e)?t:t.substring(e.length)}function vt(t,e){return!e||t.startsWith(e)?t:e+t}class Rt{#e;#t;#s;#r;#i;#n;#o;#a;#c;constructor(e,r={}){this.#a=new Ce({concurrency:1});const{documentRoot:s="/www/",absoluteUrl:n=typeof location=="object"?location?.href:"",isStaticFilePath:i=()=>!1}=r;this.php=e,this.#e=s,this.#c=i;const o=new URL(n);this.#s=o.hostname,this.#r=o.port?Number(o.port):o.protocol==="https:"?443:80,this.#t=(o.protocol||"").replace(":","");const a=this.#r!==443&&this.#r!==80;this.#i=[this.#s,a?`:${this.#r}`:""].join(""),this.#n=o.pathname.replace(/\/+$/,""),this.#o=[`${this.#t}://`,this.#i,this.#n].join("")}pathToInternalUrl(e){return`${this.absoluteUrl}${e}`}internalUrlToPath(e){const r=new URL(e);return r.pathname.startsWith(this.#n)&&(r.pathname=r.pathname.slice(this.#n.length)),oe(r)}get isRequestRunning(){return this.#a.running>0}get absoluteUrl(){return this.#o}get documentRoot(){return this.#e}async request(e){const r=e.url.startsWith("http://")||e.url.startsWith("https://"),s=new URL(e.url,r?void 0:St),n=ae(s.pathname,this.#n);return this.#c(n)?this.#l(n):await this.#u(e,s)}#l(e){const r=`${this.#e}${e}`;if(!this.php.fileExists(r))return new _(404,{},new TextEncoder().encode("404 File not found"));const s=this.php.readFileAsBuffer(r);return new _(200,{"content-length":[`${s.byteLength}`],"content-type":[Tt(r)],"accept-ranges":["bytes"],"cache-control":["public, max-age=0"]},s)}async#u(e,r){const s=await this.#a.acquire();try{this.php.addServerGlobalEntry("DOCUMENT_ROOT",this.#e),this.php.addServerGlobalEntry("HTTPS",this.#o.startsWith("https://")?"on":"");let n="GET";const i={host:this.#i,...qe(e.headers||{})},o=[];if(e.files&&Object.keys(e.files).length){n="POST";for(const c in e.files){const u=e.files[c];o.push({key:c,name:u.name,type:u.type,data:new Uint8Array(await u.arrayBuffer())})}i["content-type"]?.startsWith("multipart/form-data")&&(e.formData=xt(e.body||""),i["content-type"]="application/x-www-form-urlencoded",delete e.body)}let a;e.formData!==void 0?(n="POST",i["content-type"]=i["content-type"]||"application/x-www-form-urlencoded",a=new URLSearchParams(e.formData).toString()):a=e.body;let l;try{l=this.#h(r.pathname)}catch{return new _(404,{},new TextEncoder().encode("404 File not found"))}return await this.php.run({relativeUri:vt(oe(r),this.#n),protocol:this.#t,method:e.method||n,body:a,fileInfos:o,scriptPath:l,headers:i})}finally{s()}}#h(e){let r=ae(e,this.#n);r.includes(".php")?r=r.split(".php")[0]+".php":(r.endsWith("/")||(r+="/"),r.endsWith("index.php")||(r+="index.php"));const s=`${this.#e}${r}`;if(this.php.fileExists(s))return s;if(!this.php.fileExists(`${this.#e}/index.php`))throw new Error(`File not found: ${s}`);return`${this.#e}/index.php`}}function xt(t){const e={},r=t.match(/--(.*)\r\n/);if(!r)return e;const s=r[1],n=t.split(`--${s}`);return n.shift(),n.pop(),n.forEach(i=>{const o=i.indexOf(`\r
144
+ `,ne="\x1B[41m",yt="\x1B[1m",ie="\x1B[0m",oe="\x1B[K";let ae=!1;function Pt(t){if(!ae){ae=!0,console.log(`${ne}
145
+ ${oe}
146
+ ${yt} WASM ERROR${ie}${ne}`);for(const e of t.split(`
147
+ `))console.log(`${oe} ${e} `);console.log(`${ie}`)}}function bt(t){try{const e=t.split(`
148
+ `).slice(1).map(r=>{const s=r.trim().substring(3).split(" ");return{fn:s.length>=2?s[0]:"<unknown>",isWasm:r.includes("wasm://")}}).filter(({fn:r,isWasm:s})=>s&&!r.startsWith("dynCall_")&&!r.startsWith("invoke_")).map(({fn:r})=>r);return Array.from(new Set(e))}catch{return[]}}class b{constructor(e,r,s,n="",i=0){this.httpStatusCode=e,this.headers=r,this.bytes=s,this.exitCode=i,this.errors=n}static fromRawData(e){return new b(e.httpStatusCode,e.headers,e.bytes,e.errors,e.exitCode)}toRawData(){return{headers:this.headers,bytes:this.bytes,errors:this.errors,exitCode:this.exitCode,httpStatusCode:this.httpStatusCode}}get json(){return JSON.parse(this.text)}get text(){return new TextDecoder().decode(this.bytes)}}const N=["8.2","8.1","8.0","7.4","7.3","7.2","7.1","7.0","5.6"],Me=N[0],_t=N;class $t{#e;#t;constructor(e,r={}){this.requestHandler=e,this.#e={},this.#t={handleRedirects:!1,maxRedirects:4,...r}}async request(e,r=0){const s=await this.requestHandler.request({...e,headers:{...e.headers,cookie:this.#r()}});if(s.headers["set-cookie"]&&this.#s(s.headers["set-cookie"]),this.#t.handleRedirects&&s.headers.location&&r<this.#t.maxRedirects){const n=new URL(s.headers.location[0],this.requestHandler.absoluteUrl);return this.request({url:n.toString(),method:"GET",headers:{}},r+1)}return s}pathToInternalUrl(e){return this.requestHandler.pathToInternalUrl(e)}internalUrlToPath(e){return this.requestHandler.internalUrlToPath(e)}get absoluteUrl(){return this.requestHandler.absoluteUrl}get documentRoot(){return this.requestHandler.documentRoot}#s(e){for(const r of e)try{if(!r.includes("="))continue;const s=r.indexOf("="),n=r.substring(0,s),i=r.substring(s+1).split(";")[0];this.#e[n]=i}catch(s){console.error(s)}}#r(){const e=[];for(const r in this.#e)e.push(`${r}=${this.#e[r]}`);return e.join("; ")}}const Et="http://example.com";function ce(t){return t.toString().substring(t.origin.length)}function le(t,e){return!e||!t.startsWith(e)?t:t.substring(e.length)}function vt(t,e){return!e||t.startsWith(e)?t:e+t}class St{#e;#t;#s;#r;#i;#n;#o;#a;#c;constructor(e,r={}){this.#a=new Te({concurrency:1});const{documentRoot:s="/www/",absoluteUrl:n=typeof location=="object"?location?.href:"",isStaticFilePath:i=()=>!1}=r;this.php=e,this.#e=s,this.#c=i;const o=new URL(n);this.#s=o.hostname,this.#r=o.port?Number(o.port):o.protocol==="https:"?443:80,this.#t=(o.protocol||"").replace(":","");const a=this.#r!==443&&this.#r!==80;this.#i=[this.#s,a?`:${this.#r}`:""].join(""),this.#n=o.pathname.replace(/\/+$/,""),this.#o=[`${this.#t}://`,this.#i,this.#n].join("")}pathToInternalUrl(e){return`${this.absoluteUrl}${e}`}internalUrlToPath(e){const r=new URL(e);return r.pathname.startsWith(this.#n)&&(r.pathname=r.pathname.slice(this.#n.length)),ce(r)}get isRequestRunning(){return this.#a.running>0}get absoluteUrl(){return this.#o}get documentRoot(){return this.#e}async request(e){const r=e.url.startsWith("http://")||e.url.startsWith("https://"),s=new URL(e.url,r?void 0:Et),n=le(s.pathname,this.#n);return this.#c(n)?this.#l(n):await this.#u(e,s)}#l(e){const r=`${this.#e}${e}`;if(!this.php.fileExists(r))return new b(404,{},new TextEncoder().encode("404 File not found"));const s=this.php.readFileAsBuffer(r);return new b(200,{"content-length":[`${s.byteLength}`],"content-type":[xt(r)],"accept-ranges":["bytes"],"cache-control":["public, max-age=0"]},s)}async#u(e,r){const s=await this.#a.acquire();try{this.php.addServerGlobalEntry("DOCUMENT_ROOT",this.#e),this.php.addServerGlobalEntry("HTTPS",this.#o.startsWith("https://")?"on":"");let n="GET";const i={host:this.#i,...De(e.headers||{})},o=[];if(e.files&&Object.keys(e.files).length){n="POST";for(const c in e.files){const u=e.files[c];o.push({key:c,name:u.name,type:u.type,data:new Uint8Array(await u.arrayBuffer())})}i["content-type"]?.startsWith("multipart/form-data")&&(e.formData=Rt(e.body||""),i["content-type"]="application/x-www-form-urlencoded",delete e.body)}let a;e.formData!==void 0?(n="POST",i["content-type"]=i["content-type"]||"application/x-www-form-urlencoded",a=new URLSearchParams(e.formData).toString()):a=e.body;let l;try{l=this.#h(r.pathname)}catch{return new b(404,{},new TextEncoder().encode("404 File not found"))}return await this.php.run({relativeUri:vt(ce(r),this.#n),protocol:this.#t,method:e.method||n,body:a,fileInfos:o,scriptPath:l,headers:i})}finally{s()}}#h(e){let r=le(e,this.#n);r.includes(".php")?r=r.split(".php")[0]+".php":(r.endsWith("/")||(r+="/"),r.endsWith("index.php")||(r+="index.php"));const s=`${this.#e}${r}`;if(this.php.fileExists(s))return s;if(!this.php.fileExists(`${this.#e}/index.php`))throw new Error(`File not found: ${s}`);return`${this.#e}/index.php`}}function Rt(t){const e={},r=t.match(/--(.*)\r\n/);if(!r)return e;const s=r[1],n=t.split(`--${s}`);return n.shift(),n.pop(),n.forEach(i=>{const o=i.indexOf(`\r
143
149
  \r
144
- `),a=i.substring(0,o).trim(),l=i.substring(o+4).trim(),c=a.match(/name="([^"]+)"/);if(c){const u=c[1];e[u]=l}}),e}function Tt(t){switch(t.split(".").pop()){case"css":return"text/css";case"js":return"application/javascript";case"png":return"image/png";case"jpg":case"jpeg":return"image/jpeg";case"gif":return"image/gif";case"svg":return"image/svg+xml";case"woff":return"font/woff";case"woff2":return"font/woff2";case"ttf":return"font/ttf";case"otf":return"font/otf";case"eot":return"font/eot";case"ico":return"image/x-icon";case"html":return"text/html";case"json":return"application/json";case"xml":return"application/xml";case"txt":case"md":return"text/plain";default:return"application-octet-stream"}}const ce={0:"No error occurred. System call completed successfully.",1:"Argument list too long.",2:"Permission denied.",3:"Address in use.",4:"Address not available.",5:"Address family not supported.",6:"Resource unavailable, or operation would block.",7:"Connection already in progress.",8:"Bad file descriptor.",9:"Bad message.",10:"Device or resource busy.",11:"Operation canceled.",12:"No child processes.",13:"Connection aborted.",14:"Connection refused.",15:"Connection reset.",16:"Resource deadlock would occur.",17:"Destination address required.",18:"Mathematics argument out of domain of function.",19:"Reserved.",20:"File exists.",21:"Bad address.",22:"File too large.",23:"Host is unreachable.",24:"Identifier removed.",25:"Illegal byte sequence.",26:"Operation in progress.",27:"Interrupted function.",28:"Invalid argument.",29:"I/O error.",30:"Socket is connected.",31:"There is a directory under that path.",32:"Too many levels of symbolic links.",33:"File descriptor value too large.",34:"Too many links.",35:"Message too large.",36:"Reserved.",37:"Filename too long.",38:"Network is down.",39:"Connection aborted by network.",40:"Network unreachable.",41:"Too many files open in system.",42:"No buffer space available.",43:"No such device.",44:"There is no such file or directory OR the parent directory does not exist.",45:"Executable file format error.",46:"No locks available.",47:"Reserved.",48:"Not enough space.",49:"No message of the desired type.",50:"Protocol not available.",51:"No space left on device.",52:"Function not supported.",53:"The socket is not connected.",54:"Not a directory or a symbolic link to a directory.",55:"Directory not empty.",56:"State not recoverable.",57:"Not a socket.",58:"Not supported, or operation not supported on socket.",59:"Inappropriate I/O control operation.",60:"No such device or address.",61:"Value too large to be stored in data type.",62:"Previous owner died.",63:"Operation not permitted.",64:"Broken pipe.",65:"Protocol error.",66:"Protocol not supported.",67:"Protocol wrong type for socket.",68:"Result too large.",69:"Read-only file system.",70:"Invalid seek.",71:"No such process.",72:"Reserved.",73:"Connection timed out.",74:"Text file busy.",75:"Cross-device link.",76:"Extension: Capabilities insufficient."};function m(t=""){return function(r,s,n){const i=n.value;n.value=function(...o){try{return i.apply(this,o)}catch(a){const l=typeof a=="object"?a?.errno:null;if(l in ce){const c=ce[l],u=typeof o[0]=="string"?o[0]:null,d=u!==null?t.replaceAll("{path}",u):t;throw new Error(`${d}: ${c}`,{cause:a})}throw a}}}}const Ct=[];function Ft(t){return Ct[t]}(function(){return typeof process<"u"&&process.release?.name==="node"?"NODE":typeof window<"u"?"WEB":typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope?"WORKER":"NODE"})();var kt=Object.defineProperty,Ot=Object.getOwnPropertyDescriptor,g=(t,e,r,s)=>{for(var n=s>1?void 0:s?Ot(e,r):e,i=t.length-1,o;i>=0;i--)(o=t[i])&&(n=(s?o(e,r,n):o(n))||n);return s&&n&&kt(e,r,n),n};const f="string",S="number",h=Symbol("__private__dont__use");class w{constructor(e,r){this.#e=[],this.#t=!1,this.#s=null,this.#r={},e!==void 0&&this.initializeRuntime(e),r&&(this.requestHandler=new Et(new Rt(this,r)))}#e;#t;#s;#r;get absoluteUrl(){return this.requestHandler.requestHandler.absoluteUrl}get documentRoot(){return this.requestHandler.requestHandler.documentRoot}pathToInternalUrl(e){return this.requestHandler.requestHandler.pathToInternalUrl(e)}internalUrlToPath(e){return this.requestHandler.requestHandler.internalUrlToPath(e)}initializeRuntime(e){if(this[h])throw new Error("PHP runtime already initialized.");const r=Ft(e);if(!r)throw new Error("Invalid PHP runtime id.");this[h]=r,this.#s=mt(r)}setPhpIniPath(e){if(this.#t)throw new Error("Cannot set PHP ini path after calling run().");this[h].ccall("wasm_set_phpini_path",null,["string"],[e])}setPhpIniEntry(e,r){if(this.#t)throw new Error("Cannot set PHP ini entries after calling run().");this.#e.push([e,r])}chdir(e){this[h].FS.chdir(e)}async request(e,r){if(!this.requestHandler)throw new Error("No request handler available.");return this.requestHandler.request(e,r)}async run(e){this.#t||(this.#i(),this.#t=!0),this.#h(e.scriptPath||""),this.#o(e.relativeUri||""),this.#c(e.method||"GET");const{host:r,...s}={host:"example.com:443",...qe(e.headers||{})};if(this.#a(r,e.protocol||"http"),this.#l(s),e.body&&this.#u(e.body),e.fileInfos)for(const n of e.fileInfos)this.#p(n);return e.code&&this.#f(" ?>"+e.code),this.#d(),await this.#m()}#i(){if(this.#e.length>0){const e=this.#e.map(([r,s])=>`${r}=${s}`).join(`
150
+ `),a=i.substring(0,o).trim(),l=i.substring(o+4).trim(),c=a.match(/name="([^"]+)"/);if(c){const u=c[1];e[u]=l}}),e}function xt(t){switch(t.split(".").pop()){case"css":return"text/css";case"js":return"application/javascript";case"png":return"image/png";case"jpg":case"jpeg":return"image/jpeg";case"gif":return"image/gif";case"svg":return"image/svg+xml";case"woff":return"font/woff";case"woff2":return"font/woff2";case"ttf":return"font/ttf";case"otf":return"font/otf";case"eot":return"font/eot";case"ico":return"image/x-icon";case"html":return"text/html";case"json":return"application/json";case"xml":return"application/xml";case"txt":case"md":return"text/plain";default:return"application-octet-stream"}}const ue={0:"No error occurred. System call completed successfully.",1:"Argument list too long.",2:"Permission denied.",3:"Address in use.",4:"Address not available.",5:"Address family not supported.",6:"Resource unavailable, or operation would block.",7:"Connection already in progress.",8:"Bad file descriptor.",9:"Bad message.",10:"Device or resource busy.",11:"Operation canceled.",12:"No child processes.",13:"Connection aborted.",14:"Connection refused.",15:"Connection reset.",16:"Resource deadlock would occur.",17:"Destination address required.",18:"Mathematics argument out of domain of function.",19:"Reserved.",20:"File exists.",21:"Bad address.",22:"File too large.",23:"Host is unreachable.",24:"Identifier removed.",25:"Illegal byte sequence.",26:"Operation in progress.",27:"Interrupted function.",28:"Invalid argument.",29:"I/O error.",30:"Socket is connected.",31:"There is a directory under that path.",32:"Too many levels of symbolic links.",33:"File descriptor value too large.",34:"Too many links.",35:"Message too large.",36:"Reserved.",37:"Filename too long.",38:"Network is down.",39:"Connection aborted by network.",40:"Network unreachable.",41:"Too many files open in system.",42:"No buffer space available.",43:"No such device.",44:"There is no such file or directory OR the parent directory does not exist.",45:"Executable file format error.",46:"No locks available.",47:"Reserved.",48:"Not enough space.",49:"No message of the desired type.",50:"Protocol not available.",51:"No space left on device.",52:"Function not supported.",53:"The socket is not connected.",54:"Not a directory or a symbolic link to a directory.",55:"Directory not empty.",56:"State not recoverable.",57:"Not a socket.",58:"Not supported, or operation not supported on socket.",59:"Inappropriate I/O control operation.",60:"No such device or address.",61:"Value too large to be stored in data type.",62:"Previous owner died.",63:"Operation not permitted.",64:"Broken pipe.",65:"Protocol error.",66:"Protocol not supported.",67:"Protocol wrong type for socket.",68:"Result too large.",69:"Read-only file system.",70:"Invalid seek.",71:"No such process.",72:"Reserved.",73:"Connection timed out.",74:"Text file busy.",75:"Cross-device link.",76:"Extension: Capabilities insufficient."};function m(t=""){return function(r,s,n){const i=n.value;n.value=function(...o){try{return i.apply(this,o)}catch(a){const l=typeof a=="object"?a?.errno:null;if(l in ue){const c=ue[l],u=typeof o[0]=="string"?o[0]:null,d=u!==null?t.replaceAll("{path}",u):t;throw new Error(`${d}: ${c}`,{cause:a})}throw a}}}}const Tt=[];function Ft(t){return Tt[t]}(function(){return typeof process<"u"&&process.release?.name==="node"?"NODE":typeof window<"u"?"WEB":typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope?"WORKER":"NODE"})();var Ct=Object.defineProperty,kt=Object.getOwnPropertyDescriptor,w=(t,e,r,s)=>{for(var n=s>1?void 0:s?kt(e,r):e,i=t.length-1,o;i>=0;i--)(o=t[i])&&(n=(s?o(e,r,n):o(n))||n);return s&&n&&Ct(e,r,n),n};const f="string",E="number",h=Symbol("__private__dont__use");class g{constructor(e,r){this.#e=[],this.#t=!1,this.#s=null,this.#r={},e!==void 0&&this.initializeRuntime(e),r&&(this.requestHandler=new $t(new St(this,r)))}#e;#t;#s;#r;get absoluteUrl(){return this.requestHandler.requestHandler.absoluteUrl}get documentRoot(){return this.requestHandler.requestHandler.documentRoot}pathToInternalUrl(e){return this.requestHandler.requestHandler.pathToInternalUrl(e)}internalUrlToPath(e){return this.requestHandler.requestHandler.internalUrlToPath(e)}initializeRuntime(e){if(this[h])throw new Error("PHP runtime already initialized.");const r=Ft(e);if(!r)throw new Error("Invalid PHP runtime id.");this[h]=r,this.#s=ft(r)}setPhpIniPath(e){if(this.#t)throw new Error("Cannot set PHP ini path after calling run().");this[h].ccall("wasm_set_phpini_path",null,["string"],[e])}setPhpIniEntry(e,r){if(this.#t)throw new Error("Cannot set PHP ini entries after calling run().");this.#e.push([e,r])}chdir(e){this[h].FS.chdir(e)}async request(e,r){if(!this.requestHandler)throw new Error("No request handler available.");return this.requestHandler.request(e,r)}async run(e){this.#t||(this.#i(),this.#t=!0),this.#h(e.scriptPath||""),this.#o(e.relativeUri||""),this.#c(e.method||"GET");const{host:r,...s}={host:"example.com:443",...De(e.headers||{})};if(this.#a(r,e.protocol||"http"),this.#l(s),e.body&&this.#u(e.body),e.fileInfos)for(const n of e.fileInfos)this.#p(n);return e.code&&this.#f(" ?>"+e.code),this.#d(),await this.#m()}#i(){if(this.#e.length>0){const e=this.#e.map(([r,s])=>`${r}=${s}`).join(`
145
151
  `)+`
146
152
 
147
- `;this[h].ccall("wasm_set_phpini_entries",null,[f],[e])}this[h].ccall("php_wasm_init",null,[],[])}#n(){const e="/tmp/headers.json";if(!this.fileExists(e))throw new Error("SAPI Error: Could not find response headers file.");const r=JSON.parse(this.readFileAsText(e)),s={};for(const n of r.headers){if(!n.includes(": "))continue;const i=n.indexOf(": "),o=n.substring(0,i).toLowerCase(),a=n.substring(i+2);o in s||(s[o]=[]),s[o].push(a)}return{headers:s,httpStatusCode:r.status}}#o(e){if(this[h].ccall("wasm_set_request_uri",null,[f],[e]),e.includes("?")){const r=e.substring(e.indexOf("?")+1);this[h].ccall("wasm_set_query_string",null,[f],[r])}}#a(e,r){this[h].ccall("wasm_set_request_host",null,[f],[e]);let s;try{s=parseInt(new URL(e).port,10)}catch{}(!s||isNaN(s)||s===80)&&(s=r==="https"?443:80),this[h].ccall("wasm_set_request_port",null,[S],[s]),(r==="https"||!r&&s===443)&&this.addServerGlobalEntry("HTTPS","on")}#c(e){this[h].ccall("wasm_set_request_method",null,[f],[e])}#l(e){e.cookie&&this[h].ccall("wasm_set_cookies",null,[f],[e.cookie]),e["content-type"]&&this[h].ccall("wasm_set_content_type",null,[f],[e["content-type"]]),e["content-length"]&&this[h].ccall("wasm_set_content_length",null,[S],[parseInt(e["content-length"],10)]);for(const r in e)this.addServerGlobalEntry(`HTTP_${r.toUpperCase().replace(/-/g,"_")}`,e[r])}#u(e){this[h].ccall("wasm_set_request_body",null,[f],[e]),this[h].ccall("wasm_set_content_length",null,[S],[new TextEncoder().encode(e).length])}#h(e){this[h].ccall("wasm_set_path_translated",null,[f],[e])}addServerGlobalEntry(e,r){this.#r[e]=r}#d(){for(const e in this.#r)this[h].ccall("wasm_add_SERVER_entry",null,[f,f],[e,this.#r[e]])}#p(e){const{key:r,name:s,type:n,data:i}=e,o=`/tmp/${Math.random().toFixed(20)}`;this.writeFile(o,i);const a=0;this[h].ccall("wasm_add_uploaded_file",null,[f,f,f,f,S,S],[r,s,n,o,a,i.byteLength])}#f(e){this[h].ccall("wasm_set_php_code",null,[f],[e])}async#m(){let e,r;try{e=await new Promise((i,o)=>{r=l=>{const c=new Error("Rethrown");c.cause=l.error,c.betterMessage=l.message,o(c)},this.#s?.addEventListener("error",r);const a=this[h].ccall("wasm_sapi_handle_request",S,[],[]);return a instanceof Promise?a.then(i,o):i(a)})}catch(i){for(const c in this)typeof this[c]=="function"&&(this[c]=()=>{throw new Error("PHP runtime has crashed – see the earlier error for details.")});this.functionsMaybeMissingFromAsyncify=gt();const o=i,a="betterMessage"in o?o.betterMessage:o.message,l=new Error(a);throw l.cause=o,l}finally{this.#s?.removeEventListener("error",r),this.#r={}}const{headers:s,httpStatusCode:n}=this.#n();return new _(n,s,this.readFileAsBuffer("/tmp/stdout"),this.readFileAsText("/tmp/stderr"),e)}mkdir(e){this[h].FS.mkdirTree(e)}mkdirTree(e){this.mkdir(e)}readFileAsText(e){return new TextDecoder().decode(this.readFileAsBuffer(e))}readFileAsBuffer(e){return this[h].FS.readFile(e)}writeFile(e,r){this[h].FS.writeFile(e,r)}unlink(e){this[h].FS.unlink(e)}mv(e,r){this[h].FS.mv(e,r)}rmdir(e,r={recursive:!0}){r?.recursive&&this.listFiles(e).forEach(s=>{const n=`${e}/${s}`;this.isDir(n)?this.rmdir(n,r):this.unlink(n)}),this[h].FS.rmdir(e)}listFiles(e){if(!this.fileExists(e))return[];try{return this[h].FS.readdir(e).filter(r=>r!=="."&&r!=="..")}catch(r){return console.error(r,{path:e}),[]}}isDir(e){return this.fileExists(e)?this[h].FS.isDir(this[h].FS.lookupPath(e).node.mode):!1}fileExists(e){try{return this[h].FS.lookupPath(e),!0}catch{return!1}}}g([m('Could not create directory "{path}"')],w.prototype,"mkdir",1);g([m('Could not create directory "{path}"')],w.prototype,"mkdirTree",1);g([m('Could not read "{path}"')],w.prototype,"readFileAsText",1);g([m('Could not read "{path}"')],w.prototype,"readFileAsBuffer",1);g([m('Could not write to "{path}"')],w.prototype,"writeFile",1);g([m('Could not unlink "{path}"')],w.prototype,"unlink",1);g([m('Could not move "{path}"')],w.prototype,"mv",1);g([m('Could not remove directory "{path}"')],w.prototype,"rmdir",1);g([m('Could not list files in "{path}"')],w.prototype,"listFiles",1);g([m('Could not stat "{path}"')],w.prototype,"isDir",1);g([m('Could not stat "{path}"')],w.prototype,"fileExists",1);function qe(t){const e={};for(const r in t)e[r.toLowerCase()]=t[r];return e}const Lt=["vfs","literal","wordpress.org/themes","wordpress.org/plugins","url"];function At(t){return t&&typeof t=="object"&&typeof t.resource=="string"&&Lt.includes(t.resource)}class E{static create(e,{semaphore:r,progress:s}){let n;switch(e.resource){case"vfs":n=new Ut(e,s);break;case"literal":n=new Ht(e,s);break;case"wordpress.org/themes":n=new Mt(e,s);break;case"wordpress.org/plugins":n=new zt(e,s);break;case"url":n=new Wt(e,s);break;default:throw new Error(`Invalid resource: ${e}`)}return n=new Dt(n),r&&(n=new qt(n,r)),n}setPlayground(e){this.playground=e}get isAsync(){return!1}}class Ut extends E{constructor(e,r){super(),this.resource=e,this.progress=r}async resolve(){const e=await this.playground.readFileAsBuffer(this.resource.path);return this.progress?.set(100),new File([e],this.name)}get name(){return this.resource.path}}class Ht extends E{constructor(e,r){super(),this.resource=e,this.progress=r}async resolve(){return this.progress?.set(100),new File([this.resource.contents],this.resource.name)}get name(){return this.resource.name}}class B extends E{constructor(e){super(),this.progress=e}async resolve(){this.progress?.setCaption(this.caption);const e=this.getURL();let r=await fetch(e);if(r=await dt(r,this.progress?.loadingListener??It),r.status!==200)throw new Error(`Could not download "${e}"`);return new File([await r.blob()],this.name)}get caption(){return`Downloading ${this.name}`}get name(){try{return new URL(this.getURL(),"http://example.com").pathname.split("/").pop()}catch{return this.getURL()}}get isAsync(){return!0}}const It=()=>{};class Wt extends B{constructor(e,r){super(r),this.resource=e}getURL(){return this.resource.url}get caption(){return this.resource.caption??super.caption}}let V="https://playground.wordpress.net/plugin-proxy";function Nt(t){V=t}class Mt extends B{constructor(e,r){super(r),this.resource=e}get name(){return A(this.resource.slug)}getURL(){const e=je(this.resource.slug);return`${V}?theme=`+e}}class zt extends B{constructor(e,r){super(r),this.resource=e}get name(){return A(this.resource.slug)}getURL(){const e=je(this.resource.slug);return`${V}?plugin=`+e}}function je(t){return!t||t.endsWith(".zip")?t:t+".latest-stable.zip"}class Be extends E{constructor(e){super(),this.resource=e}async resolve(){return this.resource.resolve()}async setPlayground(e){return this.resource.setPlayground(e)}get progress(){return this.resource.progress}set progress(e){this.resource.progress=e}get name(){return this.resource.name}get isAsync(){return this.resource.isAsync}}class Dt extends Be{async resolve(){return this.promise||(this.promise=super.resolve()),this.promise}}class qt extends Be{constructor(e,r){super(e),this.semaphore=r}async resolve(){return this.isAsync?this.semaphore.run(()=>super.resolve()):super.resolve()}}const jt=["6.2","6.1","6.0","5.9"];function Ve(t,{progress:e=new H,semaphore:r=new Ce({concurrency:3}),onStepCompleted:s=()=>{}}={}){const n=(t.steps||[]).filter(Bt),i=n.reduce((a,l)=>a+(l.progress?.weight||1),0),o=n.map(a=>Vt(a,{semaphore:r,rootProgressTracker:e,totalProgressWeight:i}));return{versions:{php:le(t.preferredVersions?.php,I,De),wp:le(t.preferredVersions?.wp,jt,"6.2")},run:async a=>{try{for(const{resources:l}of o)for(const c of l)c.setPlayground(a),c.isAsync&&c.resolve();for(const{run:l,step:c}of o){const u=await l(a);s(u,c)}try{await a.goTo(t.landingPage||"/")}catch{}}finally{e.finish()}}}}function le(t,e,r){return t&&e.includes(t)?t:r}function Bt(t){return!!(typeof t=="object"&&t)}function Vt(t,{semaphore:e,rootProgressTracker:r,totalProgressWeight:s}){const n=r.stage((t.progress?.weight||1)/s),i={};for(const u of Object.keys(t)){let d=t[u];At(d)&&(d=E.create(d,{semaphore:e})),i[u]=d}const o=async u=>{try{return n.fillSlowly(),await ut[t.step](u,await Gt(i),{tracker:n,initialCaption:t.progress?.caption})}finally{n.finish()}},a=ue(i),l=ue(i).filter(u=>u.isAsync),c=1/(l.length+1);for(const u of l)u.progress=n.stage(c);return{run:o,step:t,resources:a}}function ue(t){const e=[];for(const r in t){const s=t[r];s instanceof E&&e.push(s)}return e}async function Gt(t){const e={};for(const r in t){const s=t[r];s instanceof E?e[r]=await s.resolve():e[r]=s}return e}async function Ge(t,e){await t.run(e)}/**
153
+ `;this[h].ccall("wasm_set_phpini_entries",null,[f],[e])}this[h].ccall("php_wasm_init",null,[],[])}#n(){const e="/tmp/headers.json";if(!this.fileExists(e))throw new Error("SAPI Error: Could not find response headers file.");const r=JSON.parse(this.readFileAsText(e)),s={};for(const n of r.headers){if(!n.includes(": "))continue;const i=n.indexOf(": "),o=n.substring(0,i).toLowerCase(),a=n.substring(i+2);o in s||(s[o]=[]),s[o].push(a)}return{headers:s,httpStatusCode:r.status}}#o(e){if(this[h].ccall("wasm_set_request_uri",null,[f],[e]),e.includes("?")){const r=e.substring(e.indexOf("?")+1);this[h].ccall("wasm_set_query_string",null,[f],[r])}}#a(e,r){this[h].ccall("wasm_set_request_host",null,[f],[e]);let s;try{s=parseInt(new URL(e).port,10)}catch{}(!s||isNaN(s)||s===80)&&(s=r==="https"?443:80),this[h].ccall("wasm_set_request_port",null,[E],[s]),(r==="https"||!r&&s===443)&&this.addServerGlobalEntry("HTTPS","on")}#c(e){this[h].ccall("wasm_set_request_method",null,[f],[e])}#l(e){e.cookie&&this[h].ccall("wasm_set_cookies",null,[f],[e.cookie]),e["content-type"]&&this[h].ccall("wasm_set_content_type",null,[f],[e["content-type"]]),e["content-length"]&&this[h].ccall("wasm_set_content_length",null,[E],[parseInt(e["content-length"],10)]);for(const r in e){let s="HTTP_";["content-type","content-length"].includes(r.toLowerCase())&&(s=""),this.addServerGlobalEntry(`${s}${r.toUpperCase().replace(/-/g,"_")}`,e[r])}}#u(e){this[h].ccall("wasm_set_request_body",null,[f],[e]),this[h].ccall("wasm_set_content_length",null,[E],[new TextEncoder().encode(e).length])}#h(e){this[h].ccall("wasm_set_path_translated",null,[f],[e])}addServerGlobalEntry(e,r){this.#r[e]=r}#d(){for(const e in this.#r)this[h].ccall("wasm_add_SERVER_entry",null,[f,f],[e,this.#r[e]])}#p(e){const{key:r,name:s,type:n,data:i}=e,o=`/tmp/${Math.random().toFixed(20)}`;this.writeFile(o,i);const a=0;this[h].ccall("wasm_add_uploaded_file",null,[f,f,f,f,E,E],[r,s,n,o,a,i.byteLength])}#f(e){this[h].ccall("wasm_set_php_code",null,[f],[e])}async#m(){let e,r;try{e=await new Promise((i,o)=>{r=l=>{const c=new Error("Rethrown");c.cause=l.error,c.betterMessage=l.message,o(c)},this.#s?.addEventListener("error",r);const a=this[h].ccall("wasm_sapi_handle_request",E,[],[]);return a instanceof Promise?a.then(i,o):i(a)})}catch(i){for(const c in this)typeof this[c]=="function"&&(this[c]=()=>{throw new Error("PHP runtime has crashed – see the earlier error for details.")});this.functionsMaybeMissingFromAsyncify=mt();const o=i,a="betterMessage"in o?o.betterMessage:o.message,l=new Error(a);throw l.cause=o,l}finally{this.#s?.removeEventListener("error",r),this.#r={}}const{headers:s,httpStatusCode:n}=this.#n();return new b(n,s,this.readFileAsBuffer("/tmp/stdout"),this.readFileAsText("/tmp/stderr"),e)}mkdir(e){this[h].FS.mkdirTree(e)}mkdirTree(e){this.mkdir(e)}readFileAsText(e){return new TextDecoder().decode(this.readFileAsBuffer(e))}readFileAsBuffer(e){return this[h].FS.readFile(e)}writeFile(e,r){this[h].FS.writeFile(e,r)}unlink(e){this[h].FS.unlink(e)}mv(e,r){this[h].FS.rename(e,r)}rmdir(e,r={recursive:!0}){r?.recursive&&this.listFiles(e).forEach(s=>{const n=`${e}/${s}`;this.isDir(n)?this.rmdir(n,r):this.unlink(n)}),this[h].FS.rmdir(e)}listFiles(e,r={prependPath:!1}){if(!this.fileExists(e))return[];try{const s=this[h].FS.readdir(e).filter(n=>n!=="."&&n!=="..");if(r.prependPath){const n=e.replace(/\/$/,"");return s.map(i=>`${n}/${i}`)}return s}catch(s){return console.error(s,{path:e}),[]}}isDir(e){return this.fileExists(e)?this[h].FS.isDir(this[h].FS.lookupPath(e).node.mode):!1}fileExists(e){try{return this[h].FS.lookupPath(e),!0}catch{return!1}}}w([m('Could not create directory "{path}"')],g.prototype,"mkdir",1);w([m('Could not create directory "{path}"')],g.prototype,"mkdirTree",1);w([m('Could not read "{path}"')],g.prototype,"readFileAsText",1);w([m('Could not read "{path}"')],g.prototype,"readFileAsBuffer",1);w([m('Could not write to "{path}"')],g.prototype,"writeFile",1);w([m('Could not unlink "{path}"')],g.prototype,"unlink",1);w([m('Could not move "{path}"')],g.prototype,"mv",1);w([m('Could not remove directory "{path}"')],g.prototype,"rmdir",1);w([m('Could not list files in "{path}"')],g.prototype,"listFiles",1);w([m('Could not stat "{path}"')],g.prototype,"isDir",1);w([m('Could not stat "{path}"')],g.prototype,"fileExists",1);function De(t){const e={};for(const r in t)e[r.toLowerCase()]=t[r];return e}const At=["vfs","literal","wordpress.org/themes","wordpress.org/plugins","url"];function Lt(t){return t&&typeof t=="object"&&typeof t.resource=="string"&&At.includes(t.resource)}class ${static create(e,{semaphore:r,progress:s}){let n;switch(e.resource){case"vfs":n=new Ot(e,s);break;case"literal":n=new Ut(e,s);break;case"wordpress.org/themes":n=new It(e,s);break;case"wordpress.org/plugins":n=new zt(e,s);break;case"url":n=new Nt(e,s);break;default:throw new Error(`Invalid resource: ${e}`)}return n=new Mt(n),r&&(n=new Dt(n,r)),n}setPlayground(e){this.playground=e}get isAsync(){return!1}}class Ot extends ${constructor(e,r){super(),this.resource=e,this.progress=r}async resolve(){const e=await this.playground.readFileAsBuffer(this.resource.path);return this.progress?.set(100),new j([e],this.name)}get name(){return this.resource.path.split("/").pop()||""}}class Ut extends ${constructor(e,r){super(),this.resource=e,this.progress=r}async resolve(){return this.progress?.set(100),new j([this.resource.contents],this.resource.name)}get name(){return this.resource.name}}class Y extends ${constructor(e){super(),this.progress=e}async resolve(){this.progress?.setCaption(this.caption);const e=this.getURL();let r=await fetch(e);if(r=await ht(r,this.progress?.loadingListener??Ht),r.status!==200)throw new Error(`Could not download "${e}"`);return new j([await r.blob()],this.name)}get caption(){return`Downloading ${this.name}`}get name(){try{return new URL(this.getURL(),"http://example.com").pathname.split("/").pop()}catch{return this.getURL()}}get isAsync(){return!0}}const Ht=()=>{};class Nt extends Y{constructor(e,r){super(r),this.resource=e}getURL(){return this.resource.url}get caption(){return this.resource.caption??super.caption}}let J="https://playground.wordpress.net/plugin-proxy";function Wt(t){J=t}class It extends Y{constructor(e,r){super(r),this.resource=e}get name(){return L(this.resource.slug)}getURL(){const e=qe(this.resource.slug);return`${J}?theme=`+e}}class zt extends Y{constructor(e,r){super(r),this.resource=e}get name(){return L(this.resource.slug)}getURL(){const e=qe(this.resource.slug);return`${J}?plugin=`+e}}function qe(t){return!t||t.endsWith(".zip")?t:t+".latest-stable.zip"}class je extends ${constructor(e){super(),this.resource=e}async resolve(){return this.resource.resolve()}async setPlayground(e){return this.resource.setPlayground(e)}get progress(){return this.resource.progress}set progress(e){this.resource.progress=e}get name(){return this.resource.name}get isAsync(){return this.resource.isAsync}}class Mt extends je{async resolve(){return this.promise||(this.promise=super.resolve()),this.promise}}class Dt extends je{constructor(e,r){super(e),this.semaphore=r}async resolve(){return this.isAsync?this.semaphore.run(()=>super.resolve()):super.resolve()}}const qt=["6.2","6.1","6.0","5.9"];function Be(t,{progress:e=new H,semaphore:r=new Te({concurrency:3}),onStepCompleted:s=()=>{}}={}){const n=(t.steps||[]).filter(jt),i=n.reduce((a,l)=>a+(l.progress?.weight||1),0),o=n.map(a=>Bt(a,{semaphore:r,rootProgressTracker:e,totalProgressWeight:i}));return{versions:{php:he(t.preferredVersions?.php,N,Me),wp:he(t.preferredVersions?.wp,qt,"6.2")},run:async a=>{try{for(const{resources:l}of o)for(const c of l)c.setPlayground(a),c.isAsync&&c.resolve();for(const{run:l,step:c}of o){const u=await l(a);s(u,c)}try{await a.goTo(t.landingPage||"/")}catch{}}finally{e.finish()}}}}function he(t,e,r){return t&&e.includes(t)?t:r}function jt(t){return!!(typeof t=="object"&&t)}function Bt(t,{semaphore:e,rootProgressTracker:r,totalProgressWeight:s}){const n=r.stage((t.progress?.weight||1)/s),i={};for(const u of Object.keys(t)){let d=t[u];Lt(d)&&(d=$.create(d,{semaphore:e})),i[u]=d}const o=async u=>{try{return n.fillSlowly(),await lt[t.step](u,await Vt(i),{tracker:n,initialCaption:t.progress?.caption})}finally{n.finish()}},a=de(i),l=de(i).filter(u=>u.isAsync),c=1/(l.length+1);for(const u of l)u.progress=n.stage(c);return{run:o,step:t,resources:a}}function de(t){const e=[];for(const r in t){const s=t[r];s instanceof $&&e.push(s)}return e}async function Vt(t){const e={};for(const r in t){const s=t[r];s instanceof $?e[r]=await s.resolve():e[r]=s}return e}async function Ve(t,e){await t.run(e)}/**
148
154
  * @license
149
155
  * Copyright 2019 Google LLC
150
156
  * SPDX-License-Identifier: Apache-2.0
151
- */const Je=Symbol("Comlink.proxy"),Jt=Symbol("Comlink.endpoint"),Yt=Symbol("Comlink.releaseProxy"),N=Symbol("Comlink.finalizer"),T=Symbol("Comlink.thrown"),Ye=t=>typeof t=="object"&&t!==null||typeof t=="function",Kt={canHandle:t=>Ye(t)&&t[Je],serialize(t){const{port1:e,port2:r}=new MessageChannel;return G(t,e),[r,[r]]},deserialize(t){return t.start(),J(t)}},Qt={canHandle:t=>Ye(t)&&T in t,serialize({value:t}){let e;return t instanceof Error?e={isError:!0,value:{message:t.message,name:t.name,stack:t.stack}}:e={isError:!1,value:t},[e,[]]},deserialize(t){throw t.isError?Object.assign(new Error(t.value.message),t.value):t.value}},R=new Map([["proxy",Kt],["throw",Qt]]);function Xt(t,e){for(const r of t)if(e===r||r==="*"||r instanceof RegExp&&r.test(e))return!0;return!1}function G(t,e=globalThis,r=["*"]){e.addEventListener("message",function s(n){if(!n||!n.data)return;if(!Xt(r,n.origin)){console.warn(`Invalid origin '${n.origin}' for comlink proxy`);return}const{id:i,type:o,path:a}=Object.assign({path:[]},n.data),l=(n.data.argumentList||[]).map(b);let c;try{const u=a.slice(0,-1).reduce((p,y)=>p[y],t),d=a.reduce((p,y)=>p[y],t);switch(o){case"GET":c=d;break;case"SET":u[a.slice(-1)[0]]=b(n.data.value),c=!0;break;case"APPLY":c=d.apply(u,l);break;case"CONSTRUCT":{const p=new d(...l);c=Ze(p)}break;case"ENDPOINT":{const{port1:p,port2:y}=new MessageChannel;G(t,y),c=sr(p,[p])}break;case"RELEASE":c=void 0;break;default:return}}catch(u){c={value:u,[T]:0}}Promise.resolve(c).catch(u=>({value:u,[T]:0})).then(u=>{const[d,p]=L(u);e.postMessage(Object.assign(Object.assign({},d),{id:i}),p),o==="RELEASE"&&(e.removeEventListener("message",s),Ke(e),N in t&&typeof t[N]=="function"&&t[N]())}).catch(u=>{const[d,p]=L({value:new TypeError("Unserializable return value"),[T]:0});e.postMessage(Object.assign(Object.assign({},d),{id:i}),p)})}),e.start&&e.start()}function Zt(t){return t.constructor.name==="MessagePort"}function Ke(t){Zt(t)&&t.close()}function J(t,e){return z(t,[],e)}function x(t){if(t)throw new Error("Proxy has been released and is not useable")}function Qe(t){return v(t,{type:"RELEASE"}).then(()=>{Ke(t)})}const k=new WeakMap,O="FinalizationRegistry"in globalThis&&new FinalizationRegistry(t=>{const e=(k.get(t)||0)-1;k.set(t,e),e===0&&Qe(t)});function er(t,e){const r=(k.get(e)||0)+1;k.set(e,r),O&&O.register(t,e,t)}function tr(t){O&&O.unregister(t)}function z(t,e=[],r=function(){}){let s=!1;const n=new Proxy(r,{get(i,o){if(x(s),o===Yt)return()=>{tr(n),Qe(t),s=!0};if(o==="then"){if(e.length===0)return{then:()=>n};const a=v(t,{type:"GET",path:e.map(l=>l.toString())}).then(b);return a.then.bind(a)}return z(t,[...e,o])},set(i,o,a){x(s);const[l,c]=L(a);return v(t,{type:"SET",path:[...e,o].map(u=>u.toString()),value:l},c).then(b)},apply(i,o,a){x(s);const l=e[e.length-1];if(l===Jt)return v(t,{type:"ENDPOINT"}).then(b);if(l==="bind")return z(t,e.slice(0,-1));const[c,u]=he(a);return v(t,{type:"APPLY",path:e.map(d=>d.toString()),argumentList:c},u).then(b)},construct(i,o){x(s);const[a,l]=he(o);return v(t,{type:"CONSTRUCT",path:e.map(c=>c.toString()),argumentList:a},l).then(b)}});return er(n,t),n}function rr(t){return Array.prototype.concat.apply([],t)}function he(t){const e=t.map(L);return[e.map(r=>r[0]),rr(e.map(r=>r[1]))]}const Xe=new WeakMap;function sr(t,e){return Xe.set(t,e),t}function Ze(t){return Object.assign(t,{[Je]:!0})}function nr(t,e=globalThis,r="*"){return{postMessage:(s,n)=>t.postMessage(s,r,n),addEventListener:e.addEventListener.bind(e),removeEventListener:e.removeEventListener.bind(e)}}function L(t){for(const[e,r]of R)if(r.canHandle(t)){const[s,n]=r.serialize(t);return[{type:"HANDLER",name:e,value:s},n]}return[{type:"RAW",value:t},Xe.get(t)||[]]}function b(t){switch(t.type){case"HANDLER":return R.get(t.name).deserialize(t.value);case"RAW":return t.value}}function v(t,e,r){return new Promise(s=>{const n=ir();t.addEventListener("message",function i(o){!o.data||!o.data.id||o.data.id!==n||(t.removeEventListener("message",i),s(o.data))}),t.start&&t.start(),t.postMessage(Object.assign({id:n},e),r)})}function ir(){return new Array(4).fill(0).map(()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16)).join("-")}function et(t){or();const e=t instanceof Worker?t:nr(t),r=J(e),s=tt(r);return new Proxy(s,{get:(n,i)=>i==="isConnected"?()=>r.isConnected():r[i]})}let de=!1;function or(){de||(de=!0,R.set("EVENT",{canHandle:t=>t instanceof CustomEvent,serialize:t=>[{detail:t.detail},[]],deserialize:t=>t}),R.set("FUNCTION",{canHandle:t=>typeof t=="function",serialize(t){console.debug("[Comlink][Performance] Proxying a function");const{port1:e,port2:r}=new MessageChannel;return G(t,e),[r,[r]]},deserialize(t){return t.start(),J(t)}}),R.set("PHPResponse",{canHandle:t=>typeof t=="object"&&t!==null&&"headers"in t&&"bytes"in t&&"errors"in t&&"exitCode"in t&&"httpStatusCode"in t,serialize(t){return[t.toRawData(),[]]},deserialize(t){return _.fromRawData(t)}}))}function tt(t){return new Proxy(t,{get(e,r){switch(typeof e[r]){case"function":return(...s)=>e[r](...s);case"object":return e[r]===null?e[r]:tt(e[r]);case"undefined":case"number":case"string":return e[r];default:return Ze(e[r])}}})}(function(){return typeof navigator<"u"&&navigator?.userAgent?.toLowerCase().indexOf("firefox")>-1?"iframe":"webworker"})();async function rt({iframe:t,blueprint:e,remoteUrl:r,progressTracker:s=new H,disableProgressBar:n,onBlueprintStepCompleted:i}){if(ar(r),r=fe(r,{progressbar:!n}),s.setCaption("Preparing WordPress"),!e)return pe(t,r,s);const o=Ve(e,{progress:s.stage(.5),onStepCompleted:i}),a=await pe(t,fe(r,{php:o.versions.php,wp:o.versions.wp}),s);return await Ge(o,a),s.finish(),a}async function pe(t,e,r){await new Promise(i=>{t.src=e,t.addEventListener("load",i,!1)});const s=et(t.contentWindow);await s.isConnected(),r.pipe(s);const n=r.stage();return await s.onDownloadProgress(n.loadingListener),await s.isReady(),n.finish(),s}const C="https://playground.wordpress.net";function ar(t){const e=new URL(t,C);if((e.origin===C||e.hostname==="localhost")&&e.pathname!=="/remote.html")throw new Error(`Invalid remote URL: ${e}. Expected origin to be ${C}/remote.html.`)}function fe(t,e){const r=new URL(t,C),s=new URLSearchParams(r.search);for(const[n,i]of Object.entries(e))i!=null&&i!==!1&&s.set(n,i.toString());return r.search=s.toString(),r.toString()}async function cr(t,e){if(console.warn("`connectPlayground` is deprecated and will be removed. Use `startPlayground` instead."),e?.loadRemote)return rt({iframe:t,remoteUrl:e.loadRemote});const r=et(t.contentWindow);return await r.isConnected(),r}exports.LatestSupportedPHPVersion=De;exports.SupportedPHPVersions=I;exports.SupportedPHPVersionsList=$t;exports.activatePlugin=me;exports.activateTheme=ge;exports.applyWordPressPatches=we;exports.compileBlueprint=Ve;exports.connectPlayground=cr;exports.cp=$e;exports.defineSiteUrl=Te;exports.defineVirtualWpConfigConsts=ze;exports.defineWpConfigConsts=D;exports.importFile=Oe;exports.installPlugin=Ae;exports.installTheme=Ue;exports.login=He;exports.mkdir=Se;exports.mv=Ee;exports.phpVar=$;exports.phpVars=U;exports.replaceSite=ke;exports.request=_e;exports.rm=ve;exports.rmdir=Re;exports.runBlueprintSteps=Ge;exports.runPHP=ye;exports.runPHPWithOptions=Pe;exports.runWpInstallationWizard=Ie;exports.setPhpIniEntry=be;exports.setPluginProxyURL=Nt;exports.setSiteOptions=We;exports.startPlaygroundWeb=rt;exports.unzip=q;exports.updateUserMeta=Ne;exports.writeFile=xe;exports.zipEntireSite=Fe;
157
+ */const Ge=Symbol("Comlink.proxy"),Gt=Symbol("Comlink.endpoint"),Yt=Symbol("Comlink.releaseProxy"),I=Symbol("Comlink.finalizer"),T=Symbol("Comlink.thrown"),Ye=t=>typeof t=="object"&&t!==null||typeof t=="function",Jt={canHandle:t=>Ye(t)&&t[Ge],serialize(t){const{port1:e,port2:r}=new MessageChannel;return K(t,e),[r,[r]]},deserialize(t){return t.start(),Z(t)}},Kt={canHandle:t=>Ye(t)&&T in t,serialize({value:t}){let e;return t instanceof Error?e={isError:!0,value:{message:t.message,name:t.name,stack:t.stack}}:e={isError:!1,value:t},[e,[]]},deserialize(t){throw t.isError?Object.assign(new Error(t.value.message),t.value):t.value}},R=new Map([["proxy",Jt],["throw",Kt]]);function Zt(t,e){for(const r of t)if(e===r||r==="*"||r instanceof RegExp&&r.test(e))return!0;return!1}function K(t,e=globalThis,r=["*"]){e.addEventListener("message",function s(n){if(!n||!n.data)return;if(!Zt(r,n.origin)){console.warn(`Invalid origin '${n.origin}' for comlink proxy`);return}const{id:i,type:o,path:a}=Object.assign({path:[]},n.data),l=(n.data.argumentList||[]).map(P);let c;try{const u=a.slice(0,-1).reduce((p,y)=>p[y],t),d=a.reduce((p,y)=>p[y],t);switch(o){case"GET":c=d;break;case"SET":u[a.slice(-1)[0]]=P(n.data.value),c=!0;break;case"APPLY":c=d.apply(u,l);break;case"CONSTRUCT":{const p=new d(...l);c=Qe(p)}break;case"ENDPOINT":{const{port1:p,port2:y}=new MessageChannel;K(t,y),c=rr(p,[p])}break;case"RELEASE":c=void 0;break;default:return}}catch(u){c={value:u,[T]:0}}Promise.resolve(c).catch(u=>({value:u,[T]:0})).then(u=>{const[d,p]=A(u);e.postMessage(Object.assign(Object.assign({},d),{id:i}),p),o==="RELEASE"&&(e.removeEventListener("message",s),Je(e),I in t&&typeof t[I]=="function"&&t[I]())}).catch(u=>{const[d,p]=A({value:new TypeError("Unserializable return value"),[T]:0});e.postMessage(Object.assign(Object.assign({},d),{id:i}),p)})}),e.start&&e.start()}function Qt(t){return t.constructor.name==="MessagePort"}function Je(t){Qt(t)&&t.close()}function Z(t,e){return M(t,[],e)}function x(t){if(t)throw new Error("Proxy has been released and is not useable")}function Ke(t){return v(t,{type:"RELEASE"}).then(()=>{Je(t)})}const C=new WeakMap,k="FinalizationRegistry"in globalThis&&new FinalizationRegistry(t=>{const e=(C.get(t)||0)-1;C.set(t,e),e===0&&Ke(t)});function Xt(t,e){const r=(C.get(e)||0)+1;C.set(e,r),k&&k.register(t,e,t)}function er(t){k&&k.unregister(t)}function M(t,e=[],r=function(){}){let s=!1;const n=new Proxy(r,{get(i,o){if(x(s),o===Yt)return()=>{er(n),Ke(t),s=!0};if(o==="then"){if(e.length===0)return{then:()=>n};const a=v(t,{type:"GET",path:e.map(l=>l.toString())}).then(P);return a.then.bind(a)}return M(t,[...e,o])},set(i,o,a){x(s);const[l,c]=A(a);return v(t,{type:"SET",path:[...e,o].map(u=>u.toString()),value:l},c).then(P)},apply(i,o,a){x(s);const l=e[e.length-1];if(l===Gt)return v(t,{type:"ENDPOINT"}).then(P);if(l==="bind")return M(t,e.slice(0,-1));const[c,u]=pe(a);return v(t,{type:"APPLY",path:e.map(d=>d.toString()),argumentList:c},u).then(P)},construct(i,o){x(s);const[a,l]=pe(o);return v(t,{type:"CONSTRUCT",path:e.map(c=>c.toString()),argumentList:a},l).then(P)}});return Xt(n,t),n}function tr(t){return Array.prototype.concat.apply([],t)}function pe(t){const e=t.map(A);return[e.map(r=>r[0]),tr(e.map(r=>r[1]))]}const Ze=new WeakMap;function rr(t,e){return Ze.set(t,e),t}function Qe(t){return Object.assign(t,{[Ge]:!0})}function sr(t,e=globalThis,r="*"){return{postMessage:(s,n)=>t.postMessage(s,r,n),addEventListener:e.addEventListener.bind(e),removeEventListener:e.removeEventListener.bind(e)}}function A(t){for(const[e,r]of R)if(r.canHandle(t)){const[s,n]=r.serialize(t);return[{type:"HANDLER",name:e,value:s},n]}return[{type:"RAW",value:t},Ze.get(t)||[]]}function P(t){switch(t.type){case"HANDLER":return R.get(t.name).deserialize(t.value);case"RAW":return t.value}}function v(t,e,r){return new Promise(s=>{const n=nr();t.addEventListener("message",function i(o){!o.data||!o.data.id||o.data.id!==n||(t.removeEventListener("message",i),s(o.data))}),t.start&&t.start(),t.postMessage(Object.assign({id:n},e),r)})}function nr(){return new Array(4).fill(0).map(()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16)).join("-")}function Xe(t){ir();const e=t instanceof Worker?t:sr(t),r=Z(e),s=et(r);return new Proxy(s,{get:(n,i)=>i==="isConnected"?()=>r.isConnected():r[i]})}let fe=!1;function ir(){fe||(fe=!0,R.set("EVENT",{canHandle:t=>t instanceof CustomEvent,serialize:t=>[{detail:t.detail},[]],deserialize:t=>t}),R.set("FUNCTION",{canHandle:t=>typeof t=="function",serialize(t){console.debug("[Comlink][Performance] Proxying a function");const{port1:e,port2:r}=new MessageChannel;return K(t,e),[r,[r]]},deserialize(t){return t.start(),Z(t)}}),R.set("PHPResponse",{canHandle:t=>typeof t=="object"&&t!==null&&"headers"in t&&"bytes"in t&&"errors"in t&&"exitCode"in t&&"httpStatusCode"in t,serialize(t){return[t.toRawData(),[]]},deserialize(t){return b.fromRawData(t)}}))}function et(t){return new Proxy(t,{get(e,r){switch(typeof e[r]){case"function":return(...s)=>e[r](...s);case"object":return e[r]===null?e[r]:et(e[r]);case"undefined":case"number":case"string":return e[r];default:return Qe(e[r])}}})}(function(){return typeof navigator<"u"&&navigator?.userAgent?.toLowerCase().indexOf("firefox")>-1?"iframe":"webworker"})();async function tt({iframe:t,blueprint:e,remoteUrl:r,progressTracker:s=new H,disableProgressBar:n,onBlueprintStepCompleted:i}){if(or(r),r=we(r,{progressbar:!n}),s.setCaption("Preparing WordPress"),!e)return me(t,r,s);const o=Be(e,{progress:s.stage(.5),onStepCompleted:i}),a=await me(t,we(r,{php:o.versions.php,wp:o.versions.wp}),s);return await Ve(o,a),s.finish(),a}async function me(t,e,r){await new Promise(i=>{t.src=e,t.addEventListener("load",i,!1)});const s=Xe(t.contentWindow);await s.isConnected(),r.pipe(s);const n=r.stage();return await s.onDownloadProgress(n.loadingListener),await s.isReady(),n.finish(),s}const F="https://playground.wordpress.net";function or(t){const e=new URL(t,F);if((e.origin===F||e.hostname==="localhost")&&e.pathname!=="/remote.html")throw new Error(`Invalid remote URL: ${e}. Expected origin to be ${F}/remote.html.`)}function we(t,e){const r=new URL(t,F),s=new URLSearchParams(r.search);for(const[n,i]of Object.entries(e))i!=null&&i!==!1&&s.set(n,i.toString());return r.search=s.toString(),r.toString()}async function ar(t,e){if(console.warn("`connectPlayground` is deprecated and will be removed. Use `startPlayground` instead."),e?.loadRemote)return tt({iframe:t,remoteUrl:e.loadRemote});const r=Xe(t.contentWindow);return await r.isConnected(),r}exports.LatestSupportedPHPVersion=Me;exports.SupportedPHPVersions=N;exports.SupportedPHPVersionsList=_t;exports.activatePlugin=D;exports.activateTheme=q;exports.applyWordPressPatches=ge;exports.compileBlueprint=Be;exports.connectPlayground=ar;exports.cp=$e;exports.defineSiteUrl=xe;exports.defineWpConfigConsts=V;exports.importFile=ke;exports.installPlugin=Oe;exports.installTheme=Ue;exports.login=He;exports.mkdir=ve;exports.mv=Ee;exports.phpVar=_;exports.phpVars=O;exports.replaceSite=Ce;exports.request=_e;exports.rm=Se;exports.rmdir=Re;exports.runBlueprintSteps=Ve;exports.runPHP=ye;exports.runPHPWithOptions=Pe;exports.runWpInstallationWizard=Ne;exports.setPhpIniEntry=be;exports.setPluginProxyURL=Wt;exports.setSiteOptions=We;exports.startPlaygroundWeb=tt;exports.unzip=U;exports.updateUserMeta=Ie;exports.writeFile=B;exports.zipEntireSite=Fe;
package/index.d.ts CHANGED
@@ -407,9 +407,10 @@ export interface IsomorphicLocalPHP extends RequestHandler {
407
407
  * Lists the files and directories in the given directory.
408
408
  *
409
409
  * @param path - The directory path to list.
410
+ * @param options - Options for the listing.
410
411
  * @returns The list of files and directories in the given directory.
411
412
  */
412
- listFiles(path: string): string[];
413
+ listFiles(path: string, options?: ListFilesOptions): string[];
413
414
  /**
414
415
  * Checks if a directory exists in the PHP filesystem.
415
416
  *
@@ -593,6 +594,13 @@ export interface RmDirOptions {
593
594
  */
594
595
  recursive?: boolean;
595
596
  }
597
+ export interface ListFilesOptions {
598
+ /**
599
+ * If true, prepend given folder path to all file names.
600
+ * Default: false.
601
+ */
602
+ prependPath: boolean;
603
+ }
596
604
  /**
597
605
  * Emscripten's filesystem-related Exception.
598
606
  *
@@ -782,7 +790,7 @@ declare abstract class BasePHP implements IsomorphicLocalPHP {
782
790
  /** @inheritDoc */
783
791
  rmdir(path: string, options?: RmDirOptions): void;
784
792
  /** @inheritDoc */
785
- listFiles(path: string): string[];
793
+ listFiles(path: string, options?: ListFilesOptions): string[];
786
794
  /** @inheritDoc */
787
795
  isDir(path: string): boolean;
788
796
  /** @inheritDoc */
@@ -1012,12 +1020,12 @@ export declare class SemaphoreResource<T extends Resource> extends DecoratedReso
1012
1020
  export interface ActivatePluginStep {
1013
1021
  step: "activatePlugin";
1014
1022
  pluginPath: string;
1023
+ pluginName?: string;
1015
1024
  }
1016
1025
  /**
1017
1026
  * Activates a WordPress plugin in the Playground.
1018
1027
  *
1019
1028
  * @param playground The playground client.
1020
- * @param plugin The plugin slug.
1021
1029
  */
1022
1030
  export declare const activatePlugin: StepHandler<ActivatePluginStep>;
1023
1031
  export interface ApplyWordPressPatchesStep {
@@ -1130,8 +1138,6 @@ export interface InstallPluginOptions {
1130
1138
  }
1131
1139
  /**
1132
1140
  * Installs a WordPress plugin in the Playground.
1133
- * Technically, it uses the same plugin upload form as a WordPress user
1134
- * would, and then activates the plugin if needed.
1135
1141
  *
1136
1142
  * @param playground The playground client.
1137
1143
  * @param pluginZipFile The plugin zip file.
@@ -1184,8 +1190,6 @@ export interface InstallThemeOptions {
1184
1190
  }
1185
1191
  /**
1186
1192
  * Installs a WordPress theme in the Playground.
1187
- * Technically, it uses the same theme upload form as a WordPress user
1188
- * would, and then activates the theme if needed.
1189
1193
  *
1190
1194
  * @param playground The playground client.
1191
1195
  * @param themeZipFile The theme zip file.
@@ -1322,7 +1326,7 @@ export declare const runPHP: StepHandler<RunPHPStep>;
1322
1326
  * {
1323
1327
  * "step": "runPHP",
1324
1328
  * "options": {
1325
- * "code": "<?php echo $_SERVER['HTTP_CONTENT_TYPE']; ?>",
1329
+ * "code": "<?php echo $_SERVER['CONTENT_TYPE']; ?>",
1326
1330
  * "headers": {
1327
1331
  * "Content-type": "text/plain"
1328
1332
  * }
@@ -1526,12 +1530,20 @@ export interface DefineWpConfigConstsStep {
1526
1530
  step: "defineWpConfigConsts";
1527
1531
  /** The constants to define */
1528
1532
  consts: Record<string, unknown>;
1533
+ /**
1534
+ * Enables the virtualization of wp-config.php and playground-consts.json files, leaving the local system files untouched.
1535
+ * The variables defined in the /vfs-blueprints/playground-consts.json file are loaded via the auto_prepend_file directive in the php.ini file.
1536
+ * @default false
1537
+ * @see https://www.php.net/manual/en/ini.core.php#ini.auto-prepend-file
1538
+ */
1539
+ virtualize?: boolean;
1529
1540
  }
1530
1541
  /**
1531
1542
  * Sets site URL of the WordPress installation.
1532
1543
  *
1533
1544
  * @param playground The playground client.
1534
- * @param wpConfigConst
1545
+ * @param wpConfigConst An object containing the constants to be defined and the optional virtual file system configuration file path.
1546
+ * @returns Returns the virtual file system configuration file path.
1535
1547
  */
1536
1548
  export declare const defineWpConfigConsts: StepHandler<DefineWpConfigConstsStep>;
1537
1549
  export interface ActivateThemeStep {
@@ -1545,24 +1557,6 @@ export interface ActivateThemeStep {
1545
1557
  * @param themeFolderName The theme folder name.
1546
1558
  */
1547
1559
  export declare const activateTheme: StepHandler<ActivateThemeStep>;
1548
- /**
1549
- * The step object for defining constants in the VFS_CONFIG_FILE_PATH php file and loaded using the auto_prepend_file php.ini directive.
1550
- */
1551
- export interface DefineVirtualWpConfigConstsStep {
1552
- step: "defineVirtualWpConfigConsts";
1553
- /** The constants to define */
1554
- consts: Record<string, unknown>;
1555
- }
1556
- /**
1557
- * Function to define constants in the virtual VFS_CONFIG_FILE_PATH php file of a WordPress installation.
1558
- * The file should be dynamically loaded using the auto_prepend_file php.ini directive after this step.
1559
- *
1560
- * @param playground The playground client.
1561
- * @param wpConfigConst An object containing the constants to be defined and the optional virtual file system configuration file path.
1562
- * @returns Returns the virtual file system configuration file path.
1563
- * @see {@link https://www.php.net/manual/en/ini.core.php#ini.auto-prepend-file}
1564
- */
1565
- export declare const defineVirtualWpConfigConsts: StepHandler<DefineVirtualWpConfigConstsStep>;
1566
1560
  export type Step = GenericStep<FileReference>;
1567
1561
  export type StepDefinition = Step & {
1568
1562
  progress?: {
@@ -1574,19 +1568,19 @@ export type StepDefinition = Step & {
1574
1568
  * If you add a step here, make sure to also
1575
1569
  * add it to the exports below.
1576
1570
  */
1577
- export type GenericStep<Resource> = ActivatePluginStep | ActivateThemeStep | ApplyWordPressPatchesStep | CpStep | DefineWpConfigConstsStep | DefineVirtualWpConfigConstsStep | DefineSiteUrlStep | ImportFileStep<Resource> | InstallPluginStep<Resource> | InstallThemeStep<Resource> | LoginStep | MkdirStep | MvStep | RequestStep | ReplaceSiteStep<Resource> | RmStep | RmdirStep | RunPHPStep | RunPHPWithOptionsStep | RunWpInstallationWizardStep | SetPhpIniEntryStep | SetSiteOptionsStep | UnzipStep | UpdateUserMetaStep | WriteFileStep<Resource>;
1578
- export type StepHandler<S extends GenericStep<File>> = (
1579
- /**
1580
- * A PHP instance or Playground client.
1581
- */
1582
- php: UniversalPHP, args: Omit<S, "step">,
1571
+ export type GenericStep<Resource> = ActivatePluginStep | ActivateThemeStep | ApplyWordPressPatchesStep | CpStep | DefineWpConfigConstsStep | DefineSiteUrlStep | ImportFileStep<Resource> | InstallPluginStep<Resource> | InstallThemeStep<Resource> | LoginStep | MkdirStep | MvStep | RequestStep | ReplaceSiteStep<Resource> | RmStep | RmdirStep | RunPHPStep | RunPHPWithOptionsStep | RunWpInstallationWizardStep | SetPhpIniEntryStep | SetSiteOptionsStep | UnzipStep | UpdateUserMetaStep | WriteFileStep<Resource>;
1583
1572
  /**
1584
1573
  * Progress reporting details.
1585
1574
  */
1586
- progressArgs?: {
1575
+ export type StepProgress = {
1587
1576
  tracker: ProgressTracker;
1588
1577
  initialCaption?: string;
1589
- }) => any;
1578
+ };
1579
+ export type StepHandler<S extends GenericStep<File>> = (
1580
+ /**
1581
+ * A PHP instance or Playground client.
1582
+ */
1583
+ php: UniversalPHP, args: Omit<S, "step">, progressArgs?: StepProgress) => any;
1590
1584
  export interface Blueprint {
1591
1585
  /**
1592
1586
  * The URL to navigate to after the blueprint has been run.
@@ -1736,7 +1730,7 @@ declare class WebPHPEndpoint implements IsomorphicLocalPHP {
1736
1730
  /** @inheritDoc @php-wasm/web!WebPHP.unlink */
1737
1731
  unlink(path: string): void;
1738
1732
  /** @inheritDoc @php-wasm/web!WebPHP.listFiles */
1739
- listFiles(path: string): string[];
1733
+ listFiles(path: string, options?: ListFilesOptions): string[];
1740
1734
  /** @inheritDoc @php-wasm/web!WebPHP.isDir */
1741
1735
  isDir(path: string): boolean;
1742
1736
  /** @inheritDoc @php-wasm/web!WebPHP.fileExists */