@wp-playground/client 0.1.40 → 0.1.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/blueprint-schema.json +39 -4
- package/index.cjs +28 -21
- package/index.d.ts +47 -1
- package/index.js +500 -475
- package/package.json +2 -2
package/blueprint-schema.json
CHANGED
|
@@ -213,7 +213,39 @@
|
|
|
213
213
|
},
|
|
214
214
|
"consts": {
|
|
215
215
|
"type": "object",
|
|
216
|
-
"additionalProperties": {}
|
|
216
|
+
"additionalProperties": {},
|
|
217
|
+
"description": "The constants to define"
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
"required": [
|
|
221
|
+
"consts",
|
|
222
|
+
"step"
|
|
223
|
+
]
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
"type": "object",
|
|
227
|
+
"additionalProperties": false,
|
|
228
|
+
"properties": {
|
|
229
|
+
"progress": {
|
|
230
|
+
"type": "object",
|
|
231
|
+
"properties": {
|
|
232
|
+
"weight": {
|
|
233
|
+
"type": "number"
|
|
234
|
+
},
|
|
235
|
+
"caption": {
|
|
236
|
+
"type": "string"
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
"additionalProperties": false
|
|
240
|
+
},
|
|
241
|
+
"step": {
|
|
242
|
+
"type": "string",
|
|
243
|
+
"const": "defineVirtualWpConfigConsts"
|
|
244
|
+
},
|
|
245
|
+
"consts": {
|
|
246
|
+
"type": "object",
|
|
247
|
+
"additionalProperties": {},
|
|
248
|
+
"description": "The constants to define"
|
|
217
249
|
}
|
|
218
250
|
},
|
|
219
251
|
"required": [
|
|
@@ -297,13 +329,16 @@
|
|
|
297
329
|
},
|
|
298
330
|
"step": {
|
|
299
331
|
"type": "string",
|
|
300
|
-
"const": "installPlugin"
|
|
332
|
+
"const": "installPlugin",
|
|
333
|
+
"description": "The step identifier."
|
|
301
334
|
},
|
|
302
335
|
"pluginZipFile": {
|
|
303
|
-
"$ref": "#/definitions/FileReference"
|
|
336
|
+
"$ref": "#/definitions/FileReference",
|
|
337
|
+
"description": "The plugin zip file to install."
|
|
304
338
|
},
|
|
305
339
|
"options": {
|
|
306
|
-
"$ref": "#/definitions/InstallPluginOptions"
|
|
340
|
+
"$ref": "#/definitions/InstallPluginOptions",
|
|
341
|
+
"description": "Optional installation options."
|
|
307
342
|
}
|
|
308
343
|
},
|
|
309
344
|
"required": [
|
package/index.cjs
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function x(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
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function x(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 nt(t){return new Uint8Array(await t.arrayBuffer())}const Y="/vfs-blueprints",K="/vfs-blueprints/wp-config-consts.php",me=async(t,{plugin:e},r)=>{r?.tracker.setCaption(`Activating ${e}`);const i=x(await t.request({url:"/wp-admin/plugins.php"})).querySelector(`tr[data-slug="${e}"] a`).attributes.getNamedItem("href").value;await t.request({url:"/wp-admin/"+i})},ge=async(t,e)=>{const r=new it(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 it{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
|
|
2
2
|
if(!defined('WP_HOME')) {
|
|
3
3
|
define('WP_HOME', "${this.scopedSiteUrl}");
|
|
4
4
|
define('WP_SITEURL', "${this.scopedSiteUrl}");
|
|
5
5
|
}
|
|
6
|
-
?>${e}`)}async disableSiteHealth(){await
|
|
6
|
+
?>${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 we=async(t,{code:e})=>await t.run({code:e}),ye=async(t,{options:e})=>await t.run(e),Pe=async(t,{key:e,value:r})=>{await t.setPhpIniEntry(e,r)},be=async(t,{request:e})=>await t.request(e),_e=async(t,{fromPath:e,toPath:r})=>{await t.writeFile(r,await t.readFileAsBuffer(e))},$e=async(t,{fromPath:e,toPath:r})=>{await t.mv(e,r)},Se=async(t,{path:e})=>{await t.mkdir(e)},Ee=async(t,{path:e})=>{await t.unlink(e)},ve=async(t,{path:e})=>{await t.rmdir(e)},Re=async(t,{path:e,data:r})=>{r instanceof File&&(r=await nt(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
|
|
7
7
|
$consts = json_decode(file_get_contents('./playground-consts.json'), true);
|
|
8
8
|
foreach ($consts as $const => $value) {
|
|
9
9
|
if (!defined($const)) {
|
|
10
10
|
define($const, $value);
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
|
-
?>${s}`)},
|
|
13
|
+
?>${s}`)},xe=async(t,{siteUrl:e})=>await D(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 ot=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 ot 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
|
|
14
14
|
|
|
15
15
|
function zipDir($dir, $output, $additionalFiles = array())
|
|
16
16
|
{
|
|
@@ -72,34 +72,39 @@ function delTree($dir)
|
|
|
72
72
|
}
|
|
73
73
|
return rmdir($dir);
|
|
74
74
|
}
|
|
75
|
-
`;async function
|
|
75
|
+
`;async function Ce(t){const e="wordpress-playground.zip",r=`/${e}`,s=U({zipPath:r,documentRoot:await t.documentRoot});await Oe(t,`zipDir(${s.documentRoot}, ${s.zipPath});`);const n=await t.readFileAsBuffer(r);return t.unlink(r),new File([n],e)}const Fe=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 ct(t,`${n}/wp-config.php`,o=>`<?php
|
|
76
76
|
if(!defined('WP_HOME')) {
|
|
77
77
|
define('WP_HOME', ${i.absoluteUrl});
|
|
78
78
|
define('WP_SITEURL', ${i.absoluteUrl});
|
|
79
79
|
}
|
|
80
|
-
?>${o}`)},q=async(t,{zipPath:e,extractToPath:r})=>{const s=U({zipPath:e,extractToPath:r});await
|
|
80
|
+
?>${o}`)},q=async(t,{zipPath:e,extractToPath:r})=>{const s=U({zipPath:e,extractToPath:r});await Oe(t,`unzip(${s.zipPath}, ${s.extractToPath});`)},ke=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=at(i);o.fetch_attachments="1";for(const a in o)if(a.startsWith("user_map[")){const c="user_new["+a.slice(9,-1)+"]";o[c]="1"}await t.request({url:i.action,method:"POST",formData:o})};function X(t){return new DOMParser().parseFromString(t.text,"text/html")}function at(t){return Object.fromEntries(new FormData(t).entries())}async function ct(t,e,r){await t.writeFile(e,r(await t.readFileAsText(e)))}async function Oe(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 Le=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=x(i),a=new FormData(o.querySelector(".wp-upload-form")),{pluginzip:c,...l}=Object.fromEntries(a.entries()),u=await t.request({url:"/wp-admin/update.php?action=upload-plugin",method:"POST",formData:l,files:{pluginzip:e}});if(n){const p=x(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 Ae=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=x(i),a=new FormData(o.querySelector(".wp-upload-form")),{themezip:c,...l}=Object.fromEntries(a.entries()),u=await t.request({url:"/wp-admin/update.php?action=upload-theme",method:"POST",formData:l,files:{themezip:e}});if(n){const d=x(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 rt=y.attributes.getNamedItem("href").value,st=new URL(rt,await t.pathToInternalUrl("/wp-admin/")).toString();await t.request({url:st})}}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)}},Ue=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"}})},He=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"}})},Ie=async(t,{options:e})=>{const r=`<?php
|
|
81
81
|
include 'wordpress/wp-load.php';
|
|
82
|
-
$site_options = ${
|
|
82
|
+
$site_options = ${_(e)};
|
|
83
83
|
foreach($site_options as $name => $value) {
|
|
84
84
|
update_option($name, $value);
|
|
85
85
|
}
|
|
86
86
|
echo "Success";
|
|
87
|
-
`,s=await t.run({code:r});return
|
|
87
|
+
`,s=await t.run({code:r});return We(s),{code:r,result:s}},Ne=async(t,{meta:e,userId:r})=>{const s=`<?php
|
|
88
88
|
include 'wordpress/wp-load.php';
|
|
89
|
-
$meta = ${
|
|
89
|
+
$meta = ${_(e)};
|
|
90
90
|
foreach($meta as $name => $value) {
|
|
91
|
-
update_user_meta(${
|
|
91
|
+
update_user_meta(${_(r)}, $name, $value);
|
|
92
92
|
}
|
|
93
93
|
echo "Success";
|
|
94
|
-
`,n=await t.run({code:s});return
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
`,n=await t.run({code:s});return We(n),{code:s,result:n}};async function We(t){if(t.text!=="Success")throw console.log(t),new Error(`Failed to run code: ${t.text} ${t.errors}`)}const Me=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
|
|
95
|
+
$consts = json_decode(file_get_contents('${r}'), true);
|
|
96
|
+
foreach ($consts as $const => $value) {
|
|
97
|
+
if (!defined($const)) {
|
|
98
|
+
define($const, $value);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
?>${s}`),K},lt=Object.freeze(Object.defineProperty({__proto__:null,activatePlugin:me,applyWordPressPatches:ge,cp:_e,defineSiteUrl:xe,defineVirtualWpConfigConsts:Me,defineWpConfigConsts:D,importFile:ke,installPlugin:Le,installTheme:Ae,login:Ue,mkdir:Se,mv:$e,replaceSite:Fe,request:be,rm:Ee,rmdir:ve,runPHP:we,runPHPWithOptions:ye,runWpInstallationWizard:He,setPhpIniEntry:Pe,setSiteOptions:Ie,unzip:q,updateUserMeta:Ne,writeFile:Re,zipEntireSite:Ce},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:c,value:l}=await o.read();if(l&&(a+=l.byteLength),c){n(a,a),i.close();break}else n(a,s),i.enqueue(l)}catch(c){console.error({e:c}),i.error(c);break}}}),{status:t.status,statusText:t.statusText,headers:t.headers})}const N=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<-N)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+N>=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+N>=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 dt=typeof globalThis.ErrorEvent=="function"?globalThis.ErrorEvent:j;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=gt(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 M=[];function mt(){return M}function gt(t,e){if(t.message==="unreachable"){let r=wt;e||(r+=`
|
|
97
102
|
|
|
98
103
|
This stack trace is lacking. For a better one initialize
|
|
99
104
|
the PHP runtime with { debug: true }, e.g. PHPNode.load('8.1', { debug: true }).
|
|
100
105
|
|
|
101
|
-
`),M=
|
|
102
|
-
`;return r}return t.message}const
|
|
106
|
+
`),M=bt(e||t.stack||"");for(const s of M)r+=` * ${s}
|
|
107
|
+
`;return r}return t.message}const wt=`
|
|
103
108
|
"unreachable" WASM instruction executed.
|
|
104
109
|
|
|
105
110
|
The typical reason is a PHP function missing from the ASYNCIFY_ONLY
|
|
@@ -123,15 +128,17 @@ the Dockerfile, you'll need to trigger this error again with long stack
|
|
|
123
128
|
traces enabled. In node.js, you can do it using the --stack-trace-limit=100
|
|
124
129
|
CLI option:
|
|
125
130
|
|
|
126
|
-
`,
|
|
127
|
-
${
|
|
128
|
-
${
|
|
129
|
-
`))console.log(`${
|
|
130
|
-
`).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[]}}
|
|
131
|
+
`,re="\x1B[41m",yt="\x1B[1m",se="\x1B[0m",ne="\x1B[K";let ie=!1;function Pt(t){if(!ie){ie=!0,console.log(`${re}
|
|
132
|
+
${ne}
|
|
133
|
+
${yt} WASM ERROR${se}${re}`);for(const e of t.split(`
|
|
134
|
+
`))console.log(`${ne} ${e} `);console.log(`${se}`)}}function bt(t){try{const e=t.split(`
|
|
135
|
+
`).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 v{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 v(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"],ze=I[0],_t=I;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 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 Et(t,e){return!e||t.startsWith(e)?t:e+t}class vt{#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)),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 v(404,{},new TextEncoder().encode("404 File not found"));const s=this.php.readFileAsBuffer(r);return new v(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 l=e.files[c];o.push({key:c,name:l.name,type:l.type,data:new Uint8Array(await l.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;return 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,await this.php.run({relativeUri:Et(oe(r),this.#n),protocol:this.#t,method:e.method||n,body:a,fileInfos:o,scriptPath:this.#h(r.pathname),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}`;return this.php.fileExists(s)?s:`${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
|
|
136
|
+
\r
|
|
137
|
+
`),a=i.substring(0,o).trim(),c=i.substring(o+4).trim(),l=a.match(/name="([^"]+)"/);if(l){const u=l[1];e[u]=c}}),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 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 c=typeof a=="object"?a?.errno:null;if(c in ce){const l=ce[c],u=typeof o[0]=="string"?o[0]:null,d=u!==null?t.replaceAll("{path}",u):t;throw new Error(`${d}: ${l}`,{cause:a})}throw a}}}}const Tt=[];function Ct(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 Ft=Object.defineProperty,kt=Object.getOwnPropertyDescriptor,g=(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&&Ft(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 $t(new vt(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=Ct(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(`
|
|
131
138
|
`)+`
|
|
132
139
|
|
|
133
|
-
`;this[h].ccall("wasm_set_phpini_entries",null,[f],[e])}this[h].ccall("php_wasm_init",null,[],[])}#
|
|
140
|
+
`;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(async(i,o)=>{r=a=>{const c=new Error("Rethrown");c.cause=a.error,c.betterMessage=a.message,o(c)},this.#s?.addEventListener("error",r);try{i(await await this[h].ccall("wasm_sapi_handle_request",S,[],[]))}catch(a){o(a)}})}catch(i){for(const l in this)typeof this[l]=="function"&&(this[l]=()=>{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,c=new Error(a);throw c.cause=o,c}finally{this.#s?.removeEventListener("error",r),this.#r={}}const{headers:s,httpStatusCode:n}=this.#n();return new v(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 De(t){const e={};for(const r in t)e[r.toLowerCase()]=t[r];return e}const Ot=["vfs","literal","wordpress.org/themes","wordpress.org/plugins","url"];function Lt(t){return t&&typeof t=="object"&&typeof t.resource=="string"&&Ot.includes(t.resource)}class ${static create(e,{semaphore:r,progress:s}){let n;switch(e.resource){case"vfs":n=new At(e,s);break;case"literal":n=new Ut(e,s);break;case"wordpress.org/themes":n=new Wt(e,s);break;case"wordpress.org/plugins":n=new Mt(e,s);break;case"url":n=new It(e,s);break;default:throw new Error(`Invalid resource: ${e}`)}return n=new zt(n),r&&(n=new Dt(n,r)),n}setPlayground(e){this.playground=e}get isAsync(){return!1}}class At 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 File([e],this.name)}get name(){return this.resource.path}}class Ut extends ${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 ${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 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 Ht=()=>{};class It 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 Wt extends B{constructor(e,r){super(r),this.resource=e}get name(){return A(this.resource.slug)}getURL(){const e=qe(this.resource.slug);return`${V}?theme=`+e}}class Mt extends B{constructor(e,r){super(r),this.resource=e}get name(){return A(this.resource.slug)}getURL(){const e=qe(this.resource.slug);return`${V}?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 zt 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,c)=>a+(c.progress?.weight||1),0),o=n.map(a=>Bt(a,{semaphore:r,rootProgressTracker:e,totalProgressWeight:i}));return{versions:{php:le(t.preferredVersions?.php,I,ze),wp:le(t.preferredVersions?.wp,qt,"6.2")},run:async a=>{try{for(const{resources:c}of o)for(const l of c)l.setPlayground(a),l.isAsync&&l.resolve();for(const{run:c,step:l}of o){const u=await c(a);s(u,l)}try{await a.goTo(t.landingPage||"/")}catch{}}finally{e.finish()}}}}function le(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=ue(i),c=ue(i).filter(u=>u.isAsync),l=1/(c.length+1);for(const u of c)u.progress=n.stage(l);return{run:o,step:t,resources:a}}function ue(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)}/**
|
|
134
141
|
* @license
|
|
135
142
|
* Copyright 2019 Google LLC
|
|
136
143
|
* SPDX-License-Identifier: Apache-2.0
|
|
137
|
-
*/const
|
|
144
|
+
*/const Ge=Symbol("Comlink.proxy"),Gt=Symbol("Comlink.endpoint"),Jt=Symbol("Comlink.releaseProxy"),W=Symbol("Comlink.finalizer"),C=Symbol("Comlink.thrown"),Je=t=>typeof t=="object"&&t!==null||typeof t=="function",Yt={canHandle:t=>Je(t)&&t[Ge],serialize(t){const{port1:e,port2:r}=new MessageChannel;return G(t,e),[r,[r]]},deserialize(t){return t.start(),J(t)}},Kt={canHandle:t=>Je(t)&&C 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",Yt],["throw",Kt]]);function Qt(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(!Qt(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),c=(n.data.argumentList||[]).map(b);let l;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":l=d;break;case"SET":u[a.slice(-1)[0]]=b(n.data.value),l=!0;break;case"APPLY":l=d.apply(u,c);break;case"CONSTRUCT":{const p=new d(...c);l=Xe(p)}break;case"ENDPOINT":{const{port1:p,port2:y}=new MessageChannel;G(t,y),l=rr(p,[p])}break;case"RELEASE":l=void 0;break;default:return}}catch(u){l={value:u,[C]:0}}Promise.resolve(l).catch(u=>({value:u,[C]:0})).then(u=>{const[d,p]=L(u);e.postMessage(Object.assign(Object.assign({},d),{id:i}),p),o==="RELEASE"&&(e.removeEventListener("message",s),Ye(e),W in t&&typeof t[W]=="function"&&t[W]())}).catch(u=>{const[d,p]=L({value:new TypeError("Unserializable return value"),[C]:0});e.postMessage(Object.assign(Object.assign({},d),{id:i}),p)})}),e.start&&e.start()}function Xt(t){return t.constructor.name==="MessagePort"}function Ye(t){Xt(t)&&t.close()}function J(t,e){return z(t,[],e)}function T(t){if(t)throw new Error("Proxy has been released and is not useable")}function Ke(t){return E(t,{type:"RELEASE"}).then(()=>{Ye(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&&Ke(t)});function Zt(t,e){const r=(k.get(e)||0)+1;k.set(e,r),O&&O.register(t,e,t)}function er(t){O&&O.unregister(t)}function z(t,e=[],r=function(){}){let s=!1;const n=new Proxy(r,{get(i,o){if(T(s),o===Jt)return()=>{er(n),Ke(t),s=!0};if(o==="then"){if(e.length===0)return{then:()=>n};const a=E(t,{type:"GET",path:e.map(c=>c.toString())}).then(b);return a.then.bind(a)}return z(t,[...e,o])},set(i,o,a){T(s);const[c,l]=L(a);return E(t,{type:"SET",path:[...e,o].map(u=>u.toString()),value:c},l).then(b)},apply(i,o,a){T(s);const c=e[e.length-1];if(c===Gt)return E(t,{type:"ENDPOINT"}).then(b);if(c==="bind")return z(t,e.slice(0,-1));const[l,u]=he(a);return E(t,{type:"APPLY",path:e.map(d=>d.toString()),argumentList:l},u).then(b)},construct(i,o){T(s);const[a,c]=he(o);return E(t,{type:"CONSTRUCT",path:e.map(l=>l.toString()),argumentList:a},c).then(b)}});return Zt(n,t),n}function tr(t){return Array.prototype.concat.apply([],t)}function he(t){const e=t.map(L);return[e.map(r=>r[0]),tr(e.map(r=>r[1]))]}const Qe=new WeakMap;function rr(t,e){return Qe.set(t,e),t}function Xe(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 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},Qe.get(t)||[]]}function b(t){switch(t.type){case"HANDLER":return R.get(t.name).deserialize(t.value);case"RAW":return t.value}}function E(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 Ze(t){ir();const e=t instanceof Worker?t:sr(t),r=J(e),s=et(r);return new Proxy(s,{get:(n,i)=>i==="isConnected"?()=>r.isConnected():r[i]})}let de=!1;function ir(){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 v.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 Xe(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=fe(r,{progressbar:!n}),s.setCaption("Preparing WordPress"),!e)return pe(t,r,s);const o=Be(e,{progress:s.stage(.5),onStepCompleted:i}),a=await pe(t,fe(r,{php:o.versions.php,wp:o.versions.wp}),s);return await Ve(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=Ze(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 fe(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=Ze(t.contentWindow);return await r.isConnected(),r}exports.LatestSupportedPHPVersion=ze;exports.SupportedPHPVersions=I;exports.SupportedPHPVersionsList=_t;exports.activatePlugin=me;exports.applyWordPressPatches=ge;exports.compileBlueprint=Be;exports.connectPlayground=ar;exports.cp=_e;exports.defineSiteUrl=xe;exports.defineVirtualWpConfigConsts=Me;exports.defineWpConfigConsts=D;exports.importFile=ke;exports.installPlugin=Le;exports.installTheme=Ae;exports.login=Ue;exports.mkdir=Se;exports.mv=$e;exports.phpVar=_;exports.phpVars=U;exports.replaceSite=Fe;exports.request=be;exports.rm=Ee;exports.rmdir=ve;exports.runBlueprintSteps=Ve;exports.runPHP=we;exports.runPHPWithOptions=ye;exports.runWpInstallationWizard=He;exports.setPhpIniEntry=Pe;exports.setPluginProxyURL=Nt;exports.setSiteOptions=Ie;exports.startPlaygroundWeb=tt;exports.unzip=q;exports.updateUserMeta=Ne;exports.writeFile=Re;exports.zipEntireSite=Ce;
|
package/index.d.ts
CHANGED
|
@@ -1003,9 +1003,33 @@ export interface ImportFileStep<ResourceType> {
|
|
|
1003
1003
|
* @param file The file to import.
|
|
1004
1004
|
*/
|
|
1005
1005
|
export declare const importFile: StepHandler<ImportFileStep<File>>;
|
|
1006
|
+
/**
|
|
1007
|
+
* The step to install a WordPress plugin in the Playground.
|
|
1008
|
+
*
|
|
1009
|
+
* @example
|
|
1010
|
+
*
|
|
1011
|
+
* <code>
|
|
1012
|
+
* {
|
|
1013
|
+
* "step": "installPlugin",
|
|
1014
|
+
* "pluginZipFile": "http://example.com/plugin.zip",
|
|
1015
|
+
* "options": {
|
|
1016
|
+
* "activate": true
|
|
1017
|
+
* }
|
|
1018
|
+
* }
|
|
1019
|
+
* </code>
|
|
1020
|
+
*/
|
|
1006
1021
|
export interface InstallPluginStep<ResourceType> {
|
|
1022
|
+
/**
|
|
1023
|
+
* The step identifier.
|
|
1024
|
+
*/
|
|
1007
1025
|
step: "installPlugin";
|
|
1026
|
+
/**
|
|
1027
|
+
* The plugin zip file to install.
|
|
1028
|
+
*/
|
|
1008
1029
|
pluginZipFile: ResourceType;
|
|
1030
|
+
/**
|
|
1031
|
+
* Optional installation options.
|
|
1032
|
+
*/
|
|
1009
1033
|
options?: InstallPluginOptions;
|
|
1010
1034
|
}
|
|
1011
1035
|
export interface InstallPluginOptions {
|
|
@@ -1140,8 +1164,12 @@ export interface WriteFileStep<ResourceType> {
|
|
|
1140
1164
|
data: ResourceType | string | Uint8Array;
|
|
1141
1165
|
}
|
|
1142
1166
|
export declare const writeFile: StepHandler<WriteFileStep<File>>;
|
|
1167
|
+
/**
|
|
1168
|
+
* The step object for defining constants in the wp-config.php file of a WordPress installation.
|
|
1169
|
+
*/
|
|
1143
1170
|
export interface DefineWpConfigConstsStep {
|
|
1144
1171
|
step: "defineWpConfigConsts";
|
|
1172
|
+
/** The constants to define */
|
|
1145
1173
|
consts: Record<string, unknown>;
|
|
1146
1174
|
}
|
|
1147
1175
|
/**
|
|
@@ -1151,6 +1179,24 @@ export interface DefineWpConfigConstsStep {
|
|
|
1151
1179
|
* @param wpConfigConst
|
|
1152
1180
|
*/
|
|
1153
1181
|
export declare const defineWpConfigConsts: StepHandler<DefineWpConfigConstsStep>;
|
|
1182
|
+
/**
|
|
1183
|
+
* The step object for defining constants in the VFS_CONFIG_FILE_PATH php file and loaded using the auto_prepend_file php.ini directive.
|
|
1184
|
+
*/
|
|
1185
|
+
export interface DefineVirtualWpConfigConstsStep {
|
|
1186
|
+
step: "defineVirtualWpConfigConsts";
|
|
1187
|
+
/** The constants to define */
|
|
1188
|
+
consts: Record<string, unknown>;
|
|
1189
|
+
}
|
|
1190
|
+
/**
|
|
1191
|
+
* Function to define constants in the virtual VFS_CONFIG_FILE_PATH php file of a WordPress installation.
|
|
1192
|
+
* The file should be dynamically loaded using the auto_prepend_file php.ini directive after this step.
|
|
1193
|
+
*
|
|
1194
|
+
* @param playground The playground client.
|
|
1195
|
+
* @param wpConfigConst An object containing the constants to be defined and the optional virtual file system configuration file path.
|
|
1196
|
+
* @returns Returns the virtual file system configuration file path.
|
|
1197
|
+
* @see {@link https://www.php.net/manual/en/ini.core.php#ini.auto-prepend-file}
|
|
1198
|
+
*/
|
|
1199
|
+
export declare const defineVirtualWpConfigConsts: StepHandler<DefineVirtualWpConfigConstsStep>;
|
|
1154
1200
|
export type Step = GenericStep<FileReference>;
|
|
1155
1201
|
export type StepDefinition = Step & {
|
|
1156
1202
|
progress?: {
|
|
@@ -1158,7 +1204,7 @@ export type StepDefinition = Step & {
|
|
|
1158
1204
|
caption?: string;
|
|
1159
1205
|
};
|
|
1160
1206
|
};
|
|
1161
|
-
export type GenericStep<Resource> = ActivatePluginStep | 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>;
|
|
1207
|
+
export type GenericStep<Resource> = ActivatePluginStep | 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>;
|
|
1162
1208
|
export type StepHandler<S extends GenericStep<File>> = (php: UniversalPHP, args: Omit<S, "step">, progressArgs?: {
|
|
1163
1209
|
tracker: ProgressTracker;
|
|
1164
1210
|
initialCaption?: string;
|