@php-wasm/universal 0.6.1 → 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}typeof crypto>"u"&&Promise.resolve().then(()=>require("./__vite-browser-external-b3701507.cjs")).then(e=>{global.crypto=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 S in t.files){const L=t.files[S];d.push({key:S,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 S=r.pathname;if((o=t.headers)!=null&&o["x-rewrite-url"])try{S=new URL(t.headers["x-rewrite-url"]).pathname}catch{}I=p(this,M,ee).call(this,S)}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 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;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,b,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,b,[]),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,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,_)||(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]}}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(){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) {
@@ -45,4 +49,4 @@ ${bold} WASM ERROR${reset}${redBg}`);for(const t of e.split(`
45
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();
@@ -67,9 +67,6 @@ if (typeof CustomEvent > "u") {
67
67
  }
68
68
  globalThis.CustomEvent = e;
69
69
  }
70
- typeof crypto > "u" && import("./__vite-browser-external-2447137e.js").then((e) => {
71
- global.crypto = e;
72
- });
73
70
  const kError = Symbol("error"), kMessage = Symbol("message");
74
71
  class ErrorEvent2 extends Event {
75
72
  /**
@@ -117,16 +114,16 @@ function improveWASMErrorReporting(e) {
117
114
  for (const r in e.asm)
118
115
  if (typeof e.asm[r] == "function") {
119
116
  const s = e.asm[r];
120
- e.asm[r] = function(...i) {
121
- var n;
117
+ e.asm[r] = function(...n) {
118
+ var i;
122
119
  try {
123
- return s(...i);
120
+ return s(...n);
124
121
  } catch (o) {
125
122
  if (!(o instanceof Error))
126
123
  throw o;
127
124
  const l = clarifyErrorMessage(
128
125
  o,
129
- (n = e.lastAsyncifyStackSource) == null ? void 0 : n.stack
126
+ (i = e.lastAsyncifyStackSource) == null ? void 0 : i.stack
130
127
  );
131
128
  if (e.lastAsyncifyStackSource && (o.cause = e.lastAsyncifyStackSource), t.hasListeners()) {
132
129
  t.dispatchEvent(
@@ -269,8 +266,8 @@ function normalizePath(e) {
269
266
  function normalizePathsArray(e, t) {
270
267
  let r = 0;
271
268
  for (let s = e.length - 1; s >= 0; s--) {
272
- const i = e[s];
273
- 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--);
274
271
  }
275
272
  if (t)
276
273
  for (; r; r--)
@@ -334,7 +331,7 @@ class ChildProcess extends EventEmitter {
334
331
  }
335
332
  function concatUint8Array(...e) {
336
333
  const t = new Uint8Array(
337
- e.reduce((s, i) => s + i.length, 0)
334
+ e.reduce((s, n) => s + n.length, 0)
338
335
  );
339
336
  let r = 0;
340
337
  for (const s of e)
@@ -368,22 +365,22 @@ function concatBytes(e) {
368
365
  function limitBytes(e, t) {
369
366
  if (t === 0)
370
367
  return new ReadableStream({
371
- start(i) {
372
- i.close();
368
+ start(n) {
369
+ n.close();
373
370
  }
374
371
  });
375
372
  const r = e.getReader({ mode: "byob" });
376
373
  let s = 0;
377
374
  return new ReadableStream({
378
- async pull(i) {
379
- const { value: n, done: o } = await r.read(
375
+ async pull(n) {
376
+ const { value: i, done: o } = await r.read(
380
377
  new Uint8Array(t - s)
381
378
  );
382
379
  if (o) {
383
- r.releaseLock(), i.close();
380
+ r.releaseLock(), n.close();
384
381
  return;
385
382
  }
386
- 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());
387
384
  },
388
385
  cancel() {
389
386
  r.cancel();
@@ -462,25 +459,25 @@ function streamReadFileFromPHP(e, t) {
462
459
  async function* iteratePhpFiles(e, t, {
463
460
  relativePaths: r = !0,
464
461
  pathPrefix: s,
465
- exceptPaths: i = []
462
+ exceptPaths: n = []
466
463
  } = {}) {
467
464
  t = normalizePath(t);
468
- const n = [t];
469
- for (; n.length; ) {
470
- const o = n.pop();
465
+ const i = [t];
466
+ for (; i.length; ) {
467
+ const o = i.pop();
471
468
  if (!o)
472
469
  return;
473
470
  const l = await e.listFiles(o);
474
- for (const h of l) {
475
- const d = `${o}/${h}`;
476
- 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)))
477
474
  continue;
478
- await e.isDir(d) ? n.push(d) : yield new StreamedFile(
479
- streamReadFileFromPHP(e, d),
475
+ await e.isDir(u) ? i.push(u) : yield new StreamedFile(
476
+ streamReadFileFromPHP(e, u),
480
477
  r ? joinPaths(
481
478
  s || "",
482
- d.substring(t.length + 1)
483
- ) : d
479
+ u.substring(t.length + 1)
480
+ ) : u
484
481
  );
485
482
  }
486
483
  }
@@ -497,8 +494,8 @@ function writeFilesStreamToPhp(e, t) {
497
494
  });
498
495
  }
499
496
  class PHPResponse {
500
- constructor(t, r, s, i = "", n = 0) {
501
- 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;
502
499
  }
503
500
  static fromRawData(t) {
504
501
  return new PHPResponse(
@@ -549,7 +546,7 @@ const SupportedPHPVersions = [
549
546
  ], SupportedPHPExtensionBundles = {
550
547
  "kitchen-sink": SupportedPHPExtensionsList
551
548
  };
552
- var E, H;
549
+ var E, S;
553
550
  class PHPBrowser {
554
551
  /**
555
552
  * @param server - The PHP server to browse.
@@ -557,8 +554,8 @@ class PHPBrowser {
557
554
  */
558
555
  constructor(t, r = {}) {
559
556
  c(this, E, void 0);
560
- c(this, H, void 0);
561
- 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, {
562
559
  handleRedirects: !1,
563
560
  maxRedirects: 4,
564
561
  ...r
@@ -586,14 +583,14 @@ class PHPBrowser {
586
583
  cookie: this.serializeCookies()
587
584
  }
588
585
  });
589
- if (s.headers["set-cookie"] && this.setCookies(s.headers["set-cookie"]), a(this, H).handleRedirects && s.headers.location && r < a(this, H).maxRedirects) {
590
- 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(
591
588
  s.headers.location[0],
592
589
  this.requestHandler.absoluteUrl
593
590
  );
594
591
  return this.request(
595
592
  {
596
- url: i.toString(),
593
+ url: n.toString(),
597
594
  method: "GET",
598
595
  headers: {}
599
596
  },
@@ -623,8 +620,8 @@ class PHPBrowser {
623
620
  try {
624
621
  if (!r.includes("="))
625
622
  continue;
626
- const s = r.indexOf("="), i = r.substring(0, s), n = r.substring(s + 1).split(";")[0];
627
- 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;
628
625
  } catch (s) {
629
626
  console.error(s);
630
627
  }
@@ -636,7 +633,7 @@ class PHPBrowser {
636
633
  return t.join("; ");
637
634
  }
638
635
  }
639
- E = new WeakMap(), H = new WeakMap();
636
+ E = new WeakMap(), S = new WeakMap();
640
637
  const DEFAULT_BASE_URL = "http://example.com";
641
638
  function toRelativeUrl(e) {
642
639
  return e.toString().substring(e.origin.length);
@@ -647,7 +644,35 @@ function removePathPrefix(e, t) {
647
644
  function ensurePathPrefix(e, t) {
648
645
  return !t || e.startsWith(t) ? e : t + e;
649
646
  }
650
- 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;
651
676
  class PHPRequestHandler {
652
677
  /**
653
678
  * @param php - The PHP instance.
@@ -660,7 +685,7 @@ class PHPRequestHandler {
660
685
  * @param fsPath - Absolute path of the static file to serve.
661
686
  * @returns The response.
662
687
  */
663
- c(this, L);
688
+ c(this, U);
664
689
  /**
665
690
  * Runs the requested PHP file with all the request and $_SERVER
666
691
  * superglobals populated.
@@ -668,7 +693,7 @@ class PHPRequestHandler {
668
693
  * @param request - The request.
669
694
  * @returns The response.
670
695
  */
671
- c(this, N);
696
+ c(this, I);
672
697
  /**
673
698
  * Resolve the requested path to the filesystem path of the requested PHP file.
674
699
  *
@@ -678,31 +703,31 @@ class PHPRequestHandler {
678
703
  * @throws {Error} If the requested path doesn't exist.
679
704
  * @returns The resolved filesystem path.
680
705
  */
681
- c(this, M);
706
+ c(this, L);
682
707
  c(this, P, void 0);
683
- c(this, x, void 0);
684
- c(this, A, void 0);
708
+ c(this, H, void 0);
709
+ c(this, k, void 0);
685
710
  c(this, v, void 0);
711
+ c(this, x, void 0);
712
+ c(this, _, void 0);
686
713
  c(this, F, void 0);
687
- c(this, m, void 0);
688
- c(this, T, void 0);
689
714
  c(this, R, void 0);
690
- u(this, R, new Semaphore({ concurrency: 1 }));
715
+ h(this, R, new Semaphore({ concurrency: 1 }));
691
716
  const {
692
717
  documentRoot: s = "/www/",
693
- absoluteUrl: i = typeof location == "object" ? location == null ? void 0 : location.href : ""
718
+ absoluteUrl: n = typeof location == "object" ? location == null ? void 0 : location.href : ""
694
719
  } = r;
695
- this.php = t, u(this, P, s);
696
- const n = new URL(i);
697
- 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(":", ""));
698
723
  const o = a(this, v) !== 443 && a(this, v) !== 80;
699
- u(this, F, [
700
- a(this, A),
724
+ h(this, x, [
725
+ a(this, k),
701
726
  o ? `:${a(this, v)}` : ""
702
- ].join("")), u(this, m, n.pathname.replace(/\/+$/, "")), u(this, T, [
703
- `${a(this, x)}://`,
704
- a(this, F),
705
- a(this, m)
727
+ ].join("")), h(this, _, i.pathname.replace(/\/+$/, "")), h(this, F, [
728
+ `${a(this, H)}://`,
729
+ a(this, x),
730
+ a(this, _)
706
731
  ].join(""));
707
732
  }
708
733
  /** @inheritDoc */
@@ -712,14 +737,14 @@ class PHPRequestHandler {
712
737
  /** @inheritDoc */
713
738
  internalUrlToPath(t) {
714
739
  const r = new URL(t);
715
- 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);
716
741
  }
717
742
  get isRequestRunning() {
718
743
  return a(this, R).running > 0;
719
744
  }
720
745
  /** @inheritDoc */
721
746
  get absoluteUrl() {
722
- return a(this, T);
747
+ return a(this, F);
723
748
  }
724
749
  /** @inheritDoc */
725
750
  get documentRoot() {
@@ -730,14 +755,14 @@ class PHPRequestHandler {
730
755
  const r = t.url.startsWith("http://") || t.url.startsWith("https://"), s = new URL(
731
756
  t.url,
732
757
  r ? void 0 : DEFAULT_BASE_URL
733
- ), i = removePathPrefix(
758
+ ), n = removePathPrefix(
734
759
  s.pathname,
735
- a(this, m)
736
- ), n = `${a(this, P)}${i}`;
737
- 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);
738
763
  }
739
764
  }
740
- 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) {
741
766
  if (!this.php.fileExists(t))
742
767
  return new PHPResponse(
743
768
  404,
@@ -762,9 +787,9 @@ P = new WeakMap(), x = new WeakMap(), A = new WeakMap(), v = new WeakMap(), F =
762
787
  },
763
788
  r
764
789
  );
765
- }, N = new WeakSet(), X = async function(t, r) {
766
- var i, n, o;
767
- 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")
768
793
  return console.warn(
769
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."
770
795
  ), new PHPResponse(
@@ -776,43 +801,30 @@ P = new WeakMap(), x = new WeakMap(), A = new WeakMap(), v = new WeakMap(), F =
776
801
  try {
777
802
  this.php.addServerGlobalEntry("REMOTE_ADDR", "127.0.0.1"), this.php.addServerGlobalEntry("DOCUMENT_ROOT", a(this, P)), this.php.addServerGlobalEntry(
778
803
  "HTTPS",
779
- a(this, T).startsWith("https://") ? "on" : ""
804
+ a(this, F).startsWith("https://") ? "on" : ""
780
805
  );
781
- let l = "GET";
782
- const h = {
783
- host: a(this, F),
806
+ let o = "GET";
807
+ const l = {
808
+ host: a(this, x),
784
809
  ...normalizeHeaders(t.headers || {})
785
- }, d = [];
786
- if (t.files && Object.keys(t.files).length) {
787
- l = "POST";
788
- for (const S in t.files) {
789
- const U = t.files[S];
790
- d.push({
791
- key: S,
792
- name: U.name,
793
- type: U.type,
794
- data: new Uint8Array(await U.arrayBuffer())
795
- });
796
- }
797
- (n = h["content-type"]) != null && n.startsWith("multipart/form-data") && (t.formData = parseMultipartFormDataString(
798
- t.body || ""
799
- ), 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;
800
816
  }
801
- let p;
802
- t.formData !== void 0 ? (l = "POST", h["content-type"] = h["content-type"] || "application/x-www-form-urlencoded", p = new URLSearchParams(
803
- t.formData
804
- ).toString()) : p = t.body;
805
- let I;
817
+ let u;
806
818
  try {
807
- let S = r.pathname;
808
- if ((o = t.headers) != null && o["x-rewrite-url"])
819
+ let p = r.pathname;
820
+ if ((i = t.headers) != null && i["x-rewrite-url"])
809
821
  try {
810
- S = new URL(
822
+ p = new URL(
811
823
  t.headers["x-rewrite-url"]
812
824
  ).pathname;
813
825
  } catch {
814
826
  }
815
- I = f(this, M, ee).call(this, S);
827
+ u = f(this, L, K).call(this, p);
816
828
  } catch {
817
829
  return new PHPResponse(
818
830
  404,
@@ -823,41 +835,25 @@ P = new WeakMap(), x = new WeakMap(), A = new WeakMap(), v = new WeakMap(), F =
823
835
  return await this.php.run({
824
836
  relativeUri: ensurePathPrefix(
825
837
  toRelativeUrl(r),
826
- a(this, m)
838
+ a(this, _)
827
839
  ),
828
- protocol: a(this, x),
829
- method: t.method || l,
830
- body: p,
831
- fileInfos: d,
832
- scriptPath: I,
833
- headers: h
840
+ protocol: a(this, H),
841
+ method: t.method || o,
842
+ body: d,
843
+ scriptPath: u,
844
+ headers: l
834
845
  });
835
846
  } finally {
836
847
  s();
837
848
  }
838
- }, M = new WeakSet(), ee = function(t) {
839
- let r = removePathPrefix(t, a(this, m));
849
+ }, L = new WeakSet(), K = function(t) {
850
+ let r = removePathPrefix(t, a(this, _));
840
851
  r.includes(".php") ? r = r.split(".php")[0] + ".php" : (r.endsWith("/") || (r += "/"), r.endsWith("index.php") || (r += "index.php"));
841
852
  const s = `${a(this, P)}${r}`;
842
853
  if (this.php.fileExists(s))
843
854
  return s;
844
855
  throw new Error(`File not found: ${s}`);
845
856
  };
846
- function parseMultipartFormDataString(e) {
847
- const t = {}, r = e.match(/--(.*)\r\n/);
848
- if (!r)
849
- return t;
850
- const s = r[1], i = e.split(`--${s}`);
851
- return i.shift(), i.pop(), i.forEach((n) => {
852
- const o = n.indexOf(`\r
853
- \r
854
- `), l = n.substring(0, o).trim(), h = n.substring(o + 4).trim(), d = l.match(/name="([^"]+)"/);
855
- if (d) {
856
- const p = d[1];
857
- t[p] = h;
858
- }
859
- }), t;
860
- }
861
857
  function inferMimeType(e) {
862
858
  switch (e.split(".").pop()) {
863
859
  case "css":
@@ -992,16 +988,16 @@ function getEmscriptenFsError(e) {
992
988
  return FileErrorCodes[t];
993
989
  }
994
990
  function rethrowFileSystemError(e = "") {
995
- return function(r, s, i) {
996
- const n = i.value;
997
- i.value = function(...o) {
991
+ return function(r, s, n) {
992
+ const i = n.value;
993
+ n.value = function(...o) {
998
994
  try {
999
- return n.apply(this, o);
995
+ return i.apply(this, o);
1000
996
  } catch (l) {
1001
- const h = typeof l == "object" ? l == null ? void 0 : l.errno : null;
1002
- if (h in FileErrorCodes) {
1003
- const d = FileErrorCodes[h], p = typeof o[0] == "string" ? o[0] : null, I = p !== null ? e.replaceAll("{path}", p) : e;
1004
- 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}`, {
1005
1001
  cause: l
1006
1002
  });
1007
1003
  }
@@ -1013,9 +1009,9 @@ function rethrowFileSystemError(e = "") {
1013
1009
  const RuntimeId = Symbol("RuntimeId"), loadedRuntimes = /* @__PURE__ */ new Map();
1014
1010
  let lastRuntimeId = 0;
1015
1011
  async function loadPHPRuntime(e, t = {}) {
1016
- const [r, s, i] = makePromise(), n = e.init(currentJsRuntime, {
1012
+ const [r, s, n] = makePromise(), i = e.init(currentJsRuntime, {
1017
1013
  onAbort(l) {
1018
- i(l), console.error(l);
1014
+ n(l), console.error(l);
1019
1015
  },
1020
1016
  ENV: {},
1021
1017
  // Emscripten sometimes prepends a '/' to the path, which
@@ -1030,9 +1026,9 @@ async function loadPHPRuntime(e, t = {}) {
1030
1026
  });
1031
1027
  await r;
1032
1028
  const o = ++lastRuntimeId;
1033
- return n.id = o, n.originalExit = n._exit, n._exit = function(l) {
1034
- return loadedRuntimes.delete(o), n.originalExit(l);
1035
- }, 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;
1036
1032
  }
1037
1033
  function getLoadedRuntime(e) {
1038
1034
  return loadedRuntimes.get(e);
@@ -1047,12 +1043,12 @@ const currentJsRuntime = function() {
1047
1043
  return e.unshift(t), e;
1048
1044
  };
1049
1045
  var __defProp = Object.defineProperty, __getOwnPropDesc = Object.getOwnPropertyDescriptor, __decorateClass = (e, t, r, s) => {
1050
- for (var i = s > 1 ? void 0 : s ? __getOwnPropDesc(t, r) : t, n = e.length - 1, o; n >= 0; n--)
1051
- (o = e[n]) && (i = (s ? o(t, r, i) : o(i)) || i);
1052
- 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;
1053
1049
  };
1054
1050
  const STRING = "string", NUMBER = "number", __private__dont__use = Symbol("__private__dont__use");
1055
- 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;
1056
1052
  class BasePHP {
1057
1053
  /**
1058
1054
  * Initializes a PHP runtime.
@@ -1063,35 +1059,25 @@ class BasePHP {
1063
1059
  */
1064
1060
  constructor(e, t) {
1065
1061
  c(this, q);
1062
+ c(this, N);
1063
+ c(this, M);
1064
+ c(this, $);
1066
1065
  c(this, O);
1067
1066
  c(this, D);
1068
- c(this, $);
1069
1067
  c(this, j);
1070
1068
  c(this, z);
1071
- c(this, G);
1072
1069
  c(this, W);
1070
+ c(this, G);
1073
1071
  c(this, V);
1074
- /**
1075
- * Adds file information to $_FILES superglobal in PHP.
1076
- *
1077
- * In particular:
1078
- * * Creates the file data in the filesystem
1079
- * * Registers the file details in PHP
1080
- *
1081
- * @param fileInfo - File details
1082
- */
1083
- c(this, J);
1084
- c(this, Y);
1085
- c(this, Z);
1086
1072
  c(this, b, void 0);
1087
- c(this, C, void 0);
1088
- c(this, k, void 0);
1089
- c(this, _, void 0);
1073
+ c(this, T, void 0);
1074
+ c(this, A, void 0);
1075
+ c(this, m, void 0);
1090
1076
  c(this, w, void 0);
1091
1077
  c(this, g, void 0);
1092
1078
  c(this, y, void 0);
1093
- c(this, B, void 0);
1094
- 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(
1095
1081
  new PHPRequestHandler(this, t)
1096
1082
  ));
1097
1083
  }
@@ -1110,7 +1096,7 @@ class BasePHP {
1110
1096
  }
1111
1097
  /** @inheritDoc */
1112
1098
  async onMessage(e) {
1113
- a(this, B).push(e);
1099
+ a(this, C).push(e);
1114
1100
  }
1115
1101
  /** @inheritDoc */
1116
1102
  async setSpawnHandler(handler) {
@@ -1141,13 +1127,13 @@ class BasePHP {
1141
1127
  if (!t)
1142
1128
  throw new Error("Invalid PHP runtime id.");
1143
1129
  this[__private__dont__use] = t, t.onMessage = async (r) => {
1144
- for (const s of a(this, B)) {
1145
- const i = await s(r);
1146
- if (i)
1147
- return i;
1130
+ for (const s of a(this, C)) {
1131
+ const n = await s(r);
1132
+ if (n)
1133
+ return n;
1148
1134
  }
1149
1135
  return "";
1150
- }, u(this, w, improveWASMErrorReporting(t)), this.dispatchEvent({
1136
+ }, h(this, w, improveWASMErrorReporting(t)), this.dispatchEvent({
1151
1137
  type: "runtime.initialized"
1152
1138
  });
1153
1139
  }
@@ -1162,13 +1148,13 @@ class BasePHP {
1162
1148
  throw new Error(
1163
1149
  "Could not set SAPI name. This can only be done before the PHP WASM module is initialized.Did you already dispatch any requests?"
1164
1150
  );
1165
- u(this, k, e);
1151
+ h(this, A, e);
1166
1152
  }
1167
1153
  /** @inheritDoc */
1168
1154
  setPhpIniPath(e) {
1169
- if (a(this, _))
1155
+ if (a(this, m))
1170
1156
  throw new Error("Cannot set PHP ini path after calling run().");
1171
- u(this, C, e), this[__private__dont__use].ccall(
1157
+ h(this, T, e), this[__private__dont__use].ccall(
1172
1158
  "wasm_set_phpini_path",
1173
1159
  null,
1174
1160
  ["string"],
@@ -1177,7 +1163,7 @@ class BasePHP {
1177
1163
  }
1178
1164
  /** @inheritDoc */
1179
1165
  setPhpIniEntry(e, t) {
1180
- if (a(this, _))
1166
+ if (a(this, m))
1181
1167
  throw new Error("Cannot set PHP ini entries after calling run().");
1182
1168
  a(this, b).push([e, t]);
1183
1169
  }
@@ -1196,25 +1182,22 @@ class BasePHP {
1196
1182
  const t = await this.semaphore.acquire();
1197
1183
  let r;
1198
1184
  try {
1199
- 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");
1200
- const s = normalizeHeaders(e.headers || {}), i = s.host || "example.com:443";
1201
- 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)
1202
- for (const o of e.fileInfos)
1203
- f(this, J, ue).call(this, o);
1204
- typeof e.code == "string" && f(this, Y, de).call(this, " ?>" + e.code), f(this, V, ce).call(this);
1205
- const n = await f(this, Z, he).call(this);
1206
- 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) {
1207
1190
  const o = {
1208
- stdout: n.text,
1209
- stderr: n.errors
1191
+ stdout: i.text,
1192
+ stderr: i.errors
1210
1193
  };
1211
1194
  console.warn("PHP.run() output was:", o);
1212
1195
  const l = new Error(
1213
- `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`
1214
1197
  );
1215
1198
  throw l.output = o, l;
1216
1199
  }
1217
- return n;
1200
+ return i;
1218
1201
  } finally {
1219
1202
  try {
1220
1203
  r && this[__private__dont__use].free(r);
@@ -1291,7 +1274,7 @@ class BasePHP {
1291
1274
  );
1292
1275
  if (t.prependPath) {
1293
1276
  const s = e.replace(/\/$/, "");
1294
- return r.map((i) => `${s}/${i}`);
1277
+ return r.map((n) => `${s}/${n}`);
1295
1278
  }
1296
1279
  return r;
1297
1280
  } catch (r) {
@@ -1322,7 +1305,7 @@ class BasePHP {
1322
1305
  this.exit();
1323
1306
  } catch {
1324
1307
  }
1325
- 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) {
1326
1309
  const r = this.documentRoot;
1327
1310
  recreateMemFS(this[__private__dont__use].FS, t, r);
1328
1311
  }
@@ -1335,10 +1318,10 @@ class BasePHP {
1335
1318
  this[__private__dont__use]._exit(e);
1336
1319
  } catch {
1337
1320
  }
1338
- 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];
1339
1322
  }
1340
1323
  }
1341
- 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() {
1342
1325
  if (this.setPhpIniEntry("auto_prepend_file", "/tmp/consts.php"), this.fileExists("/tmp/consts.php") || this.writeFile(
1343
1326
  "/tmp/consts.php",
1344
1327
  `<?php
@@ -1363,7 +1346,7 @@ b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), _ = new WeakMap(), w =
1363
1346
  );
1364
1347
  }
1365
1348
  this[__private__dont__use].ccall("php_wasm_init", null, [], []);
1366
- }, O = new WeakSet(), re = function() {
1349
+ }, N = new WeakSet(), X = function() {
1367
1350
  const e = "/tmp/headers.json";
1368
1351
  if (!this.fileExists(e))
1369
1352
  throw new Error(
@@ -1373,14 +1356,14 @@ b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), _ = new WeakMap(), w =
1373
1356
  for (const s of t.headers) {
1374
1357
  if (!s.includes(": "))
1375
1358
  continue;
1376
- const i = s.indexOf(": "), n = s.substring(0, i).toLowerCase(), o = s.substring(i + 2);
1377
- 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);
1378
1361
  }
1379
1362
  return {
1380
1363
  headers: r,
1381
1364
  httpStatusCode: t.status
1382
1365
  };
1383
- }, D = new WeakSet(), se = function(e) {
1366
+ }, M = new WeakSet(), ee = function(e) {
1384
1367
  if (this[__private__dont__use].ccall(
1385
1368
  "wasm_set_request_uri",
1386
1369
  null,
@@ -1395,7 +1378,7 @@ b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), _ = new WeakMap(), w =
1395
1378
  [t]
1396
1379
  );
1397
1380
  }
1398
- }, $ = new WeakSet(), ne = function(e, t) {
1381
+ }, $ = new WeakSet(), te = function(e, t) {
1399
1382
  this[__private__dont__use].ccall(
1400
1383
  "wasm_set_request_host",
1401
1384
  null,
@@ -1413,14 +1396,14 @@ b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), _ = new WeakMap(), w =
1413
1396
  [NUMBER],
1414
1397
  [r]
1415
1398
  ), (t === "https" || !t && r === 443) && this.addServerGlobalEntry("HTTPS", "on");
1416
- }, j = new WeakSet(), ie = function(e) {
1399
+ }, O = new WeakSet(), re = function(e) {
1417
1400
  this[__private__dont__use].ccall(
1418
1401
  "wasm_set_request_method",
1419
1402
  null,
1420
1403
  [STRING],
1421
1404
  [e]
1422
1405
  );
1423
- }, z = new WeakSet(), oe = function(e) {
1406
+ }, D = new WeakSet(), se = function(e) {
1424
1407
  e.cookie && this[__private__dont__use].ccall(
1425
1408
  "wasm_set_cookies",
1426
1409
  null,
@@ -1444,33 +1427,37 @@ b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), _ = new WeakMap(), w =
1444
1427
  e[t]
1445
1428
  );
1446
1429
  }
1447
- }, G = new WeakSet(), ae = function(e) {
1448
- const t = this[__private__dont__use].lengthBytesUTF8(e), r = this[__private__dont__use].malloc(t + 1);
1449
- 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)
1450
1437
  throw new Error("Could not allocate memory for the request body.");
1451
- return this[__private__dont__use].stringToUTF8(
1438
+ return typeof e == "string" ? this[__private__dont__use].stringToUTF8(
1452
1439
  e,
1453
- r,
1440
+ s,
1454
1441
  t + 1
1455
- ), this[__private__dont__use].ccall(
1442
+ ) : this[__private__dont__use].HEAPU8.set(e, s), this[__private__dont__use].ccall(
1456
1443
  "wasm_set_request_body",
1457
1444
  null,
1458
1445
  [NUMBER],
1459
- [r]
1446
+ [s]
1460
1447
  ), this[__private__dont__use].ccall(
1461
1448
  "wasm_set_content_length",
1462
1449
  null,
1463
1450
  [NUMBER],
1464
- [new TextEncoder().encode(e).length]
1465
- ), r;
1466
- }, W = new WeakSet(), le = function(e) {
1451
+ [r]
1452
+ ), s;
1453
+ }, z = new WeakSet(), ie = function(e) {
1467
1454
  this[__private__dont__use].ccall(
1468
1455
  "wasm_set_path_translated",
1469
1456
  null,
1470
1457
  [STRING],
1471
1458
  [e]
1472
1459
  );
1473
- }, V = new WeakSet(), ce = function() {
1460
+ }, W = new WeakSet(), oe = function() {
1474
1461
  for (const e in a(this, g))
1475
1462
  this[__private__dont__use].ccall(
1476
1463
  "wasm_add_SERVER_entry",
@@ -1478,33 +1465,23 @@ b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), _ = new WeakMap(), w =
1478
1465
  [STRING, STRING],
1479
1466
  [e, a(this, g)[e]]
1480
1467
  );
1481
- }, J = new WeakSet(), ue = function(e) {
1482
- const { key: t, name: r, type: s, data: i } = e, n = `/tmp/${Math.random().toFixed(20)}`;
1483
- this.writeFile(n, i);
1484
- const o = 0;
1485
- this[__private__dont__use].ccall(
1486
- "wasm_add_uploaded_file",
1487
- null,
1488
- [STRING, STRING, STRING, STRING, NUMBER, NUMBER],
1489
- [t, r, s, n, o, i.byteLength]
1490
- );
1491
- }, Y = new WeakSet(), de = function(e) {
1468
+ }, G = new WeakSet(), ae = function(e) {
1492
1469
  this[__private__dont__use].ccall(
1493
1470
  "wasm_set_php_code",
1494
1471
  null,
1495
1472
  [STRING],
1496
1473
  [e]
1497
1474
  );
1498
- }, Z = new WeakSet(), he = async function() {
1499
- var i;
1475
+ }, V = new WeakSet(), le = async function() {
1476
+ var n;
1500
1477
  let e, t;
1501
1478
  try {
1502
- e = await new Promise((n, o) => {
1503
- var h;
1504
- t = (d) => {
1479
+ e = await new Promise((i, o) => {
1480
+ var d;
1481
+ t = (u) => {
1505
1482
  const p = new Error("Rethrown");
1506
- p.cause = d.error, p.betterMessage = d.message, o(p);
1507
- }, (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(
1508
1485
  "error",
1509
1486
  t
1510
1487
  );
@@ -1515,22 +1492,22 @@ b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), _ = new WeakMap(), w =
1515
1492
  [],
1516
1493
  { async: !0 }
1517
1494
  );
1518
- return l instanceof Promise ? l.then(n, o) : n(l);
1495
+ return l instanceof Promise ? l.then(i, o) : i(l);
1519
1496
  });
1520
- } catch (n) {
1521
- for (const d in this)
1522
- typeof this[d] == "function" && (this[d] = () => {
1497
+ } catch (i) {
1498
+ for (const u in this)
1499
+ typeof this[u] == "function" && (this[u] = () => {
1523
1500
  throw new Error(
1524
1501
  "PHP runtime has crashed – see the earlier error for details."
1525
1502
  );
1526
1503
  });
1527
1504
  this.functionsMaybeMissingFromAsyncify = getFunctionsMaybeMissingFromAsyncify();
1528
- const o = n, l = "betterMessage" in o ? o.betterMessage : o.message, h = new Error(l);
1529
- 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;
1530
1507
  } finally {
1531
- (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, {});
1532
1509
  }
1533
- const { headers: r, httpStatusCode: s } = f(this, O, re).call(this);
1510
+ const { headers: r, httpStatusCode: s } = f(this, N, X).call(this);
1534
1511
  return new PHPResponse(
1535
1512
  s,
1536
1513
  r,
@@ -1594,9 +1571,9 @@ function recreateMemFS(e, t, r) {
1594
1571
  return;
1595
1572
  }
1596
1573
  e.mkdirTree(r);
1597
- const i = t.readdir(r).filter((n) => n !== "." && n !== "..");
1598
- for (const n of i)
1599
- 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));
1600
1577
  }
1601
1578
  function isLocalPHP(e) {
1602
1579
  return !(e instanceof BasePHP);
@@ -1610,26 +1587,26 @@ function rotatePHPRuntime({
1610
1587
  maxRequests: r
1611
1588
  }) {
1612
1589
  let s = 0;
1613
- async function i() {
1590
+ async function n() {
1614
1591
  if (++s < r)
1615
1592
  return;
1616
1593
  s = 0;
1617
- const n = await e.semaphore.acquire();
1594
+ const i = await e.semaphore.acquire();
1618
1595
  try {
1619
1596
  e.hotSwapPHPRuntime(await t());
1620
1597
  } finally {
1621
- n();
1598
+ i();
1622
1599
  }
1623
1600
  }
1624
- return e.addEventListener("request.end", i), function() {
1625
- e.removeEventListener("request.end", i);
1601
+ return e.addEventListener("request.end", n), function() {
1602
+ e.removeEventListener("request.end", n);
1626
1603
  };
1627
1604
  }
1628
1605
  async function writeFiles(e, t, r, { rmRoot: s = !1 } = {}) {
1629
1606
  s && await e.isDir(t) && await e.rmdir(t, { recursive: !0 });
1630
- for (const [i, n] of Object.entries(r)) {
1631
- const o = joinPaths(t, i);
1632
- 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);
1633
1610
  }
1634
1611
  }
1635
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.1",
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": "171b22b853786b8912d9624ea064eaa1e985e96b",
39
+ "gitHead": "0a8916ec08aa5f02de5fea308b287171e7948e4b",
40
40
  "engines": {
41
41
  "node": ">=18.18.2",
42
42
  "npm": ">=8.11.0"
@@ -1,4 +0,0 @@
1
- const e = {};
2
- export {
3
- e as default
4
- };
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e={};exports.default=e;