@php-wasm/universal 0.1.61 → 0.3.0

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,10 +1,10 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const E=Symbol("error"),S=Symbol("message");class v extends Event{constructor(e,t={}){super(e),this[E]=t.error===void 0?null:t.error,this[S]=t.message===void 0?"":t.message}get error(){return this[E]}get message(){return this[S]}}Object.defineProperty(v.prototype,"error",{enumerable:!0});Object.defineProperty(v.prototype,"message",{enumerable:!0});const M=typeof globalThis.ErrorEvent=="function"?globalThis.ErrorEvent:v;class C extends EventTarget{constructor(){super(...arguments),this.listenersCount=0}addEventListener(e,t){++this.listenersCount,super.addEventListener(e,t)}removeEventListener(e,t){--this.listenersCount,super.removeEventListener(e,t)}hasListeners(){return this.listenersCount>0}}function B(n){n.asm={...n.asm};const e=new C;for(const t in n.asm)if(typeof n.asm[t]=="function"){const r=n.asm[t];n.asm[t]=function(...s){try{return r(...s)}catch(o){if(!(o instanceof Error))throw o;if("exitCode"in o&&o?.exitCode===0)return;const i=q(o,n.lastAsyncifyStackSource?.stack);if(n.lastAsyncifyStackSource&&(o.cause=n.lastAsyncifyStackSource),!e.hasListeners())throw z(i),o;e.dispatchEvent(new M("error",{error:o,message:i}))}}}return e}let w=[];function D(){return w}function q(n,e){if(n.message==="unreachable"){let t=W;e||(t+=`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const R=Symbol("error"),S=Symbol("message");class E extends Event{constructor(e,t={}){super(e),this[R]=t.error===void 0?null:t.error,this[S]=t.message===void 0?"":t.message}get error(){return this[R]}get message(){return this[S]}}Object.defineProperty(E.prototype,"error",{enumerable:!0});Object.defineProperty(E.prototype,"message",{enumerable:!0});const D=typeof globalThis.ErrorEvent=="function"?globalThis.ErrorEvent:E;function A(s){return s instanceof Error?"exitCode"in s&&s?.exitCode===0||s?.name==="ExitStatus"&&"status"in s&&s.status===0:!1}class U extends EventTarget{constructor(){super(...arguments),this.listenersCount=0}addEventListener(e,t){++this.listenersCount,super.addEventListener(e,t)}removeEventListener(e,t){--this.listenersCount,super.removeEventListener(e,t)}hasListeners(){return this.listenersCount>0}}function W(s){s.asm={...s.asm};const e=new U;for(const t in s.asm)if(typeof s.asm[t]=="function"){const r=s.asm[t];s.asm[t]=function(...n){try{return r(...n)}catch(o){if(!(o instanceof Error))throw o;const i=z(o,s.lastAsyncifyStackSource?.stack);if(s.lastAsyncifyStackSource&&(o.cause=s.lastAsyncifyStackSource),e.hasListeners()){e.dispatchEvent(new D("error",{error:o,message:i}));return}throw A(o)||Y(i),o}}}return e}let P=[];function j(){return P}function z(s,e){if(s.message==="unreachable"){let t=G;e||(t+=`
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 }).
5
5
 
6
- `),w=G(e||n.stack||"");for(const r of w)t+=` * ${r}
7
- `;return t}return n.message}const W=`
6
+ `),P=J(e||s.stack||"");for(const r of P)t+=` * ${r}
7
+ `;return t}return s.message}const G=`
8
8
  "unreachable" WASM instruction executed.
9
9
 
10
10
  The typical reason is a PHP function missing from the ASYNCIFY_ONLY
@@ -28,13 +28,13 @@ the Dockerfile, you'll need to trigger this error again with long stack
28
28
  traces enabled. In node.js, you can do it using the --stack-trace-limit=100
29
29
  CLI option:
30
30
 
31
- `,x="\x1B[41m",j="\x1B[1m",H="\x1B[0m",T="\x1B[K";let k=!1;function z(n){if(!k){k=!0,console.log(`${x}
32
- ${T}
33
- ${j} WASM ERROR${H}${x}`);for(const e of n.split(`
34
- `))console.log(`${T} ${e} `);console.log(`${H}`)}}function G(n){try{const e=n.split(`
35
- `).slice(1).map(t=>{const r=t.trim().substring(3).split(" ");return{fn:r.length>=2?r[0]:"<unknown>",isWasm:t.includes("wasm://")}}).filter(({fn:t,isWasm:r})=>r&&!t.startsWith("dynCall_")&&!t.startsWith("invoke_")).map(({fn:t})=>t);return Array.from(new Set(e))}catch{return[]}}class y{constructor(e,t,r,s="",o=0){this.httpStatusCode=e,this.headers=t,this.bytes=r,this.exitCode=o,this.errors=s}static fromRawData(e){return new y(e.httpStatusCode,e.headers,e.bytes,e.errors,e.exitCode)}toRawData(){return{headers:this.headers,bytes:this.bytes,errors:this.errors,exitCode:this.exitCode,httpStatusCode:this.httpStatusCode}}get json(){return JSON.parse(this.text)}get text(){return new TextDecoder().decode(this.bytes)}}const R=["8.2","8.1","8.0","7.4","7.3","7.2","7.1","7.0","5.6"],V=R[0],Y=R;class U{#e;#t;constructor(e,t={}){this.requestHandler=e,this.#e={},this.#t={handleRedirects:!1,maxRedirects:4,...t}}async request(e,t=0){const r=await this.requestHandler.request({...e,headers:{...e.headers,cookie:this.#r()}});if(r.headers["set-cookie"]&&this.#s(r.headers["set-cookie"]),this.#t.handleRedirects&&r.headers.location&&t<this.#t.maxRedirects){const s=new URL(r.headers.location[0],this.requestHandler.absoluteUrl);return this.request({url:s.toString(),method:"GET",headers:{}},t+1)}return r}pathToInternalUrl(e){return this.requestHandler.pathToInternalUrl(e)}internalUrlToPath(e){return this.requestHandler.internalUrlToPath(e)}get absoluteUrl(){return this.requestHandler.absoluteUrl}get documentRoot(){return this.requestHandler.documentRoot}#s(e){for(const t of e)try{if(!t.includes("="))continue;const r=t.indexOf("="),s=t.substring(0,r),o=t.substring(r+1).split(";")[0];this.#e[s]=o}catch(r){console.error(r)}}#r(){const e=[];for(const t in this.#e)e.push(`${t}=${this.#e[t]}`);return e.join("; ")}}class J{constructor({concurrency:e}){this._running=0,this.concurrency=e,this.queue=[]}get running(){return this._running}async acquire(){for(;;)if(this._running>=this.concurrency)await new Promise(e=>this.queue.push(e));else{this._running++;let e=!1;return()=>{e||(e=!0,this._running--,this.queue.length>0&&this.queue.shift()())}}}async run(e){const t=await this.acquire();try{return await e()}finally{t()}}}const A="http://example.com";function P(n){return n.toString().substring(n.origin.length)}function b(n,e){return!e||!n.startsWith(e)?n:n.substring(e.length)}function O(n,e){return!e||n.startsWith(e)?n:e+n}class I{#e;#t;#s;#r;#o;#n;#i;#a;#l;constructor(e,t={}){this.#a=new J({concurrency:1});const{documentRoot:r="/www/",absoluteUrl:s=typeof location=="object"?location?.href:"",isStaticFilePath:o=()=>!1}=t;this.php=e,this.#e=r,this.#l=o;const i=new URL(s);this.#s=i.hostname,this.#r=i.port?Number(i.port):i.protocol==="https:"?443:80,this.#t=(i.protocol||"").replace(":","");const l=this.#r!==443&&this.#r!==80;this.#o=[this.#s,l?`:${this.#r}`:""].join(""),this.#n=i.pathname.replace(/\/+$/,""),this.#i=[`${this.#t}://`,this.#o,this.#n].join("")}pathToInternalUrl(e){return`${this.absoluteUrl}${e}`}internalUrlToPath(e){const t=new URL(e);return t.pathname.startsWith(this.#n)&&(t.pathname=t.pathname.slice(this.#n.length)),P(t)}get isRequestRunning(){return this.#a.running>0}get absoluteUrl(){return this.#i}get documentRoot(){return this.#e}async request(e){const t=e.url.startsWith("http://")||e.url.startsWith("https://"),r=new URL(e.url,t?void 0:A),s=b(r.pathname,this.#n);return this.#l(s)?this.#c(s):await this.#h(e,r)}#c(e){const t=`${this.#e}${e}`;if(!this.php.fileExists(t))return new y(404,{},new TextEncoder().encode("404 File not found"));const r=this.php.readFileAsBuffer(t);return new y(200,{"content-length":[`${r.byteLength}`],"content-type":[Q(t)],"accept-ranges":["bytes"],"cache-control":["public, max-age=0"]},r)}async#h(e,t){const r=await this.#a.acquire();try{this.php.addServerGlobalEntry("DOCUMENT_ROOT",this.#e),this.php.addServerGlobalEntry("HTTPS",this.#i.startsWith("https://")?"on":"");let s="GET";const o={host:this.#o,...L(e.headers||{})},i=[];if(e.files&&Object.keys(e.files).length){s="POST";for(const u in e.files){const m=e.files[u];i.push({key:u,name:m.name,type:m.type,data:new Uint8Array(await m.arrayBuffer())})}o["content-type"]?.startsWith("multipart/form-data")&&(e.formData=K(e.body||""),o["content-type"]="application/x-www-form-urlencoded",delete e.body)}let l;e.formData!==void 0?(s="POST",o["content-type"]=o["content-type"]||"application/x-www-form-urlencoded",l=new URLSearchParams(e.formData).toString()):l=e.body;let c;try{c=this.#u(t.pathname)}catch{return new y(404,{},new TextEncoder().encode("404 File not found"))}return await this.php.run({relativeUri:O(P(t),this.#n),protocol:this.#t,method:e.method||s,body:l,fileInfos:i,scriptPath:c,headers:o})}finally{r()}}#u(e){let t=b(e,this.#n);t.includes(".php")?t=t.split(".php")[0]+".php":(t.endsWith("/")||(t+="/"),t.endsWith("index.php")||(t+="index.php"));const r=`${this.#e}${t}`;if(this.php.fileExists(r))return r;if(!this.php.fileExists(`${this.#e}/index.php`))throw new Error(`File not found: ${r}`);return`${this.#e}/index.php`}}function K(n){const e={},t=n.match(/--(.*)\r\n/);if(!t)return e;const r=t[1],s=n.split(`--${r}`);return s.shift(),s.pop(),s.forEach(o=>{const i=o.indexOf(`\r
31
+ `,x="\x1B[41m",V="\x1B[1m",H="\x1B[0m",k="\x1B[K";let T=!1;function Y(s){if(!T){T=!0,console.log(`${x}
32
+ ${k}
33
+ ${V} WASM ERROR${H}${x}`);for(const e of s.split(`
34
+ `))console.log(`${k} ${e} `);console.log(`${H}`)}}function J(s){try{const e=s.split(`
35
+ `).slice(1).map(t=>{const r=t.trim().substring(3).split(" ");return{fn:r.length>=2?r[0]:"<unknown>",isWasm:t.includes("wasm://")}}).filter(({fn:t,isWasm:r})=>r&&!t.startsWith("dynCall_")&&!t.startsWith("invoke_")).map(({fn:t})=>t);return Array.from(new Set(e))}catch{return[]}}class y{constructor(e,t,r,n="",o=0){this.httpStatusCode=e,this.headers=t,this.bytes=r,this.exitCode=o,this.errors=n}static fromRawData(e){return new y(e.httpStatusCode,e.headers,e.bytes,e.errors,e.exitCode)}toRawData(){return{headers:this.headers,bytes:this.bytes,errors:this.errors,exitCode:this.exitCode,httpStatusCode:this.httpStatusCode}}get json(){return JSON.parse(this.text)}get text(){return new TextDecoder().decode(this.bytes)}}const v=["8.2","8.1","8.0","7.4","7.3","7.2","7.1","7.0","5.6"],K=v[0],Z=v,L=["iconv","mbstring","xml-bundle","gd"],Q={"kitchen-sink":L};class O{#e;#t;constructor(e,t={}){this.requestHandler=e,this.#e={},this.#t={handleRedirects:!1,maxRedirects:4,...t}}async request(e,t=0){const r=await this.requestHandler.request({...e,headers:{...e.headers,cookie:this.#r()}});if(r.headers["set-cookie"]&&this.#s(r.headers["set-cookie"]),this.#t.handleRedirects&&r.headers.location&&t<this.#t.maxRedirects){const n=new URL(r.headers.location[0],this.requestHandler.absoluteUrl);return this.request({url:n.toString(),method:"GET",headers:{}},t+1)}return r}pathToInternalUrl(e){return this.requestHandler.pathToInternalUrl(e)}internalUrlToPath(e){return this.requestHandler.internalUrlToPath(e)}get absoluteUrl(){return this.requestHandler.absoluteUrl}get documentRoot(){return this.requestHandler.documentRoot}#s(e){for(const t of e)try{if(!t.includes("="))continue;const r=t.indexOf("="),n=t.substring(0,r),o=t.substring(r+1).split(";")[0];this.#e[n]=o}catch(r){console.error(r)}}#r(){const e=[];for(const t in this.#e)e.push(`${t}=${this.#e[t]}`);return e.join("; ")}}class X{constructor({concurrency:e}){this._running=0,this.concurrency=e,this.queue=[]}get running(){return this._running}async acquire(){for(;;)if(this._running>=this.concurrency)await new Promise(e=>this.queue.push(e));else{this._running++;let e=!1;return()=>{e||(e=!0,this._running--,this.queue.length>0&&this.queue.shift()())}}}async run(e){const t=await this.acquire();try{return await e()}finally{t()}}}const I="http://example.com";function w(s){return s.toString().substring(s.origin.length)}function b(s,e){return!e||!s.startsWith(e)?s:s.substring(e.length)}function N(s,e){return!e||s.startsWith(e)?s:e+s}class ${#e;#t;#s;#r;#o;#n;#i;#a;constructor(e,t={}){this.#a=new X({concurrency:1});const{documentRoot:r="/www/",absoluteUrl:n=typeof location=="object"?location?.href:""}=t;this.php=e,this.#e=r;const o=new URL(n);this.#s=o.hostname,this.#r=o.port?Number(o.port):o.protocol==="https:"?443:80,this.#t=(o.protocol||"").replace(":","");const i=this.#r!==443&&this.#r!==80;this.#o=[this.#s,i?`:${this.#r}`:""].join(""),this.#n=o.pathname.replace(/\/+$/,""),this.#i=[`${this.#t}://`,this.#o,this.#n].join("")}pathToInternalUrl(e){return`${this.absoluteUrl}${e}`}internalUrlToPath(e){const t=new URL(e);return t.pathname.startsWith(this.#n)&&(t.pathname=t.pathname.slice(this.#n.length)),w(t)}get isRequestRunning(){return this.#a.running>0}get absoluteUrl(){return this.#i}get documentRoot(){return this.#e}async request(e){const t=e.url.startsWith("http://")||e.url.startsWith("https://"),r=new URL(e.url,t?void 0:I),n=b(r.pathname,this.#n),o=`${this.#e}${n}`;return re(o)?await this.#c(e,r):this.#l(o)}#l(e){if(!this.php.fileExists(e))return new y(404,{"x-file-type":["static"]},new TextEncoder().encode("404 File not found"));const t=this.php.readFileAsBuffer(e);return new y(200,{"content-length":[`${t.byteLength}`],"content-type":[te(e)],"accept-ranges":["bytes"],"cache-control":["public, max-age=0"]},t)}async#c(e,t){const r=await this.#a.acquire();try{this.php.addServerGlobalEntry("DOCUMENT_ROOT",this.#e),this.php.addServerGlobalEntry("HTTPS",this.#i.startsWith("https://")?"on":"");let n="GET";const o={host:this.#o,...B(e.headers||{})},i=[];if(e.files&&Object.keys(e.files).length){n="POST";for(const c in e.files){const m=e.files[c];i.push({key:c,name:m.name,type:m.type,data:new Uint8Array(await m.arrayBuffer())})}o["content-type"]?.startsWith("multipart/form-data")&&(e.formData=ee(e.body||""),o["content-type"]="application/x-www-form-urlencoded",delete e.body)}let l;e.formData!==void 0?(n="POST",o["content-type"]=o["content-type"]||"application/x-www-form-urlencoded",l=new URLSearchParams(e.formData).toString()):l=e.body;let u;try{u=this.#u(t.pathname)}catch{return new y(404,{},new TextEncoder().encode("404 File not found"))}return await this.php.run({relativeUri:N(w(t),this.#n),protocol:this.#t,method:e.method||n,body:l,fileInfos:i,scriptPath:u,headers:o})}finally{r()}}#u(e){let t=b(e,this.#n);t.includes(".php")?t=t.split(".php")[0]+".php":(t.endsWith("/")||(t+="/"),t.endsWith("index.php")||(t+="index.php"));const r=`${this.#e}${t}`;if(this.php.fileExists(r))return r;if(!this.php.fileExists(`${this.#e}/index.php`))throw new Error(`File not found: ${r}`);return`${this.#e}/index.php`}}function ee(s){const e={},t=s.match(/--(.*)\r\n/);if(!t)return e;const r=t[1],n=s.split(`--${r}`);return n.shift(),n.pop(),n.forEach(o=>{const i=o.indexOf(`\r
36
36
  \r
37
- `),l=o.substring(0,i).trim(),c=o.substring(i+4).trim(),u=l.match(/name="([^"]+)"/);if(u){const m=u[1];e[m]=c}}),e}function Q(n){switch(n.split(".").pop()){case"css":return"text/css";case"js":return"application/javascript";case"png":return"image/png";case"jpg":case"jpeg":return"image/jpeg";case"gif":return"image/gif";case"svg":return"image/svg+xml";case"woff":return"font/woff";case"woff2":return"font/woff2";case"ttf":return"font/ttf";case"otf":return"font/otf";case"eot":return"font/eot";case"ico":return"image/x-icon";case"html":return"text/html";case"json":return"application/json";case"xml":return"application/xml";case"txt":case"md":return"text/plain";default:return"application-octet-stream"}}const F={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 p(n=""){return function(t,r,s){const o=s.value;s.value=function(...i){try{return o.apply(this,i)}catch(l){const c=typeof l=="object"?l?.errno:null;if(c in F){const u=F[c],m=typeof i[0]=="string"?i[0]:null,$=m!==null?n.replaceAll("{path}",m):n;throw new Error(`${$}: ${u}`,{cause:l})}throw l}}}}async function X(n,e={},t=[]){let r,s;const o=new Promise(c=>{s=c}),i=new Promise(c=>{r=c}),l=n.init(ee,{onAbort(c){console.error("WASM aborted: "),console.error(c)},ENV:{},locateFile:c=>c,...e,noInitialRun:!0,onRuntimeInitialized(){e.onRuntimeInitialized&&e.onRuntimeInitialized(),r()},monitorRunDependencies(c){c===0&&(delete l.monitorRunDependencies,s())}});for(const{default:c}of t)c(l);return t.length||s(),await o,await i,_.push(l),_.length-1}const _=[];function Z(n){return _[n]}const ee=function(){return typeof process<"u"&&process.release?.name==="node"?"NODE":typeof window<"u"?"WEB":typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope?"WORKER":"NODE"}();var te=Object.defineProperty,re=Object.getOwnPropertyDescriptor,f=(n,e,t,r)=>{for(var s=r>1?void 0:r?re(e,t):e,o=n.length-1,i;o>=0;o--)(i=n[o])&&(s=(r?i(e,t,s):i(s))||s);return r&&s&&te(e,t,s),s};const h="string",g="number",a=Symbol("__private__dont__use");class d{constructor(e,t){this.#e=[],this.#t=!1,this.#s=null,this.#r={},this.#o=[],e!==void 0&&this.initializeRuntime(e),t&&(this.requestHandler=new U(new I(this,t)))}#e;#t;#s;#r;#o;async onMessage(e){this.#o.push(e)}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[a])throw new Error("PHP runtime already initialized.");const t=Z(e);if(!t)throw new Error("Invalid PHP runtime id.");this[a]=t,t.onMessage=r=>{for(const s of this.#o)s(r)},this.#s=B(t)}setPhpIniPath(e){if(this.#t)throw new Error("Cannot set PHP ini path after calling run().");this[a].ccall("wasm_set_phpini_path",null,["string"],[e])}setPhpIniEntry(e,t){if(this.#t)throw new Error("Cannot set PHP ini entries after calling run().");this.#e.push([e,t])}chdir(e){this[a].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){this.#t||(this.#n(),this.#t=!0),this.#d(e.scriptPath||""),this.#a(e.relativeUri||""),this.#c(e.method||"GET");const{host:t,...r}={host:"example.com:443",...L(e.headers||{})};if(this.#l(t,e.protocol||"http"),this.#h(r),e.body&&this.#u(e.body),e.fileInfos)for(const s of e.fileInfos)this.#f(s);return e.code&&this.#m(" ?>"+e.code),this.#p(),await this.#y()}#n(){if(this.#e.length>0){const e=this.#e.map(([t,r])=>`${t}=${r}`).join(`
37
+ `),l=o.substring(0,i).trim(),u=o.substring(i+4).trim(),c=l.match(/name="([^"]+)"/);if(c){const m=c[1];e[m]=u}}),e}function te(s){switch(s.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 re(s){return se(s)||ne(s)}function se(s){return s.endsWith(".php")||s.includes(".php/")}function ne(s){return!s.split("/").pop().includes(".")}const C={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 p(s=""){return function(t,r,n){const o=n.value;n.value=function(...i){try{return o.apply(this,i)}catch(l){const u=typeof l=="object"?l?.errno:null;if(u in C){const c=C[u],m=typeof i[0]=="string"?i[0]:null,q=m!==null?s.replaceAll("{path}",m):s;throw new Error(`${q}: ${c}`,{cause:l})}throw l}}}}async function oe(s,e={},t=[]){const[r,n,o]=F(),[i,l]=F(),u=s.init(ae,{onAbort(c){o(c),l(),console.error(c)},ENV:{},locateFile:c=>c,...e,noInitialRun:!0,onRuntimeInitialized(){e.onRuntimeInitialized&&e.onRuntimeInitialized(),n()},monitorRunDependencies(c){c===0&&(delete u.monitorRunDependencies,l())}});return await Promise.all(t.map(({default:c})=>c(u))),t.length||l(),await i,await r,_.push(u),_.length-1}const _=[];function ie(s){return _[s]}const ae=function(){return typeof process<"u"&&process.release?.name==="node"?"NODE":typeof window<"u"?"WEB":typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope?"WORKER":"NODE"}(),F=()=>{const s=[],e=new Promise((t,r)=>{s.push(t,r)});return s.unshift(e),s};var le=Object.defineProperty,ce=Object.getOwnPropertyDescriptor,f=(s,e,t,r)=>{for(var n=r>1?void 0:r?ce(e,t):e,o=s.length-1,i;o>=0;o--)(i=s[o])&&(n=(r?i(e,t,n):i(n))||n);return r&&n&&le(e,t,n),n};const h="string",g="number",a=Symbol("__private__dont__use");class d{constructor(e,t){this.#e=[],this.#t=!1,this.#s=null,this.#r={},this.#o=[],e!==void 0&&this.initializeRuntime(e),t&&(this.requestHandler=new O(new $(this,t)))}#e;#t;#s;#r;#o;async onMessage(e){this.#o.push(e)}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[a])throw new Error("PHP runtime already initialized.");const t=ie(e);if(!t)throw new Error("Invalid PHP runtime id.");this[a]=t,t.onMessage=r=>{for(const n of this.#o)n(r)},this.#s=W(t)}setPhpIniPath(e){if(this.#t)throw new Error("Cannot set PHP ini path after calling run().");this[a].ccall("wasm_set_phpini_path",null,["string"],[e])}setPhpIniEntry(e,t){if(this.#t)throw new Error("Cannot set PHP ini entries after calling run().");this.#e.push([e,t])}chdir(e){this[a].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){this.#t||(this.#n(),this.#t=!0),this.#d(e.scriptPath||""),this.#a(e.relativeUri||""),this.#c(e.method||"GET");const{host:t,...r}={host:"example.com:443",...B(e.headers||{})};if(this.#l(t,e.protocol||"http"),this.#u(r),e.body&&this.#h(e.body),e.fileInfos)for(const n of e.fileInfos)this.#f(n);return e.code&&this.#m(" ?>"+e.code),this.#p(),await this.#y()}#n(){if(this.#e.length>0){const e=this.#e.map(([t,r])=>`${t}=${r}`).join(`
38
38
  `)+`
39
39
 
40
- `;this[a].ccall("wasm_set_phpini_entries",null,[h],[e])}this[a].ccall("php_wasm_init",null,[],[])}#i(){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 o=s.indexOf(": "),i=s.substring(0,o).toLowerCase(),l=s.substring(o+2);i in r||(r[i]=[]),r[i].push(l)}return{headers:r,httpStatusCode:t.status}}#a(e){if(this[a].ccall("wasm_set_request_uri",null,[h],[e]),e.includes("?")){const t=e.substring(e.indexOf("?")+1);this[a].ccall("wasm_set_query_string",null,[h],[t])}}#l(e,t){this[a].ccall("wasm_set_request_host",null,[h],[e]);let r;try{r=parseInt(new URL(e).port,10)}catch{}(!r||isNaN(r)||r===80)&&(r=t==="https"?443:80),this[a].ccall("wasm_set_request_port",null,[g],[r]),(t==="https"||!t&&r===443)&&this.addServerGlobalEntry("HTTPS","on")}#c(e){this[a].ccall("wasm_set_request_method",null,[h],[e])}#h(e){e.cookie&&this[a].ccall("wasm_set_cookies",null,[h],[e.cookie]),e["content-type"]&&this[a].ccall("wasm_set_content_type",null,[h],[e["content-type"]]),e["content-length"]&&this[a].ccall("wasm_set_content_length",null,[g],[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])}}#u(e){this[a].ccall("wasm_set_request_body",null,[h],[e]),this[a].ccall("wasm_set_content_length",null,[g],[new TextEncoder().encode(e).length])}#d(e){this[a].ccall("wasm_set_path_translated",null,[h],[e])}addServerGlobalEntry(e,t){this.#r[e]=t}#p(){for(const e in this.#r)this[a].ccall("wasm_add_SERVER_entry",null,[h,h],[e,this.#r[e]])}#f(e){const{key:t,name:r,type:s,data:o}=e,i=`/tmp/${Math.random().toFixed(20)}`;this.writeFile(i,o);const l=0;this[a].ccall("wasm_add_uploaded_file",null,[h,h,h,h,g,g],[t,r,s,i,l,o.byteLength])}#m(e){this[a].ccall("wasm_set_php_code",null,[h],[e])}async#y(){let e,t;try{e=await new Promise((o,i)=>{t=c=>{const u=new Error("Rethrown");u.cause=c.error,u.betterMessage=c.message,i(u)},this.#s?.addEventListener("error",t);const l=this[a].ccall("wasm_sapi_handle_request",g,[],[]);return l instanceof Promise?l.then(o,i):o(l)})}catch(o){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=D();const i=o,l="betterMessage"in i?i.betterMessage:i.message,c=new Error(l);throw c.cause=i,c}finally{this.#s?.removeEventListener("error",t),this.#r={}}const{headers:r,httpStatusCode:s}=this.#i();return new y(s,r,this.readFileAsBuffer("/tmp/stdout"),this.readFileAsText("/tmp/stderr"),e)}mkdir(e){this[a].FS.mkdirTree(e)}mkdirTree(e){this.mkdir(e)}readFileAsText(e){return new TextDecoder().decode(this.readFileAsBuffer(e))}readFileAsBuffer(e){return this[a].FS.readFile(e)}writeFile(e,t){this[a].FS.writeFile(e,t)}unlink(e){this[a].FS.unlink(e)}mv(e,t){this[a].FS.rename(e,t)}rmdir(e,t={recursive:!0}){t?.recursive&&this.listFiles(e).forEach(r=>{const s=`${e}/${r}`;this.isDir(s)?this.rmdir(s,t):this.unlink(s)}),this[a].FS.rmdir(e)}listFiles(e,t={prependPath:!1}){if(!this.fileExists(e))return[];try{const r=this[a].FS.readdir(e).filter(s=>s!=="."&&s!=="..");if(t.prependPath){const s=e.replace(/\/$/,"");return r.map(o=>`${s}/${o}`)}return r}catch(r){return console.error(r,{path:e}),[]}}isDir(e){return this.fileExists(e)?this[a].FS.isDir(this[a].FS.lookupPath(e).node.mode):!1}fileExists(e){try{return this[a].FS.lookupPath(e),!0}catch{return!1}}}f([p('Could not create directory "{path}"')],d.prototype,"mkdir",1);f([p('Could not create directory "{path}"')],d.prototype,"mkdirTree",1);f([p('Could not read "{path}"')],d.prototype,"readFileAsText",1);f([p('Could not read "{path}"')],d.prototype,"readFileAsBuffer",1);f([p('Could not write to "{path}"')],d.prototype,"writeFile",1);f([p('Could not unlink "{path}"')],d.prototype,"unlink",1);f([p('Could not move "{path}"')],d.prototype,"mv",1);f([p('Could not remove directory "{path}"')],d.prototype,"rmdir",1);f([p('Could not list files in "{path}"')],d.prototype,"listFiles",1);f([p('Could not stat "{path}"')],d.prototype,"isDir",1);f([p('Could not stat "{path}"')],d.prototype,"fileExists",1);function L(n){const e={};for(const t in n)e[t.toLowerCase()]=n[t];return e}function N(n){return!(n instanceof d)}function se(n){return!N(n)}exports.BasePHP=d;exports.DEFAULT_BASE_URL=A;exports.LatestSupportedPHPVersion=V;exports.PHPBrowser=U;exports.PHPRequestHandler=I;exports.PHPResponse=y;exports.SupportedPHPVersions=R;exports.SupportedPHPVersionsList=Y;exports.UnhandledRejectionsTarget=C;exports.__private__dont__use=a;exports.ensurePathPrefix=O;exports.isLocalPHP=N;exports.isRemotePHP=se;exports.loadPHPRuntime=X;exports.removePathPrefix=b;exports.rethrowFileSystemError=p;exports.toRelativeUrl=P;
40
+ `;this[a].ccall("wasm_set_phpini_entries",null,[h],[e])}this[a].ccall("php_wasm_init",null,[],[])}#i(){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 n of t.headers){if(!n.includes(": "))continue;const o=n.indexOf(": "),i=n.substring(0,o).toLowerCase(),l=n.substring(o+2);i in r||(r[i]=[]),r[i].push(l)}return{headers:r,httpStatusCode:t.status}}#a(e){if(this[a].ccall("wasm_set_request_uri",null,[h],[e]),e.includes("?")){const t=e.substring(e.indexOf("?")+1);this[a].ccall("wasm_set_query_string",null,[h],[t])}}#l(e,t){this[a].ccall("wasm_set_request_host",null,[h],[e]);let r;try{r=parseInt(new URL(e).port,10)}catch{}(!r||isNaN(r)||r===80)&&(r=t==="https"?443:80),this[a].ccall("wasm_set_request_port",null,[g],[r]),(t==="https"||!t&&r===443)&&this.addServerGlobalEntry("HTTPS","on")}#c(e){this[a].ccall("wasm_set_request_method",null,[h],[e])}#u(e){e.cookie&&this[a].ccall("wasm_set_cookies",null,[h],[e.cookie]),e["content-type"]&&this[a].ccall("wasm_set_content_type",null,[h],[e["content-type"]]),e["content-length"]&&this[a].ccall("wasm_set_content_length",null,[g],[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])}}#h(e){this[a].ccall("wasm_set_request_body",null,[h],[e]),this[a].ccall("wasm_set_content_length",null,[g],[new TextEncoder().encode(e).length])}#d(e){this[a].ccall("wasm_set_path_translated",null,[h],[e])}addServerGlobalEntry(e,t){this.#r[e]=t}#p(){for(const e in this.#r)this[a].ccall("wasm_add_SERVER_entry",null,[h,h],[e,this.#r[e]])}#f(e){const{key:t,name:r,type:n,data:o}=e,i=`/tmp/${Math.random().toFixed(20)}`;this.writeFile(i,o);const l=0;this[a].ccall("wasm_add_uploaded_file",null,[h,h,h,h,g,g],[t,r,n,i,l,o.byteLength])}#m(e){this[a].ccall("wasm_set_php_code",null,[h],[e])}async#y(){let e,t;try{e=await new Promise((o,i)=>{t=u=>{const c=new Error("Rethrown");c.cause=u.error,c.betterMessage=u.message,i(c)},this.#s?.addEventListener("error",t);const l=this[a].ccall("wasm_sapi_handle_request",g,[],[]);return l instanceof Promise?l.then(o,i):o(l)})}catch(o){for(const c in this)typeof this[c]=="function"&&(this[c]=()=>{throw new Error("PHP runtime has crashed – see the earlier error for details.")});this.functionsMaybeMissingFromAsyncify=j();const i=o,l="betterMessage"in i?i.betterMessage:i.message,u=new Error(l);throw u.cause=i,u}finally{this.#s?.removeEventListener("error",t),this.#r={}}const{headers:r,httpStatusCode:n}=this.#i();return new y(n,r,this.readFileAsBuffer("/tmp/stdout"),this.readFileAsText("/tmp/stderr"),e)}mkdir(e){this[a].FS.mkdirTree(e)}mkdirTree(e){this.mkdir(e)}readFileAsText(e){return new TextDecoder().decode(this.readFileAsBuffer(e))}readFileAsBuffer(e){return this[a].FS.readFile(e)}writeFile(e,t){this[a].FS.writeFile(e,t)}unlink(e){this[a].FS.unlink(e)}mv(e,t){this[a].FS.rename(e,t)}rmdir(e,t={recursive:!0}){t?.recursive&&this.listFiles(e).forEach(r=>{const n=`${e}/${r}`;this.isDir(n)?this.rmdir(n,t):this.unlink(n)}),this[a].FS.rmdir(e)}listFiles(e,t={prependPath:!1}){if(!this.fileExists(e))return[];try{const r=this[a].FS.readdir(e).filter(n=>n!=="."&&n!=="..");if(t.prependPath){const n=e.replace(/\/$/,"");return r.map(o=>`${n}/${o}`)}return r}catch(r){return console.error(r,{path:e}),[]}}isDir(e){return this.fileExists(e)?this[a].FS.isDir(this[a].FS.lookupPath(e).node.mode):!1}fileExists(e){try{return this[a].FS.lookupPath(e),!0}catch{return!1}}}f([p('Could not create directory "{path}"')],d.prototype,"mkdir",1);f([p('Could not create directory "{path}"')],d.prototype,"mkdirTree",1);f([p('Could not read "{path}"')],d.prototype,"readFileAsText",1);f([p('Could not read "{path}"')],d.prototype,"readFileAsBuffer",1);f([p('Could not write to "{path}"')],d.prototype,"writeFile",1);f([p('Could not unlink "{path}"')],d.prototype,"unlink",1);f([p('Could not move "{path}"')],d.prototype,"mv",1);f([p('Could not remove directory "{path}"')],d.prototype,"rmdir",1);f([p('Could not list files in "{path}"')],d.prototype,"listFiles",1);f([p('Could not stat "{path}"')],d.prototype,"isDir",1);f([p('Could not stat "{path}"')],d.prototype,"fileExists",1);function B(s){const e={};for(const t in s)e[t.toLowerCase()]=s[t];return e}function M(s){return!(s instanceof d)}function ue(s){return!M(s)}exports.BasePHP=d;exports.DEFAULT_BASE_URL=I;exports.LatestSupportedPHPVersion=K;exports.PHPBrowser=O;exports.PHPRequestHandler=$;exports.PHPResponse=y;exports.SupportedPHPExtensionBundles=Q;exports.SupportedPHPExtensionsList=L;exports.SupportedPHPVersions=v;exports.SupportedPHPVersionsList=Z;exports.UnhandledRejectionsTarget=U;exports.__private__dont__use=a;exports.ensurePathPrefix=N;exports.isExitCodeZero=A;exports.isLocalPHP=M;exports.isRemotePHP=ue;exports.loadPHPRuntime=oe;exports.removePathPrefix=b;exports.rethrowFileSystemError=p;exports.toRelativeUrl=w;
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- const v = Symbol("error"), _ = Symbol("message");
1
+ const v = Symbol("error"), E = Symbol("message");
2
2
  class b extends Event {
3
3
  /**
4
4
  * Create a new `ErrorEvent`.
@@ -8,19 +8,22 @@ class b extends Event {
8
8
  * attributes via object members of the same name.
9
9
  */
10
10
  constructor(e, t = {}) {
11
- super(e), this[v] = t.error === void 0 ? null : t.error, this[_] = t.message === void 0 ? "" : t.message;
11
+ super(e), this[v] = t.error === void 0 ? null : t.error, this[E] = t.message === void 0 ? "" : t.message;
12
12
  }
13
13
  get error() {
14
14
  return this[v];
15
15
  }
16
16
  get message() {
17
- return this[_];
17
+ return this[E];
18
18
  }
19
19
  }
20
20
  Object.defineProperty(b.prototype, "error", { enumerable: !0 });
21
21
  Object.defineProperty(b.prototype, "message", { enumerable: !0 });
22
- const A = typeof globalThis.ErrorEvent == "function" ? globalThis.ErrorEvent : b;
23
- class O extends EventTarget {
22
+ const U = typeof globalThis.ErrorEvent == "function" ? globalThis.ErrorEvent : b;
23
+ function I(s) {
24
+ return s instanceof Error ? "exitCode" in s && s?.exitCode === 0 || s?.name === "ExitStatus" && "status" in s && s.status === 0 : !1;
25
+ }
26
+ class L extends EventTarget {
24
27
  constructor() {
25
28
  super(...arguments), this.listenersCount = 0;
26
29
  }
@@ -34,62 +37,62 @@ class O extends EventTarget {
34
37
  return this.listenersCount > 0;
35
38
  }
36
39
  }
37
- function I(n) {
38
- n.asm = {
39
- ...n.asm
40
+ function N(s) {
41
+ s.asm = {
42
+ ...s.asm
40
43
  };
41
- const e = new O();
42
- for (const t in n.asm)
43
- if (typeof n.asm[t] == "function") {
44
- const r = n.asm[t];
45
- n.asm[t] = function(...s) {
44
+ const e = new L();
45
+ for (const t in s.asm)
46
+ if (typeof s.asm[t] == "function") {
47
+ const r = s.asm[t];
48
+ s.asm[t] = function(...n) {
46
49
  try {
47
- return r(...s);
50
+ return r(...n);
48
51
  } catch (o) {
49
52
  if (!(o instanceof Error))
50
53
  throw o;
51
- if ("exitCode" in o && o?.exitCode === 0)
52
- return;
53
- const i = $(
54
+ const i = M(
54
55
  o,
55
- n.lastAsyncifyStackSource?.stack
56
- );
57
- if (n.lastAsyncifyStackSource && (o.cause = n.lastAsyncifyStackSource), !e.hasListeners())
58
- throw D(i), o;
59
- e.dispatchEvent(
60
- new A("error", {
61
- error: o,
62
- message: i
63
- })
56
+ s.lastAsyncifyStackSource?.stack
64
57
  );
58
+ if (s.lastAsyncifyStackSource && (o.cause = s.lastAsyncifyStackSource), e.hasListeners()) {
59
+ e.dispatchEvent(
60
+ new U("error", {
61
+ error: o,
62
+ message: i
63
+ })
64
+ );
65
+ return;
66
+ }
67
+ throw I(o) || D(i), o;
65
68
  }
66
69
  };
67
70
  }
68
71
  return e;
69
72
  }
70
73
  let w = [];
71
- function N() {
74
+ function $() {
72
75
  return w;
73
76
  }
74
- function $(n, e) {
75
- if (n.message === "unreachable") {
76
- let t = L;
77
+ function M(s, e) {
78
+ if (s.message === "unreachable") {
79
+ let t = q;
77
80
  e || (t += `
78
81
 
79
82
  This stack trace is lacking. For a better one initialize
80
83
  the PHP runtime with { debug: true }, e.g. PHPNode.load('8.1', { debug: true }).
81
84
 
82
- `), w = B(
83
- e || n.stack || ""
85
+ `), w = W(
86
+ e || s.stack || ""
84
87
  );
85
88
  for (const r of w)
86
89
  t += ` * ${r}
87
90
  `;
88
91
  return t;
89
92
  }
90
- return n.message;
93
+ return s.message;
91
94
  }
92
- const L = `
95
+ const q = `
93
96
  "unreachable" WASM instruction executed.
94
97
 
95
98
  The typical reason is a PHP function missing from the ASYNCIFY_ONLY
@@ -113,22 +116,22 @@ the Dockerfile, you'll need to trigger this error again with long stack
113
116
  traces enabled. In node.js, you can do it using the --stack-trace-limit=100
114
117
  CLI option:
115
118
 
116
- `, R = "\x1B[41m", M = "\x1B[1m", E = "\x1B[0m", S = "\x1B[K";
117
- let x = !1;
118
- function D(n) {
119
- if (!x) {
120
- x = !0, console.log(`${R}
121
- ${S}
122
- ${M} WASM ERROR${E}${R}`);
123
- for (const e of n.split(`
119
+ `, _ = "\x1B[41m", B = "\x1B[1m", R = "\x1B[0m", x = "\x1B[K";
120
+ let S = !1;
121
+ function D(s) {
122
+ if (!S) {
123
+ S = !0, console.log(`${_}
124
+ ${x}
125
+ ${B} WASM ERROR${R}${_}`);
126
+ for (const e of s.split(`
124
127
  `))
125
- console.log(`${S} ${e} `);
126
- console.log(`${E}`);
128
+ console.log(`${x} ${e} `);
129
+ console.log(`${R}`);
127
130
  }
128
131
  }
129
- function B(n) {
132
+ function W(s) {
130
133
  try {
131
- const e = n.split(`
134
+ const e = s.split(`
132
135
  `).slice(1).map((t) => {
133
136
  const r = t.trim().substring(3).split(" ");
134
137
  return {
@@ -144,8 +147,8 @@ function B(n) {
144
147
  }
145
148
  }
146
149
  class g {
147
- constructor(e, t, r, s = "", o = 0) {
148
- this.httpStatusCode = e, this.headers = t, this.bytes = r, this.exitCode = o, this.errors = s;
150
+ constructor(e, t, r, n = "", o = 0) {
151
+ this.httpStatusCode = e, this.headers = t, this.bytes = r, this.exitCode = o, this.errors = n;
149
152
  }
150
153
  static fromRawData(e) {
151
154
  return new g(
@@ -178,7 +181,7 @@ class g {
178
181
  return new TextDecoder().decode(this.bytes);
179
182
  }
180
183
  }
181
- const C = [
184
+ const F = [
182
185
  "8.2",
183
186
  "8.1",
184
187
  "8.0",
@@ -188,8 +191,15 @@ const C = [
188
191
  "7.1",
189
192
  "7.0",
190
193
  "5.6"
191
- ], ee = C[0], te = C;
192
- class q {
194
+ ], ie = F[0], ae = F, j = [
195
+ "iconv",
196
+ "mbstring",
197
+ "xml-bundle",
198
+ "gd"
199
+ ], le = {
200
+ "kitchen-sink": j
201
+ };
202
+ class z {
193
203
  #e;
194
204
  #t;
195
205
  /**
@@ -226,13 +236,13 @@ class q {
226
236
  }
227
237
  });
228
238
  if (r.headers["set-cookie"] && this.#s(r.headers["set-cookie"]), this.#t.handleRedirects && r.headers.location && t < this.#t.maxRedirects) {
229
- const s = new URL(
239
+ const n = new URL(
230
240
  r.headers.location[0],
231
241
  this.requestHandler.absoluteUrl
232
242
  );
233
243
  return this.request(
234
244
  {
235
- url: s.toString(),
245
+ url: n.toString(),
236
246
  method: "GET",
237
247
  headers: {}
238
248
  },
@@ -262,8 +272,8 @@ class q {
262
272
  try {
263
273
  if (!t.includes("="))
264
274
  continue;
265
- const r = t.indexOf("="), s = t.substring(0, r), o = t.substring(r + 1).split(";")[0];
266
- this.#e[s] = o;
275
+ const r = t.indexOf("="), n = t.substring(0, r), o = t.substring(r + 1).split(";")[0];
276
+ this.#e[n] = o;
267
277
  } catch (r) {
268
278
  console.error(r);
269
279
  }
@@ -275,7 +285,7 @@ class q {
275
285
  return e.join("; ");
276
286
  }
277
287
  }
278
- class W {
288
+ class G {
279
289
  constructor({ concurrency: e }) {
280
290
  this._running = 0, this.concurrency = e, this.queue = [];
281
291
  }
@@ -303,17 +313,17 @@ class W {
303
313
  }
304
314
  }
305
315
  }
306
- const j = "http://example.com";
307
- function T(n) {
308
- return n.toString().substring(n.origin.length);
316
+ const V = "http://example.com";
317
+ function k(s) {
318
+ return s.toString().substring(s.origin.length);
309
319
  }
310
- function k(n, e) {
311
- return !e || !n.startsWith(e) ? n : n.substring(e.length);
320
+ function H(s, e) {
321
+ return !e || !s.startsWith(e) ? s : s.substring(e.length);
312
322
  }
313
- function z(n, e) {
314
- return !e || n.startsWith(e) ? n : e + n;
323
+ function Y(s, e) {
324
+ return !e || s.startsWith(e) ? s : e + s;
315
325
  }
316
- class G {
326
+ class J {
317
327
  #e;
318
328
  #t;
319
329
  #s;
@@ -322,26 +332,24 @@ class G {
322
332
  #n;
323
333
  #i;
324
334
  #a;
325
- #l;
326
335
  /**
327
336
  * @param php - The PHP instance.
328
337
  * @param config - Request Handler configuration.
329
338
  */
330
339
  constructor(e, t = {}) {
331
- this.#a = new W({ concurrency: 1 });
340
+ this.#a = new G({ concurrency: 1 });
332
341
  const {
333
342
  documentRoot: r = "/www/",
334
- absoluteUrl: s = typeof location == "object" ? location?.href : "",
335
- isStaticFilePath: o = () => !1
343
+ absoluteUrl: n = typeof location == "object" ? location?.href : ""
336
344
  } = t;
337
- this.php = e, this.#e = r, this.#l = o;
338
- const i = new URL(s);
339
- this.#s = i.hostname, this.#r = i.port ? Number(i.port) : i.protocol === "https:" ? 443 : 80, this.#t = (i.protocol || "").replace(":", "");
340
- const l = this.#r !== 443 && this.#r !== 80;
345
+ this.php = e, this.#e = r;
346
+ const o = new URL(n);
347
+ this.#s = o.hostname, this.#r = o.port ? Number(o.port) : o.protocol === "https:" ? 443 : 80, this.#t = (o.protocol || "").replace(":", "");
348
+ const i = this.#r !== 443 && this.#r !== 80;
341
349
  this.#o = [
342
350
  this.#s,
343
- l ? `:${this.#r}` : ""
344
- ].join(""), this.#n = i.pathname.replace(/\/+$/, ""), this.#i = [
351
+ i ? `:${this.#r}` : ""
352
+ ].join(""), this.#n = o.pathname.replace(/\/+$/, ""), this.#i = [
345
353
  `${this.#t}://`,
346
354
  this.#o,
347
355
  this.#n
@@ -354,7 +362,7 @@ class G {
354
362
  /** @inheritDoc */
355
363
  internalUrlToPath(e) {
356
364
  const t = new URL(e);
357
- return t.pathname.startsWith(this.#n) && (t.pathname = t.pathname.slice(this.#n.length)), T(t);
365
+ return t.pathname.startsWith(this.#n) && (t.pathname = t.pathname.slice(this.#n.length)), k(t);
358
366
  }
359
367
  get isRequestRunning() {
360
368
  return this.#a.running > 0;
@@ -371,40 +379,43 @@ class G {
371
379
  async request(e) {
372
380
  const t = e.url.startsWith("http://") || e.url.startsWith("https://"), r = new URL(
373
381
  e.url,
374
- t ? void 0 : j
375
- ), s = k(
382
+ t ? void 0 : V
383
+ ), n = H(
376
384
  r.pathname,
377
385
  this.#n
378
- );
379
- return this.#l(s) ? this.#c(s) : await this.#h(e, r);
386
+ ), o = `${this.#e}${n}`;
387
+ return Q(o) ? await this.#c(e, r) : this.#l(o);
380
388
  }
381
389
  /**
382
390
  * Serves a static file from the PHP filesystem.
383
391
  *
384
- * @param path - The requested static file path.
392
+ * @param fsPath - Absolute path of the static file to serve.
385
393
  * @returns The response.
386
394
  */
387
- #c(e) {
388
- const t = `${this.#e}${e}`;
389
- if (!this.php.fileExists(t))
395
+ #l(e) {
396
+ if (!this.php.fileExists(e))
390
397
  return new g(
391
398
  404,
392
- {},
399
+ // Let the service worker know that no static file was found
400
+ // and that it's okay to issue a real fetch() to the server.
401
+ {
402
+ "x-file-type": ["static"]
403
+ },
393
404
  new TextEncoder().encode("404 File not found")
394
405
  );
395
- const r = this.php.readFileAsBuffer(t);
406
+ const t = this.php.readFileAsBuffer(e);
396
407
  return new g(
397
408
  200,
398
409
  {
399
- "content-length": [`${r.byteLength}`],
410
+ "content-length": [`${t.byteLength}`],
400
411
  // @TODO: Infer the content-type from the arrayBuffer instead of the file path.
401
412
  // The code below won't return the correct mime-type if the extension
402
413
  // was tampered with.
403
- "content-type": [Y(t)],
414
+ "content-type": [Z(e)],
404
415
  "accept-ranges": ["bytes"],
405
416
  "cache-control": ["public, max-age=0"]
406
417
  },
407
- r
418
+ t
408
419
  );
409
420
  }
410
421
  /**
@@ -414,40 +425,40 @@ class G {
414
425
  * @param request - The request.
415
426
  * @returns The response.
416
427
  */
417
- async #h(e, t) {
428
+ async #c(e, t) {
418
429
  const r = await this.#a.acquire();
419
430
  try {
420
431
  this.php.addServerGlobalEntry("DOCUMENT_ROOT", this.#e), this.php.addServerGlobalEntry(
421
432
  "HTTPS",
422
433
  this.#i.startsWith("https://") ? "on" : ""
423
434
  );
424
- let s = "GET";
435
+ let n = "GET";
425
436
  const o = {
426
437
  host: this.#o,
427
- ...H(e.headers || {})
438
+ ...A(e.headers || {})
428
439
  }, i = [];
429
440
  if (e.files && Object.keys(e.files).length) {
430
- s = "POST";
431
- for (const u in e.files) {
432
- const m = e.files[u];
441
+ n = "POST";
442
+ for (const c in e.files) {
443
+ const m = e.files[c];
433
444
  i.push({
434
- key: u,
445
+ key: c,
435
446
  name: m.name,
436
447
  type: m.type,
437
448
  data: new Uint8Array(await m.arrayBuffer())
438
449
  });
439
450
  }
440
- o["content-type"]?.startsWith("multipart/form-data") && (e.formData = V(
451
+ o["content-type"]?.startsWith("multipart/form-data") && (e.formData = K(
441
452
  e.body || ""
442
453
  ), o["content-type"] = "application/x-www-form-urlencoded", delete e.body);
443
454
  }
444
455
  let l;
445
- e.formData !== void 0 ? (s = "POST", o["content-type"] = o["content-type"] || "application/x-www-form-urlencoded", l = new URLSearchParams(
456
+ e.formData !== void 0 ? (n = "POST", o["content-type"] = o["content-type"] || "application/x-www-form-urlencoded", l = new URLSearchParams(
446
457
  e.formData
447
458
  ).toString()) : l = e.body;
448
- let c;
459
+ let h;
449
460
  try {
450
- c = this.#u(t.pathname);
461
+ h = this.#h(t.pathname);
451
462
  } catch {
452
463
  return new g(
453
464
  404,
@@ -456,15 +467,15 @@ class G {
456
467
  );
457
468
  }
458
469
  return await this.php.run({
459
- relativeUri: z(
460
- T(t),
470
+ relativeUri: Y(
471
+ k(t),
461
472
  this.#n
462
473
  ),
463
474
  protocol: this.#t,
464
- method: e.method || s,
475
+ method: e.method || n,
465
476
  body: l,
466
477
  fileInfos: i,
467
- scriptPath: c,
478
+ scriptPath: h,
468
479
  headers: o
469
480
  });
470
481
  } finally {
@@ -480,8 +491,8 @@ class G {
480
491
  * @throws {Error} If the requested path doesn't exist.
481
492
  * @returns The resolved filesystem path.
482
493
  */
483
- #u(e) {
484
- let t = k(e, this.#n);
494
+ #h(e) {
495
+ let t = H(e, this.#n);
485
496
  t.includes(".php") ? t = t.split(".php")[0] + ".php" : (t.endsWith("/") || (t += "/"), t.endsWith("index.php") || (t += "index.php"));
486
497
  const r = `${this.#e}${t}`;
487
498
  if (this.php.fileExists(r))
@@ -491,23 +502,23 @@ class G {
491
502
  return `${this.#e}/index.php`;
492
503
  }
493
504
  }
494
- function V(n) {
495
- const e = {}, t = n.match(/--(.*)\r\n/);
505
+ function K(s) {
506
+ const e = {}, t = s.match(/--(.*)\r\n/);
496
507
  if (!t)
497
508
  return e;
498
- const r = t[1], s = n.split(`--${r}`);
499
- return s.shift(), s.pop(), s.forEach((o) => {
509
+ const r = t[1], n = s.split(`--${r}`);
510
+ return n.shift(), n.pop(), n.forEach((o) => {
500
511
  const i = o.indexOf(`\r
501
512
  \r
502
- `), l = o.substring(0, i).trim(), c = o.substring(i + 4).trim(), u = l.match(/name="([^"]+)"/);
503
- if (u) {
504
- const m = u[1];
505
- e[m] = c;
513
+ `), l = o.substring(0, i).trim(), h = o.substring(i + 4).trim(), c = l.match(/name="([^"]+)"/);
514
+ if (c) {
515
+ const m = c[1];
516
+ e[m] = h;
506
517
  }
507
518
  }), e;
508
519
  }
509
- function Y(n) {
510
- switch (n.split(".").pop()) {
520
+ function Z(s) {
521
+ switch (s.split(".").pop()) {
511
522
  case "css":
512
523
  return "text/css";
513
524
  case "js":
@@ -546,7 +557,16 @@ function Y(n) {
546
557
  return "application-octet-stream";
547
558
  }
548
559
  }
549
- const F = {
560
+ function Q(s) {
561
+ return X(s) || ee(s);
562
+ }
563
+ function X(s) {
564
+ return s.endsWith(".php") || s.includes(".php/");
565
+ }
566
+ function ee(s) {
567
+ return !s.split("/").pop().includes(".");
568
+ }
569
+ const T = {
550
570
  0: "No error occurred. System call completed successfully.",
551
571
  1: "Argument list too long.",
552
572
  2: "Permission denied.",
@@ -625,17 +645,17 @@ const F = {
625
645
  75: "Cross-device link.",
626
646
  76: "Extension: Capabilities insufficient."
627
647
  };
628
- function p(n = "") {
629
- return function(t, r, s) {
630
- const o = s.value;
631
- s.value = function(...i) {
648
+ function p(s = "") {
649
+ return function(t, r, n) {
650
+ const o = n.value;
651
+ n.value = function(...i) {
632
652
  try {
633
653
  return o.apply(this, i);
634
654
  } catch (l) {
635
- const c = typeof l == "object" ? l?.errno : null;
636
- if (c in F) {
637
- const u = F[c], m = typeof i[0] == "string" ? i[0] : null, U = m !== null ? n.replaceAll("{path}", m) : n;
638
- throw new Error(`${U}: ${u}`, {
655
+ const h = typeof l == "object" ? l?.errno : null;
656
+ if (h in T) {
657
+ const c = T[h], m = typeof i[0] == "string" ? i[0] : null, O = m !== null ? s.replaceAll("{path}", m) : s;
658
+ throw new Error(`${O}: ${c}`, {
639
659
  cause: l
640
660
  });
641
661
  }
@@ -644,15 +664,10 @@ function p(n = "") {
644
664
  };
645
665
  };
646
666
  }
647
- async function re(n, e = {}, t = []) {
648
- let r, s;
649
- const o = new Promise((c) => {
650
- s = c;
651
- }), i = new Promise((c) => {
652
- r = c;
653
- }), l = n.init(K, {
667
+ async function ce(s, e = {}, t = []) {
668
+ const [r, n, o] = C(), [i, l] = C(), h = s.init(re, {
654
669
  onAbort(c) {
655
- console.error("WASM aborted: "), console.error(c);
670
+ o(c), l(), console.error(c);
656
671
  },
657
672
  ENV: {},
658
673
  // Emscripten sometimes prepends a '/' to the path, which
@@ -662,29 +677,36 @@ async function re(n, e = {}, t = []) {
662
677
  ...e,
663
678
  noInitialRun: !0,
664
679
  onRuntimeInitialized() {
665
- e.onRuntimeInitialized && e.onRuntimeInitialized(), r();
680
+ e.onRuntimeInitialized && e.onRuntimeInitialized(), n();
666
681
  },
667
682
  monitorRunDependencies(c) {
668
- c === 0 && (delete l.monitorRunDependencies, s());
683
+ c === 0 && (delete h.monitorRunDependencies, l());
669
684
  }
670
685
  });
671
- for (const { default: c } of t)
672
- c(l);
673
- return t.length || s(), await o, await i, P.push(l), P.length - 1;
686
+ return await Promise.all(
687
+ t.map(
688
+ ({ default: c }) => c(h)
689
+ )
690
+ ), t.length || l(), await i, await r, P.push(h), P.length - 1;
674
691
  }
675
692
  const P = [];
676
- function J(n) {
677
- return P[n];
693
+ function te(s) {
694
+ return P[s];
678
695
  }
679
- const K = function() {
696
+ const re = function() {
680
697
  return typeof process < "u" && process.release?.name === "node" ? "NODE" : typeof window < "u" ? "WEB" : typeof WorkerGlobalScope < "u" && self instanceof WorkerGlobalScope ? "WORKER" : "NODE";
681
- }();
682
- var Q = Object.defineProperty, X = Object.getOwnPropertyDescriptor, f = (n, e, t, r) => {
683
- for (var s = r > 1 ? void 0 : r ? X(e, t) : e, o = n.length - 1, i; o >= 0; o--)
684
- (i = n[o]) && (s = (r ? i(e, t, s) : i(s)) || s);
685
- return r && s && Q(e, t, s), s;
698
+ }(), C = () => {
699
+ const s = [], e = new Promise((t, r) => {
700
+ s.push(t, r);
701
+ });
702
+ return s.unshift(e), s;
703
+ };
704
+ var se = Object.defineProperty, ne = Object.getOwnPropertyDescriptor, f = (s, e, t, r) => {
705
+ for (var n = r > 1 ? void 0 : r ? ne(e, t) : e, o = s.length - 1, i; o >= 0; o--)
706
+ (i = s[o]) && (n = (r ? i(e, t, n) : i(n)) || n);
707
+ return r && n && se(e, t, n), n;
686
708
  };
687
- const h = "string", y = "number", a = Symbol("__private__dont__use");
709
+ const u = "string", y = "number", a = Symbol("__private__dont__use");
688
710
  class d {
689
711
  /**
690
712
  * Initializes a PHP runtime.
@@ -694,8 +716,8 @@ class d {
694
716
  * @param serverOptions - Optional. Options for the PHPRequestHandler. If undefined, no request handler will be initialized.
695
717
  */
696
718
  constructor(e, t) {
697
- this.#e = [], this.#t = !1, this.#s = null, this.#r = {}, this.#o = [], e !== void 0 && this.initializeRuntime(e), t && (this.requestHandler = new q(
698
- new G(this, t)
719
+ this.#e = [], this.#t = !1, this.#s = null, this.#r = {}, this.#o = [], e !== void 0 && this.initializeRuntime(e), t && (this.requestHandler = new z(
720
+ new J(this, t)
699
721
  ));
700
722
  }
701
723
  #e;
@@ -728,13 +750,13 @@ class d {
728
750
  initializeRuntime(e) {
729
751
  if (this[a])
730
752
  throw new Error("PHP runtime already initialized.");
731
- const t = J(e);
753
+ const t = te(e);
732
754
  if (!t)
733
755
  throw new Error("Invalid PHP runtime id.");
734
756
  this[a] = t, t.onMessage = (r) => {
735
- for (const s of this.#o)
736
- s(r);
737
- }, this.#s = I(t);
757
+ for (const n of this.#o)
758
+ n(r);
759
+ }, this.#s = N(t);
738
760
  }
739
761
  /** @inheritDoc */
740
762
  setPhpIniPath(e) {
@@ -768,11 +790,11 @@ class d {
768
790
  this.#t || (this.#n(), this.#t = !0), this.#d(e.scriptPath || ""), this.#a(e.relativeUri || ""), this.#c(e.method || "GET");
769
791
  const { host: t, ...r } = {
770
792
  host: "example.com:443",
771
- ...H(e.headers || {})
793
+ ...A(e.headers || {})
772
794
  };
773
795
  if (this.#l(t, e.protocol || "http"), this.#h(r), e.body && this.#u(e.body), e.fileInfos)
774
- for (const s of e.fileInfos)
775
- this.#f(s);
796
+ for (const n of e.fileInfos)
797
+ this.#f(n);
776
798
  return e.code && this.#m(" ?>" + e.code), this.#p(), await this.#y();
777
799
  }
778
800
  #n() {
@@ -784,7 +806,7 @@ class d {
784
806
  this[a].ccall(
785
807
  "wasm_set_phpini_entries",
786
808
  null,
787
- [h],
809
+ [u],
788
810
  [e]
789
811
  );
790
812
  }
@@ -797,10 +819,10 @@ class d {
797
819
  "SAPI Error: Could not find response headers file."
798
820
  );
799
821
  const t = JSON.parse(this.readFileAsText(e)), r = {};
800
- for (const s of t.headers) {
801
- if (!s.includes(": "))
822
+ for (const n of t.headers) {
823
+ if (!n.includes(": "))
802
824
  continue;
803
- const o = s.indexOf(": "), i = s.substring(0, o).toLowerCase(), l = s.substring(o + 2);
825
+ const o = n.indexOf(": "), i = n.substring(0, o).toLowerCase(), l = n.substring(o + 2);
804
826
  i in r || (r[i] = []), r[i].push(l);
805
827
  }
806
828
  return {
@@ -812,14 +834,14 @@ class d {
812
834
  if (this[a].ccall(
813
835
  "wasm_set_request_uri",
814
836
  null,
815
- [h],
837
+ [u],
816
838
  [e]
817
839
  ), e.includes("?")) {
818
840
  const t = e.substring(e.indexOf("?") + 1);
819
841
  this[a].ccall(
820
842
  "wasm_set_query_string",
821
843
  null,
822
- [h],
844
+ [u],
823
845
  [t]
824
846
  );
825
847
  }
@@ -828,7 +850,7 @@ class d {
828
850
  this[a].ccall(
829
851
  "wasm_set_request_host",
830
852
  null,
831
- [h],
853
+ [u],
832
854
  [e]
833
855
  );
834
856
  let r;
@@ -847,7 +869,7 @@ class d {
847
869
  this[a].ccall(
848
870
  "wasm_set_request_method",
849
871
  null,
850
- [h],
872
+ [u],
851
873
  [e]
852
874
  );
853
875
  }
@@ -855,12 +877,12 @@ class d {
855
877
  e.cookie && this[a].ccall(
856
878
  "wasm_set_cookies",
857
879
  null,
858
- [h],
880
+ [u],
859
881
  [e.cookie]
860
882
  ), e["content-type"] && this[a].ccall(
861
883
  "wasm_set_content_type",
862
884
  null,
863
- [h],
885
+ [u],
864
886
  [e["content-type"]]
865
887
  ), e["content-length"] && this[a].ccall(
866
888
  "wasm_set_content_length",
@@ -880,7 +902,7 @@ class d {
880
902
  this[a].ccall(
881
903
  "wasm_set_request_body",
882
904
  null,
883
- [h],
905
+ [u],
884
906
  [e]
885
907
  ), this[a].ccall(
886
908
  "wasm_set_content_length",
@@ -893,7 +915,7 @@ class d {
893
915
  this[a].ccall(
894
916
  "wasm_set_path_translated",
895
917
  null,
896
- [h],
918
+ [u],
897
919
  [e]
898
920
  );
899
921
  }
@@ -905,7 +927,7 @@ class d {
905
927
  this[a].ccall(
906
928
  "wasm_add_SERVER_entry",
907
929
  null,
908
- [h, h],
930
+ [u, u],
909
931
  [e, this.#r[e]]
910
932
  );
911
933
  }
@@ -919,21 +941,21 @@ class d {
919
941
  * @param fileInfo - File details
920
942
  */
921
943
  #f(e) {
922
- const { key: t, name: r, type: s, data: o } = e, i = `/tmp/${Math.random().toFixed(20)}`;
944
+ const { key: t, name: r, type: n, data: o } = e, i = `/tmp/${Math.random().toFixed(20)}`;
923
945
  this.writeFile(i, o);
924
946
  const l = 0;
925
947
  this[a].ccall(
926
948
  "wasm_add_uploaded_file",
927
949
  null,
928
- [h, h, h, h, y, y],
929
- [t, r, s, i, l, o.byteLength]
950
+ [u, u, u, u, y, y],
951
+ [t, r, n, i, l, o.byteLength]
930
952
  );
931
953
  }
932
954
  #m(e) {
933
955
  this[a].ccall(
934
956
  "wasm_set_php_code",
935
957
  null,
936
- [h],
958
+ [u],
937
959
  [e]
938
960
  );
939
961
  }
@@ -941,9 +963,9 @@ class d {
941
963
  let e, t;
942
964
  try {
943
965
  e = await new Promise((o, i) => {
944
- t = (c) => {
945
- const u = new Error("Rethrown");
946
- u.cause = c.error, u.betterMessage = c.message, i(u);
966
+ t = (h) => {
967
+ const c = new Error("Rethrown");
968
+ c.cause = h.error, c.betterMessage = h.message, i(c);
947
969
  }, this.#s?.addEventListener(
948
970
  "error",
949
971
  t
@@ -957,21 +979,21 @@ class d {
957
979
  return l instanceof Promise ? l.then(o, i) : o(l);
958
980
  });
959
981
  } catch (o) {
960
- for (const u in this)
961
- typeof this[u] == "function" && (this[u] = () => {
982
+ for (const c in this)
983
+ typeof this[c] == "function" && (this[c] = () => {
962
984
  throw new Error(
963
985
  "PHP runtime has crashed – see the earlier error for details."
964
986
  );
965
987
  });
966
- this.functionsMaybeMissingFromAsyncify = N();
967
- const i = o, l = "betterMessage" in i ? i.betterMessage : i.message, c = new Error(l);
968
- throw c.cause = i, c;
988
+ this.functionsMaybeMissingFromAsyncify = $();
989
+ const i = o, l = "betterMessage" in i ? i.betterMessage : i.message, h = new Error(l);
990
+ throw h.cause = i, h;
969
991
  } finally {
970
992
  this.#s?.removeEventListener("error", t), this.#r = {};
971
993
  }
972
- const { headers: r, httpStatusCode: s } = this.#i();
994
+ const { headers: r, httpStatusCode: n } = this.#i();
973
995
  return new g(
974
- s,
996
+ n,
975
997
  r,
976
998
  this.readFileAsBuffer("/tmp/stdout"),
977
999
  this.readFileAsText("/tmp/stderr"),
@@ -1001,8 +1023,8 @@ class d {
1001
1023
  }
1002
1024
  rmdir(e, t = { recursive: !0 }) {
1003
1025
  t?.recursive && this.listFiles(e).forEach((r) => {
1004
- const s = `${e}/${r}`;
1005
- this.isDir(s) ? this.rmdir(s, t) : this.unlink(s);
1026
+ const n = `${e}/${r}`;
1027
+ this.isDir(n) ? this.rmdir(n, t) : this.unlink(n);
1006
1028
  }), this[a].FS.rmdir(e);
1007
1029
  }
1008
1030
  listFiles(e, t = { prependPath: !1 }) {
@@ -1010,11 +1032,11 @@ class d {
1010
1032
  return [];
1011
1033
  try {
1012
1034
  const r = this[a].FS.readdir(e).filter(
1013
- (s) => s !== "." && s !== ".."
1035
+ (n) => n !== "." && n !== ".."
1014
1036
  );
1015
1037
  if (t.prependPath) {
1016
- const s = e.replace(/\/$/, "");
1017
- return r.map((o) => `${s}/${o}`);
1038
+ const n = e.replace(/\/$/, "");
1039
+ return r.map((o) => `${n}/${o}`);
1018
1040
  }
1019
1041
  return r;
1020
1042
  } catch (r) {
@@ -1067,34 +1089,37 @@ f([
1067
1089
  f([
1068
1090
  p('Could not stat "{path}"')
1069
1091
  ], d.prototype, "fileExists", 1);
1070
- function H(n) {
1092
+ function A(s) {
1071
1093
  const e = {};
1072
- for (const t in n)
1073
- e[t.toLowerCase()] = n[t];
1094
+ for (const t in s)
1095
+ e[t.toLowerCase()] = s[t];
1074
1096
  return e;
1075
1097
  }
1076
- function Z(n) {
1077
- return !(n instanceof d);
1098
+ function oe(s) {
1099
+ return !(s instanceof d);
1078
1100
  }
1079
- function se(n) {
1080
- return !Z(n);
1101
+ function he(s) {
1102
+ return !oe(s);
1081
1103
  }
1082
1104
  export {
1083
1105
  d as BasePHP,
1084
- j as DEFAULT_BASE_URL,
1085
- ee as LatestSupportedPHPVersion,
1086
- q as PHPBrowser,
1087
- G as PHPRequestHandler,
1106
+ V as DEFAULT_BASE_URL,
1107
+ ie as LatestSupportedPHPVersion,
1108
+ z as PHPBrowser,
1109
+ J as PHPRequestHandler,
1088
1110
  g as PHPResponse,
1089
- C as SupportedPHPVersions,
1090
- te as SupportedPHPVersionsList,
1091
- O as UnhandledRejectionsTarget,
1111
+ le as SupportedPHPExtensionBundles,
1112
+ j as SupportedPHPExtensionsList,
1113
+ F as SupportedPHPVersions,
1114
+ ae as SupportedPHPVersionsList,
1115
+ L as UnhandledRejectionsTarget,
1092
1116
  a as __private__dont__use,
1093
- z as ensurePathPrefix,
1094
- Z as isLocalPHP,
1095
- se as isRemotePHP,
1096
- re as loadPHPRuntime,
1097
- k as removePathPrefix,
1117
+ Y as ensurePathPrefix,
1118
+ I as isExitCodeZero,
1119
+ oe as isLocalPHP,
1120
+ he as isRemotePHP,
1121
+ ce as loadPHPRuntime,
1122
+ H as removePathPrefix,
1098
1123
  p as rethrowFileSystemError,
1099
- T as toRelativeUrl
1124
+ k as toRelativeUrl
1100
1125
  };
package/lib/index.d.ts CHANGED
@@ -5,6 +5,8 @@ export type { PHPResponseData } from './php-response';
5
5
  export type { ErrnoError } from './rethrow-file-system-error';
6
6
  export { LatestSupportedPHPVersion, SupportedPHPVersions, SupportedPHPVersionsList, } from './supported-php-versions';
7
7
  export type { SupportedPHPVersion } from './supported-php-versions';
8
+ export { SupportedPHPExtensionsList, SupportedPHPExtensionBundles, } from './supported-php-extensions';
9
+ export type { SupportedPHPExtension, SupportedPHPExtensionBundle, } from './supported-php-extensions';
8
10
  export { BasePHP, __private__dont__use } from './base-php';
9
11
  export { loadPHPRuntime } from './load-php-runtime';
10
12
  export type { DataModule, EmscriptenOptions, PHPLoaderModule, PHPRuntime, PHPRuntimeId, RuntimeType, } from './load-php-runtime';
@@ -16,3 +18,4 @@ export { PHPRequestHandler } from './php-request-handler';
16
18
  export type { PHPBrowserConfiguration } from './php-browser';
17
19
  export { PHPBrowser } from './php-browser';
18
20
  export { DEFAULT_BASE_URL, ensurePathPrefix, removePathPrefix, toRelativeUrl, } from './urls';
21
+ export { isExitCodeZero } from './is-exit-code-zero';
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Check if the Emscripten-thrown error is an exit code 0 error.
3
+ *
4
+ * @param e The error to check
5
+ * @returns True if the error is an exit code 0 error
6
+ */
7
+ export declare function isExitCodeZero(e: any): boolean;
@@ -11,11 +11,6 @@ export interface PHPRequestHandlerConfiguration {
11
11
  * Request Handler URL. Used to populate $_SERVER details like HTTP_HOST.
12
12
  */
13
13
  absoluteUrl?: string;
14
- /**
15
- * Callback used by the PHPRequestHandler to decide whether
16
- * the requested path refers to a PHP file or a static file.
17
- */
18
- isStaticFilePath?: (path: string) => boolean;
19
14
  }
20
15
  /** @inheritDoc */
21
16
  export declare class PHPRequestHandler implements RequestHandler {
@@ -41,3 +36,20 @@ export declare class PHPRequestHandler implements RequestHandler {
41
36
  /** @inheritDoc */
42
37
  request(request: PHPRequest): Promise<PHPResponse>;
43
38
  }
39
+ /**
40
+ * Guesses whether the given path looks like a PHP file.
41
+ *
42
+ * @example
43
+ * ```js
44
+ * seemsLikeAPHPRequestHandlerPath('/index.php') // true
45
+ * seemsLikeAPHPRequestHandlerPath('/index.php') // true
46
+ * seemsLikeAPHPRequestHandlerPath('/index.php/foo/bar') // true
47
+ * seemsLikeAPHPRequestHandlerPath('/index.html') // false
48
+ * seemsLikeAPHPRequestHandlerPath('/index.html/foo/bar') // false
49
+ * seemsLikeAPHPRequestHandlerPath('/') // true
50
+ * ```
51
+ *
52
+ * @param path The path to check.
53
+ * @returns Whether the path seems like a PHP server path.
54
+ */
55
+ export declare function seemsLikeAPHPRequestHandlerPath(path: string): boolean;
@@ -0,0 +1,6 @@
1
+ export type SupportedPHPExtension = 'iconv' | 'mbstring' | 'xml-bundle' | 'gd';
2
+ export declare const SupportedPHPExtensionsList: string[];
3
+ export declare const SupportedPHPExtensionBundles: {
4
+ 'kitchen-sink': string[];
5
+ };
6
+ export type SupportedPHPExtensionBundle = 'kitchen-sink';
@@ -73,7 +73,7 @@ export interface RequestHandler {
73
73
  * }
74
74
  * })
75
75
  * php.writeFile("/www/index.php", `<?php echo file_get_contents("php://input");`);
76
- * const result = await php.run({
76
+ * const result = await php.request({
77
77
  * method: "GET",
78
78
  * headers: {
79
79
  * "Content-Type": "text/plain"
@@ -311,7 +311,7 @@ export interface IsomorphicLocalPHP extends RequestHandler {
311
311
  * post_message_to_js(string $data)
312
312
  *
313
313
  * Arguments:
314
- * $data – any extra information as a string
314
+ * $data (string) Data to pass to JavaScript.
315
315
  *
316
316
  * @example
317
317
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@php-wasm/universal",
3
- "version": "0.1.61",
3
+ "version": "0.3.0",
4
4
  "description": "PHP.wasm – emscripten bindings for PHP",
5
5
  "repository": {
6
6
  "type": "git",
@@ -36,5 +36,9 @@
36
36
  "main": "./index.cjs",
37
37
  "module": "./index.js",
38
38
  "license": "GPL-2.0-or-later",
39
- "gitHead": "f2cd7382004f7b003904b5db1d33d37fd2b1bfab"
39
+ "gitHead": "6890ff9243f9a10f0b86755fead101647a8c8535",
40
+ "engines": {
41
+ "node": ">=16.15.1",
42
+ "npm": ">=8.11.0"
43
+ }
40
44
  }