@php-wasm/universal 0.6.2 → 0.6.3

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/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var K=(e,t,r)=>{if(!t.has(e))throw TypeError("Cannot "+r)};var a=(e,t,r)=>(K(e,t,"read from private field"),r?r.call(e):t.get(e)),c=(e,t,r)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,r)},u=(e,t,r,s)=>(K(e,t,"write to private field"),s?s.call(e,r):t.set(e,r),r);var p=(e,t,r)=>(K(e,t,"access private method"),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});if(typeof File>"u"){class e extends Blob{constructor(r,s,i){super(r);let n;i!=null&&i.lastModified&&(n=new Date),(!n||isNaN(n.getFullYear()))&&(n=new Date),this.lastModifiedDate=n,this.lastModified=n.getMilliseconds(),this.name=s||""}}global.File=e}function asPromise(e){return new Promise(function(t,r){e.onload=e.onerror=function(s){e.onload=e.onerror=null,s.type==="load"?t(e.result):r(new Error("Failed to read the blob/file"))}})}typeof Blob.prototype.arrayBuffer>"u"&&(Blob.prototype.arrayBuffer=function(){const t=new FileReader;return t.readAsArrayBuffer(this),asPromise(t)});typeof Blob.prototype.text>"u"&&(Blob.prototype.text=function(){const t=new FileReader;return t.readAsText(this),asPromise(t)});function isByobSupported(){const e=new Uint8Array([1,2,3,4]),r=new File([e],"test").stream();try{return r.getReader({mode:"byob"}),!0}catch{return!1}}(typeof Blob.prototype.stream>"u"||!isByobSupported())&&(Blob.prototype.stream=function(){let e=0;const t=this;return new ReadableStream({type:"bytes",autoAllocateChunkSize:512*1024,async pull(r){const s=r.byobRequest.view,n=await t.slice(e,e+s.byteLength).arrayBuffer(),o=new Uint8Array(n);new Uint8Array(s.buffer).set(o);const l=o.byteLength;r.byobRequest.respond(l),e+=l,e>=t.size&&r.close()}})});if(typeof CustomEvent>"u"){class e extends Event{constructor(r,s={}){super(r,s),this.detail=s.detail}initCustomEvent(){}}globalThis.CustomEvent=e}const kError=Symbol("error"),kMessage=Symbol("message");class ErrorEvent2 extends Event{constructor(t,r={}){super(t),this[kError]=r.error===void 0?null:r.error,this[kMessage]=r.message===void 0?"":r.message}get error(){return this[kError]}get message(){return this[kMessage]}}Object.defineProperty(ErrorEvent2.prototype,"error",{enumerable:!0});Object.defineProperty(ErrorEvent2.prototype,"message",{enumerable:!0});const ErrorEvent=typeof globalThis.ErrorEvent=="function"?globalThis.ErrorEvent:ErrorEvent2;function isExitCodeZero(e){return e instanceof Error?"exitCode"in e&&(e==null?void 0:e.exitCode)===0||(e==null?void 0:e.name)==="ExitStatus"&&"status"in e&&e.status===0:!1}class UnhandledRejectionsTarget extends EventTarget{constructor(){super(...arguments),this.listenersCount=0}addEventListener(t,r){++this.listenersCount,super.addEventListener(t,r)}removeEventListener(t,r){--this.listenersCount,super.removeEventListener(t,r)}hasListeners(){return this.listenersCount>0}}function improveWASMErrorReporting(e){e.asm={...e.asm};const t=new UnhandledRejectionsTarget;for(const r in e.asm)if(typeof e.asm[r]=="function"){const s=e.asm[r];e.asm[r]=function(...i){var n;try{return s(...i)}catch(o){if(!(o instanceof Error))throw o;const l=clarifyErrorMessage(o,(n=e.lastAsyncifyStackSource)==null?void 0:n.stack);if(e.lastAsyncifyStackSource&&(o.cause=e.lastAsyncifyStackSource),t.hasListeners()){t.dispatchEvent(new ErrorEvent("error",{error:o,message:l}));return}throw isExitCodeZero(o)||showCriticalErrorBox(l),o}}}return t}let functionsMaybeMissingFromAsyncify=[];function getFunctionsMaybeMissingFromAsyncify(){return functionsMaybeMissingFromAsyncify}function clarifyErrorMessage(e,t){if(e.message==="unreachable"){let r=UNREACHABLE_ERROR;t||(r+=`
1
+ "use strict";var J=(e,t,r)=>{if(!t.has(e))throw TypeError("Cannot "+r)};var a=(e,t,r)=>(J(e,t,"read from private field"),r?r.call(e):t.get(e)),c=(e,t,r)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,r)},h=(e,t,r,s)=>(J(e,t,"write to private field"),s?s.call(e,r):t.set(e,r),r);var p=(e,t,r)=>(J(e,t,"access private method"),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});if(typeof File>"u"){class e extends Blob{constructor(r,s,n){super(r);let i;n!=null&&n.lastModified&&(i=new Date),(!i||isNaN(i.getFullYear()))&&(i=new Date),this.lastModifiedDate=i,this.lastModified=i.getMilliseconds(),this.name=s||""}}global.File=e}function asPromise(e){return new Promise(function(t,r){e.onload=e.onerror=function(s){e.onload=e.onerror=null,s.type==="load"?t(e.result):r(new Error("Failed to read the blob/file"))}})}typeof Blob.prototype.arrayBuffer>"u"&&(Blob.prototype.arrayBuffer=function(){const t=new FileReader;return t.readAsArrayBuffer(this),asPromise(t)});typeof Blob.prototype.text>"u"&&(Blob.prototype.text=function(){const t=new FileReader;return t.readAsText(this),asPromise(t)});function isByobSupported(){const e=new Uint8Array([1,2,3,4]),r=new File([e],"test").stream();try{return r.getReader({mode:"byob"}),!0}catch{return!1}}(typeof Blob.prototype.stream>"u"||!isByobSupported())&&(Blob.prototype.stream=function(){let e=0;const t=this;return new ReadableStream({type:"bytes",autoAllocateChunkSize:512*1024,async pull(r){const s=r.byobRequest.view,i=await t.slice(e,e+s.byteLength).arrayBuffer(),o=new Uint8Array(i);new Uint8Array(s.buffer).set(o);const l=o.byteLength;r.byobRequest.respond(l),e+=l,e>=t.size&&r.close()}})});if(typeof CustomEvent>"u"){class e extends Event{constructor(r,s={}){super(r,s),this.detail=s.detail}initCustomEvent(){}}globalThis.CustomEvent=e}const kError=Symbol("error"),kMessage=Symbol("message");class ErrorEvent2 extends Event{constructor(t,r={}){super(t),this[kError]=r.error===void 0?null:r.error,this[kMessage]=r.message===void 0?"":r.message}get error(){return this[kError]}get message(){return this[kMessage]}}Object.defineProperty(ErrorEvent2.prototype,"error",{enumerable:!0});Object.defineProperty(ErrorEvent2.prototype,"message",{enumerable:!0});const ErrorEvent=typeof globalThis.ErrorEvent=="function"?globalThis.ErrorEvent:ErrorEvent2;function isExitCodeZero(e){return e instanceof Error?"exitCode"in e&&(e==null?void 0:e.exitCode)===0||(e==null?void 0:e.name)==="ExitStatus"&&"status"in e&&e.status===0:!1}class UnhandledRejectionsTarget extends EventTarget{constructor(){super(...arguments),this.listenersCount=0}addEventListener(t,r){++this.listenersCount,super.addEventListener(t,r)}removeEventListener(t,r){--this.listenersCount,super.removeEventListener(t,r)}hasListeners(){return this.listenersCount>0}}function improveWASMErrorReporting(e){e.asm={...e.asm};const t=new UnhandledRejectionsTarget;for(const r in e.asm)if(typeof e.asm[r]=="function"){const s=e.asm[r];e.asm[r]=function(...n){var i;try{return s(...n)}catch(o){if(!(o instanceof Error))throw o;const l=clarifyErrorMessage(o,(i=e.lastAsyncifyStackSource)==null?void 0:i.stack);if(e.lastAsyncifyStackSource&&(o.cause=e.lastAsyncifyStackSource),t.hasListeners()){t.dispatchEvent(new ErrorEvent("error",{error:o,message:l}));return}throw isExitCodeZero(o)||showCriticalErrorBox(l),o}}}return t}let functionsMaybeMissingFromAsyncify=[];function getFunctionsMaybeMissingFromAsyncify(){return functionsMaybeMissingFromAsyncify}function clarifyErrorMessage(e,t){if(e.message==="unreachable"){let r=UNREACHABLE_ERROR;t||(r+=`
2
2
 
3
3
  This stack trace is lacking. For a better one initialize
4
4
  the PHP runtime with { debug: true }, e.g. PHPNode.load('8.1', { debug: true }).
@@ -32,9 +32,13 @@ CLI option:
32
32
  ${eol}
33
33
  ${bold} WASM ERROR${reset}${redBg}`);for(const t of e.split(`
34
34
  `))console.log(`${eol} ${t} `);console.log(`${reset}`)}}function extractPHPFunctionsFromStack(e){try{const t=e.split(`
35
- `).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(t))}catch{return[]}}class Semaphore{constructor({concurrency:t}){this._running=0,this.concurrency=t,this.queue=[]}get running(){return this._running}async acquire(){for(;;)if(this._running>=this.concurrency)await new Promise(t=>this.queue.push(t));else{this._running++;let t=!1;return()=>{t||(t=!0,this._running--,this.queue.length>0&&this.queue.shift()())}}}async run(t){const r=await this.acquire();try{return await t()}finally{r()}}}function joinPaths(...e){let t=e.join("/");const r=t[0]==="/",s=t.substring(t.length-1)==="/";return t=normalizePath(t),!t&&!r&&(t="."),t&&s&&(t+="/"),t}function dirname(e){if(e==="/")return"/";e=normalizePath(e);const t=e.lastIndexOf("/");return t===-1?"":t===0?"/":e.substr(0,t)}function normalizePath(e){const t=e[0]==="/";return e=normalizePathsArray(e.split("/").filter(r=>!!r),!t).join("/"),(t?"/":"")+e.replace(/\/$/,"")}function normalizePathsArray(e,t){let r=0;for(let s=e.length-1;s>=0;s--){const i=e[s];i==="."?e.splice(s,1):i===".."?(e.splice(s,1),r++):r&&(e.splice(s,1),r--)}if(t)for(;r;r--)e.unshift("..");return e}function createSpawnHandler(e){return function(t){const r=new ChildProcess,s=new ProcessApi(r);return setTimeout(async()=>{await e(t,s),r.emit("spawn",!0)}),r}}class EventEmitter{constructor(){this.listeners={}}emit(t,r){this.listeners[t]&&this.listeners[t].forEach(function(s){s(r)})}on(t,r){this.listeners[t]||(this.listeners[t]=[]),this.listeners[t].push(r)}}class ProcessApi extends EventEmitter{constructor(t){super(),this.childProcess=t,this.exited=!1,this.stdinData=[],t.on("stdin",r=>{this.stdinData?this.stdinData.push(r.slice()):this.emit("stdin",r)})}stdout(t){typeof t=="string"&&(t=new TextEncoder().encode(t)),this.childProcess.stdout.emit("data",t)}stderr(t){typeof t=="string"&&(t=new TextEncoder().encode(t)),this.childProcess.stderr.emit("data",t)}exit(t){this.exited||(this.exited=!0,this.childProcess.emit("exit",t))}flushStdin(){if(this.stdinData)for(let t=0;t<this.stdinData.length;t++)this.emit("stdin",this.stdinData[t]);this.stdinData=null}}let lastPid=9743;class ChildProcess extends EventEmitter{constructor(t=lastPid++){super(),this.pid=t,this.stdout=new EventEmitter,this.stderr=new EventEmitter;const r=this;this.stdin={write:s=>{r.emit("stdin",s)}}}}function concatUint8Array(...e){const t=new Uint8Array(e.reduce((s,i)=>s+i.length,0));let r=0;for(const s of e)t.set(s,r),r+=s.length;return t}function concatBytes(e){if(e===void 0){let t=new Uint8Array;return new TransformStream({transform(r){t=concatUint8Array(t,r)},flush(r){r.enqueue(t)}})}else{const t=new ArrayBuffer(e||0);let r=0;return new TransformStream({transform(s){new Uint8Array(t).set(s,r),r+=s.byteLength},flush(s){s.enqueue(new Uint8Array(t))}})}}function limitBytes(e,t){if(t===0)return new ReadableStream({start(i){i.close()}});const r=e.getReader({mode:"byob"});let s=0;return new ReadableStream({async pull(i){const{value:n,done:o}=await r.read(new Uint8Array(t-s));if(o){r.releaseLock(),i.close();return}s+=n.length,i.enqueue(n),s>=t&&(r.releaseLock(),i.close())},cancel(){r.cancel()}})}async function collectBytes(e,t){return t!==void 0&&(e=limitBytes(e,t)),await e.pipeThrough(concatBytes(t)).getReader().read().then(({value:r})=>r)}class StreamedFile extends File{constructor(t,r,s){super([],r,{type:s}),this.readableStream=t}slice(){throw new Error("slice() is not possible on a StreamedFile")}stream(){return this.readableStream}async text(){return new TextDecoder().decode(await this.arrayBuffer())}async arrayBuffer(){return await collectBytes(this.stream())}}ReadableStream.prototype[Symbol.asyncIterator]||(ReadableStream.prototype[Symbol.asyncIterator]=async function*(){const e=this.getReader();try{for(;;){const{done:t,value:r}=await e.read();if(t)return;yield r}}finally{e.releaseLock()}},ReadableStream.prototype.iterate=ReadableStream.prototype[Symbol.asyncIterator]);function streamReadFileFromPHP(e,t){return new ReadableStream({async pull(r){const s=await e.readFileAsBuffer(t);r.enqueue(s),r.close()}})}async function*iteratePhpFiles(e,t,{relativePaths:r=!0,pathPrefix:s,exceptPaths:i=[]}={}){t=normalizePath(t);const n=[t];for(;n.length;){const o=n.pop();if(!o)return;const l=await e.listFiles(o);for(const h of l){const d=`${o}/${h}`;if(i.includes(d.substring(t.length+1)))continue;await e.isDir(d)?n.push(d):yield new StreamedFile(streamReadFileFromPHP(e,d),r?joinPaths(s||"",d.substring(t.length+1)):d)}}}function writeFilesStreamToPhp(e,t){return new WritableStream({async write(r){const s=joinPaths(t,r.name);r.type==="directory"?await e.mkdir(s):(await e.mkdir(dirname(s)),await e.writeFile(s,new Uint8Array(await r.arrayBuffer())))}})}class PHPResponse{constructor(t,r,s,i="",n=0){this.httpStatusCode=t,this.headers=r,this.bytes=s,this.exitCode=n,this.errors=i}static fromRawData(t){return new PHPResponse(t.httpStatusCode,t.headers,t.bytes,t.errors,t.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 SupportedPHPVersions=["8.3","8.2","8.1","8.0","7.4","7.3","7.2","7.1","7.0"],LatestSupportedPHPVersion=SupportedPHPVersions[0],SupportedPHPVersionsList=SupportedPHPVersions,SupportedPHPExtensionsList=["iconv","mbstring","xml-bundle","gd"],SupportedPHPExtensionBundles={"kitchen-sink":SupportedPHPExtensionsList};var E,x;class PHPBrowser{constructor(t,r={}){c(this,E,void 0);c(this,x,void 0);this.requestHandler=t,u(this,E,{}),u(this,x,{handleRedirects:!1,maxRedirects:4,...r})}async request(t,r=0){const s=await this.requestHandler.request({...t,headers:{...t.headers,cookie:this.serializeCookies()}});if(s.headers["set-cookie"]&&this.setCookies(s.headers["set-cookie"]),a(this,x).handleRedirects&&s.headers.location&&r<a(this,x).maxRedirects){const i=new URL(s.headers.location[0],this.requestHandler.absoluteUrl);return this.request({url:i.toString(),method:"GET",headers:{}},r+1)}return s}pathToInternalUrl(t){return this.requestHandler.pathToInternalUrl(t)}internalUrlToPath(t){return this.requestHandler.internalUrlToPath(t)}get absoluteUrl(){return this.requestHandler.absoluteUrl}get documentRoot(){return this.requestHandler.documentRoot}setCookies(t){for(const r of t)try{if(!r.includes("="))continue;const s=r.indexOf("="),i=r.substring(0,s),n=r.substring(s+1).split(";")[0];a(this,E)[i]=n}catch(s){console.error(s)}}serializeCookies(){const t=[];for(const r in a(this,E))t.push(`${r}=${a(this,E)[r]}`);return t.join("; ")}}E=new WeakMap,x=new WeakMap;const DEFAULT_BASE_URL="http://example.com";function toRelativeUrl(e){return e.toString().substring(e.origin.length)}function removePathPrefix(e,t){return!t||!e.startsWith(t)?e:e.substring(t.length)}function ensurePathPrefix(e,t){return!t||e.startsWith(t)?e:t+e}var P,H,A,v,F,m,T,R,U,Q,N,X,M,ee;class PHPRequestHandler{constructor(t,r={}){c(this,U);c(this,N);c(this,M);c(this,P,void 0);c(this,H,void 0);c(this,A,void 0);c(this,v,void 0);c(this,F,void 0);c(this,m,void 0);c(this,T,void 0);c(this,R,void 0);u(this,R,new Semaphore({concurrency:1}));const{documentRoot:s="/www/",absoluteUrl:i=typeof location=="object"?location==null?void 0:location.href:""}=r;this.php=t,u(this,P,s);const n=new URL(i);u(this,A,n.hostname),u(this,v,n.port?Number(n.port):n.protocol==="https:"?443:80),u(this,H,(n.protocol||"").replace(":",""));const o=a(this,v)!==443&&a(this,v)!==80;u(this,F,[a(this,A),o?`:${a(this,v)}`:""].join("")),u(this,m,n.pathname.replace(/\/+$/,"")),u(this,T,[`${a(this,H)}://`,a(this,F),a(this,m)].join(""))}pathToInternalUrl(t){return`${this.absoluteUrl}${t}`}internalUrlToPath(t){const r=new URL(t);return r.pathname.startsWith(a(this,m))&&(r.pathname=r.pathname.slice(a(this,m).length)),toRelativeUrl(r)}get isRequestRunning(){return a(this,R).running>0}get absoluteUrl(){return a(this,T)}get documentRoot(){return a(this,P)}async request(t){const r=t.url.startsWith("http://")||t.url.startsWith("https://"),s=new URL(t.url,r?void 0:DEFAULT_BASE_URL),i=removePathPrefix(s.pathname,a(this,m)),n=`${a(this,P)}${i}`;return seemsLikeAPHPRequestHandlerPath(n)?await p(this,N,X).call(this,t,s):p(this,U,Q).call(this,n)}}P=new WeakMap,H=new WeakMap,A=new WeakMap,v=new WeakMap,F=new WeakMap,m=new WeakMap,T=new WeakMap,R=new WeakMap,U=new WeakSet,Q=function(t){if(!this.php.fileExists(t))return new PHPResponse(404,{"x-file-type":["static"]},new TextEncoder().encode("404 File not found"));const r=this.php.readFileAsBuffer(t);return new PHPResponse(200,{"content-length":[`${r.byteLength}`],"content-type":[inferMimeType(t)],"accept-ranges":["bytes"],"cache-control":["public, max-age=0"]},r)},N=new WeakSet,X=async function(t,r){var i,n,o;if(a(this,R).running>0&&((i=t.headers)==null?void 0:i["x-request-issuer"])==="php")return console.warn("Possible deadlock: Called request() before the previous request() have finished. PHP likely issued an HTTP call to itself. Normally this would lead to infinite waiting as Request 1 holds the lock that the Request 2 is waiting to acquire. That's not useful, so PHPRequestHandler will return error 502 instead."),new PHPResponse(502,{},new TextEncoder().encode("502 Bad Gateway"));const s=await a(this,R).acquire();try{this.php.addServerGlobalEntry("REMOTE_ADDR","127.0.0.1"),this.php.addServerGlobalEntry("DOCUMENT_ROOT",a(this,P)),this.php.addServerGlobalEntry("HTTPS",a(this,T).startsWith("https://")?"on":"");let l="GET";const h={host:a(this,F),...normalizeHeaders(t.headers||{})},d=[];if(t.files&&Object.keys(t.files).length){l="POST";for(const b in t.files){const L=t.files[b];d.push({key:b,name:L.name,type:L.type,data:new Uint8Array(await L.arrayBuffer())})}(n=h["content-type"])!=null&&n.startsWith("multipart/form-data")&&(t.formData=parseMultipartFormDataString(t.body||""),h["content-type"]="application/x-www-form-urlencoded",delete t.body)}let f;t.formData!==void 0?(l="POST",h["content-type"]=h["content-type"]||"application/x-www-form-urlencoded",f=new URLSearchParams(t.formData).toString()):f=t.body;let I;try{let b=r.pathname;if((o=t.headers)!=null&&o["x-rewrite-url"])try{b=new URL(t.headers["x-rewrite-url"]).pathname}catch{}I=p(this,M,ee).call(this,b)}catch{return new PHPResponse(404,{},new TextEncoder().encode("404 File not found"))}return await this.php.run({relativeUri:ensurePathPrefix(toRelativeUrl(r),a(this,m)),protocol:a(this,H),method:t.method||l,body:f,fileInfos:d,scriptPath:I,headers:h})}finally{s()}},M=new WeakSet,ee=function(t){let r=removePathPrefix(t,a(this,m));r.includes(".php")?r=r.split(".php")[0]+".php":(r.endsWith("/")||(r+="/"),r.endsWith("index.php")||(r+="index.php"));const s=`${a(this,P)}${r}`;if(this.php.fileExists(s))return s;throw new Error(`File not found: ${s}`)};function parseMultipartFormDataString(e){const t={},r=e.match(/--(.*)\r\n/);if(!r)return t;const s=r[1],i=e.split(`--${s}`);return i.shift(),i.pop(),i.forEach(n=>{const o=n.indexOf(`\r
35
+ `).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(t))}catch{return[]}}class Semaphore{constructor({concurrency:t}){this._running=0,this.concurrency=t,this.queue=[]}get running(){return this._running}async acquire(){for(;;)if(this._running>=this.concurrency)await new Promise(t=>this.queue.push(t));else{this._running++;let t=!1;return()=>{t||(t=!0,this._running--,this.queue.length>0&&this.queue.shift()())}}}async run(t){const r=await this.acquire();try{return await t()}finally{r()}}}function joinPaths(...e){let t=e.join("/");const r=t[0]==="/",s=t.substring(t.length-1)==="/";return t=normalizePath(t),!t&&!r&&(t="."),t&&s&&(t+="/"),t}function dirname(e){if(e==="/")return"/";e=normalizePath(e);const t=e.lastIndexOf("/");return t===-1?"":t===0?"/":e.substr(0,t)}function normalizePath(e){const t=e[0]==="/";return e=normalizePathsArray(e.split("/").filter(r=>!!r),!t).join("/"),(t?"/":"")+e.replace(/\/$/,"")}function normalizePathsArray(e,t){let r=0;for(let s=e.length-1;s>=0;s--){const n=e[s];n==="."?e.splice(s,1):n===".."?(e.splice(s,1),r++):r&&(e.splice(s,1),r--)}if(t)for(;r;r--)e.unshift("..");return e}function createSpawnHandler(e){return function(t){const r=new ChildProcess,s=new ProcessApi(r);return setTimeout(async()=>{await e(t,s),r.emit("spawn",!0)}),r}}class EventEmitter{constructor(){this.listeners={}}emit(t,r){this.listeners[t]&&this.listeners[t].forEach(function(s){s(r)})}on(t,r){this.listeners[t]||(this.listeners[t]=[]),this.listeners[t].push(r)}}class ProcessApi extends EventEmitter{constructor(t){super(),this.childProcess=t,this.exited=!1,this.stdinData=[],t.on("stdin",r=>{this.stdinData?this.stdinData.push(r.slice()):this.emit("stdin",r)})}stdout(t){typeof t=="string"&&(t=new TextEncoder().encode(t)),this.childProcess.stdout.emit("data",t)}stderr(t){typeof t=="string"&&(t=new TextEncoder().encode(t)),this.childProcess.stderr.emit("data",t)}exit(t){this.exited||(this.exited=!0,this.childProcess.emit("exit",t))}flushStdin(){if(this.stdinData)for(let t=0;t<this.stdinData.length;t++)this.emit("stdin",this.stdinData[t]);this.stdinData=null}}let lastPid=9743;class ChildProcess extends EventEmitter{constructor(t=lastPid++){super(),this.pid=t,this.stdout=new EventEmitter,this.stderr=new EventEmitter;const r=this;this.stdin={write:s=>{r.emit("stdin",s)}}}}function concatUint8Array(...e){const t=new Uint8Array(e.reduce((s,n)=>s+n.length,0));let r=0;for(const s of e)t.set(s,r),r+=s.length;return t}function concatBytes(e){if(e===void 0){let t=new Uint8Array;return new TransformStream({transform(r){t=concatUint8Array(t,r)},flush(r){r.enqueue(t)}})}else{const t=new ArrayBuffer(e||0);let r=0;return new TransformStream({transform(s){new Uint8Array(t).set(s,r),r+=s.byteLength},flush(s){s.enqueue(new Uint8Array(t))}})}}function limitBytes(e,t){if(t===0)return new ReadableStream({start(n){n.close()}});const r=e.getReader({mode:"byob"});let s=0;return new ReadableStream({async pull(n){const{value:i,done:o}=await r.read(new Uint8Array(t-s));if(o){r.releaseLock(),n.close();return}s+=i.length,n.enqueue(i),s>=t&&(r.releaseLock(),n.close())},cancel(){r.cancel()}})}async function collectBytes(e,t){return t!==void 0&&(e=limitBytes(e,t)),await e.pipeThrough(concatBytes(t)).getReader().read().then(({value:r})=>r)}class StreamedFile extends File{constructor(t,r,s){super([],r,{type:s}),this.readableStream=t}slice(){throw new Error("slice() is not possible on a StreamedFile")}stream(){return this.readableStream}async text(){return new TextDecoder().decode(await this.arrayBuffer())}async arrayBuffer(){return await collectBytes(this.stream())}}ReadableStream.prototype[Symbol.asyncIterator]||(ReadableStream.prototype[Symbol.asyncIterator]=async function*(){const e=this.getReader();try{for(;;){const{done:t,value:r}=await e.read();if(t)return;yield r}}finally{e.releaseLock()}},ReadableStream.prototype.iterate=ReadableStream.prototype[Symbol.asyncIterator]);function streamReadFileFromPHP(e,t){return new ReadableStream({async pull(r){const s=await e.readFileAsBuffer(t);r.enqueue(s),r.close()}})}async function*iteratePhpFiles(e,t,{relativePaths:r=!0,pathPrefix:s,exceptPaths:n=[]}={}){t=normalizePath(t);const i=[t];for(;i.length;){const o=i.pop();if(!o)return;const l=await e.listFiles(o);for(const d of l){const u=`${o}/${d}`;if(n.includes(u.substring(t.length+1)))continue;await e.isDir(u)?i.push(u):yield new StreamedFile(streamReadFileFromPHP(e,u),r?joinPaths(s||"",u.substring(t.length+1)):u)}}}function writeFilesStreamToPhp(e,t){return new WritableStream({async write(r){const s=joinPaths(t,r.name);r.type==="directory"?await e.mkdir(s):(await e.mkdir(dirname(s)),await e.writeFile(s,new Uint8Array(await r.arrayBuffer())))}})}class PHPResponse{constructor(t,r,s,n="",i=0){this.httpStatusCode=t,this.headers=r,this.bytes=s,this.exitCode=i,this.errors=n}static fromRawData(t){return new PHPResponse(t.httpStatusCode,t.headers,t.bytes,t.errors,t.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 SupportedPHPVersions=["8.3","8.2","8.1","8.0","7.4","7.3","7.2","7.1","7.0"],LatestSupportedPHPVersion=SupportedPHPVersions[0],SupportedPHPVersionsList=SupportedPHPVersions,SupportedPHPExtensionsList=["iconv","mbstring","xml-bundle","gd"],SupportedPHPExtensionBundles={"kitchen-sink":SupportedPHPExtensionsList};var E,S;class PHPBrowser{constructor(t,r={}){c(this,E,void 0);c(this,S,void 0);this.requestHandler=t,h(this,E,{}),h(this,S,{handleRedirects:!1,maxRedirects:4,...r})}async request(t,r=0){const s=await this.requestHandler.request({...t,headers:{...t.headers,cookie:this.serializeCookies()}});if(s.headers["set-cookie"]&&this.setCookies(s.headers["set-cookie"]),a(this,S).handleRedirects&&s.headers.location&&r<a(this,S).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(t){return this.requestHandler.pathToInternalUrl(t)}internalUrlToPath(t){return this.requestHandler.internalUrlToPath(t)}get absoluteUrl(){return this.requestHandler.absoluteUrl}get documentRoot(){return this.requestHandler.documentRoot}setCookies(t){for(const r of t)try{if(!r.includes("="))continue;const s=r.indexOf("="),n=r.substring(0,s),i=r.substring(s+1).split(";")[0];a(this,E)[n]=i}catch(s){console.error(s)}}serializeCookies(){const t=[];for(const r in a(this,E))t.push(`${r}=${a(this,E)[r]}`);return t.join("; ")}}E=new WeakMap,S=new WeakMap;const DEFAULT_BASE_URL="http://example.com";function toRelativeUrl(e){return e.toString().substring(e.origin.length)}function removePathPrefix(e,t){return!t||!e.startsWith(t)?e:e.substring(t.length)}function ensurePathPrefix(e,t){return!t||e.startsWith(t)?e:t+e}async function encodeAsMultipart(e){const t=`----${Math.random().toString(36).slice(2)}`,r=`multipart/form-data; boundary=${t}`,s=new TextEncoder,n=[];for(const[d,u]of Object.entries(e))n.push(`--${t}\r
36
+ `),n.push(`Content-Disposition: form-data; name="${d}"`),u instanceof File&&n.push(`; filename="${u.name}"`),n.push(`\r
37
+ `),u instanceof File&&n.push("Content-Type: application/octet-stream"),n.push(`\r
36
38
  \r
37
- `),l=n.substring(0,o).trim(),h=n.substring(o+4).trim(),d=l.match(/name="([^"]+)"/);if(d){const f=d[1];t[f]=h}}),t}function inferMimeType(e){switch(e.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"}}function seemsLikeAPHPRequestHandlerPath(e){return seemsLikeAPHPFile(e)||seemsLikeADirectoryRoot(e)}function seemsLikeAPHPFile(e){return e.endsWith(".php")||e.includes(".php/")}function seemsLikeADirectoryRoot(e){return!e.split("/").pop().includes(".")}const FileErrorCodes={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 getEmscriptenFsError(e){const t=typeof e=="object"?e==null?void 0:e.errno:null;if(t in FileErrorCodes)return FileErrorCodes[t]}function rethrowFileSystemError(e=""){return function(r,s,i){const n=i.value;i.value=function(...o){try{return n.apply(this,o)}catch(l){const h=typeof l=="object"?l==null?void 0:l.errno:null;if(h in FileErrorCodes){const d=FileErrorCodes[h],f=typeof o[0]=="string"?o[0]:null,I=f!==null?e.replaceAll("{path}",f):e;throw new Error(`${I}: ${d}`,{cause:l})}throw l}}}}const RuntimeId=Symbol("RuntimeId"),loadedRuntimes=new Map;let lastRuntimeId=0;async function loadPHPRuntime(e,t={}){const[r,s,i]=makePromise(),n=e.init(currentJsRuntime,{onAbort(l){i(l),console.error(l)},ENV:{},locateFile:l=>l,...t,noInitialRun:!0,onRuntimeInitialized(){t.onRuntimeInitialized&&t.onRuntimeInitialized(),s()}});await r;const o=++lastRuntimeId;return n.id=o,n.originalExit=n._exit,n._exit=function(l){return loadedRuntimes.delete(o),n.originalExit(l)},n[RuntimeId]=o,loadedRuntimes.set(o,n),o}function getLoadedRuntime(e){return loadedRuntimes.get(e)}const currentJsRuntime=function(){var e;return typeof process<"u"&&((e=process.release)==null?void 0:e.name)==="node"?"NODE":typeof window<"u"?"WEB":typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope?"WORKER":"NODE"}(),makePromise=()=>{const e=[],t=new Promise((r,s)=>{e.push(r,s)});return e.unshift(t),e};var __defProp=Object.defineProperty,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__decorateClass=(e,t,r,s)=>{for(var i=s>1?void 0:s?__getOwnPropDesc(t,r):t,n=e.length-1,o;n>=0;n--)(o=e[n])&&(i=(s?o(t,r,i):o(i))||i);return s&&i&&__defProp(t,r,i),i};const STRING="string",NUMBER="number",__private__dont__use=Symbol("__private__dont__use");var S,C,k,_,w,g,y,B,q,te,O,re,D,se,$,ne,j,ie,z,oe,G,ae,W,le,V,ce,J,ue,Y,de,Z,he;class BasePHP{constructor(e,t){c(this,q);c(this,O);c(this,D);c(this,$);c(this,j);c(this,z);c(this,G);c(this,W);c(this,V);c(this,J);c(this,Y);c(this,Z);c(this,S,void 0);c(this,C,void 0);c(this,k,void 0);c(this,_,void 0);c(this,w,void 0);c(this,g,void 0);c(this,y,void 0);c(this,B,void 0);u(this,S,[]),u(this,_,!1),u(this,w,null),u(this,g,{}),u(this,y,new Map),u(this,B,[]),this.semaphore=new Semaphore({concurrency:1}),e!==void 0&&this.initializeRuntime(e),t&&(this.requestHandler=new PHPBrowser(new PHPRequestHandler(this,t)))}addEventListener(e,t){a(this,y).has(e)||a(this,y).set(e,new Set),a(this,y).get(e).add(t)}removeEventListener(e,t){var r;(r=a(this,y).get(e))==null||r.delete(t)}dispatchEvent(e){const t=a(this,y).get(e.type);if(t)for(const r of t)r(e)}async onMessage(e){a(this,B).push(e)}async setSpawnHandler(handler){typeof handler=="string"&&(handler=createSpawnHandler(eval(handler))),this[__private__dont__use].spawnProcess=handler}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[__private__dont__use])throw new Error("PHP runtime already initialized.");const t=getLoadedRuntime(e);if(!t)throw new Error("Invalid PHP runtime id.");this[__private__dont__use]=t,t.onMessage=async r=>{for(const s of a(this,B)){const i=await s(r);if(i)return i}return""},u(this,w,improveWASMErrorReporting(t)),this.dispatchEvent({type:"runtime.initialized"})}async setSapiName(e){if(this[__private__dont__use].ccall("wasm_set_sapi_name",NUMBER,[STRING],[e])!==0)throw new Error("Could not set SAPI name. This can only be done before the PHP WASM module is initialized.Did you already dispatch any requests?");u(this,k,e)}setPhpIniPath(e){if(a(this,_))throw new Error("Cannot set PHP ini path after calling run().");u(this,C,e),this[__private__dont__use].ccall("wasm_set_phpini_path",null,["string"],[e])}setPhpIniEntry(e,t){if(a(this,_))throw new Error("Cannot set PHP ini entries after calling run().");a(this,S).push([e,t])}chdir(e){this[__private__dont__use].FS.chdir(e)}async request(e,t){if(!this.requestHandler)throw new Error("No request handler available.");return this.requestHandler.request(e,t)}async run(e){const t=await this.semaphore.acquire();let r;try{a(this,_)||(p(this,q,te).call(this),u(this,_,!0)),p(this,W,le).call(this,e.scriptPath||""),p(this,D,se).call(this,e.relativeUri||""),p(this,j,ie).call(this,e.method||"GET");const s=normalizeHeaders(e.headers||{}),i=s.host||"example.com:443";if(p(this,$,ne).call(this,i,e.protocol||"http"),p(this,z,oe).call(this,s),e.body&&(r=p(this,G,ae).call(this,e.body)),e.fileInfos)for(const o of e.fileInfos)p(this,J,ue).call(this,o);typeof e.code=="string"&&p(this,Y,de).call(this," ?>"+e.code),p(this,V,ce).call(this);const n=await p(this,Z,he).call(this);if(e.throwOnError&&n.exitCode!==0){const o={stdout:n.text,stderr:n.errors};console.warn("PHP.run() output was:",o);const l=new Error(`PHP.run() failed with exit code ${n.exitCode} and the following output`);throw l.output=o,l}return n}finally{try{r&&this[__private__dont__use].free(r)}finally{t(),this.dispatchEvent({type:"request.end"})}}}addServerGlobalEntry(e,t){a(this,g)[e]=t}defineConstant(e,t){let r={};try{r=JSON.parse(this.fileExists("/tmp/consts.json")&&this.readFileAsText("/tmp/consts.json")||"{}")}catch{}this.writeFile("/tmp/consts.json",JSON.stringify({...r,[e]:t}))}mkdir(e){this[__private__dont__use].FS.mkdirTree(e)}mkdirTree(e){this.mkdir(e)}readFileAsText(e){return new TextDecoder().decode(this.readFileAsBuffer(e))}readFileAsBuffer(e){return this[__private__dont__use].FS.readFile(e)}writeFile(e,t){this[__private__dont__use].FS.writeFile(e,t)}unlink(e){this[__private__dont__use].FS.unlink(e)}mv(e,t){try{this[__private__dont__use].FS.rename(e,t)}catch(r){const s=getEmscriptenFsError(r);throw s?new Error(`Could not move ${e} to ${t}: ${s}`,{cause:r}):r}}rmdir(e,t={recursive:!0}){t!=null&&t.recursive&&this.listFiles(e).forEach(r=>{const s=`${e}/${r}`;this.isDir(s)?this.rmdir(s,t):this.unlink(s)}),this[__private__dont__use].FS.rmdir(e)}listFiles(e,t={prependPath:!1}){if(!this.fileExists(e))return[];try{const r=this[__private__dont__use].FS.readdir(e).filter(s=>s!=="."&&s!=="..");if(t.prependPath){const s=e.replace(/\/$/,"");return r.map(i=>`${s}/${i}`)}return r}catch(r){return console.error(r,{path:e}),[]}}isDir(e){return this.fileExists(e)?this[__private__dont__use].FS.isDir(this[__private__dont__use].FS.lookupPath(e).node.mode):!1}fileExists(e){try{return this[__private__dont__use].FS.lookupPath(e),!0}catch{return!1}}hotSwapPHPRuntime(e){const t=this[__private__dont__use].FS;try{this.exit()}catch{}if(this.initializeRuntime(e),a(this,C)&&this.setPhpIniPath(a(this,C)),a(this,k)&&this.setSapiName(a(this,k)),this.requestHandler){const r=this.documentRoot;recreateMemFS(this[__private__dont__use].FS,t,r)}}exit(e=0){this.dispatchEvent({type:"runtime.beforedestroy"});try{this[__private__dont__use]._exit(e)}catch{}u(this,_,!1),u(this,w,null),delete this[__private__dont__use].onMessage,delete this[__private__dont__use]}}S=new WeakMap,C=new WeakMap,k=new WeakMap,_=new WeakMap,w=new WeakMap,g=new WeakMap,y=new WeakMap,B=new WeakMap,q=new WeakSet,te=function(){if(this.setPhpIniEntry("auto_prepend_file","/tmp/consts.php"),this.fileExists("/tmp/consts.php")||this.writeFile("/tmp/consts.php",`<?php
39
+ `),u instanceof File?n.push(await fileToUint8Array(u)):n.push(u),n.push(`\r
40
+ `);n.push(`--${t}--\r
41
+ `);const i=n.reduce((d,u)=>d+u.length,0),o=new Uint8Array(i);let l=0;for(const d of n)o.set(typeof d=="string"?s.encode(d):d,l),l+=d.length;return{bytes:o,contentType:r}}function fileToUint8Array(e){return new Promise(t=>{const r=new FileReader;r.onload=()=>{t(new Uint8Array(r.result))},r.readAsArrayBuffer(e)})}var P,x,k,v,H,_,F,R,L,Y,U,Z,I,K;class PHPRequestHandler{constructor(t,r={}){c(this,L);c(this,U);c(this,I);c(this,P,void 0);c(this,x,void 0);c(this,k,void 0);c(this,v,void 0);c(this,H,void 0);c(this,_,void 0);c(this,F,void 0);c(this,R,void 0);h(this,R,new Semaphore({concurrency:1}));const{documentRoot:s="/www/",absoluteUrl:n=typeof location=="object"?location==null?void 0:location.href:""}=r;this.php=t,h(this,P,s);const i=new URL(n);h(this,k,i.hostname),h(this,v,i.port?Number(i.port):i.protocol==="https:"?443:80),h(this,x,(i.protocol||"").replace(":",""));const o=a(this,v)!==443&&a(this,v)!==80;h(this,H,[a(this,k),o?`:${a(this,v)}`:""].join("")),h(this,_,i.pathname.replace(/\/+$/,"")),h(this,F,[`${a(this,x)}://`,a(this,H),a(this,_)].join(""))}pathToInternalUrl(t){return`${this.absoluteUrl}${t}`}internalUrlToPath(t){const r=new URL(t);return r.pathname.startsWith(a(this,_))&&(r.pathname=r.pathname.slice(a(this,_).length)),toRelativeUrl(r)}get isRequestRunning(){return a(this,R).running>0}get absoluteUrl(){return a(this,F)}get documentRoot(){return a(this,P)}async request(t){const r=t.url.startsWith("http://")||t.url.startsWith("https://"),s=new URL(t.url,r?void 0:DEFAULT_BASE_URL),n=removePathPrefix(s.pathname,a(this,_)),i=`${a(this,P)}${n}`;return seemsLikeAPHPRequestHandlerPath(i)?await p(this,U,Z).call(this,t,s):p(this,L,Y).call(this,i)}}P=new WeakMap,x=new WeakMap,k=new WeakMap,v=new WeakMap,H=new WeakMap,_=new WeakMap,F=new WeakMap,R=new WeakMap,L=new WeakSet,Y=function(t){if(!this.php.fileExists(t))return new PHPResponse(404,{"x-file-type":["static"]},new TextEncoder().encode("404 File not found"));const r=this.php.readFileAsBuffer(t);return new PHPResponse(200,{"content-length":[`${r.byteLength}`],"content-type":[inferMimeType(t)],"accept-ranges":["bytes"],"cache-control":["public, max-age=0"]},r)},U=new WeakSet,Z=async function(t,r){var n,i;if(a(this,R).running>0&&((n=t.headers)==null?void 0:n["x-request-issuer"])==="php")return console.warn("Possible deadlock: Called request() before the previous request() have finished. PHP likely issued an HTTP call to itself. Normally this would lead to infinite waiting as Request 1 holds the lock that the Request 2 is waiting to acquire. That's not useful, so PHPRequestHandler will return error 502 instead."),new PHPResponse(502,{},new TextEncoder().encode("502 Bad Gateway"));const s=await a(this,R).acquire();try{this.php.addServerGlobalEntry("REMOTE_ADDR","127.0.0.1"),this.php.addServerGlobalEntry("DOCUMENT_ROOT",a(this,P)),this.php.addServerGlobalEntry("HTTPS",a(this,F).startsWith("https://")?"on":"");let o="GET";const l={host:a(this,H),...normalizeHeaders(t.headers||{})};let d=t.body;if(typeof d=="object"&&!(d instanceof Uint8Array)){o="POST";const{bytes:f,contentType:B}=await encodeAsMultipart(d);d=f,l["content-type"]=B}let u;try{let f=r.pathname;if((i=t.headers)!=null&&i["x-rewrite-url"])try{f=new URL(t.headers["x-rewrite-url"]).pathname}catch{}u=p(this,I,K).call(this,f)}catch{return new PHPResponse(404,{},new TextEncoder().encode("404 File not found"))}return await this.php.run({relativeUri:ensurePathPrefix(toRelativeUrl(r),a(this,_)),protocol:a(this,x),method:t.method||o,body:d,scriptPath:u,headers:l})}finally{s()}},I=new WeakSet,K=function(t){let r=removePathPrefix(t,a(this,_));r.includes(".php")?r=r.split(".php")[0]+".php":(r.endsWith("/")||(r+="/"),r.endsWith("index.php")||(r+="index.php"));const s=`${a(this,P)}${r}`;if(this.php.fileExists(s))return s;throw new Error(`File not found: ${s}`)};function inferMimeType(e){switch(e.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"}}function seemsLikeAPHPRequestHandlerPath(e){return seemsLikeAPHPFile(e)||seemsLikeADirectoryRoot(e)}function seemsLikeAPHPFile(e){return e.endsWith(".php")||e.includes(".php/")}function seemsLikeADirectoryRoot(e){return!e.split("/").pop().includes(".")}const FileErrorCodes={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 getEmscriptenFsError(e){const t=typeof e=="object"?e==null?void 0:e.errno:null;if(t in FileErrorCodes)return FileErrorCodes[t]}function rethrowFileSystemError(e=""){return function(r,s,n){const i=n.value;n.value=function(...o){try{return i.apply(this,o)}catch(l){const d=typeof l=="object"?l==null?void 0:l.errno:null;if(d in FileErrorCodes){const u=FileErrorCodes[d],f=typeof o[0]=="string"?o[0]:null,B=f!==null?e.replaceAll("{path}",f):e;throw new Error(`${B}: ${u}`,{cause:l})}throw l}}}}const RuntimeId=Symbol("RuntimeId"),loadedRuntimes=new Map;let lastRuntimeId=0;async function loadPHPRuntime(e,t={}){const[r,s,n]=makePromise(),i=e.init(currentJsRuntime,{onAbort(l){n(l),console.error(l)},ENV:{},locateFile:l=>l,...t,noInitialRun:!0,onRuntimeInitialized(){t.onRuntimeInitialized&&t.onRuntimeInitialized(),s()}});await r;const o=++lastRuntimeId;return i.id=o,i.originalExit=i._exit,i._exit=function(l){return loadedRuntimes.delete(o),i.originalExit(l)},i[RuntimeId]=o,loadedRuntimes.set(o,i),o}function getLoadedRuntime(e){return loadedRuntimes.get(e)}const currentJsRuntime=function(){var e;return typeof process<"u"&&((e=process.release)==null?void 0:e.name)==="node"?"NODE":typeof window<"u"?"WEB":typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope?"WORKER":"NODE"}(),makePromise=()=>{const e=[],t=new Promise((r,s)=>{e.push(r,s)});return e.unshift(t),e};var __defProp=Object.defineProperty,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__decorateClass=(e,t,r,s)=>{for(var n=s>1?void 0:s?__getOwnPropDesc(t,r):t,i=e.length-1,o;i>=0;i--)(o=e[i])&&(n=(s?o(t,r,n):o(n))||n);return s&&n&&__defProp(t,r,n),n};const STRING="string",NUMBER="number",__private__dont__use=Symbol("__private__dont__use");var b,T,A,m,w,g,y,C,q,Q,N,X,M,ee,$,te,O,re,D,se,j,ne,z,ie,W,oe,G,ae,V,le;class BasePHP{constructor(e,t){c(this,q);c(this,N);c(this,M);c(this,$);c(this,O);c(this,D);c(this,j);c(this,z);c(this,W);c(this,G);c(this,V);c(this,b,void 0);c(this,T,void 0);c(this,A,void 0);c(this,m,void 0);c(this,w,void 0);c(this,g,void 0);c(this,y,void 0);c(this,C,void 0);h(this,b,[]),h(this,m,!1),h(this,w,null),h(this,g,{}),h(this,y,new Map),h(this,C,[]),this.semaphore=new Semaphore({concurrency:1}),e!==void 0&&this.initializeRuntime(e),t&&(this.requestHandler=new PHPBrowser(new PHPRequestHandler(this,t)))}addEventListener(e,t){a(this,y).has(e)||a(this,y).set(e,new Set),a(this,y).get(e).add(t)}removeEventListener(e,t){var r;(r=a(this,y).get(e))==null||r.delete(t)}dispatchEvent(e){const t=a(this,y).get(e.type);if(t)for(const r of t)r(e)}async onMessage(e){a(this,C).push(e)}async setSpawnHandler(handler){typeof handler=="string"&&(handler=createSpawnHandler(eval(handler))),this[__private__dont__use].spawnProcess=handler}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[__private__dont__use])throw new Error("PHP runtime already initialized.");const t=getLoadedRuntime(e);if(!t)throw new Error("Invalid PHP runtime id.");this[__private__dont__use]=t,t.onMessage=async r=>{for(const s of a(this,C)){const n=await s(r);if(n)return n}return""},h(this,w,improveWASMErrorReporting(t)),this.dispatchEvent({type:"runtime.initialized"})}async setSapiName(e){if(this[__private__dont__use].ccall("wasm_set_sapi_name",NUMBER,[STRING],[e])!==0)throw new Error("Could not set SAPI name. This can only be done before the PHP WASM module is initialized.Did you already dispatch any requests?");h(this,A,e)}setPhpIniPath(e){if(a(this,m))throw new Error("Cannot set PHP ini path after calling run().");h(this,T,e),this[__private__dont__use].ccall("wasm_set_phpini_path",null,["string"],[e])}setPhpIniEntry(e,t){if(a(this,m))throw new Error("Cannot set PHP ini entries after calling run().");a(this,b).push([e,t])}chdir(e){this[__private__dont__use].FS.chdir(e)}async request(e,t){if(!this.requestHandler)throw new Error("No request handler available.");return this.requestHandler.request(e,t)}async run(e){const t=await this.semaphore.acquire();let r;try{a(this,m)||(p(this,q,Q).call(this),h(this,m,!0)),p(this,z,ie).call(this,e.scriptPath||""),p(this,M,ee).call(this,e.relativeUri||""),p(this,O,re).call(this,e.method||"GET");const s=normalizeHeaders(e.headers||{}),n=s.host||"example.com:443";p(this,$,te).call(this,n,e.protocol||"http"),p(this,D,se).call(this,s),e.body&&(r=p(this,j,ne).call(this,e.body)),typeof e.code=="string"&&p(this,G,ae).call(this," ?>"+e.code),p(this,W,oe).call(this);const i=await p(this,V,le).call(this);if(e.throwOnError&&i.exitCode!==0){const o={stdout:i.text,stderr:i.errors};console.warn("PHP.run() output was:",o);const l=new Error(`PHP.run() failed with exit code ${i.exitCode} and the following output`);throw l.output=o,l}return i}finally{try{r&&this[__private__dont__use].free(r)}finally{t(),this.dispatchEvent({type:"request.end"})}}}addServerGlobalEntry(e,t){a(this,g)[e]=t}defineConstant(e,t){let r={};try{r=JSON.parse(this.fileExists("/tmp/consts.json")&&this.readFileAsText("/tmp/consts.json")||"{}")}catch{}this.writeFile("/tmp/consts.json",JSON.stringify({...r,[e]:t}))}mkdir(e){this[__private__dont__use].FS.mkdirTree(e)}mkdirTree(e){this.mkdir(e)}readFileAsText(e){return new TextDecoder().decode(this.readFileAsBuffer(e))}readFileAsBuffer(e){return this[__private__dont__use].FS.readFile(e)}writeFile(e,t){this[__private__dont__use].FS.writeFile(e,t)}unlink(e){this[__private__dont__use].FS.unlink(e)}mv(e,t){try{this[__private__dont__use].FS.rename(e,t)}catch(r){const s=getEmscriptenFsError(r);throw s?new Error(`Could not move ${e} to ${t}: ${s}`,{cause:r}):r}}rmdir(e,t={recursive:!0}){t!=null&&t.recursive&&this.listFiles(e).forEach(r=>{const s=`${e}/${r}`;this.isDir(s)?this.rmdir(s,t):this.unlink(s)}),this[__private__dont__use].FS.rmdir(e)}listFiles(e,t={prependPath:!1}){if(!this.fileExists(e))return[];try{const r=this[__private__dont__use].FS.readdir(e).filter(s=>s!=="."&&s!=="..");if(t.prependPath){const s=e.replace(/\/$/,"");return r.map(n=>`${s}/${n}`)}return r}catch(r){return console.error(r,{path:e}),[]}}isDir(e){return this.fileExists(e)?this[__private__dont__use].FS.isDir(this[__private__dont__use].FS.lookupPath(e).node.mode):!1}fileExists(e){try{return this[__private__dont__use].FS.lookupPath(e),!0}catch{return!1}}hotSwapPHPRuntime(e){const t=this[__private__dont__use].FS;try{this.exit()}catch{}if(this.initializeRuntime(e),a(this,T)&&this.setPhpIniPath(a(this,T)),a(this,A)&&this.setSapiName(a(this,A)),this.requestHandler){const r=this.documentRoot;recreateMemFS(this[__private__dont__use].FS,t,r)}}exit(e=0){this.dispatchEvent({type:"runtime.beforedestroy"});try{this[__private__dont__use]._exit(e)}catch{}h(this,m,!1),h(this,w,null),delete this[__private__dont__use].onMessage,delete this[__private__dont__use]}}b=new WeakMap,T=new WeakMap,A=new WeakMap,m=new WeakMap,w=new WeakMap,g=new WeakMap,y=new WeakMap,C=new WeakMap,q=new WeakSet,Q=function(){if(this.setPhpIniEntry("auto_prepend_file","/tmp/consts.php"),this.fileExists("/tmp/consts.php")||this.writeFile("/tmp/consts.php",`<?php
38
42
  if(file_exists('/tmp/consts.json')) {
39
43
  $consts = json_decode(file_get_contents('/tmp/consts.json'), true);
40
44
  foreach ($consts as $const => $value) {
@@ -42,7 +46,7 @@ ${bold} WASM ERROR${reset}${redBg}`);for(const t of e.split(`
42
46
  define($const, $value);
43
47
  }
44
48
  }
45
- }`),a(this,S).length>0){const e=a(this,S).map(([t,r])=>`${t}=${r}`).join(`
49
+ }`),a(this,b).length>0){const e=a(this,b).map(([t,r])=>`${t}=${r}`).join(`
46
50
  `)+`
47
51
 
48
- `;this[__private__dont__use].ccall("wasm_set_phpini_entries",null,[STRING],[e])}this[__private__dont__use].ccall("php_wasm_init",null,[],[])},O=new WeakSet,re=function(){const e="/tmp/headers.json";if(!this.fileExists(e))throw new Error("SAPI Error: Could not find response headers file.");const t=JSON.parse(this.readFileAsText(e)),r={};for(const s of t.headers){if(!s.includes(": "))continue;const i=s.indexOf(": "),n=s.substring(0,i).toLowerCase(),o=s.substring(i+2);n in r||(r[n]=[]),r[n].push(o)}return{headers:r,httpStatusCode:t.status}},D=new WeakSet,se=function(e){if(this[__private__dont__use].ccall("wasm_set_request_uri",null,[STRING],[e]),e.includes("?")){const t=e.substring(e.indexOf("?")+1);this[__private__dont__use].ccall("wasm_set_query_string",null,[STRING],[t])}},$=new WeakSet,ne=function(e,t){this[__private__dont__use].ccall("wasm_set_request_host",null,[STRING],[e]);let r;try{r=parseInt(new URL(e).port,10)}catch{}(!r||isNaN(r)||r===80)&&(r=t==="https"?443:80),this[__private__dont__use].ccall("wasm_set_request_port",null,[NUMBER],[r]),(t==="https"||!t&&r===443)&&this.addServerGlobalEntry("HTTPS","on")},j=new WeakSet,ie=function(e){this[__private__dont__use].ccall("wasm_set_request_method",null,[STRING],[e])},z=new WeakSet,oe=function(e){e.cookie&&this[__private__dont__use].ccall("wasm_set_cookies",null,[STRING],[e.cookie]),e["content-type"]&&this[__private__dont__use].ccall("wasm_set_content_type",null,[STRING],[e["content-type"]]),e["content-length"]&&this[__private__dont__use].ccall("wasm_set_content_length",null,[NUMBER],[parseInt(e["content-length"],10)]);for(const t in e){let r="HTTP_";["content-type","content-length"].includes(t.toLowerCase())&&(r=""),this.addServerGlobalEntry(`${r}${t.toUpperCase().replace(/-/g,"_")}`,e[t])}},G=new WeakSet,ae=function(e){const t=this[__private__dont__use].lengthBytesUTF8(e),r=this[__private__dont__use].malloc(t+1);if(!r)throw new Error("Could not allocate memory for the request body.");return this[__private__dont__use].stringToUTF8(e,r,t+1),this[__private__dont__use].ccall("wasm_set_request_body",null,[NUMBER],[r]),this[__private__dont__use].ccall("wasm_set_content_length",null,[NUMBER],[new TextEncoder().encode(e).length]),r},W=new WeakSet,le=function(e){this[__private__dont__use].ccall("wasm_set_path_translated",null,[STRING],[e])},V=new WeakSet,ce=function(){for(const e in a(this,g))this[__private__dont__use].ccall("wasm_add_SERVER_entry",null,[STRING,STRING],[e,a(this,g)[e]])},J=new WeakSet,ue=function(e){const{key:t,name:r,type:s,data:i}=e,n=`/tmp/${Math.random().toFixed(20)}`;this.writeFile(n,i);const o=0;this[__private__dont__use].ccall("wasm_add_uploaded_file",null,[STRING,STRING,STRING,STRING,NUMBER,NUMBER],[t,r,s,n,o,i.byteLength])},Y=new WeakSet,de=function(e){this[__private__dont__use].ccall("wasm_set_php_code",null,[STRING],[e])},Z=new WeakSet,he=async function(){var i;let e,t;try{e=await new Promise((n,o)=>{var h;t=d=>{const f=new Error("Rethrown");f.cause=d.error,f.betterMessage=d.message,o(f)},(h=a(this,w))==null||h.addEventListener("error",t);const l=this[__private__dont__use].ccall("wasm_sapi_handle_request",NUMBER,[],[],{async:!0});return l instanceof Promise?l.then(n,o):n(l)})}catch(n){for(const d in this)typeof this[d]=="function"&&(this[d]=()=>{throw new Error("PHP runtime has crashed – see the earlier error for details.")});this.functionsMaybeMissingFromAsyncify=getFunctionsMaybeMissingFromAsyncify();const o=n,l="betterMessage"in o?o.betterMessage:o.message,h=new Error(l);throw h.cause=o,h}finally{(i=a(this,w))==null||i.removeEventListener("error",t),u(this,g,{})}const{headers:r,httpStatusCode:s}=p(this,O,re).call(this);return new PHPResponse(s,r,this.readFileAsBuffer("/tmp/stdout"),this.readFileAsText("/tmp/stderr"),e)};__decorateClass([rethrowFileSystemError('Could not create directory "{path}"')],BasePHP.prototype,"mkdir",1);__decorateClass([rethrowFileSystemError('Could not create directory "{path}"')],BasePHP.prototype,"mkdirTree",1);__decorateClass([rethrowFileSystemError('Could not read "{path}"')],BasePHP.prototype,"readFileAsText",1);__decorateClass([rethrowFileSystemError('Could not read "{path}"')],BasePHP.prototype,"readFileAsBuffer",1);__decorateClass([rethrowFileSystemError('Could not write to "{path}"')],BasePHP.prototype,"writeFile",1);__decorateClass([rethrowFileSystemError('Could not unlink "{path}"')],BasePHP.prototype,"unlink",1);__decorateClass([rethrowFileSystemError('Could not remove directory "{path}"')],BasePHP.prototype,"rmdir",1);__decorateClass([rethrowFileSystemError('Could not list files in "{path}"')],BasePHP.prototype,"listFiles",1);__decorateClass([rethrowFileSystemError('Could not stat "{path}"')],BasePHP.prototype,"isDir",1);__decorateClass([rethrowFileSystemError('Could not stat "{path}"')],BasePHP.prototype,"fileExists",1);function normalizeHeaders(e){const t={};for(const r in e)t[r.toLowerCase()]=e[r];return t}function recreateMemFS(e,t,r){let s;try{s=t.lookupPath(r)}catch{return}if(!("contents"in s.node))return;try{e=e.lookupPath(r);return}catch{}if(!t.isDir(s.node.mode)){e.writeFile(r,t.readFile(r));return}e.mkdirTree(r);const i=t.readdir(r).filter(n=>n!=="."&&n!=="..");for(const n of i)recreateMemFS(e,t,joinPaths(r,n))}function isLocalPHP(e){return!(e instanceof BasePHP)}function isRemotePHP(e){return!isLocalPHP(e)}function rotatePHPRuntime({php:e,recreateRuntime:t,maxRequests:r}){let s=0;async function i(){if(++s<r)return;s=0;const n=await e.semaphore.acquire();try{e.hotSwapPHPRuntime(await t())}finally{n()}}return e.addEventListener("request.end",i),function(){e.removeEventListener("request.end",i)}}async function writeFiles(e,t,r,{rmRoot:s=!1}={}){s&&await e.isDir(t)&&await e.rmdir(t,{recursive:!0});for(const[i,n]of Object.entries(r)){const o=joinPaths(t,i);await e.fileExists(dirname(o))||await e.mkdir(dirname(o)),await e.writeFile(o,n)}}exports.BasePHP=BasePHP;exports.DEFAULT_BASE_URL=DEFAULT_BASE_URL;exports.LatestSupportedPHPVersion=LatestSupportedPHPVersion;exports.PHPBrowser=PHPBrowser;exports.PHPRequestHandler=PHPRequestHandler;exports.PHPResponse=PHPResponse;exports.SupportedPHPExtensionBundles=SupportedPHPExtensionBundles;exports.SupportedPHPExtensionsList=SupportedPHPExtensionsList;exports.SupportedPHPVersions=SupportedPHPVersions;exports.SupportedPHPVersionsList=SupportedPHPVersionsList;exports.UnhandledRejectionsTarget=UnhandledRejectionsTarget;exports.__private__dont__use=__private__dont__use;exports.ensurePathPrefix=ensurePathPrefix;exports.isExitCodeZero=isExitCodeZero;exports.isLocalPHP=isLocalPHP;exports.isRemotePHP=isRemotePHP;exports.iterateFiles=iteratePhpFiles;exports.loadPHPRuntime=loadPHPRuntime;exports.removePathPrefix=removePathPrefix;exports.rethrowFileSystemError=rethrowFileSystemError;exports.rotatePHPRuntime=rotatePHPRuntime;exports.toRelativeUrl=toRelativeUrl;exports.writeFiles=writeFiles;exports.writeFilesStreamToPhp=writeFilesStreamToPhp;
52
+ `;this[__private__dont__use].ccall("wasm_set_phpini_entries",null,[STRING],[e])}this[__private__dont__use].ccall("php_wasm_init",null,[],[])},N=new WeakSet,X=function(){const e="/tmp/headers.json";if(!this.fileExists(e))throw new Error("SAPI Error: Could not find response headers file.");const t=JSON.parse(this.readFileAsText(e)),r={};for(const s of t.headers){if(!s.includes(": "))continue;const n=s.indexOf(": "),i=s.substring(0,n).toLowerCase(),o=s.substring(n+2);i in r||(r[i]=[]),r[i].push(o)}return{headers:r,httpStatusCode:t.status}},M=new WeakSet,ee=function(e){if(this[__private__dont__use].ccall("wasm_set_request_uri",null,[STRING],[e]),e.includes("?")){const t=e.substring(e.indexOf("?")+1);this[__private__dont__use].ccall("wasm_set_query_string",null,[STRING],[t])}},$=new WeakSet,te=function(e,t){this[__private__dont__use].ccall("wasm_set_request_host",null,[STRING],[e]);let r;try{r=parseInt(new URL(e).port,10)}catch{}(!r||isNaN(r)||r===80)&&(r=t==="https"?443:80),this[__private__dont__use].ccall("wasm_set_request_port",null,[NUMBER],[r]),(t==="https"||!t&&r===443)&&this.addServerGlobalEntry("HTTPS","on")},O=new WeakSet,re=function(e){this[__private__dont__use].ccall("wasm_set_request_method",null,[STRING],[e])},D=new WeakSet,se=function(e){e.cookie&&this[__private__dont__use].ccall("wasm_set_cookies",null,[STRING],[e.cookie]),e["content-type"]&&this[__private__dont__use].ccall("wasm_set_content_type",null,[STRING],[e["content-type"]]),e["content-length"]&&this[__private__dont__use].ccall("wasm_set_content_length",null,[NUMBER],[parseInt(e["content-length"],10)]);for(const t in e){let r="HTTP_";["content-type","content-length"].includes(t.toLowerCase())&&(r=""),this.addServerGlobalEntry(`${r}${t.toUpperCase().replace(/-/g,"_")}`,e[t])}},j=new WeakSet,ne=function(e){let t,r;typeof e=="string"?(console.warn("Passing a string as the request body is deprecated. Please use a Uint8Array instead. See https://github.com/WordPress/wordpress-playground/issues/997 for more details"),r=this[__private__dont__use].lengthBytesUTF8(e),t=r+1):(r=e.byteLength,t=e.byteLength);const s=this[__private__dont__use].malloc(t);if(!s)throw new Error("Could not allocate memory for the request body.");return typeof e=="string"?this[__private__dont__use].stringToUTF8(e,s,t+1):this[__private__dont__use].HEAPU8.set(e,s),this[__private__dont__use].ccall("wasm_set_request_body",null,[NUMBER],[s]),this[__private__dont__use].ccall("wasm_set_content_length",null,[NUMBER],[r]),s},z=new WeakSet,ie=function(e){this[__private__dont__use].ccall("wasm_set_path_translated",null,[STRING],[e])},W=new WeakSet,oe=function(){for(const e in a(this,g))this[__private__dont__use].ccall("wasm_add_SERVER_entry",null,[STRING,STRING],[e,a(this,g)[e]])},G=new WeakSet,ae=function(e){this[__private__dont__use].ccall("wasm_set_php_code",null,[STRING],[e])},V=new WeakSet,le=async function(){var n;let e,t;try{e=await new Promise((i,o)=>{var d;t=u=>{const f=new Error("Rethrown");f.cause=u.error,f.betterMessage=u.message,o(f)},(d=a(this,w))==null||d.addEventListener("error",t);const l=this[__private__dont__use].ccall("wasm_sapi_handle_request",NUMBER,[],[],{async:!0});return l instanceof Promise?l.then(i,o):i(l)})}catch(i){for(const u in this)typeof this[u]=="function"&&(this[u]=()=>{throw new Error("PHP runtime has crashed – see the earlier error for details.")});this.functionsMaybeMissingFromAsyncify=getFunctionsMaybeMissingFromAsyncify();const o=i,l="betterMessage"in o?o.betterMessage:o.message,d=new Error(l);throw d.cause=o,d}finally{(n=a(this,w))==null||n.removeEventListener("error",t),h(this,g,{})}const{headers:r,httpStatusCode:s}=p(this,N,X).call(this);return new PHPResponse(s,r,this.readFileAsBuffer("/tmp/stdout"),this.readFileAsText("/tmp/stderr"),e)};__decorateClass([rethrowFileSystemError('Could not create directory "{path}"')],BasePHP.prototype,"mkdir",1);__decorateClass([rethrowFileSystemError('Could not create directory "{path}"')],BasePHP.prototype,"mkdirTree",1);__decorateClass([rethrowFileSystemError('Could not read "{path}"')],BasePHP.prototype,"readFileAsText",1);__decorateClass([rethrowFileSystemError('Could not read "{path}"')],BasePHP.prototype,"readFileAsBuffer",1);__decorateClass([rethrowFileSystemError('Could not write to "{path}"')],BasePHP.prototype,"writeFile",1);__decorateClass([rethrowFileSystemError('Could not unlink "{path}"')],BasePHP.prototype,"unlink",1);__decorateClass([rethrowFileSystemError('Could not remove directory "{path}"')],BasePHP.prototype,"rmdir",1);__decorateClass([rethrowFileSystemError('Could not list files in "{path}"')],BasePHP.prototype,"listFiles",1);__decorateClass([rethrowFileSystemError('Could not stat "{path}"')],BasePHP.prototype,"isDir",1);__decorateClass([rethrowFileSystemError('Could not stat "{path}"')],BasePHP.prototype,"fileExists",1);function normalizeHeaders(e){const t={};for(const r in e)t[r.toLowerCase()]=e[r];return t}function recreateMemFS(e,t,r){let s;try{s=t.lookupPath(r)}catch{return}if(!("contents"in s.node))return;try{e=e.lookupPath(r);return}catch{}if(!t.isDir(s.node.mode)){e.writeFile(r,t.readFile(r));return}e.mkdirTree(r);const n=t.readdir(r).filter(i=>i!=="."&&i!=="..");for(const i of n)recreateMemFS(e,t,joinPaths(r,i))}function isLocalPHP(e){return!(e instanceof BasePHP)}function isRemotePHP(e){return!isLocalPHP(e)}function rotatePHPRuntime({php:e,recreateRuntime:t,maxRequests:r}){let s=0;async function n(){if(++s<r)return;s=0;const i=await e.semaphore.acquire();try{e.hotSwapPHPRuntime(await t())}finally{i()}}return e.addEventListener("request.end",n),function(){e.removeEventListener("request.end",n)}}async function writeFiles(e,t,r,{rmRoot:s=!1}={}){s&&await e.isDir(t)&&await e.rmdir(t,{recursive:!0});for(const[n,i]of Object.entries(r)){const o=joinPaths(t,n);await e.fileExists(dirname(o))||await e.mkdir(dirname(o)),await e.writeFile(o,i)}}exports.BasePHP=BasePHP;exports.DEFAULT_BASE_URL=DEFAULT_BASE_URL;exports.LatestSupportedPHPVersion=LatestSupportedPHPVersion;exports.PHPBrowser=PHPBrowser;exports.PHPRequestHandler=PHPRequestHandler;exports.PHPResponse=PHPResponse;exports.SupportedPHPExtensionBundles=SupportedPHPExtensionBundles;exports.SupportedPHPExtensionsList=SupportedPHPExtensionsList;exports.SupportedPHPVersions=SupportedPHPVersions;exports.SupportedPHPVersionsList=SupportedPHPVersionsList;exports.UnhandledRejectionsTarget=UnhandledRejectionsTarget;exports.__private__dont__use=__private__dont__use;exports.ensurePathPrefix=ensurePathPrefix;exports.isExitCodeZero=isExitCodeZero;exports.isLocalPHP=isLocalPHP;exports.isRemotePHP=isRemotePHP;exports.iterateFiles=iteratePhpFiles;exports.loadPHPRuntime=loadPHPRuntime;exports.removePathPrefix=removePathPrefix;exports.rethrowFileSystemError=rethrowFileSystemError;exports.rotatePHPRuntime=rotatePHPRuntime;exports.toRelativeUrl=toRelativeUrl;exports.writeFiles=writeFiles;exports.writeFilesStreamToPhp=writeFilesStreamToPhp;
package/index.js CHANGED
@@ -1,19 +1,19 @@
1
- var K = (e, t, r) => {
1
+ var J = (e, t, r) => {
2
2
  if (!t.has(e))
3
3
  throw TypeError("Cannot " + r);
4
4
  };
5
- var a = (e, t, r) => (K(e, t, "read from private field"), r ? r.call(e) : t.get(e)), c = (e, t, r) => {
5
+ var a = (e, t, r) => (J(e, t, "read from private field"), r ? r.call(e) : t.get(e)), c = (e, t, r) => {
6
6
  if (t.has(e))
7
7
  throw TypeError("Cannot add the same private member more than once");
8
8
  t instanceof WeakSet ? t.add(e) : t.set(e, r);
9
- }, u = (e, t, r, s) => (K(e, t, "write to private field"), s ? s.call(e, r) : t.set(e, r), r);
10
- var f = (e, t, r) => (K(e, t, "access private method"), r);
9
+ }, h = (e, t, r, s) => (J(e, t, "write to private field"), s ? s.call(e, r) : t.set(e, r), r);
10
+ var f = (e, t, r) => (J(e, t, "access private method"), r);
11
11
  if (typeof File > "u") {
12
12
  class e extends Blob {
13
- constructor(r, s, i) {
13
+ constructor(r, s, n) {
14
14
  super(r);
15
- let n;
16
- i != null && i.lastModified && (n = /* @__PURE__ */ new Date()), (!n || isNaN(n.getFullYear())) && (n = /* @__PURE__ */ new Date()), this.lastModifiedDate = n, this.lastModified = n.getMilliseconds(), this.name = s || "";
15
+ let i;
16
+ n != null && n.lastModified && (i = /* @__PURE__ */ new Date()), (!i || isNaN(i.getFullYear())) && (i = /* @__PURE__ */ new Date()), this.lastModifiedDate = i, this.lastModified = i.getMilliseconds(), this.name = s || "";
17
17
  }
18
18
  }
19
19
  global.File = e;
@@ -50,7 +50,7 @@ function isByobSupported() {
50
50
  // this if needed.
51
51
  autoAllocateChunkSize: 512 * 1024,
52
52
  async pull(r) {
53
- const s = r.byobRequest.view, n = await t.slice(e, e + s.byteLength).arrayBuffer(), o = new Uint8Array(n);
53
+ const s = r.byobRequest.view, i = await t.slice(e, e + s.byteLength).arrayBuffer(), o = new Uint8Array(i);
54
54
  new Uint8Array(s.buffer).set(o);
55
55
  const l = o.byteLength;
56
56
  r.byobRequest.respond(l), e += l, e >= t.size && r.close();
@@ -114,16 +114,16 @@ function improveWASMErrorReporting(e) {
114
114
  for (const r in e.asm)
115
115
  if (typeof e.asm[r] == "function") {
116
116
  const s = e.asm[r];
117
- e.asm[r] = function(...i) {
118
- var n;
117
+ e.asm[r] = function(...n) {
118
+ var i;
119
119
  try {
120
- return s(...i);
120
+ return s(...n);
121
121
  } catch (o) {
122
122
  if (!(o instanceof Error))
123
123
  throw o;
124
124
  const l = clarifyErrorMessage(
125
125
  o,
126
- (n = e.lastAsyncifyStackSource) == null ? void 0 : n.stack
126
+ (i = e.lastAsyncifyStackSource) == null ? void 0 : i.stack
127
127
  );
128
128
  if (e.lastAsyncifyStackSource && (o.cause = e.lastAsyncifyStackSource), t.hasListeners()) {
129
129
  t.dispatchEvent(
@@ -266,8 +266,8 @@ function normalizePath(e) {
266
266
  function normalizePathsArray(e, t) {
267
267
  let r = 0;
268
268
  for (let s = e.length - 1; s >= 0; s--) {
269
- const i = e[s];
270
- i === "." ? e.splice(s, 1) : i === ".." ? (e.splice(s, 1), r++) : r && (e.splice(s, 1), r--);
269
+ const n = e[s];
270
+ n === "." ? e.splice(s, 1) : n === ".." ? (e.splice(s, 1), r++) : r && (e.splice(s, 1), r--);
271
271
  }
272
272
  if (t)
273
273
  for (; r; r--)
@@ -331,7 +331,7 @@ class ChildProcess extends EventEmitter {
331
331
  }
332
332
  function concatUint8Array(...e) {
333
333
  const t = new Uint8Array(
334
- e.reduce((s, i) => s + i.length, 0)
334
+ e.reduce((s, n) => s + n.length, 0)
335
335
  );
336
336
  let r = 0;
337
337
  for (const s of e)
@@ -365,22 +365,22 @@ function concatBytes(e) {
365
365
  function limitBytes(e, t) {
366
366
  if (t === 0)
367
367
  return new ReadableStream({
368
- start(i) {
369
- i.close();
368
+ start(n) {
369
+ n.close();
370
370
  }
371
371
  });
372
372
  const r = e.getReader({ mode: "byob" });
373
373
  let s = 0;
374
374
  return new ReadableStream({
375
- async pull(i) {
376
- const { value: n, done: o } = await r.read(
375
+ async pull(n) {
376
+ const { value: i, done: o } = await r.read(
377
377
  new Uint8Array(t - s)
378
378
  );
379
379
  if (o) {
380
- r.releaseLock(), i.close();
380
+ r.releaseLock(), n.close();
381
381
  return;
382
382
  }
383
- s += n.length, i.enqueue(n), s >= t && (r.releaseLock(), i.close());
383
+ s += i.length, n.enqueue(i), s >= t && (r.releaseLock(), n.close());
384
384
  },
385
385
  cancel() {
386
386
  r.cancel();
@@ -459,25 +459,25 @@ function streamReadFileFromPHP(e, t) {
459
459
  async function* iteratePhpFiles(e, t, {
460
460
  relativePaths: r = !0,
461
461
  pathPrefix: s,
462
- exceptPaths: i = []
462
+ exceptPaths: n = []
463
463
  } = {}) {
464
464
  t = normalizePath(t);
465
- const n = [t];
466
- for (; n.length; ) {
467
- const o = n.pop();
465
+ const i = [t];
466
+ for (; i.length; ) {
467
+ const o = i.pop();
468
468
  if (!o)
469
469
  return;
470
470
  const l = await e.listFiles(o);
471
- for (const h of l) {
472
- const d = `${o}/${h}`;
473
- if (i.includes(d.substring(t.length + 1)))
471
+ for (const d of l) {
472
+ const u = `${o}/${d}`;
473
+ if (n.includes(u.substring(t.length + 1)))
474
474
  continue;
475
- await e.isDir(d) ? n.push(d) : yield new StreamedFile(
476
- streamReadFileFromPHP(e, d),
475
+ await e.isDir(u) ? i.push(u) : yield new StreamedFile(
476
+ streamReadFileFromPHP(e, u),
477
477
  r ? joinPaths(
478
478
  s || "",
479
- d.substring(t.length + 1)
480
- ) : d
479
+ u.substring(t.length + 1)
480
+ ) : u
481
481
  );
482
482
  }
483
483
  }
@@ -494,8 +494,8 @@ function writeFilesStreamToPhp(e, t) {
494
494
  });
495
495
  }
496
496
  class PHPResponse {
497
- constructor(t, r, s, i = "", n = 0) {
498
- this.httpStatusCode = t, this.headers = r, this.bytes = s, this.exitCode = n, this.errors = i;
497
+ constructor(t, r, s, n = "", i = 0) {
498
+ this.httpStatusCode = t, this.headers = r, this.bytes = s, this.exitCode = i, this.errors = n;
499
499
  }
500
500
  static fromRawData(t) {
501
501
  return new PHPResponse(
@@ -546,7 +546,7 @@ const SupportedPHPVersions = [
546
546
  ], SupportedPHPExtensionBundles = {
547
547
  "kitchen-sink": SupportedPHPExtensionsList
548
548
  };
549
- var E, H;
549
+ var E, S;
550
550
  class PHPBrowser {
551
551
  /**
552
552
  * @param server - The PHP server to browse.
@@ -554,8 +554,8 @@ class PHPBrowser {
554
554
  */
555
555
  constructor(t, r = {}) {
556
556
  c(this, E, void 0);
557
- c(this, H, void 0);
558
- this.requestHandler = t, u(this, E, {}), u(this, H, {
557
+ c(this, S, void 0);
558
+ this.requestHandler = t, h(this, E, {}), h(this, S, {
559
559
  handleRedirects: !1,
560
560
  maxRedirects: 4,
561
561
  ...r
@@ -583,14 +583,14 @@ class PHPBrowser {
583
583
  cookie: this.serializeCookies()
584
584
  }
585
585
  });
586
- if (s.headers["set-cookie"] && this.setCookies(s.headers["set-cookie"]), a(this, H).handleRedirects && s.headers.location && r < a(this, H).maxRedirects) {
587
- const i = new URL(
586
+ if (s.headers["set-cookie"] && this.setCookies(s.headers["set-cookie"]), a(this, S).handleRedirects && s.headers.location && r < a(this, S).maxRedirects) {
587
+ const n = new URL(
588
588
  s.headers.location[0],
589
589
  this.requestHandler.absoluteUrl
590
590
  );
591
591
  return this.request(
592
592
  {
593
- url: i.toString(),
593
+ url: n.toString(),
594
594
  method: "GET",
595
595
  headers: {}
596
596
  },
@@ -620,8 +620,8 @@ class PHPBrowser {
620
620
  try {
621
621
  if (!r.includes("="))
622
622
  continue;
623
- const s = r.indexOf("="), i = r.substring(0, s), n = r.substring(s + 1).split(";")[0];
624
- a(this, E)[i] = n;
623
+ const s = r.indexOf("="), n = r.substring(0, s), i = r.substring(s + 1).split(";")[0];
624
+ a(this, E)[n] = i;
625
625
  } catch (s) {
626
626
  console.error(s);
627
627
  }
@@ -633,7 +633,7 @@ class PHPBrowser {
633
633
  return t.join("; ");
634
634
  }
635
635
  }
636
- E = new WeakMap(), H = new WeakMap();
636
+ E = new WeakMap(), S = new WeakMap();
637
637
  const DEFAULT_BASE_URL = "http://example.com";
638
638
  function toRelativeUrl(e) {
639
639
  return e.toString().substring(e.origin.length);
@@ -644,7 +644,35 @@ function removePathPrefix(e, t) {
644
644
  function ensurePathPrefix(e, t) {
645
645
  return !t || e.startsWith(t) ? e : t + e;
646
646
  }
647
- var P, x, A, v, F, m, T, R, L, Q, N, X, M, ee;
647
+ async function encodeAsMultipart(e) {
648
+ const t = `----${Math.random().toString(36).slice(2)}`, r = `multipart/form-data; boundary=${t}`, s = new TextEncoder(), n = [];
649
+ for (const [d, u] of Object.entries(e))
650
+ n.push(`--${t}\r
651
+ `), n.push(`Content-Disposition: form-data; name="${d}"`), u instanceof File && n.push(`; filename="${u.name}"`), n.push(`\r
652
+ `), u instanceof File && n.push("Content-Type: application/octet-stream"), n.push(`\r
653
+ \r
654
+ `), u instanceof File ? n.push(await fileToUint8Array(u)) : n.push(u), n.push(`\r
655
+ `);
656
+ n.push(`--${t}--\r
657
+ `);
658
+ const i = n.reduce((d, u) => d + u.length, 0), o = new Uint8Array(i);
659
+ let l = 0;
660
+ for (const d of n)
661
+ o.set(
662
+ typeof d == "string" ? s.encode(d) : d,
663
+ l
664
+ ), l += d.length;
665
+ return { bytes: o, contentType: r };
666
+ }
667
+ function fileToUint8Array(e) {
668
+ return new Promise((t) => {
669
+ const r = new FileReader();
670
+ r.onload = () => {
671
+ t(new Uint8Array(r.result));
672
+ }, r.readAsArrayBuffer(e);
673
+ });
674
+ }
675
+ var P, H, k, v, x, _, F, R, U, Y, I, Z, L, K;
648
676
  class PHPRequestHandler {
649
677
  /**
650
678
  * @param php - The PHP instance.
@@ -657,7 +685,7 @@ class PHPRequestHandler {
657
685
  * @param fsPath - Absolute path of the static file to serve.
658
686
  * @returns The response.
659
687
  */
660
- c(this, L);
688
+ c(this, U);
661
689
  /**
662
690
  * Runs the requested PHP file with all the request and $_SERVER
663
691
  * superglobals populated.
@@ -665,7 +693,7 @@ class PHPRequestHandler {
665
693
  * @param request - The request.
666
694
  * @returns The response.
667
695
  */
668
- c(this, N);
696
+ c(this, I);
669
697
  /**
670
698
  * Resolve the requested path to the filesystem path of the requested PHP file.
671
699
  *
@@ -675,31 +703,31 @@ class PHPRequestHandler {
675
703
  * @throws {Error} If the requested path doesn't exist.
676
704
  * @returns The resolved filesystem path.
677
705
  */
678
- c(this, M);
706
+ c(this, L);
679
707
  c(this, P, void 0);
680
- c(this, x, void 0);
681
- c(this, A, void 0);
708
+ c(this, H, void 0);
709
+ c(this, k, void 0);
682
710
  c(this, v, void 0);
711
+ c(this, x, void 0);
712
+ c(this, _, void 0);
683
713
  c(this, F, void 0);
684
- c(this, m, void 0);
685
- c(this, T, void 0);
686
714
  c(this, R, void 0);
687
- u(this, R, new Semaphore({ concurrency: 1 }));
715
+ h(this, R, new Semaphore({ concurrency: 1 }));
688
716
  const {
689
717
  documentRoot: s = "/www/",
690
- absoluteUrl: i = typeof location == "object" ? location == null ? void 0 : location.href : ""
718
+ absoluteUrl: n = typeof location == "object" ? location == null ? void 0 : location.href : ""
691
719
  } = r;
692
- this.php = t, u(this, P, s);
693
- const n = new URL(i);
694
- u(this, A, n.hostname), u(this, v, n.port ? Number(n.port) : n.protocol === "https:" ? 443 : 80), u(this, x, (n.protocol || "").replace(":", ""));
720
+ this.php = t, h(this, P, s);
721
+ const i = new URL(n);
722
+ h(this, k, i.hostname), h(this, v, i.port ? Number(i.port) : i.protocol === "https:" ? 443 : 80), h(this, H, (i.protocol || "").replace(":", ""));
695
723
  const o = a(this, v) !== 443 && a(this, v) !== 80;
696
- u(this, F, [
697
- a(this, A),
724
+ h(this, x, [
725
+ a(this, k),
698
726
  o ? `:${a(this, v)}` : ""
699
- ].join("")), u(this, m, n.pathname.replace(/\/+$/, "")), u(this, T, [
700
- `${a(this, x)}://`,
701
- a(this, F),
702
- a(this, m)
727
+ ].join("")), h(this, _, i.pathname.replace(/\/+$/, "")), h(this, F, [
728
+ `${a(this, H)}://`,
729
+ a(this, x),
730
+ a(this, _)
703
731
  ].join(""));
704
732
  }
705
733
  /** @inheritDoc */
@@ -709,14 +737,14 @@ class PHPRequestHandler {
709
737
  /** @inheritDoc */
710
738
  internalUrlToPath(t) {
711
739
  const r = new URL(t);
712
- return r.pathname.startsWith(a(this, m)) && (r.pathname = r.pathname.slice(a(this, m).length)), toRelativeUrl(r);
740
+ return r.pathname.startsWith(a(this, _)) && (r.pathname = r.pathname.slice(a(this, _).length)), toRelativeUrl(r);
713
741
  }
714
742
  get isRequestRunning() {
715
743
  return a(this, R).running > 0;
716
744
  }
717
745
  /** @inheritDoc */
718
746
  get absoluteUrl() {
719
- return a(this, T);
747
+ return a(this, F);
720
748
  }
721
749
  /** @inheritDoc */
722
750
  get documentRoot() {
@@ -727,14 +755,14 @@ class PHPRequestHandler {
727
755
  const r = t.url.startsWith("http://") || t.url.startsWith("https://"), s = new URL(
728
756
  t.url,
729
757
  r ? void 0 : DEFAULT_BASE_URL
730
- ), i = removePathPrefix(
758
+ ), n = removePathPrefix(
731
759
  s.pathname,
732
- a(this, m)
733
- ), n = `${a(this, P)}${i}`;
734
- return seemsLikeAPHPRequestHandlerPath(n) ? await f(this, N, X).call(this, t, s) : f(this, L, Q).call(this, n);
760
+ a(this, _)
761
+ ), i = `${a(this, P)}${n}`;
762
+ return seemsLikeAPHPRequestHandlerPath(i) ? await f(this, I, Z).call(this, t, s) : f(this, U, Y).call(this, i);
735
763
  }
736
764
  }
737
- P = new WeakMap(), x = new WeakMap(), A = new WeakMap(), v = new WeakMap(), F = new WeakMap(), m = new WeakMap(), T = new WeakMap(), R = new WeakMap(), L = new WeakSet(), Q = function(t) {
765
+ P = new WeakMap(), H = new WeakMap(), k = new WeakMap(), v = new WeakMap(), x = new WeakMap(), _ = new WeakMap(), F = new WeakMap(), R = new WeakMap(), U = new WeakSet(), Y = function(t) {
738
766
  if (!this.php.fileExists(t))
739
767
  return new PHPResponse(
740
768
  404,
@@ -759,9 +787,9 @@ P = new WeakMap(), x = new WeakMap(), A = new WeakMap(), v = new WeakMap(), F =
759
787
  },
760
788
  r
761
789
  );
762
- }, N = new WeakSet(), X = async function(t, r) {
763
- var i, n, o;
764
- if (a(this, R).running > 0 && ((i = t.headers) == null ? void 0 : i["x-request-issuer"]) === "php")
790
+ }, I = new WeakSet(), Z = async function(t, r) {
791
+ var n, i;
792
+ if (a(this, R).running > 0 && ((n = t.headers) == null ? void 0 : n["x-request-issuer"]) === "php")
765
793
  return console.warn(
766
794
  "Possible deadlock: Called request() before the previous request() have finished. PHP likely issued an HTTP call to itself. Normally this would lead to infinite waiting as Request 1 holds the lock that the Request 2 is waiting to acquire. That's not useful, so PHPRequestHandler will return error 502 instead."
767
795
  ), new PHPResponse(
@@ -773,43 +801,30 @@ P = new WeakMap(), x = new WeakMap(), A = new WeakMap(), v = new WeakMap(), F =
773
801
  try {
774
802
  this.php.addServerGlobalEntry("REMOTE_ADDR", "127.0.0.1"), this.php.addServerGlobalEntry("DOCUMENT_ROOT", a(this, P)), this.php.addServerGlobalEntry(
775
803
  "HTTPS",
776
- a(this, T).startsWith("https://") ? "on" : ""
804
+ a(this, F).startsWith("https://") ? "on" : ""
777
805
  );
778
- let l = "GET";
779
- const h = {
780
- host: a(this, F),
806
+ let o = "GET";
807
+ const l = {
808
+ host: a(this, x),
781
809
  ...normalizeHeaders(t.headers || {})
782
- }, d = [];
783
- if (t.files && Object.keys(t.files).length) {
784
- l = "POST";
785
- for (const S in t.files) {
786
- const U = t.files[S];
787
- d.push({
788
- key: S,
789
- name: U.name,
790
- type: U.type,
791
- data: new Uint8Array(await U.arrayBuffer())
792
- });
793
- }
794
- (n = h["content-type"]) != null && n.startsWith("multipart/form-data") && (t.formData = parseMultipartFormDataString(
795
- t.body || ""
796
- ), h["content-type"] = "application/x-www-form-urlencoded", delete t.body);
810
+ };
811
+ let d = t.body;
812
+ if (typeof d == "object" && !(d instanceof Uint8Array)) {
813
+ o = "POST";
814
+ const { bytes: p, contentType: B } = await encodeAsMultipart(d);
815
+ d = p, l["content-type"] = B;
797
816
  }
798
- let p;
799
- t.formData !== void 0 ? (l = "POST", h["content-type"] = h["content-type"] || "application/x-www-form-urlencoded", p = new URLSearchParams(
800
- t.formData
801
- ).toString()) : p = t.body;
802
- let I;
817
+ let u;
803
818
  try {
804
- let S = r.pathname;
805
- if ((o = t.headers) != null && o["x-rewrite-url"])
819
+ let p = r.pathname;
820
+ if ((i = t.headers) != null && i["x-rewrite-url"])
806
821
  try {
807
- S = new URL(
822
+ p = new URL(
808
823
  t.headers["x-rewrite-url"]
809
824
  ).pathname;
810
825
  } catch {
811
826
  }
812
- I = f(this, M, ee).call(this, S);
827
+ u = f(this, L, K).call(this, p);
813
828
  } catch {
814
829
  return new PHPResponse(
815
830
  404,
@@ -820,41 +835,25 @@ P = new WeakMap(), x = new WeakMap(), A = new WeakMap(), v = new WeakMap(), F =
820
835
  return await this.php.run({
821
836
  relativeUri: ensurePathPrefix(
822
837
  toRelativeUrl(r),
823
- a(this, m)
838
+ a(this, _)
824
839
  ),
825
- protocol: a(this, x),
826
- method: t.method || l,
827
- body: p,
828
- fileInfos: d,
829
- scriptPath: I,
830
- headers: h
840
+ protocol: a(this, H),
841
+ method: t.method || o,
842
+ body: d,
843
+ scriptPath: u,
844
+ headers: l
831
845
  });
832
846
  } finally {
833
847
  s();
834
848
  }
835
- }, M = new WeakSet(), ee = function(t) {
836
- let r = removePathPrefix(t, a(this, m));
849
+ }, L = new WeakSet(), K = function(t) {
850
+ let r = removePathPrefix(t, a(this, _));
837
851
  r.includes(".php") ? r = r.split(".php")[0] + ".php" : (r.endsWith("/") || (r += "/"), r.endsWith("index.php") || (r += "index.php"));
838
852
  const s = `${a(this, P)}${r}`;
839
853
  if (this.php.fileExists(s))
840
854
  return s;
841
855
  throw new Error(`File not found: ${s}`);
842
856
  };
843
- function parseMultipartFormDataString(e) {
844
- const t = {}, r = e.match(/--(.*)\r\n/);
845
- if (!r)
846
- return t;
847
- const s = r[1], i = e.split(`--${s}`);
848
- return i.shift(), i.pop(), i.forEach((n) => {
849
- const o = n.indexOf(`\r
850
- \r
851
- `), l = n.substring(0, o).trim(), h = n.substring(o + 4).trim(), d = l.match(/name="([^"]+)"/);
852
- if (d) {
853
- const p = d[1];
854
- t[p] = h;
855
- }
856
- }), t;
857
- }
858
857
  function inferMimeType(e) {
859
858
  switch (e.split(".").pop()) {
860
859
  case "css":
@@ -989,16 +988,16 @@ function getEmscriptenFsError(e) {
989
988
  return FileErrorCodes[t];
990
989
  }
991
990
  function rethrowFileSystemError(e = "") {
992
- return function(r, s, i) {
993
- const n = i.value;
994
- i.value = function(...o) {
991
+ return function(r, s, n) {
992
+ const i = n.value;
993
+ n.value = function(...o) {
995
994
  try {
996
- return n.apply(this, o);
995
+ return i.apply(this, o);
997
996
  } catch (l) {
998
- const h = typeof l == "object" ? l == null ? void 0 : l.errno : null;
999
- if (h in FileErrorCodes) {
1000
- const d = FileErrorCodes[h], p = typeof o[0] == "string" ? o[0] : null, I = p !== null ? e.replaceAll("{path}", p) : e;
1001
- throw new Error(`${I}: ${d}`, {
997
+ const d = typeof l == "object" ? l == null ? void 0 : l.errno : null;
998
+ if (d in FileErrorCodes) {
999
+ const u = FileErrorCodes[d], p = typeof o[0] == "string" ? o[0] : null, B = p !== null ? e.replaceAll("{path}", p) : e;
1000
+ throw new Error(`${B}: ${u}`, {
1002
1001
  cause: l
1003
1002
  });
1004
1003
  }
@@ -1010,9 +1009,9 @@ function rethrowFileSystemError(e = "") {
1010
1009
  const RuntimeId = Symbol("RuntimeId"), loadedRuntimes = /* @__PURE__ */ new Map();
1011
1010
  let lastRuntimeId = 0;
1012
1011
  async function loadPHPRuntime(e, t = {}) {
1013
- const [r, s, i] = makePromise(), n = e.init(currentJsRuntime, {
1012
+ const [r, s, n] = makePromise(), i = e.init(currentJsRuntime, {
1014
1013
  onAbort(l) {
1015
- i(l), console.error(l);
1014
+ n(l), console.error(l);
1016
1015
  },
1017
1016
  ENV: {},
1018
1017
  // Emscripten sometimes prepends a '/' to the path, which
@@ -1027,9 +1026,9 @@ async function loadPHPRuntime(e, t = {}) {
1027
1026
  });
1028
1027
  await r;
1029
1028
  const o = ++lastRuntimeId;
1030
- return n.id = o, n.originalExit = n._exit, n._exit = function(l) {
1031
- return loadedRuntimes.delete(o), n.originalExit(l);
1032
- }, n[RuntimeId] = o, loadedRuntimes.set(o, n), o;
1029
+ return i.id = o, i.originalExit = i._exit, i._exit = function(l) {
1030
+ return loadedRuntimes.delete(o), i.originalExit(l);
1031
+ }, i[RuntimeId] = o, loadedRuntimes.set(o, i), o;
1033
1032
  }
1034
1033
  function getLoadedRuntime(e) {
1035
1034
  return loadedRuntimes.get(e);
@@ -1044,12 +1043,12 @@ const currentJsRuntime = function() {
1044
1043
  return e.unshift(t), e;
1045
1044
  };
1046
1045
  var __defProp = Object.defineProperty, __getOwnPropDesc = Object.getOwnPropertyDescriptor, __decorateClass = (e, t, r, s) => {
1047
- for (var i = s > 1 ? void 0 : s ? __getOwnPropDesc(t, r) : t, n = e.length - 1, o; n >= 0; n--)
1048
- (o = e[n]) && (i = (s ? o(t, r, i) : o(i)) || i);
1049
- return s && i && __defProp(t, r, i), i;
1046
+ for (var n = s > 1 ? void 0 : s ? __getOwnPropDesc(t, r) : t, i = e.length - 1, o; i >= 0; i--)
1047
+ (o = e[i]) && (n = (s ? o(t, r, n) : o(n)) || n);
1048
+ return s && n && __defProp(t, r, n), n;
1050
1049
  };
1051
1050
  const STRING = "string", NUMBER = "number", __private__dont__use = Symbol("__private__dont__use");
1052
- var b, C, k, _, w, g, y, B, q, te, O, re, D, se, $, ne, j, ie, z, oe, G, ae, W, le, V, ce, J, ue, Y, de, Z, he;
1051
+ var b, T, A, m, w, g, y, C, q, Q, N, X, M, ee, $, te, O, re, D, se, j, ne, z, ie, W, oe, G, ae, V, le;
1053
1052
  class BasePHP {
1054
1053
  /**
1055
1054
  * Initializes a PHP runtime.
@@ -1060,35 +1059,25 @@ class BasePHP {
1060
1059
  */
1061
1060
  constructor(e, t) {
1062
1061
  c(this, q);
1062
+ c(this, N);
1063
+ c(this, M);
1064
+ c(this, $);
1063
1065
  c(this, O);
1064
1066
  c(this, D);
1065
- c(this, $);
1066
1067
  c(this, j);
1067
1068
  c(this, z);
1068
- c(this, G);
1069
1069
  c(this, W);
1070
+ c(this, G);
1070
1071
  c(this, V);
1071
- /**
1072
- * Adds file information to $_FILES superglobal in PHP.
1073
- *
1074
- * In particular:
1075
- * * Creates the file data in the filesystem
1076
- * * Registers the file details in PHP
1077
- *
1078
- * @param fileInfo - File details
1079
- */
1080
- c(this, J);
1081
- c(this, Y);
1082
- c(this, Z);
1083
1072
  c(this, b, void 0);
1084
- c(this, C, void 0);
1085
- c(this, k, void 0);
1086
- c(this, _, void 0);
1073
+ c(this, T, void 0);
1074
+ c(this, A, void 0);
1075
+ c(this, m, void 0);
1087
1076
  c(this, w, void 0);
1088
1077
  c(this, g, void 0);
1089
1078
  c(this, y, void 0);
1090
- c(this, B, void 0);
1091
- u(this, b, []), u(this, _, !1), u(this, w, null), u(this, g, {}), u(this, y, /* @__PURE__ */ new Map()), u(this, B, []), this.semaphore = new Semaphore({ concurrency: 1 }), e !== void 0 && this.initializeRuntime(e), t && (this.requestHandler = new PHPBrowser(
1079
+ c(this, C, void 0);
1080
+ h(this, b, []), h(this, m, !1), h(this, w, null), h(this, g, {}), h(this, y, /* @__PURE__ */ new Map()), h(this, C, []), this.semaphore = new Semaphore({ concurrency: 1 }), e !== void 0 && this.initializeRuntime(e), t && (this.requestHandler = new PHPBrowser(
1092
1081
  new PHPRequestHandler(this, t)
1093
1082
  ));
1094
1083
  }
@@ -1107,7 +1096,7 @@ class BasePHP {
1107
1096
  }
1108
1097
  /** @inheritDoc */
1109
1098
  async onMessage(e) {
1110
- a(this, B).push(e);
1099
+ a(this, C).push(e);
1111
1100
  }
1112
1101
  /** @inheritDoc */
1113
1102
  async setSpawnHandler(handler) {
@@ -1138,13 +1127,13 @@ class BasePHP {
1138
1127
  if (!t)
1139
1128
  throw new Error("Invalid PHP runtime id.");
1140
1129
  this[__private__dont__use] = t, t.onMessage = async (r) => {
1141
- for (const s of a(this, B)) {
1142
- const i = await s(r);
1143
- if (i)
1144
- return i;
1130
+ for (const s of a(this, C)) {
1131
+ const n = await s(r);
1132
+ if (n)
1133
+ return n;
1145
1134
  }
1146
1135
  return "";
1147
- }, u(this, w, improveWASMErrorReporting(t)), this.dispatchEvent({
1136
+ }, h(this, w, improveWASMErrorReporting(t)), this.dispatchEvent({
1148
1137
  type: "runtime.initialized"
1149
1138
  });
1150
1139
  }
@@ -1159,13 +1148,13 @@ class BasePHP {
1159
1148
  throw new Error(
1160
1149
  "Could not set SAPI name. This can only be done before the PHP WASM module is initialized.Did you already dispatch any requests?"
1161
1150
  );
1162
- u(this, k, e);
1151
+ h(this, A, e);
1163
1152
  }
1164
1153
  /** @inheritDoc */
1165
1154
  setPhpIniPath(e) {
1166
- if (a(this, _))
1155
+ if (a(this, m))
1167
1156
  throw new Error("Cannot set PHP ini path after calling run().");
1168
- u(this, C, e), this[__private__dont__use].ccall(
1157
+ h(this, T, e), this[__private__dont__use].ccall(
1169
1158
  "wasm_set_phpini_path",
1170
1159
  null,
1171
1160
  ["string"],
@@ -1174,7 +1163,7 @@ class BasePHP {
1174
1163
  }
1175
1164
  /** @inheritDoc */
1176
1165
  setPhpIniEntry(e, t) {
1177
- if (a(this, _))
1166
+ if (a(this, m))
1178
1167
  throw new Error("Cannot set PHP ini entries after calling run().");
1179
1168
  a(this, b).push([e, t]);
1180
1169
  }
@@ -1193,25 +1182,22 @@ class BasePHP {
1193
1182
  const t = await this.semaphore.acquire();
1194
1183
  let r;
1195
1184
  try {
1196
- a(this, _) || (f(this, q, te).call(this), u(this, _, !0)), f(this, W, le).call(this, e.scriptPath || ""), f(this, D, se).call(this, e.relativeUri || ""), f(this, j, ie).call(this, e.method || "GET");
1197
- const s = normalizeHeaders(e.headers || {}), i = s.host || "example.com:443";
1198
- if (f(this, $, ne).call(this, i, e.protocol || "http"), f(this, z, oe).call(this, s), e.body && (r = f(this, G, ae).call(this, e.body)), e.fileInfos)
1199
- for (const o of e.fileInfos)
1200
- f(this, J, ue).call(this, o);
1201
- typeof e.code == "string" && f(this, Y, de).call(this, " ?>" + e.code), f(this, V, ce).call(this);
1202
- const n = await f(this, Z, he).call(this);
1203
- if (e.throwOnError && n.exitCode !== 0) {
1185
+ a(this, m) || (f(this, q, Q).call(this), h(this, m, !0)), f(this, z, ie).call(this, e.scriptPath || ""), f(this, M, ee).call(this, e.relativeUri || ""), f(this, O, re).call(this, e.method || "GET");
1186
+ const s = normalizeHeaders(e.headers || {}), n = s.host || "example.com:443";
1187
+ f(this, $, te).call(this, n, e.protocol || "http"), f(this, D, se).call(this, s), e.body && (r = f(this, j, ne).call(this, e.body)), typeof e.code == "string" && f(this, G, ae).call(this, " ?>" + e.code), f(this, W, oe).call(this);
1188
+ const i = await f(this, V, le).call(this);
1189
+ if (e.throwOnError && i.exitCode !== 0) {
1204
1190
  const o = {
1205
- stdout: n.text,
1206
- stderr: n.errors
1191
+ stdout: i.text,
1192
+ stderr: i.errors
1207
1193
  };
1208
1194
  console.warn("PHP.run() output was:", o);
1209
1195
  const l = new Error(
1210
- `PHP.run() failed with exit code ${n.exitCode} and the following output`
1196
+ `PHP.run() failed with exit code ${i.exitCode} and the following output`
1211
1197
  );
1212
1198
  throw l.output = o, l;
1213
1199
  }
1214
- return n;
1200
+ return i;
1215
1201
  } finally {
1216
1202
  try {
1217
1203
  r && this[__private__dont__use].free(r);
@@ -1288,7 +1274,7 @@ class BasePHP {
1288
1274
  );
1289
1275
  if (t.prependPath) {
1290
1276
  const s = e.replace(/\/$/, "");
1291
- return r.map((i) => `${s}/${i}`);
1277
+ return r.map((n) => `${s}/${n}`);
1292
1278
  }
1293
1279
  return r;
1294
1280
  } catch (r) {
@@ -1319,7 +1305,7 @@ class BasePHP {
1319
1305
  this.exit();
1320
1306
  } catch {
1321
1307
  }
1322
- if (this.initializeRuntime(e), a(this, C) && this.setPhpIniPath(a(this, C)), a(this, k) && this.setSapiName(a(this, k)), this.requestHandler) {
1308
+ if (this.initializeRuntime(e), a(this, T) && this.setPhpIniPath(a(this, T)), a(this, A) && this.setSapiName(a(this, A)), this.requestHandler) {
1323
1309
  const r = this.documentRoot;
1324
1310
  recreateMemFS(this[__private__dont__use].FS, t, r);
1325
1311
  }
@@ -1332,10 +1318,10 @@ class BasePHP {
1332
1318
  this[__private__dont__use]._exit(e);
1333
1319
  } catch {
1334
1320
  }
1335
- u(this, _, !1), u(this, w, null), delete this[__private__dont__use].onMessage, delete this[__private__dont__use];
1321
+ h(this, m, !1), h(this, w, null), delete this[__private__dont__use].onMessage, delete this[__private__dont__use];
1336
1322
  }
1337
1323
  }
1338
- b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), _ = new WeakMap(), w = new WeakMap(), g = new WeakMap(), y = new WeakMap(), B = new WeakMap(), q = new WeakSet(), te = function() {
1324
+ b = new WeakMap(), T = new WeakMap(), A = new WeakMap(), m = new WeakMap(), w = new WeakMap(), g = new WeakMap(), y = new WeakMap(), C = new WeakMap(), q = new WeakSet(), Q = function() {
1339
1325
  if (this.setPhpIniEntry("auto_prepend_file", "/tmp/consts.php"), this.fileExists("/tmp/consts.php") || this.writeFile(
1340
1326
  "/tmp/consts.php",
1341
1327
  `<?php
@@ -1360,7 +1346,7 @@ b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), _ = new WeakMap(), w =
1360
1346
  );
1361
1347
  }
1362
1348
  this[__private__dont__use].ccall("php_wasm_init", null, [], []);
1363
- }, O = new WeakSet(), re = function() {
1349
+ }, N = new WeakSet(), X = function() {
1364
1350
  const e = "/tmp/headers.json";
1365
1351
  if (!this.fileExists(e))
1366
1352
  throw new Error(
@@ -1370,14 +1356,14 @@ b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), _ = new WeakMap(), w =
1370
1356
  for (const s of t.headers) {
1371
1357
  if (!s.includes(": "))
1372
1358
  continue;
1373
- const i = s.indexOf(": "), n = s.substring(0, i).toLowerCase(), o = s.substring(i + 2);
1374
- n in r || (r[n] = []), r[n].push(o);
1359
+ const n = s.indexOf(": "), i = s.substring(0, n).toLowerCase(), o = s.substring(n + 2);
1360
+ i in r || (r[i] = []), r[i].push(o);
1375
1361
  }
1376
1362
  return {
1377
1363
  headers: r,
1378
1364
  httpStatusCode: t.status
1379
1365
  };
1380
- }, D = new WeakSet(), se = function(e) {
1366
+ }, M = new WeakSet(), ee = function(e) {
1381
1367
  if (this[__private__dont__use].ccall(
1382
1368
  "wasm_set_request_uri",
1383
1369
  null,
@@ -1392,7 +1378,7 @@ b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), _ = new WeakMap(), w =
1392
1378
  [t]
1393
1379
  );
1394
1380
  }
1395
- }, $ = new WeakSet(), ne = function(e, t) {
1381
+ }, $ = new WeakSet(), te = function(e, t) {
1396
1382
  this[__private__dont__use].ccall(
1397
1383
  "wasm_set_request_host",
1398
1384
  null,
@@ -1410,14 +1396,14 @@ b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), _ = new WeakMap(), w =
1410
1396
  [NUMBER],
1411
1397
  [r]
1412
1398
  ), (t === "https" || !t && r === 443) && this.addServerGlobalEntry("HTTPS", "on");
1413
- }, j = new WeakSet(), ie = function(e) {
1399
+ }, O = new WeakSet(), re = function(e) {
1414
1400
  this[__private__dont__use].ccall(
1415
1401
  "wasm_set_request_method",
1416
1402
  null,
1417
1403
  [STRING],
1418
1404
  [e]
1419
1405
  );
1420
- }, z = new WeakSet(), oe = function(e) {
1406
+ }, D = new WeakSet(), se = function(e) {
1421
1407
  e.cookie && this[__private__dont__use].ccall(
1422
1408
  "wasm_set_cookies",
1423
1409
  null,
@@ -1441,33 +1427,37 @@ b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), _ = new WeakMap(), w =
1441
1427
  e[t]
1442
1428
  );
1443
1429
  }
1444
- }, G = new WeakSet(), ae = function(e) {
1445
- const t = this[__private__dont__use].lengthBytesUTF8(e), r = this[__private__dont__use].malloc(t + 1);
1446
- if (!r)
1430
+ }, j = new WeakSet(), ne = function(e) {
1431
+ let t, r;
1432
+ typeof e == "string" ? (console.warn(
1433
+ "Passing a string as the request body is deprecated. Please use a Uint8Array instead. See https://github.com/WordPress/wordpress-playground/issues/997 for more details"
1434
+ ), r = this[__private__dont__use].lengthBytesUTF8(e), t = r + 1) : (r = e.byteLength, t = e.byteLength);
1435
+ const s = this[__private__dont__use].malloc(t);
1436
+ if (!s)
1447
1437
  throw new Error("Could not allocate memory for the request body.");
1448
- return this[__private__dont__use].stringToUTF8(
1438
+ return typeof e == "string" ? this[__private__dont__use].stringToUTF8(
1449
1439
  e,
1450
- r,
1440
+ s,
1451
1441
  t + 1
1452
- ), this[__private__dont__use].ccall(
1442
+ ) : this[__private__dont__use].HEAPU8.set(e, s), this[__private__dont__use].ccall(
1453
1443
  "wasm_set_request_body",
1454
1444
  null,
1455
1445
  [NUMBER],
1456
- [r]
1446
+ [s]
1457
1447
  ), this[__private__dont__use].ccall(
1458
1448
  "wasm_set_content_length",
1459
1449
  null,
1460
1450
  [NUMBER],
1461
- [new TextEncoder().encode(e).length]
1462
- ), r;
1463
- }, W = new WeakSet(), le = function(e) {
1451
+ [r]
1452
+ ), s;
1453
+ }, z = new WeakSet(), ie = function(e) {
1464
1454
  this[__private__dont__use].ccall(
1465
1455
  "wasm_set_path_translated",
1466
1456
  null,
1467
1457
  [STRING],
1468
1458
  [e]
1469
1459
  );
1470
- }, V = new WeakSet(), ce = function() {
1460
+ }, W = new WeakSet(), oe = function() {
1471
1461
  for (const e in a(this, g))
1472
1462
  this[__private__dont__use].ccall(
1473
1463
  "wasm_add_SERVER_entry",
@@ -1475,33 +1465,23 @@ b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), _ = new WeakMap(), w =
1475
1465
  [STRING, STRING],
1476
1466
  [e, a(this, g)[e]]
1477
1467
  );
1478
- }, J = new WeakSet(), ue = function(e) {
1479
- const { key: t, name: r, type: s, data: i } = e, n = `/tmp/${Math.random().toFixed(20)}`;
1480
- this.writeFile(n, i);
1481
- const o = 0;
1482
- this[__private__dont__use].ccall(
1483
- "wasm_add_uploaded_file",
1484
- null,
1485
- [STRING, STRING, STRING, STRING, NUMBER, NUMBER],
1486
- [t, r, s, n, o, i.byteLength]
1487
- );
1488
- }, Y = new WeakSet(), de = function(e) {
1468
+ }, G = new WeakSet(), ae = function(e) {
1489
1469
  this[__private__dont__use].ccall(
1490
1470
  "wasm_set_php_code",
1491
1471
  null,
1492
1472
  [STRING],
1493
1473
  [e]
1494
1474
  );
1495
- }, Z = new WeakSet(), he = async function() {
1496
- var i;
1475
+ }, V = new WeakSet(), le = async function() {
1476
+ var n;
1497
1477
  let e, t;
1498
1478
  try {
1499
- e = await new Promise((n, o) => {
1500
- var h;
1501
- t = (d) => {
1479
+ e = await new Promise((i, o) => {
1480
+ var d;
1481
+ t = (u) => {
1502
1482
  const p = new Error("Rethrown");
1503
- p.cause = d.error, p.betterMessage = d.message, o(p);
1504
- }, (h = a(this, w)) == null || h.addEventListener(
1483
+ p.cause = u.error, p.betterMessage = u.message, o(p);
1484
+ }, (d = a(this, w)) == null || d.addEventListener(
1505
1485
  "error",
1506
1486
  t
1507
1487
  );
@@ -1512,22 +1492,22 @@ b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), _ = new WeakMap(), w =
1512
1492
  [],
1513
1493
  { async: !0 }
1514
1494
  );
1515
- return l instanceof Promise ? l.then(n, o) : n(l);
1495
+ return l instanceof Promise ? l.then(i, o) : i(l);
1516
1496
  });
1517
- } catch (n) {
1518
- for (const d in this)
1519
- typeof this[d] == "function" && (this[d] = () => {
1497
+ } catch (i) {
1498
+ for (const u in this)
1499
+ typeof this[u] == "function" && (this[u] = () => {
1520
1500
  throw new Error(
1521
1501
  "PHP runtime has crashed – see the earlier error for details."
1522
1502
  );
1523
1503
  });
1524
1504
  this.functionsMaybeMissingFromAsyncify = getFunctionsMaybeMissingFromAsyncify();
1525
- const o = n, l = "betterMessage" in o ? o.betterMessage : o.message, h = new Error(l);
1526
- throw h.cause = o, h;
1505
+ const o = i, l = "betterMessage" in o ? o.betterMessage : o.message, d = new Error(l);
1506
+ throw d.cause = o, d;
1527
1507
  } finally {
1528
- (i = a(this, w)) == null || i.removeEventListener("error", t), u(this, g, {});
1508
+ (n = a(this, w)) == null || n.removeEventListener("error", t), h(this, g, {});
1529
1509
  }
1530
- const { headers: r, httpStatusCode: s } = f(this, O, re).call(this);
1510
+ const { headers: r, httpStatusCode: s } = f(this, N, X).call(this);
1531
1511
  return new PHPResponse(
1532
1512
  s,
1533
1513
  r,
@@ -1591,9 +1571,9 @@ function recreateMemFS(e, t, r) {
1591
1571
  return;
1592
1572
  }
1593
1573
  e.mkdirTree(r);
1594
- const i = t.readdir(r).filter((n) => n !== "." && n !== "..");
1595
- for (const n of i)
1596
- recreateMemFS(e, t, joinPaths(r, n));
1574
+ const n = t.readdir(r).filter((i) => i !== "." && i !== "..");
1575
+ for (const i of n)
1576
+ recreateMemFS(e, t, joinPaths(r, i));
1597
1577
  }
1598
1578
  function isLocalPHP(e) {
1599
1579
  return !(e instanceof BasePHP);
@@ -1607,26 +1587,26 @@ function rotatePHPRuntime({
1607
1587
  maxRequests: r
1608
1588
  }) {
1609
1589
  let s = 0;
1610
- async function i() {
1590
+ async function n() {
1611
1591
  if (++s < r)
1612
1592
  return;
1613
1593
  s = 0;
1614
- const n = await e.semaphore.acquire();
1594
+ const i = await e.semaphore.acquire();
1615
1595
  try {
1616
1596
  e.hotSwapPHPRuntime(await t());
1617
1597
  } finally {
1618
- n();
1598
+ i();
1619
1599
  }
1620
1600
  }
1621
- return e.addEventListener("request.end", i), function() {
1622
- e.removeEventListener("request.end", i);
1601
+ return e.addEventListener("request.end", n), function() {
1602
+ e.removeEventListener("request.end", n);
1623
1603
  };
1624
1604
  }
1625
1605
  async function writeFiles(e, t, r, { rmRoot: s = !1 } = {}) {
1626
1606
  s && await e.isDir(t) && await e.rmdir(t, { recursive: !0 });
1627
- for (const [i, n] of Object.entries(r)) {
1628
- const o = joinPaths(t, i);
1629
- await e.fileExists(dirname(o)) || await e.mkdir(dirname(o)), await e.writeFile(o, n);
1607
+ for (const [n, i] of Object.entries(r)) {
1608
+ const o = joinPaths(t, n);
1609
+ await e.fileExists(dirname(o)) || await e.mkdir(dirname(o)), await e.writeFile(o, i);
1630
1610
  }
1631
1611
  }
1632
1612
  export {
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Encodes a multipart/form-data request body.
3
+ *
4
+ * @param data - The form data to encode.
5
+ * @returns The encoded body and a correctly formatted content type header.
6
+ */
7
+ export declare function encodeAsMultipart(data: Record<string, string | Uint8Array | File>): Promise<{
8
+ bytes: Uint8Array;
9
+ contentType: string;
10
+ }>;
package/lib/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type { FileInfo, IsomorphicLocalPHP, IsomorphicRemotePHP, MessageListener, PHPOutput, PHPRunOptions, UniversalPHP, ListFilesOptions, RmDirOptions, PHPEvent, PHPEventListener, HTTPMethod, PHPRequest, PHPRequestHeaders, RequestHandler, SpawnHandler, } from './universal-php';
1
+ export type { IsomorphicLocalPHP, IsomorphicRemotePHP, MessageListener, PHPOutput, PHPRunOptions, UniversalPHP, ListFilesOptions, RmDirOptions, PHPEvent, PHPEventListener, HTTPMethod, PHPRequest, PHPRequestHeaders, RequestHandler, SpawnHandler, } from './universal-php';
2
2
  export { UnhandledRejectionsTarget } from './wasm-error-reporting';
3
3
  export type { IteratePhpFilesOptions as IterateFilesOptions } from './iterate-files';
4
4
  export { iteratePhpFiles as iterateFiles } from './iterate-files';
@@ -122,7 +122,7 @@ export interface RequestHandler {
122
122
  * headers: {
123
123
  * 'X-foo': 'bar',
124
124
  * },
125
- * formData: {
125
+ * body: {
126
126
  * foo: 'bar',
127
127
  * },
128
128
  * });
@@ -431,18 +431,11 @@ export interface PHPRequest {
431
431
  */
432
432
  headers?: PHPRequestHeaders;
433
433
  /**
434
- * Uploaded files
434
+ * Request body.
435
+ * If an object is given, the request will be encoded as multipart
436
+ * and sent with a `multipart/form-data` header.
435
437
  */
436
- files?: Record<string, File>;
437
- /**
438
- * Request body without the files.
439
- */
440
- body?: string;
441
- /**
442
- * Form data. If set, the request body will be ignored and
443
- * the content-type header will be set to `application/x-www-form-urlencoded`.
444
- */
445
- formData?: Record<string, unknown>;
438
+ body?: string | Uint8Array | Record<string, string | Uint8Array | File>;
446
439
  }
447
440
  export interface PHPRunOptions {
448
441
  /**
@@ -466,13 +459,9 @@ export interface PHPRunOptions {
466
459
  */
467
460
  headers?: PHPRequestHeaders;
468
461
  /**
469
- * Request body without the files.
462
+ * Request body.
470
463
  */
471
- body?: string;
472
- /**
473
- * Uploaded files.
474
- */
475
- fileInfos?: FileInfo[];
464
+ body?: string | Uint8Array;
476
465
  /**
477
466
  * The code snippet to eval instead of a php file.
478
467
  */
@@ -494,12 +483,6 @@ export interface PHPOutput {
494
483
  /** Stderr lines */
495
484
  stderr: string[];
496
485
  }
497
- export interface FileInfo {
498
- key: string;
499
- name: string;
500
- type: string;
501
- data: Uint8Array;
502
- }
503
486
  export interface RmDirOptions {
504
487
  /**
505
488
  * If true, recursively removes the directory and all its contents.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@php-wasm/universal",
3
- "version": "0.6.2",
3
+ "version": "0.6.3",
4
4
  "description": "PHP.wasm – emscripten bindings for PHP",
5
5
  "repository": {
6
6
  "type": "git",
@@ -36,7 +36,7 @@
36
36
  "main": "./index.cjs",
37
37
  "module": "./index.js",
38
38
  "license": "GPL-2.0-or-later",
39
- "gitHead": "3c0de0d0847c3550a75a026bef9724eac421afbf",
39
+ "gitHead": "0a8916ec08aa5f02de5fea308b287171e7948e4b",
40
40
  "engines": {
41
41
  "node": ">=18.18.2",
42
42
  "npm": ">=8.11.0"