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