@php-wasm/universal 0.1.42 → 0.1.43
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 +11 -11
- package/index.js +228 -221
- package/lib/index.d.ts +1 -0
- package/package.json +2 -2
package/index.cjs
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});
|
|
2
|
-
\r
|
|
3
|
-
`),l=o.substring(0,i).trim(),c=o.substring(i+4).trim(),p=l.match(/name="([^"]+)"/);if(p){const g=p[1];e[g]=c}}),e}function q(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"}}const S={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 d(s=""){return function(t,r,n){const o=n.value;n.value=function(...i){try{return o.apply(this,i)}catch(l){const c=typeof l=="object"?l?.errno:null;if(c in S){const p=S[c],g=typeof i[0]=="string"?i[0]:null,L=g!==null?s.replaceAll("{path}",g):s;throw new Error(`${L}: ${p}`,{cause:l})}throw l}}}}async function W(s,e={},t=[]){let r,n;const o=new Promise(c=>{n=c}),i=new Promise(c=>{r=c}),l=s.init(z,{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,n())}});for(const{default:c}of t)c(l);return t.length||n(),await o,await i,b.push(l),b.length-1}const b=[];function j(s){return b[s]}const z=function(){return typeof process<"u"&&process.release?.name==="node"?"NODE":typeof window<"u"?"WEB":typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope?"WORKER":"NODE"}(),E=Symbol("error"),x=Symbol("message");class R extends Event{constructor(e,t={}){super(e),this[E]=t.error===void 0?null:t.error,this[x]=t.message===void 0?"":t.message}get error(){return this[E]}get message(){return this[x]}}Object.defineProperty(R.prototype,"error",{enumerable:!0});Object.defineProperty(R.prototype,"message",{enumerable:!0});const G=typeof globalThis.ErrorEvent=="function"?globalThis.ErrorEvent:R;class V 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 Y(s){s.asm={...s.asm};const e=new V;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;if("exitCode"in o&&o?.exitCode===0)return;const i=K(o,s.lastAsyncifyStackSource?.stack);if(s.lastAsyncifyStackSource&&(o.cause=s.lastAsyncifyStackSource),!e.hasListeners())throw Z(i),o;e.dispatchEvent(new G("error",{error:o,message:i}))}}}return e}let _=[];function J(){return _}function K(s,e){if(s.message==="unreachable"){let t=Q;e||(t+=`
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const S=Symbol("error"),E=Symbol("message");class v extends Event{constructor(e,t={}){super(e),this[S]=t.error===void 0?null:t.error,this[E]=t.message===void 0?"":t.message}get error(){return this[S]}get message(){return this[E]}}Object.defineProperty(v.prototype,"error",{enumerable:!0});Object.defineProperty(v.prototype,"message",{enumerable:!0});const B=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 M(s){s.asm={...s.asm};const e=new C;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;if("exitCode"in o&&o?.exitCode===0)return;const i=q(o,s.lastAsyncifyStackSource?.stack);if(s.lastAsyncifyStackSource&&(o.cause=s.lastAsyncifyStackSource),!e.hasListeners())throw z(i),o;e.dispatchEvent(new B("error",{error:o,message:i}))}}}return e}let w=[];function D(){return w}function q(s,e){if(s.message==="unreachable"){let t=W;e||(t+=`
|
|
4
2
|
|
|
5
3
|
This stack trace is lacking. For a better one initialize
|
|
6
4
|
the PHP runtime with { debug: true }, e.g. PHPNode.load('8.1', { debug: true }).
|
|
7
5
|
|
|
8
|
-
`),
|
|
9
|
-
`;return t}return s.message}const
|
|
6
|
+
`),w=G(e||s.stack||"");for(const r of w)t+=` * ${r}
|
|
7
|
+
`;return t}return s.message}const W=`
|
|
10
8
|
"unreachable" WASM instruction executed.
|
|
11
9
|
|
|
12
10
|
The typical reason is a PHP function missing from the ASYNCIFY_ONLY
|
|
@@ -30,11 +28,13 @@ the Dockerfile, you'll need to trigger this error again with long stack
|
|
|
30
28
|
traces enabled. In node.js, you can do it using the --stack-trace-limit=100
|
|
31
29
|
CLI option:
|
|
32
30
|
|
|
33
|
-
`,
|
|
34
|
-
${
|
|
35
|
-
${
|
|
36
|
-
`))console.log(`${
|
|
37
|
-
`).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[]}}
|
|
31
|
+
`,x="\x1B[41m",j="\x1B[1m",H="\x1B[0m",T="\x1B[K";let k=!1;function z(s){if(!k){k=!0,console.log(`${x}
|
|
32
|
+
${T}
|
|
33
|
+
${j} WASM ERROR${H}${x}`);for(const e of s.split(`
|
|
34
|
+
`))console.log(`${T} ${e} `);console.log(`${H}`)}}function G(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 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 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 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 return this._running++,()=>{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(s){return s.toString().substring(s.origin.length)}function b(s,e){return!e||!s.startsWith(e)?s:s.substring(e.length)}function O(s,e){return!e||s.startsWith(e)?s:e+s}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:n=typeof location=="object"?location?.href:"",isStaticFilePath:o=()=>!1}=t;this.php=e,this.#e=r,this.#l=o;const i=new URL(n);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),n=b(r.pathname,this.#n);return this.#l(n)?this.#c(n):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 n="GET";const o={host:this.#o,...N(e.headers||{})},i=[];if(e.files&&Object.keys(e.files).length){n="POST";for(const c in e.files){const p=e.files[c];i.push({key:c,name:p.name,type:p.type,data:new Uint8Array(await p.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;return 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,await this.php.run({relativeUri:O(P(t),this.#n),protocol:this.#t,method:e.method||n,body:l,fileInfos:i,scriptPath:this.#u(t.pathname),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}`;return this.php.fileExists(r)?r:`${this.#e}/index.php`}}function K(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
|
+
\r
|
|
37
|
+
`),l=o.substring(0,i).trim(),c=o.substring(i+4).trim(),p=l.match(/name="([^"]+)"/);if(p){const g=p[1];e[g]=c}}),e}function Q(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"}}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 d(s=""){return function(t,r,n){const o=n.value;n.value=function(...i){try{return o.apply(this,i)}catch(l){const c=typeof l=="object"?l?.errno:null;if(c in F){const p=F[c],g=typeof i[0]=="string"?i[0]:null,$=g!==null?s.replaceAll("{path}",g):s;throw new Error(`${$}: ${p}`,{cause:l})}throw l}}}}async function X(s,e={},t=[]){let r,n;const o=new Promise(c=>{n=c}),i=new Promise(c=>{r=c}),l=s.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,n())}});for(const{default:c}of t)c(l);return t.length||n(),await o,await i,_.push(l),_.length-1}const _=[];function Z(s){return _[s]}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=(s,e,t,r)=>{for(var n=r>1?void 0:r?re(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&&te(e,t,n),n};const h="string",m="number",a=Symbol("__private__dont__use");class u{constructor(e,t){this.#e=[],this.#t=!1,this.#s=null,this.#r={},e!==void 0&&this.initializeRuntime(e),t&&(this.requestHandler=new U(new I(this,t)))}#e;#t;#s;#r;get absoluteUrl(){return this.requestHandler.requestHandler.absoluteUrl}get documentRoot(){return this.requestHandler.requestHandler.documentRoot}pathToInternalUrl(e){return this.requestHandler.requestHandler.pathToInternalUrl(e)}internalUrlToPath(e){return this.requestHandler.requestHandler.internalUrlToPath(e)}initializeRuntime(e){if(this[a])throw new Error("PHP runtime already initialized.");const t=Z(e);if(!t)throw new Error("Invalid PHP runtime id.");this[a]=t,this.#s=M(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.#o(),this.#t=!0),this.#u(e.scriptPath||""),this.#i(e.relativeUri||""),this.#l(e.method||"GET");const{host:t,...r}={host:"example.com:443",...N(e.headers||{})};if(this.#a(t,e.protocol||"http"),this.#c(r),e.body&&this.#h(e.body),e.fileInfos)for(const n of e.fileInfos)this.#p(n);return e.code&&this.#f(" ?>"+e.code),this.#d(),await this.#m()}#o(){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,[],[])}#
|
|
40
|
+
`;this[a].ccall("wasm_set_phpini_entries",null,[h],[e])}this[a].ccall("php_wasm_init",null,[],[])}#n(){const e="/tmp/headers.json";if(!this.fileExists(e))throw new Error("SAPI Error: Could not find response headers file.");const 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}}#i(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])}}#a(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,[m],[r]),(t==="https"||!t&&r===443)&&this.addServerGlobalEntry("HTTPS","on")}#l(e){this[a].ccall("wasm_set_request_method",null,[h],[e])}#c(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,[m],[parseInt(e["content-length"],10)]);for(const t in e)this.addServerGlobalEntry(`HTTP_${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,[m],[new TextEncoder().encode(e).length])}#u(e){this[a].ccall("wasm_set_path_translated",null,[h],[e])}addServerGlobalEntry(e,t){this.#r[e]=t}#d(){for(const e in this.#r)this[a].ccall("wasm_add_SERVER_entry",null,[h,h],[e,this.#r[e]])}#p(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,m,m],[t,r,n,i,l,o.byteLength])}#f(e){this[a].ccall("wasm_set_php_code",null,[h],[e])}async#m(){let e,t;try{e=await new Promise(async(o,i)=>{t=l=>{const c=new Error("Rethrown");c.cause=l.error,c.betterMessage=l.message,i(c)},this.#s?.addEventListener("error",t);try{o(await await this[a].ccall("wasm_sapi_handle_request",m,[],[]))}catch(l){i(l)}})}catch(o){for(const p in this)typeof this[p]=="function"&&(this[p]=()=>{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:n}=this.#n();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.mv(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){if(!this.fileExists(e))return[];try{return this[a].FS.readdir(e).filter(t=>t!=="."&&t!=="..")}catch(t){return console.error(t,{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([d('Could not create directory "{path}"')],u.prototype,"mkdir",1);f([d('Could not create directory "{path}"')],u.prototype,"mkdirTree",1);f([d('Could not read "{path}"')],u.prototype,"readFileAsText",1);f([d('Could not read "{path}"')],u.prototype,"readFileAsBuffer",1);f([d('Could not write to "{path}"')],u.prototype,"writeFile",1);f([d('Could not unlink "{path}"')],u.prototype,"unlink",1);f([d('Could not move "{path}"')],u.prototype,"mv",1);f([d('Could not remove directory "{path}"')],u.prototype,"rmdir",1);f([d('Could not list files in "{path}"')],u.prototype,"listFiles",1);f([d('Could not stat "{path}"')],u.prototype,"isDir",1);f([d('Could not stat "{path}"')],u.prototype,"fileExists",1);function N(s){const e={};for(const t in s)e[t.toLowerCase()]=s[t];return e}function L(s){return!(s instanceof u)}function se(s){return!L(s)}exports.BasePHP=u;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=L;exports.isRemotePHP=se;exports.loadPHPRuntime=X;exports.removePathPrefix=b;exports.rethrowFileSystemError=d;exports.toRelativeUrl=P;
|
package/index.js
CHANGED
|
@@ -1,3 +1,148 @@
|
|
|
1
|
+
const v = Symbol("error"), _ = Symbol("message");
|
|
2
|
+
class b extends Event {
|
|
3
|
+
/**
|
|
4
|
+
* Create a new `ErrorEvent`.
|
|
5
|
+
*
|
|
6
|
+
* @param type The name of the event
|
|
7
|
+
* @param options A dictionary object that allows for setting
|
|
8
|
+
* attributes via object members of the same name.
|
|
9
|
+
*/
|
|
10
|
+
constructor(e, t = {}) {
|
|
11
|
+
super(e), this[v] = t.error === void 0 ? null : t.error, this[_] = t.message === void 0 ? "" : t.message;
|
|
12
|
+
}
|
|
13
|
+
get error() {
|
|
14
|
+
return this[v];
|
|
15
|
+
}
|
|
16
|
+
get message() {
|
|
17
|
+
return this[_];
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
Object.defineProperty(b.prototype, "error", { enumerable: !0 });
|
|
21
|
+
Object.defineProperty(b.prototype, "message", { enumerable: !0 });
|
|
22
|
+
const A = typeof globalThis.ErrorEvent == "function" ? globalThis.ErrorEvent : b;
|
|
23
|
+
class O extends EventTarget {
|
|
24
|
+
constructor() {
|
|
25
|
+
super(...arguments), this.listenersCount = 0;
|
|
26
|
+
}
|
|
27
|
+
addEventListener(e, t) {
|
|
28
|
+
++this.listenersCount, super.addEventListener(e, t);
|
|
29
|
+
}
|
|
30
|
+
removeEventListener(e, t) {
|
|
31
|
+
--this.listenersCount, super.removeEventListener(e, t);
|
|
32
|
+
}
|
|
33
|
+
hasListeners() {
|
|
34
|
+
return this.listenersCount > 0;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function I(s) {
|
|
38
|
+
s.asm = {
|
|
39
|
+
...s.asm
|
|
40
|
+
};
|
|
41
|
+
const e = new O();
|
|
42
|
+
for (const t in s.asm)
|
|
43
|
+
if (typeof s.asm[t] == "function") {
|
|
44
|
+
const r = s.asm[t];
|
|
45
|
+
s.asm[t] = function(...n) {
|
|
46
|
+
try {
|
|
47
|
+
return r(...n);
|
|
48
|
+
} catch (o) {
|
|
49
|
+
if (!(o instanceof Error))
|
|
50
|
+
throw o;
|
|
51
|
+
if ("exitCode" in o && o?.exitCode === 0)
|
|
52
|
+
return;
|
|
53
|
+
const i = L(
|
|
54
|
+
o,
|
|
55
|
+
s.lastAsyncifyStackSource?.stack
|
|
56
|
+
);
|
|
57
|
+
if (s.lastAsyncifyStackSource && (o.cause = s.lastAsyncifyStackSource), !e.hasListeners())
|
|
58
|
+
throw D(i), o;
|
|
59
|
+
e.dispatchEvent(
|
|
60
|
+
new A("error", {
|
|
61
|
+
error: o,
|
|
62
|
+
message: i
|
|
63
|
+
})
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return e;
|
|
69
|
+
}
|
|
70
|
+
let w = [];
|
|
71
|
+
function N() {
|
|
72
|
+
return w;
|
|
73
|
+
}
|
|
74
|
+
function L(s, e) {
|
|
75
|
+
if (s.message === "unreachable") {
|
|
76
|
+
let t = $;
|
|
77
|
+
e || (t += `
|
|
78
|
+
|
|
79
|
+
This stack trace is lacking. For a better one initialize
|
|
80
|
+
the PHP runtime with { debug: true }, e.g. PHPNode.load('8.1', { debug: true }).
|
|
81
|
+
|
|
82
|
+
`), w = B(
|
|
83
|
+
e || s.stack || ""
|
|
84
|
+
);
|
|
85
|
+
for (const r of w)
|
|
86
|
+
t += ` * ${r}
|
|
87
|
+
`;
|
|
88
|
+
return t;
|
|
89
|
+
}
|
|
90
|
+
return s.message;
|
|
91
|
+
}
|
|
92
|
+
const $ = `
|
|
93
|
+
"unreachable" WASM instruction executed.
|
|
94
|
+
|
|
95
|
+
The typical reason is a PHP function missing from the ASYNCIFY_ONLY
|
|
96
|
+
list when building PHP.wasm.
|
|
97
|
+
|
|
98
|
+
You will need to file a new issue in the WordPress Playground repository
|
|
99
|
+
and paste this error message there:
|
|
100
|
+
|
|
101
|
+
https://github.com/WordPress/wordpress-playground/issues/new
|
|
102
|
+
|
|
103
|
+
If you're a core developer, the typical fix is to:
|
|
104
|
+
|
|
105
|
+
* Isolate a minimal reproduction of the error
|
|
106
|
+
* Add a reproduction of the error to php-asyncify.spec.ts in the WordPress Playground repository
|
|
107
|
+
* Run 'npm run fix-asyncify'
|
|
108
|
+
* Commit the changes, push to the repo, release updated NPM packages
|
|
109
|
+
|
|
110
|
+
Below is a list of all the PHP functions found in the stack trace to
|
|
111
|
+
help with the minimal reproduction. If they're all already listed in
|
|
112
|
+
the Dockerfile, you'll need to trigger this error again with long stack
|
|
113
|
+
traces enabled. In node.js, you can do it using the --stack-trace-limit=100
|
|
114
|
+
CLI option:
|
|
115
|
+
|
|
116
|
+
`, R = "\x1B[41m", M = "\x1B[1m", E = "\x1B[0m", S = "\x1B[K";
|
|
117
|
+
let x = !1;
|
|
118
|
+
function D(s) {
|
|
119
|
+
if (!x) {
|
|
120
|
+
x = !0, console.log(`${R}
|
|
121
|
+
${S}
|
|
122
|
+
${M} WASM ERROR${E}${R}`);
|
|
123
|
+
for (const e of s.split(`
|
|
124
|
+
`))
|
|
125
|
+
console.log(`${S} ${e} `);
|
|
126
|
+
console.log(`${E}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function B(s) {
|
|
130
|
+
try {
|
|
131
|
+
const e = s.split(`
|
|
132
|
+
`).slice(1).map((t) => {
|
|
133
|
+
const r = t.trim().substring(3).split(" ");
|
|
134
|
+
return {
|
|
135
|
+
fn: r.length >= 2 ? r[0] : "<unknown>",
|
|
136
|
+
isWasm: t.includes("wasm://")
|
|
137
|
+
};
|
|
138
|
+
}).filter(
|
|
139
|
+
({ fn: t, isWasm: r }) => r && !t.startsWith("dynCall_") && !t.startsWith("invoke_")
|
|
140
|
+
).map(({ fn: t }) => t);
|
|
141
|
+
return Array.from(new Set(e));
|
|
142
|
+
} catch {
|
|
143
|
+
return [];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
1
146
|
class y {
|
|
2
147
|
constructor(e, t, r, n = "", o = 0) {
|
|
3
148
|
this.httpStatusCode = e, this.headers = t, this.bytes = r, this.exitCode = o, this.errors = n;
|
|
@@ -44,7 +189,7 @@ const F = [
|
|
|
44
189
|
"7.0",
|
|
45
190
|
"5.6"
|
|
46
191
|
], ee = F[0], te = F;
|
|
47
|
-
class
|
|
192
|
+
class q {
|
|
48
193
|
#e;
|
|
49
194
|
#t;
|
|
50
195
|
/**
|
|
@@ -77,10 +222,10 @@ class A {
|
|
|
77
222
|
...e,
|
|
78
223
|
headers: {
|
|
79
224
|
...e.headers,
|
|
80
|
-
cookie: this.#
|
|
225
|
+
cookie: this.#r()
|
|
81
226
|
}
|
|
82
227
|
});
|
|
83
|
-
if (r.headers["set-cookie"] && this.#
|
|
228
|
+
if (r.headers["set-cookie"] && this.#s(r.headers["set-cookie"]), this.#t.handleRedirects && r.headers.location && t < this.#t.maxRedirects) {
|
|
84
229
|
const n = new URL(
|
|
85
230
|
r.headers.location[0],
|
|
86
231
|
this.requestHandler.absoluteUrl
|
|
@@ -112,7 +257,7 @@ class A {
|
|
|
112
257
|
get documentRoot() {
|
|
113
258
|
return this.requestHandler.documentRoot;
|
|
114
259
|
}
|
|
115
|
-
#
|
|
260
|
+
#s(e) {
|
|
116
261
|
for (const t of e)
|
|
117
262
|
try {
|
|
118
263
|
if (!t.includes("="))
|
|
@@ -123,14 +268,14 @@ class A {
|
|
|
123
268
|
console.error(r);
|
|
124
269
|
}
|
|
125
270
|
}
|
|
126
|
-
#
|
|
271
|
+
#r() {
|
|
127
272
|
const e = [];
|
|
128
273
|
for (const t in this.#e)
|
|
129
274
|
e.push(`${t}=${this.#e[t]}`);
|
|
130
275
|
return e.join("; ");
|
|
131
276
|
}
|
|
132
277
|
}
|
|
133
|
-
class
|
|
278
|
+
class W {
|
|
134
279
|
constructor({ concurrency: e }) {
|
|
135
280
|
this._running = 0, this.concurrency = e, this.queue = [];
|
|
136
281
|
}
|
|
@@ -155,23 +300,23 @@ class O {
|
|
|
155
300
|
}
|
|
156
301
|
}
|
|
157
302
|
}
|
|
158
|
-
const
|
|
159
|
-
function
|
|
303
|
+
const j = "http://example.com";
|
|
304
|
+
function k(s) {
|
|
160
305
|
return s.toString().substring(s.origin.length);
|
|
161
306
|
}
|
|
162
|
-
function
|
|
307
|
+
function T(s, e) {
|
|
163
308
|
return !e || !s.startsWith(e) ? s : s.substring(e.length);
|
|
164
309
|
}
|
|
165
|
-
function
|
|
310
|
+
function z(s, e) {
|
|
166
311
|
return !e || s.startsWith(e) ? s : e + s;
|
|
167
312
|
}
|
|
168
|
-
class
|
|
313
|
+
class G {
|
|
169
314
|
#e;
|
|
170
315
|
#t;
|
|
316
|
+
#s;
|
|
171
317
|
#r;
|
|
172
|
-
#n;
|
|
173
318
|
#o;
|
|
174
|
-
#
|
|
319
|
+
#n;
|
|
175
320
|
#i;
|
|
176
321
|
#a;
|
|
177
322
|
#l;
|
|
@@ -180,7 +325,7 @@ class L {
|
|
|
180
325
|
* @param config - Request Handler configuration.
|
|
181
326
|
*/
|
|
182
327
|
constructor(e, t = {}) {
|
|
183
|
-
this.#a = new
|
|
328
|
+
this.#a = new W({ concurrency: 1 });
|
|
184
329
|
const {
|
|
185
330
|
documentRoot: r = "/www/",
|
|
186
331
|
absoluteUrl: n = typeof location == "object" ? location?.href : "",
|
|
@@ -188,15 +333,15 @@ class L {
|
|
|
188
333
|
} = t;
|
|
189
334
|
this.php = e, this.#e = r, this.#l = o;
|
|
190
335
|
const i = new URL(n);
|
|
191
|
-
this.#
|
|
192
|
-
const l = this.#
|
|
336
|
+
this.#s = i.hostname, this.#r = i.port ? Number(i.port) : i.protocol === "https:" ? 443 : 80, this.#t = (i.protocol || "").replace(":", "");
|
|
337
|
+
const l = this.#r !== 443 && this.#r !== 80;
|
|
193
338
|
this.#o = [
|
|
194
|
-
this.#
|
|
195
|
-
l ? `:${this.#
|
|
196
|
-
].join(""), this.#
|
|
339
|
+
this.#s,
|
|
340
|
+
l ? `:${this.#r}` : ""
|
|
341
|
+
].join(""), this.#n = i.pathname.replace(/\/+$/, ""), this.#i = [
|
|
197
342
|
`${this.#t}://`,
|
|
198
343
|
this.#o,
|
|
199
|
-
this.#
|
|
344
|
+
this.#n
|
|
200
345
|
].join("");
|
|
201
346
|
}
|
|
202
347
|
/** @inheritDoc */
|
|
@@ -206,7 +351,7 @@ class L {
|
|
|
206
351
|
/** @inheritDoc */
|
|
207
352
|
internalUrlToPath(e) {
|
|
208
353
|
const t = new URL(e);
|
|
209
|
-
return t.pathname.startsWith(this.#
|
|
354
|
+
return t.pathname.startsWith(this.#n) && (t.pathname = t.pathname.slice(this.#n.length)), k(t);
|
|
210
355
|
}
|
|
211
356
|
get isRequestRunning() {
|
|
212
357
|
return this.#a.running > 0;
|
|
@@ -223,10 +368,10 @@ class L {
|
|
|
223
368
|
async request(e) {
|
|
224
369
|
const t = e.url.startsWith("http://") || e.url.startsWith("https://"), r = new URL(
|
|
225
370
|
e.url,
|
|
226
|
-
t ? void 0 :
|
|
227
|
-
), n =
|
|
371
|
+
t ? void 0 : j
|
|
372
|
+
), n = T(
|
|
228
373
|
r.pathname,
|
|
229
|
-
this.#
|
|
374
|
+
this.#n
|
|
230
375
|
);
|
|
231
376
|
return this.#l(n) ? this.#c(n) : await this.#h(e, r);
|
|
232
377
|
}
|
|
@@ -252,7 +397,7 @@ class L {
|
|
|
252
397
|
// @TODO: Infer the content-type from the arrayBuffer instead of the file path.
|
|
253
398
|
// The code below won't return the correct mime-type if the extension
|
|
254
399
|
// was tampered with.
|
|
255
|
-
"content-type": [
|
|
400
|
+
"content-type": [Y(t)],
|
|
256
401
|
"accept-ranges": ["bytes"],
|
|
257
402
|
"cache-control": ["public, max-age=0"]
|
|
258
403
|
},
|
|
@@ -289,7 +434,7 @@ class L {
|
|
|
289
434
|
data: new Uint8Array(await d.arrayBuffer())
|
|
290
435
|
});
|
|
291
436
|
}
|
|
292
|
-
o["content-type"]?.startsWith("multipart/form-data") && (e.formData =
|
|
437
|
+
o["content-type"]?.startsWith("multipart/form-data") && (e.formData = V(
|
|
293
438
|
e.body || ""
|
|
294
439
|
), o["content-type"] = "application/x-www-form-urlencoded", delete e.body);
|
|
295
440
|
}
|
|
@@ -297,9 +442,9 @@ class L {
|
|
|
297
442
|
return e.formData !== void 0 ? (n = "POST", o["content-type"] = o["content-type"] || "application/x-www-form-urlencoded", l = new URLSearchParams(
|
|
298
443
|
e.formData
|
|
299
444
|
).toString()) : l = e.body, await this.php.run({
|
|
300
|
-
relativeUri:
|
|
301
|
-
|
|
302
|
-
this.#
|
|
445
|
+
relativeUri: z(
|
|
446
|
+
k(t),
|
|
447
|
+
this.#n
|
|
303
448
|
),
|
|
304
449
|
protocol: this.#t,
|
|
305
450
|
method: e.method || n,
|
|
@@ -321,13 +466,13 @@ class L {
|
|
|
321
466
|
* @returns The resolved filesystem path.
|
|
322
467
|
*/
|
|
323
468
|
#u(e) {
|
|
324
|
-
let t =
|
|
469
|
+
let t = T(e, this.#n);
|
|
325
470
|
t.includes(".php") ? t = t.split(".php")[0] + ".php" : (t.endsWith("/") || (t += "/"), t.endsWith("index.php") || (t += "index.php"));
|
|
326
471
|
const r = `${this.#e}${t}`;
|
|
327
472
|
return this.php.fileExists(r) ? r : `${this.#e}/index.php`;
|
|
328
473
|
}
|
|
329
474
|
}
|
|
330
|
-
function
|
|
475
|
+
function V(s) {
|
|
331
476
|
const e = {}, t = s.match(/--(.*)\r\n/);
|
|
332
477
|
if (!t)
|
|
333
478
|
return e;
|
|
@@ -342,7 +487,7 @@ function $(s) {
|
|
|
342
487
|
}
|
|
343
488
|
}), e;
|
|
344
489
|
}
|
|
345
|
-
function
|
|
490
|
+
function Y(s) {
|
|
346
491
|
switch (s.split(".").pop()) {
|
|
347
492
|
case "css":
|
|
348
493
|
return "text/css";
|
|
@@ -382,7 +527,7 @@ function M(s) {
|
|
|
382
527
|
return "application-octet-stream";
|
|
383
528
|
}
|
|
384
529
|
}
|
|
385
|
-
const
|
|
530
|
+
const C = {
|
|
386
531
|
0: "No error occurred. System call completed successfully.",
|
|
387
532
|
1: "Argument list too long.",
|
|
388
533
|
2: "Permission denied.",
|
|
@@ -469,8 +614,8 @@ function p(s = "") {
|
|
|
469
614
|
return o.apply(this, i);
|
|
470
615
|
} catch (l) {
|
|
471
616
|
const c = typeof l == "object" ? l?.errno : null;
|
|
472
|
-
if (c in
|
|
473
|
-
const d =
|
|
617
|
+
if (c in C) {
|
|
618
|
+
const d = C[c], g = typeof i[0] == "string" ? i[0] : null, U = g !== null ? s.replaceAll("{path}", g) : s;
|
|
474
619
|
throw new Error(`${U}: ${d}`, {
|
|
475
620
|
cause: l
|
|
476
621
|
});
|
|
@@ -486,7 +631,7 @@ async function re(s, e = {}, t = []) {
|
|
|
486
631
|
n = c;
|
|
487
632
|
}), i = new Promise((c) => {
|
|
488
633
|
r = c;
|
|
489
|
-
}), l = s.init(
|
|
634
|
+
}), l = s.init(K, {
|
|
490
635
|
onAbort(c) {
|
|
491
636
|
console.error("WASM aborted: "), console.error(c);
|
|
492
637
|
},
|
|
@@ -506,159 +651,15 @@ async function re(s, e = {}, t = []) {
|
|
|
506
651
|
});
|
|
507
652
|
for (const { default: c } of t)
|
|
508
653
|
c(l);
|
|
509
|
-
return t.length || n(), await o, await i,
|
|
510
|
-
}
|
|
511
|
-
const w = [];
|
|
512
|
-
function D(s) {
|
|
513
|
-
return w[s];
|
|
654
|
+
return t.length || n(), await o, await i, P.push(l), P.length - 1;
|
|
514
655
|
}
|
|
515
|
-
const
|
|
516
|
-
return typeof process < "u" && process.release?.name === "node" ? "NODE" : typeof window < "u" ? "WEB" : typeof WorkerGlobalScope < "u" && self instanceof WorkerGlobalScope ? "WORKER" : "NODE";
|
|
517
|
-
}(), E = Symbol("error"), S = Symbol("message");
|
|
518
|
-
class b extends Event {
|
|
519
|
-
/**
|
|
520
|
-
* Create a new `ErrorEvent`.
|
|
521
|
-
*
|
|
522
|
-
* @param type The name of the event
|
|
523
|
-
* @param options A dictionary object that allows for setting
|
|
524
|
-
* attributes via object members of the same name.
|
|
525
|
-
*/
|
|
526
|
-
constructor(e, t = {}) {
|
|
527
|
-
super(e), this[E] = t.error === void 0 ? null : t.error, this[S] = t.message === void 0 ? "" : t.message;
|
|
528
|
-
}
|
|
529
|
-
get error() {
|
|
530
|
-
return this[E];
|
|
531
|
-
}
|
|
532
|
-
get message() {
|
|
533
|
-
return this[S];
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
Object.defineProperty(b.prototype, "error", { enumerable: !0 });
|
|
537
|
-
Object.defineProperty(b.prototype, "message", { enumerable: !0 });
|
|
538
|
-
const q = typeof globalThis.ErrorEvent == "function" ? globalThis.ErrorEvent : b;
|
|
539
|
-
class W extends EventTarget {
|
|
540
|
-
constructor() {
|
|
541
|
-
super(...arguments), this.listenersCount = 0;
|
|
542
|
-
}
|
|
543
|
-
addEventListener(e, t) {
|
|
544
|
-
++this.listenersCount, super.addEventListener(e, t);
|
|
545
|
-
}
|
|
546
|
-
removeEventListener(e, t) {
|
|
547
|
-
--this.listenersCount, super.removeEventListener(e, t);
|
|
548
|
-
}
|
|
549
|
-
hasListeners() {
|
|
550
|
-
return this.listenersCount > 0;
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
function j(s) {
|
|
554
|
-
s.asm = {
|
|
555
|
-
...s.asm
|
|
556
|
-
};
|
|
557
|
-
const e = new W();
|
|
558
|
-
for (const t in s.asm)
|
|
559
|
-
if (typeof s.asm[t] == "function") {
|
|
560
|
-
const r = s.asm[t];
|
|
561
|
-
s.asm[t] = function(...n) {
|
|
562
|
-
try {
|
|
563
|
-
return r(...n);
|
|
564
|
-
} catch (o) {
|
|
565
|
-
if (!(o instanceof Error))
|
|
566
|
-
throw o;
|
|
567
|
-
if ("exitCode" in o && o?.exitCode === 0)
|
|
568
|
-
return;
|
|
569
|
-
const i = G(
|
|
570
|
-
o,
|
|
571
|
-
s.lastAsyncifyStackSource?.stack
|
|
572
|
-
);
|
|
573
|
-
if (s.lastAsyncifyStackSource && (o.cause = s.lastAsyncifyStackSource), !e.hasListeners())
|
|
574
|
-
throw J(i), o;
|
|
575
|
-
e.dispatchEvent(
|
|
576
|
-
new q("error", {
|
|
577
|
-
error: o,
|
|
578
|
-
message: i
|
|
579
|
-
})
|
|
580
|
-
);
|
|
581
|
-
}
|
|
582
|
-
};
|
|
583
|
-
}
|
|
584
|
-
return e;
|
|
585
|
-
}
|
|
586
|
-
let P = [];
|
|
587
|
-
function z() {
|
|
588
|
-
return P;
|
|
589
|
-
}
|
|
590
|
-
function G(s, e) {
|
|
591
|
-
if (s.message === "unreachable") {
|
|
592
|
-
let t = V;
|
|
593
|
-
e || (t += `
|
|
594
|
-
|
|
595
|
-
This stack trace is lacking. For a better one initialize
|
|
596
|
-
the PHP runtime with { debug: true }, e.g. PHPNode.load('8.1', { debug: true }).
|
|
597
|
-
|
|
598
|
-
`), P = K(
|
|
599
|
-
e || s.stack || ""
|
|
600
|
-
);
|
|
601
|
-
for (const r of P)
|
|
602
|
-
t += ` * ${r}
|
|
603
|
-
`;
|
|
604
|
-
return t;
|
|
605
|
-
}
|
|
606
|
-
return s.message;
|
|
607
|
-
}
|
|
608
|
-
const V = `
|
|
609
|
-
"unreachable" WASM instruction executed.
|
|
610
|
-
|
|
611
|
-
The typical reason is a PHP function missing from the ASYNCIFY_ONLY
|
|
612
|
-
list when building PHP.wasm.
|
|
613
|
-
|
|
614
|
-
You will need to file a new issue in the WordPress Playground repository
|
|
615
|
-
and paste this error message there:
|
|
616
|
-
|
|
617
|
-
https://github.com/WordPress/wordpress-playground/issues/new
|
|
618
|
-
|
|
619
|
-
If you're a core developer, the typical fix is to:
|
|
620
|
-
|
|
621
|
-
* Isolate a minimal reproduction of the error
|
|
622
|
-
* Add a reproduction of the error to php-asyncify.spec.ts in the WordPress Playground repository
|
|
623
|
-
* Run 'npm run fix-asyncify'
|
|
624
|
-
* Commit the changes, push to the repo, release updated NPM packages
|
|
625
|
-
|
|
626
|
-
Below is a list of all the PHP functions found in the stack trace to
|
|
627
|
-
help with the minimal reproduction. If they're all already listed in
|
|
628
|
-
the Dockerfile, you'll need to trigger this error again with long stack
|
|
629
|
-
traces enabled. In node.js, you can do it using the --stack-trace-limit=100
|
|
630
|
-
CLI option:
|
|
631
|
-
|
|
632
|
-
`, x = "\x1B[41m", Y = "\x1B[1m", k = "\x1B[0m", T = "\x1B[K";
|
|
633
|
-
let C = !1;
|
|
656
|
+
const P = [];
|
|
634
657
|
function J(s) {
|
|
635
|
-
|
|
636
|
-
C = !0, console.log(`${x}
|
|
637
|
-
${T}
|
|
638
|
-
${Y} WASM ERROR${k}${x}`);
|
|
639
|
-
for (const e of s.split(`
|
|
640
|
-
`))
|
|
641
|
-
console.log(`${T} ${e} `);
|
|
642
|
-
console.log(`${k}`);
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
function K(s) {
|
|
646
|
-
try {
|
|
647
|
-
const e = s.split(`
|
|
648
|
-
`).slice(1).map((t) => {
|
|
649
|
-
const r = t.trim().substring(3).split(" ");
|
|
650
|
-
return {
|
|
651
|
-
fn: r.length >= 2 ? r[0] : "<unknown>",
|
|
652
|
-
isWasm: t.includes("wasm://")
|
|
653
|
-
};
|
|
654
|
-
}).filter(
|
|
655
|
-
({ fn: t, isWasm: r }) => r && !t.startsWith("dynCall_") && !t.startsWith("invoke_")
|
|
656
|
-
).map(({ fn: t }) => t);
|
|
657
|
-
return Array.from(new Set(e));
|
|
658
|
-
} catch {
|
|
659
|
-
return [];
|
|
660
|
-
}
|
|
658
|
+
return P[s];
|
|
661
659
|
}
|
|
660
|
+
const K = function() {
|
|
661
|
+
return typeof process < "u" && process.release?.name === "node" ? "NODE" : typeof window < "u" ? "WEB" : typeof WorkerGlobalScope < "u" && self instanceof WorkerGlobalScope ? "WORKER" : "NODE";
|
|
662
|
+
}();
|
|
662
663
|
var Q = Object.defineProperty, X = Object.getOwnPropertyDescriptor, f = (s, e, t, r) => {
|
|
663
664
|
for (var n = r > 1 ? void 0 : r ? X(e, t) : e, o = s.length - 1, i; o >= 0; o--)
|
|
664
665
|
(i = s[o]) && (n = (r ? i(e, t, n) : i(n)) || n);
|
|
@@ -674,12 +675,13 @@ class u {
|
|
|
674
675
|
* @param serverOptions - Optional. Options for the PHPRequestHandler. If undefined, no request handler will be initialized.
|
|
675
676
|
*/
|
|
676
677
|
constructor(e, t) {
|
|
677
|
-
this.#e = [], this.#t = !1, this.#
|
|
678
|
-
new
|
|
678
|
+
this.#e = [], this.#t = !1, this.#s = null, this.#r = {}, e !== void 0 && this.initializeRuntime(e), t && (this.requestHandler = new q(
|
|
679
|
+
new G(this, t)
|
|
679
680
|
));
|
|
680
681
|
}
|
|
681
682
|
#e;
|
|
682
683
|
#t;
|
|
684
|
+
#s;
|
|
683
685
|
#r;
|
|
684
686
|
/** @inheritDoc */
|
|
685
687
|
get absoluteUrl() {
|
|
@@ -702,10 +704,10 @@ class u {
|
|
|
702
704
|
initializeRuntime(e) {
|
|
703
705
|
if (this[a])
|
|
704
706
|
throw new Error("PHP runtime already initialized.");
|
|
705
|
-
const t =
|
|
707
|
+
const t = J(e);
|
|
706
708
|
if (!t)
|
|
707
709
|
throw new Error("Invalid PHP runtime id.");
|
|
708
|
-
this[a] = t, this.#
|
|
710
|
+
this[a] = t, this.#s = I(t);
|
|
709
711
|
}
|
|
710
712
|
/** @inheritDoc */
|
|
711
713
|
setPhpIniPath(e) {
|
|
@@ -736,17 +738,17 @@ class u {
|
|
|
736
738
|
}
|
|
737
739
|
/** @inheritDoc */
|
|
738
740
|
async run(e) {
|
|
739
|
-
this.#t || (this.#
|
|
741
|
+
this.#t || (this.#o(), this.#t = !0), this.#u(e.scriptPath || ""), this.#i(e.relativeUri || ""), this.#l(e.method || "GET");
|
|
740
742
|
const { host: t, ...r } = {
|
|
741
743
|
host: "example.com:443",
|
|
742
744
|
...H(e.headers || {})
|
|
743
745
|
};
|
|
744
|
-
if (this.#
|
|
746
|
+
if (this.#a(t, e.protocol || "http"), this.#c(r), e.body && this.#h(e.body), e.fileInfos)
|
|
745
747
|
for (const n of e.fileInfos)
|
|
746
|
-
this.#
|
|
747
|
-
return e.code && this.#
|
|
748
|
+
this.#p(n);
|
|
749
|
+
return e.code && this.#f(" ?>" + e.code), this.#d(), await this.#m();
|
|
748
750
|
}
|
|
749
|
-
#
|
|
751
|
+
#o() {
|
|
750
752
|
if (this.#e.length > 0) {
|
|
751
753
|
const e = this.#e.map(([t, r]) => `${t}=${r}`).join(`
|
|
752
754
|
`) + `
|
|
@@ -761,7 +763,7 @@ class u {
|
|
|
761
763
|
}
|
|
762
764
|
this[a].ccall("php_wasm_init", null, [], []);
|
|
763
765
|
}
|
|
764
|
-
#
|
|
766
|
+
#n() {
|
|
765
767
|
const e = "/tmp/headers.json";
|
|
766
768
|
if (!this.fileExists(e))
|
|
767
769
|
throw new Error(
|
|
@@ -779,7 +781,7 @@ class u {
|
|
|
779
781
|
httpStatusCode: t.status
|
|
780
782
|
};
|
|
781
783
|
}
|
|
782
|
-
#
|
|
784
|
+
#i(e) {
|
|
783
785
|
if (this[a].ccall(
|
|
784
786
|
"wasm_set_request_uri",
|
|
785
787
|
null,
|
|
@@ -795,7 +797,7 @@ class u {
|
|
|
795
797
|
);
|
|
796
798
|
}
|
|
797
799
|
}
|
|
798
|
-
#
|
|
800
|
+
#a(e, t) {
|
|
799
801
|
this[a].ccall(
|
|
800
802
|
"wasm_set_request_host",
|
|
801
803
|
null,
|
|
@@ -814,7 +816,7 @@ class u {
|
|
|
814
816
|
[r]
|
|
815
817
|
), (t === "https" || !t && r === 443) && this.addServerGlobalEntry("HTTPS", "on");
|
|
816
818
|
}
|
|
817
|
-
#
|
|
819
|
+
#l(e) {
|
|
818
820
|
this[a].ccall(
|
|
819
821
|
"wasm_set_request_method",
|
|
820
822
|
null,
|
|
@@ -822,7 +824,7 @@ class u {
|
|
|
822
824
|
[e]
|
|
823
825
|
);
|
|
824
826
|
}
|
|
825
|
-
#
|
|
827
|
+
#c(e) {
|
|
826
828
|
e.cookie && this[a].ccall(
|
|
827
829
|
"wasm_set_cookies",
|
|
828
830
|
null,
|
|
@@ -845,7 +847,7 @@ class u {
|
|
|
845
847
|
e[t]
|
|
846
848
|
);
|
|
847
849
|
}
|
|
848
|
-
#
|
|
850
|
+
#h(e) {
|
|
849
851
|
this[a].ccall(
|
|
850
852
|
"wasm_set_request_body",
|
|
851
853
|
null,
|
|
@@ -858,7 +860,7 @@ class u {
|
|
|
858
860
|
[new TextEncoder().encode(e).length]
|
|
859
861
|
);
|
|
860
862
|
}
|
|
861
|
-
#
|
|
863
|
+
#u(e) {
|
|
862
864
|
this[a].ccall(
|
|
863
865
|
"wasm_set_path_translated",
|
|
864
866
|
null,
|
|
@@ -867,12 +869,16 @@ class u {
|
|
|
867
869
|
);
|
|
868
870
|
}
|
|
869
871
|
addServerGlobalEntry(e, t) {
|
|
870
|
-
this[
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
[
|
|
875
|
-
|
|
872
|
+
this.#r[e] = t;
|
|
873
|
+
}
|
|
874
|
+
#d() {
|
|
875
|
+
for (const e in this.#r)
|
|
876
|
+
this[a].ccall(
|
|
877
|
+
"wasm_add_SERVER_entry",
|
|
878
|
+
null,
|
|
879
|
+
[h, h],
|
|
880
|
+
[e, this.#r[e]]
|
|
881
|
+
);
|
|
876
882
|
}
|
|
877
883
|
/**
|
|
878
884
|
* Adds file information to $_FILES superglobal in PHP.
|
|
@@ -883,7 +889,7 @@ class u {
|
|
|
883
889
|
*
|
|
884
890
|
* @param fileInfo - File details
|
|
885
891
|
*/
|
|
886
|
-
#
|
|
892
|
+
#p(e) {
|
|
887
893
|
const { key: t, name: r, type: n, data: o } = e, i = `/tmp/${Math.random().toFixed(20)}`;
|
|
888
894
|
this.writeFile(i, o);
|
|
889
895
|
const l = 0;
|
|
@@ -894,7 +900,7 @@ class u {
|
|
|
894
900
|
[t, r, n, i, l, o.byteLength]
|
|
895
901
|
);
|
|
896
902
|
}
|
|
897
|
-
#
|
|
903
|
+
#f(e) {
|
|
898
904
|
this[a].ccall(
|
|
899
905
|
"wasm_set_php_code",
|
|
900
906
|
null,
|
|
@@ -902,14 +908,14 @@ class u {
|
|
|
902
908
|
[e]
|
|
903
909
|
);
|
|
904
910
|
}
|
|
905
|
-
async #
|
|
911
|
+
async #m() {
|
|
906
912
|
let e, t;
|
|
907
913
|
try {
|
|
908
914
|
e = await new Promise(async (o, i) => {
|
|
909
915
|
t = (l) => {
|
|
910
916
|
const c = new Error("Rethrown");
|
|
911
917
|
c.cause = l.error, c.betterMessage = l.message, i(c);
|
|
912
|
-
}, this.#
|
|
918
|
+
}, this.#s?.addEventListener(
|
|
913
919
|
"error",
|
|
914
920
|
t
|
|
915
921
|
);
|
|
@@ -939,13 +945,13 @@ class u {
|
|
|
939
945
|
"PHP runtime has crashed – see the earlier error for details."
|
|
940
946
|
);
|
|
941
947
|
});
|
|
942
|
-
this.functionsMaybeMissingFromAsyncify =
|
|
948
|
+
this.functionsMaybeMissingFromAsyncify = N();
|
|
943
949
|
const i = o, l = "betterMessage" in i ? i.betterMessage : i.message, c = new Error(l);
|
|
944
950
|
throw c.cause = i, c;
|
|
945
951
|
} finally {
|
|
946
|
-
this.#
|
|
952
|
+
this.#s?.removeEventListener("error", t), this.#r = {};
|
|
947
953
|
}
|
|
948
|
-
const { headers: r, httpStatusCode: n } = this.#
|
|
954
|
+
const { headers: r, httpStatusCode: n } = this.#n();
|
|
949
955
|
return new y(
|
|
950
956
|
n,
|
|
951
957
|
r,
|
|
@@ -1052,19 +1058,20 @@ function se(s) {
|
|
|
1052
1058
|
}
|
|
1053
1059
|
export {
|
|
1054
1060
|
u as BasePHP,
|
|
1055
|
-
|
|
1061
|
+
j as DEFAULT_BASE_URL,
|
|
1056
1062
|
ee as LatestSupportedPHPVersion,
|
|
1057
|
-
|
|
1058
|
-
|
|
1063
|
+
q as PHPBrowser,
|
|
1064
|
+
G as PHPRequestHandler,
|
|
1059
1065
|
y as PHPResponse,
|
|
1060
1066
|
F as SupportedPHPVersions,
|
|
1061
1067
|
te as SupportedPHPVersionsList,
|
|
1068
|
+
O as UnhandledRejectionsTarget,
|
|
1062
1069
|
a as __private__dont__use,
|
|
1063
|
-
|
|
1070
|
+
z as ensurePathPrefix,
|
|
1064
1071
|
Z as isLocalPHP,
|
|
1065
1072
|
se as isRemotePHP,
|
|
1066
1073
|
re as loadPHPRuntime,
|
|
1067
|
-
|
|
1074
|
+
T as removePathPrefix,
|
|
1068
1075
|
p as rethrowFileSystemError,
|
|
1069
|
-
|
|
1076
|
+
k as toRelativeUrl
|
|
1070
1077
|
};
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export type { FileInfo, IsomorphicLocalPHP, IsomorphicRemotePHP, PHPOutput, PHPRunOptions, UniversalPHP, RmDirOptions, HTTPMethod, PHPRequest, PHPRequestHeaders, RequestHandler, } from './universal-php';
|
|
2
|
+
export { UnhandledRejectionsTarget } from './wasm-error-reporting';
|
|
2
3
|
export { PHPResponse } from './php-response';
|
|
3
4
|
export type { PHPResponseData } from './php-response';
|
|
4
5
|
export type { ErrnoError } from './rethrow-file-system-error';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@php-wasm/universal",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.43",
|
|
4
4
|
"description": "PHP.wasm – emscripten bindings for PHP",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -36,5 +36,5 @@
|
|
|
36
36
|
"main": "./index.cjs",
|
|
37
37
|
"module": "./index.js",
|
|
38
38
|
"license": "GPL-2.0-or-later",
|
|
39
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "090e1dd0de51e5d5d7106ba60611a8e9f96fa35d"
|
|
40
40
|
}
|