@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 +10 -10
- package/index.js +232 -207
- package/lib/index.d.ts +3 -0
- package/lib/is-exit-code-zero.d.ts +7 -0
- package/lib/php-request-handler.d.ts +17 -5
- package/lib/supported-php-extensions.d.ts +6 -0
- package/lib/universal-php.d.ts +2 -2
- package/package.json +6 -2
package/index.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
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
|
-
`),
|
|
7
|
-
`;return t}return
|
|
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",
|
|
32
|
-
${
|
|
33
|
-
${
|
|
34
|
-
`))console.log(`${
|
|
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,
|
|
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(),
|
|
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
|
|
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"),
|
|
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[
|
|
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
|
|
23
|
-
|
|
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
|
|
38
|
-
|
|
39
|
-
...
|
|
40
|
+
function N(s) {
|
|
41
|
+
s.asm = {
|
|
42
|
+
...s.asm
|
|
40
43
|
};
|
|
41
|
-
const e = new
|
|
42
|
-
for (const t in
|
|
43
|
-
if (typeof
|
|
44
|
-
const r =
|
|
45
|
-
|
|
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(...
|
|
50
|
+
return r(...n);
|
|
48
51
|
} catch (o) {
|
|
49
52
|
if (!(o instanceof Error))
|
|
50
53
|
throw o;
|
|
51
|
-
|
|
52
|
-
return;
|
|
53
|
-
const i = $(
|
|
54
|
+
const i = M(
|
|
54
55
|
o,
|
|
55
|
-
|
|
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
|
|
74
|
+
function $() {
|
|
72
75
|
return w;
|
|
73
76
|
}
|
|
74
|
-
function
|
|
75
|
-
if (
|
|
76
|
-
let t =
|
|
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 =
|
|
83
|
-
e ||
|
|
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
|
|
93
|
+
return s.message;
|
|
91
94
|
}
|
|
92
|
-
const
|
|
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
|
-
`,
|
|
117
|
-
let
|
|
118
|
-
function D(
|
|
119
|
-
if (!
|
|
120
|
-
|
|
121
|
-
${
|
|
122
|
-
${
|
|
123
|
-
for (const e of
|
|
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(`${
|
|
126
|
-
console.log(`${
|
|
128
|
+
console.log(`${x} ${e} `);
|
|
129
|
+
console.log(`${R}`);
|
|
127
130
|
}
|
|
128
131
|
}
|
|
129
|
-
function
|
|
132
|
+
function W(s) {
|
|
130
133
|
try {
|
|
131
|
-
const e =
|
|
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,
|
|
148
|
-
this.httpStatusCode = e, this.headers = t, this.bytes = r, this.exitCode = o, this.errors =
|
|
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
|
|
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
|
-
],
|
|
192
|
-
|
|
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
|
|
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:
|
|
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("="),
|
|
266
|
-
this.#e[
|
|
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
|
|
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
|
|
307
|
-
function
|
|
308
|
-
return
|
|
316
|
+
const V = "http://example.com";
|
|
317
|
+
function k(s) {
|
|
318
|
+
return s.toString().substring(s.origin.length);
|
|
309
319
|
}
|
|
310
|
-
function
|
|
311
|
-
return !e || !
|
|
320
|
+
function H(s, e) {
|
|
321
|
+
return !e || !s.startsWith(e) ? s : s.substring(e.length);
|
|
312
322
|
}
|
|
313
|
-
function
|
|
314
|
-
return !e ||
|
|
323
|
+
function Y(s, e) {
|
|
324
|
+
return !e || s.startsWith(e) ? s : e + s;
|
|
315
325
|
}
|
|
316
|
-
class
|
|
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
|
|
340
|
+
this.#a = new G({ concurrency: 1 });
|
|
332
341
|
const {
|
|
333
342
|
documentRoot: r = "/www/",
|
|
334
|
-
absoluteUrl:
|
|
335
|
-
isStaticFilePath: o = () => !1
|
|
343
|
+
absoluteUrl: n = typeof location == "object" ? location?.href : ""
|
|
336
344
|
} = t;
|
|
337
|
-
this.php = e, this.#e = r
|
|
338
|
-
const
|
|
339
|
-
this.#s =
|
|
340
|
-
const
|
|
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
|
-
|
|
344
|
-
].join(""), this.#n =
|
|
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)),
|
|
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 :
|
|
375
|
-
),
|
|
382
|
+
t ? void 0 : V
|
|
383
|
+
), n = H(
|
|
376
384
|
r.pathname,
|
|
377
385
|
this.#n
|
|
378
|
-
)
|
|
379
|
-
return
|
|
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
|
|
392
|
+
* @param fsPath - Absolute path of the static file to serve.
|
|
385
393
|
* @returns The response.
|
|
386
394
|
*/
|
|
387
|
-
#
|
|
388
|
-
|
|
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
|
|
406
|
+
const t = this.php.readFileAsBuffer(e);
|
|
396
407
|
return new g(
|
|
397
408
|
200,
|
|
398
409
|
{
|
|
399
|
-
"content-length": [`${
|
|
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": [
|
|
414
|
+
"content-type": [Z(e)],
|
|
404
415
|
"accept-ranges": ["bytes"],
|
|
405
416
|
"cache-control": ["public, max-age=0"]
|
|
406
417
|
},
|
|
407
|
-
|
|
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 #
|
|
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
|
|
435
|
+
let n = "GET";
|
|
425
436
|
const o = {
|
|
426
437
|
host: this.#o,
|
|
427
|
-
...
|
|
438
|
+
...A(e.headers || {})
|
|
428
439
|
}, i = [];
|
|
429
440
|
if (e.files && Object.keys(e.files).length) {
|
|
430
|
-
|
|
431
|
-
for (const
|
|
432
|
-
const m = e.files[
|
|
441
|
+
n = "POST";
|
|
442
|
+
for (const c in e.files) {
|
|
443
|
+
const m = e.files[c];
|
|
433
444
|
i.push({
|
|
434
|
-
key:
|
|
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 =
|
|
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 ? (
|
|
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
|
|
459
|
+
let h;
|
|
449
460
|
try {
|
|
450
|
-
|
|
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:
|
|
460
|
-
|
|
470
|
+
relativeUri: Y(
|
|
471
|
+
k(t),
|
|
461
472
|
this.#n
|
|
462
473
|
),
|
|
463
474
|
protocol: this.#t,
|
|
464
|
-
method: e.method ||
|
|
475
|
+
method: e.method || n,
|
|
465
476
|
body: l,
|
|
466
477
|
fileInfos: i,
|
|
467
|
-
scriptPath:
|
|
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
|
-
#
|
|
484
|
-
let t =
|
|
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
|
|
495
|
-
const e = {}, t =
|
|
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],
|
|
499
|
-
return
|
|
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(),
|
|
503
|
-
if (
|
|
504
|
-
const m =
|
|
505
|
-
e[m] =
|
|
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
|
|
510
|
-
switch (
|
|
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
|
-
|
|
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(
|
|
629
|
-
return function(t, r,
|
|
630
|
-
const o =
|
|
631
|
-
|
|
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
|
|
636
|
-
if (
|
|
637
|
-
const
|
|
638
|
-
throw new Error(`${
|
|
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
|
|
648
|
-
|
|
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
|
-
|
|
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(),
|
|
680
|
+
e.onRuntimeInitialized && e.onRuntimeInitialized(), n();
|
|
666
681
|
},
|
|
667
682
|
monitorRunDependencies(c) {
|
|
668
|
-
c === 0 && (delete
|
|
683
|
+
c === 0 && (delete h.monitorRunDependencies, l());
|
|
669
684
|
}
|
|
670
685
|
});
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
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
|
|
677
|
-
return P[
|
|
693
|
+
function te(s) {
|
|
694
|
+
return P[s];
|
|
678
695
|
}
|
|
679
|
-
const
|
|
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
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
return
|
|
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
|
|
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
|
|
698
|
-
new
|
|
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 =
|
|
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
|
|
736
|
-
|
|
737
|
-
}, this.#s =
|
|
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
|
-
...
|
|
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
|
|
775
|
-
this.#f(
|
|
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
|
-
[
|
|
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
|
|
801
|
-
if (!
|
|
822
|
+
for (const n of t.headers) {
|
|
823
|
+
if (!n.includes(": "))
|
|
802
824
|
continue;
|
|
803
|
-
const o =
|
|
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
|
-
[
|
|
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
|
-
[
|
|
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
|
-
[
|
|
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
|
-
[
|
|
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
|
-
[
|
|
880
|
+
[u],
|
|
859
881
|
[e.cookie]
|
|
860
882
|
), e["content-type"] && this[a].ccall(
|
|
861
883
|
"wasm_set_content_type",
|
|
862
884
|
null,
|
|
863
|
-
[
|
|
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
|
-
[
|
|
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
|
-
[
|
|
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
|
-
[
|
|
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:
|
|
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
|
-
[
|
|
929
|
-
[t, r,
|
|
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
|
-
[
|
|
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 = (
|
|
945
|
-
const
|
|
946
|
-
|
|
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
|
|
961
|
-
typeof this[
|
|
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 =
|
|
967
|
-
const i = o, l = "betterMessage" in i ? i.betterMessage : i.message,
|
|
968
|
-
throw
|
|
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:
|
|
994
|
+
const { headers: r, httpStatusCode: n } = this.#i();
|
|
973
995
|
return new g(
|
|
974
|
-
|
|
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
|
|
1005
|
-
this.isDir(
|
|
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
|
-
(
|
|
1035
|
+
(n) => n !== "." && n !== ".."
|
|
1014
1036
|
);
|
|
1015
1037
|
if (t.prependPath) {
|
|
1016
|
-
const
|
|
1017
|
-
return r.map((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
|
|
1092
|
+
function A(s) {
|
|
1071
1093
|
const e = {};
|
|
1072
|
-
for (const t in
|
|
1073
|
-
e[t.toLowerCase()] =
|
|
1094
|
+
for (const t in s)
|
|
1095
|
+
e[t.toLowerCase()] = s[t];
|
|
1074
1096
|
return e;
|
|
1075
1097
|
}
|
|
1076
|
-
function
|
|
1077
|
-
return !(
|
|
1098
|
+
function oe(s) {
|
|
1099
|
+
return !(s instanceof d);
|
|
1078
1100
|
}
|
|
1079
|
-
function
|
|
1080
|
-
return !
|
|
1101
|
+
function he(s) {
|
|
1102
|
+
return !oe(s);
|
|
1081
1103
|
}
|
|
1082
1104
|
export {
|
|
1083
1105
|
d as BasePHP,
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1106
|
+
V as DEFAULT_BASE_URL,
|
|
1107
|
+
ie as LatestSupportedPHPVersion,
|
|
1108
|
+
z as PHPBrowser,
|
|
1109
|
+
J as PHPRequestHandler,
|
|
1088
1110
|
g as PHPResponse,
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
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
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
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
|
-
|
|
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';
|
|
@@ -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';
|
package/lib/universal-php.d.ts
CHANGED
|
@@ -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.
|
|
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 –
|
|
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.
|
|
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": "
|
|
39
|
+
"gitHead": "6890ff9243f9a10f0b86755fead101647a8c8535",
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=16.15.1",
|
|
42
|
+
"npm": ">=8.11.0"
|
|
43
|
+
}
|
|
40
44
|
}
|