@php-wasm/universal 0.6.0 → 0.6.1
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/__vite-browser-external-2447137e.js +4 -0
- package/__vite-browser-external-b3701507.cjs +1 -0
- package/index.cjs +5 -5
- package/index.js +142 -123
- package/lib/index.d.ts +1 -0
- package/lib/universal-php.d.ts +1 -1
- package/lib/write-files.d.ts +26 -0
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e={};exports.default=e;
|
package/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var K=(e,t,r)=>{if(!t.has(e))throw TypeError("Cannot "+r)};var a=(e,t,r)=>(K(e,t,"read from private field"),r?r.call(e):t.get(e)),c=(e,t,r)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,r)},u=(e,t,r,s)=>(K(e,t,"write to private field"),s?s.call(e,r):t.set(e,r),r);var p=(e,t,r)=>(K(e,t,"access private method"),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});if(typeof File>"u"){class e extends Blob{constructor(r,s,i){super(r);let n;i!=null&&i.lastModified&&(n=new Date),(!n||isNaN(n.getFullYear()))&&(n=new Date),this.lastModifiedDate=n,this.lastModified=n.getMilliseconds(),this.name=s||""}}global.File=e}function asPromise(e){return new Promise(function(t,r){e.onload=e.onerror=function(s){e.onload=e.onerror=null,s.type==="load"?t(e.result):r(new Error("Failed to read the blob/file"))}})}typeof Blob.prototype.arrayBuffer>"u"&&(Blob.prototype.arrayBuffer=function(){const t=new FileReader;return t.readAsArrayBuffer(this),asPromise(t)});typeof Blob.prototype.text>"u"&&(Blob.prototype.text=function(){const t=new FileReader;return t.readAsText(this),asPromise(t)});function isByobSupported(){const e=new Uint8Array([1,2,3,4]),r=new File([e],"test").stream();try{return r.getReader({mode:"byob"}),!0}catch{return!1}}(typeof Blob.prototype.stream>"u"||!isByobSupported())&&(Blob.prototype.stream=function(){let e=0;const t=this;return new ReadableStream({type:"bytes",autoAllocateChunkSize:512*1024,async pull(r){const s=r.byobRequest.view,n=await t.slice(e,e+s.byteLength).arrayBuffer(),o=new Uint8Array(n);new Uint8Array(s.buffer).set(o);const l=o.byteLength;r.byobRequest.respond(l),e+=l,e>=t.size&&r.close()}})});if(typeof CustomEvent>"u"){class e extends Event{constructor(r,s={}){super(r,s),this.detail=s.detail}initCustomEvent(){}}globalThis.CustomEvent=e}typeof crypto>"u"&&Promise.resolve().then(()=>require("./__vite-browser-external-b3701507.cjs")).then(e=>{global.crypto=e});const kError=Symbol("error"),kMessage=Symbol("message");class ErrorEvent2 extends Event{constructor(t,r={}){super(t),this[kError]=r.error===void 0?null:r.error,this[kMessage]=r.message===void 0?"":r.message}get error(){return this[kError]}get message(){return this[kMessage]}}Object.defineProperty(ErrorEvent2.prototype,"error",{enumerable:!0});Object.defineProperty(ErrorEvent2.prototype,"message",{enumerable:!0});const ErrorEvent=typeof globalThis.ErrorEvent=="function"?globalThis.ErrorEvent:ErrorEvent2;function isExitCodeZero(e){return e instanceof Error?"exitCode"in e&&(e==null?void 0:e.exitCode)===0||(e==null?void 0:e.name)==="ExitStatus"&&"status"in e&&e.status===0:!1}class UnhandledRejectionsTarget extends EventTarget{constructor(){super(...arguments),this.listenersCount=0}addEventListener(t,r){++this.listenersCount,super.addEventListener(t,r)}removeEventListener(t,r){--this.listenersCount,super.removeEventListener(t,r)}hasListeners(){return this.listenersCount>0}}function improveWASMErrorReporting(e){e.asm={...e.asm};const t=new UnhandledRejectionsTarget;for(const r in e.asm)if(typeof e.asm[r]=="function"){const s=e.asm[r];e.asm[r]=function(...i){var n;try{return s(...i)}catch(o){if(!(o instanceof Error))throw o;const l=clarifyErrorMessage(o,(n=e.lastAsyncifyStackSource)==null?void 0:n.stack);if(e.lastAsyncifyStackSource&&(o.cause=e.lastAsyncifyStackSource),t.hasListeners()){t.dispatchEvent(new ErrorEvent("error",{error:o,message:l}));return}throw isExitCodeZero(o)||showCriticalErrorBox(l),o}}}return t}let functionsMaybeMissingFromAsyncify=[];function getFunctionsMaybeMissingFromAsyncify(){return functionsMaybeMissingFromAsyncify}function clarifyErrorMessage(e,t){if(e.message==="unreachable"){let r=UNREACHABLE_ERROR;t||(r+=`
|
|
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,9 @@ 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 p of l){const d=`${o}/${p}`;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 v,b;class PHPBrowser{constructor(t,r={}){c(this,v,void 0);c(this,b,void 0);this.requestHandler=t,u(this,v,{}),u(this,b,{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,b).handleRedirects&&s.headers.location&&r<a(this,b).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,v)[i]=n}catch(s){console.error(s)}}serializeCookies(){const t=[];for(const r in a(this,v))t.push(`${r}=${a(this,v)[r]}`);return t.join("; ")}}v=new WeakMap,b=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 w,x,A,R,H,_,F,T,L,K,U,Q,N,X;class PHPRequestHandler{constructor(t,r={}){c(this,L);c(this,U);c(this,N);c(this,w,void 0);c(this,x,void 0);c(this,A,void 0);c(this,R,void 0);c(this,H,void 0);c(this,_,void 0);c(this,F,void 0);c(this,T,void 0);u(this,T,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,w,s);const n=new URL(i);u(this,A,n.hostname),u(this,R,n.port?Number(n.port):n.protocol==="https:"?443:80),u(this,x,(n.protocol||"").replace(":",""));const o=a(this,R)!==443&&a(this,R)!==80;u(this,H,[a(this,A),o?`:${a(this,R)}`:""].join("")),u(this,_,n.pathname.replace(/\/+$/,"")),u(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,T).running>0}get absoluteUrl(){return a(this,F)}get documentRoot(){return a(this,w)}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,_)),n=`${a(this,w)}${i}`;return seemsLikeAPHPRequestHandlerPath(n)?await h(this,U,Q).call(this,t,s):h(this,L,K).call(this,n)}}w=new WeakMap,x=new WeakMap,A=new WeakMap,R=new WeakMap,H=new WeakMap,_=new WeakMap,F=new WeakMap,T=new WeakMap,L=new WeakSet,K=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,Q=async function(t,r){var i,n;const s=await a(this,T).acquire();try{this.php.addServerGlobalEntry("REMOTE_ADDR","127.0.0.1"),this.php.addServerGlobalEntry("DOCUMENT_ROOT",a(this,w)),this.php.addServerGlobalEntry("HTTPS",a(this,F).startsWith("https://")?"on":"");let o="GET";const l={host:a(this,H),...normalizeHeaders(t.headers||{})},p=[];if(t.files&&Object.keys(t.files).length){o="POST";for(const P in t.files){const I=t.files[P];p.push({key:P,name:I.name,type:I.type,data:new Uint8Array(await I.arrayBuffer())})}(i=l["content-type"])!=null&&i.startsWith("multipart/form-data")&&(t.formData=parseMultipartFormDataString(t.body||""),l["content-type"]="application/x-www-form-urlencoded",delete t.body)}let d;t.formData!==void 0?(o="POST",l["content-type"]=l["content-type"]||"application/x-www-form-urlencoded",d=new URLSearchParams(t.formData).toString()):d=t.body;let f;try{let P=r.pathname;if((n=t.headers)!=null&&n["x-rewrite-url"])try{P=new URL(t.headers["x-rewrite-url"]).pathname}catch{}f=h(this,N,X).call(this,P)}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,fileInfos:p,scriptPath:f,headers:l})}finally{s()}},N=new WeakSet,X=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,w)}${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 i=e[s];i==="."?e.splice(s,1):i===".."?(e.splice(s,1),r++):r&&(e.splice(s,1),r--)}if(t)for(;r;r--)e.unshift("..");return e}function createSpawnHandler(e){return function(t){const r=new ChildProcess,s=new ProcessApi(r);return setTimeout(async()=>{await e(t,s),r.emit("spawn",!0)}),r}}class EventEmitter{constructor(){this.listeners={}}emit(t,r){this.listeners[t]&&this.listeners[t].forEach(function(s){s(r)})}on(t,r){this.listeners[t]||(this.listeners[t]=[]),this.listeners[t].push(r)}}class ProcessApi extends EventEmitter{constructor(t){super(),this.childProcess=t,this.exited=!1,this.stdinData=[],t.on("stdin",r=>{this.stdinData?this.stdinData.push(r.slice()):this.emit("stdin",r)})}stdout(t){typeof t=="string"&&(t=new TextEncoder().encode(t)),this.childProcess.stdout.emit("data",t)}stderr(t){typeof t=="string"&&(t=new TextEncoder().encode(t)),this.childProcess.stderr.emit("data",t)}exit(t){this.exited||(this.exited=!0,this.childProcess.emit("exit",t))}flushStdin(){if(this.stdinData)for(let t=0;t<this.stdinData.length;t++)this.emit("stdin",this.stdinData[t]);this.stdinData=null}}let lastPid=9743;class ChildProcess extends EventEmitter{constructor(t=lastPid++){super(),this.pid=t,this.stdout=new EventEmitter,this.stderr=new EventEmitter;const r=this;this.stdin={write:s=>{r.emit("stdin",s)}}}}function concatUint8Array(...e){const t=new Uint8Array(e.reduce((s,i)=>s+i.length,0));let r=0;for(const s of e)t.set(s,r),r+=s.length;return t}function concatBytes(e){if(e===void 0){let t=new Uint8Array;return new TransformStream({transform(r){t=concatUint8Array(t,r)},flush(r){r.enqueue(t)}})}else{const t=new ArrayBuffer(e||0);let r=0;return new TransformStream({transform(s){new Uint8Array(t).set(s,r),r+=s.byteLength},flush(s){s.enqueue(new Uint8Array(t))}})}}function limitBytes(e,t){if(t===0)return new ReadableStream({start(i){i.close()}});const r=e.getReader({mode:"byob"});let s=0;return new ReadableStream({async pull(i){const{value:n,done:o}=await r.read(new Uint8Array(t-s));if(o){r.releaseLock(),i.close();return}s+=n.length,i.enqueue(n),s>=t&&(r.releaseLock(),i.close())},cancel(){r.cancel()}})}async function collectBytes(e,t){return t!==void 0&&(e=limitBytes(e,t)),await e.pipeThrough(concatBytes(t)).getReader().read().then(({value:r})=>r)}class StreamedFile extends File{constructor(t,r,s){super([],r,{type:s}),this.readableStream=t}slice(){throw new Error("slice() is not possible on a StreamedFile")}stream(){return this.readableStream}async text(){return new TextDecoder().decode(await this.arrayBuffer())}async arrayBuffer(){return await collectBytes(this.stream())}}ReadableStream.prototype[Symbol.asyncIterator]||(ReadableStream.prototype[Symbol.asyncIterator]=async function*(){const e=this.getReader();try{for(;;){const{done:t,value:r}=await e.read();if(t)return;yield r}}finally{e.releaseLock()}},ReadableStream.prototype.iterate=ReadableStream.prototype[Symbol.asyncIterator]);function streamReadFileFromPHP(e,t){return new ReadableStream({async pull(r){const s=await e.readFileAsBuffer(t);r.enqueue(s),r.close()}})}async function*iteratePhpFiles(e,t,{relativePaths:r=!0,pathPrefix:s,exceptPaths:i=[]}={}){t=normalizePath(t);const n=[t];for(;n.length;){const o=n.pop();if(!o)return;const l=await e.listFiles(o);for(const h of l){const d=`${o}/${h}`;if(i.includes(d.substring(t.length+1)))continue;await e.isDir(d)?n.push(d):yield new StreamedFile(streamReadFileFromPHP(e,d),r?joinPaths(s||"",d.substring(t.length+1)):d)}}}function writeFilesStreamToPhp(e,t){return new WritableStream({async write(r){const s=joinPaths(t,r.name);r.type==="directory"?await e.mkdir(s):(await e.mkdir(dirname(s)),await e.writeFile(s,new Uint8Array(await r.arrayBuffer())))}})}class PHPResponse{constructor(t,r,s,i="",n=0){this.httpStatusCode=t,this.headers=r,this.bytes=s,this.exitCode=n,this.errors=i}static fromRawData(t){return new PHPResponse(t.httpStatusCode,t.headers,t.bytes,t.errors,t.exitCode)}toRawData(){return{headers:this.headers,bytes:this.bytes,errors:this.errors,exitCode:this.exitCode,httpStatusCode:this.httpStatusCode}}get json(){return JSON.parse(this.text)}get text(){return new TextDecoder().decode(this.bytes)}}const SupportedPHPVersions=["8.3","8.2","8.1","8.0","7.4","7.3","7.2","7.1","7.0"],LatestSupportedPHPVersion=SupportedPHPVersions[0],SupportedPHPVersionsList=SupportedPHPVersions,SupportedPHPExtensionsList=["iconv","mbstring","xml-bundle","gd"],SupportedPHPExtensionBundles={"kitchen-sink":SupportedPHPExtensionsList};var E,x;class PHPBrowser{constructor(t,r={}){c(this,E,void 0);c(this,x,void 0);this.requestHandler=t,u(this,E,{}),u(this,x,{handleRedirects:!1,maxRedirects:4,...r})}async request(t,r=0){const s=await this.requestHandler.request({...t,headers:{...t.headers,cookie:this.serializeCookies()}});if(s.headers["set-cookie"]&&this.setCookies(s.headers["set-cookie"]),a(this,x).handleRedirects&&s.headers.location&&r<a(this,x).maxRedirects){const i=new URL(s.headers.location[0],this.requestHandler.absoluteUrl);return this.request({url:i.toString(),method:"GET",headers:{}},r+1)}return s}pathToInternalUrl(t){return this.requestHandler.pathToInternalUrl(t)}internalUrlToPath(t){return this.requestHandler.internalUrlToPath(t)}get absoluteUrl(){return this.requestHandler.absoluteUrl}get documentRoot(){return this.requestHandler.documentRoot}setCookies(t){for(const r of t)try{if(!r.includes("="))continue;const s=r.indexOf("="),i=r.substring(0,s),n=r.substring(s+1).split(";")[0];a(this,E)[i]=n}catch(s){console.error(s)}}serializeCookies(){const t=[];for(const r in a(this,E))t.push(`${r}=${a(this,E)[r]}`);return t.join("; ")}}E=new WeakMap,x=new WeakMap;const DEFAULT_BASE_URL="http://example.com";function toRelativeUrl(e){return e.toString().substring(e.origin.length)}function removePathPrefix(e,t){return!t||!e.startsWith(t)?e:e.substring(t.length)}function ensurePathPrefix(e,t){return!t||e.startsWith(t)?e:t+e}var P,H,A,v,F,m,T,R,U,Q,N,X,M,ee;class PHPRequestHandler{constructor(t,r={}){c(this,U);c(this,N);c(this,M);c(this,P,void 0);c(this,H,void 0);c(this,A,void 0);c(this,v,void 0);c(this,F,void 0);c(this,m,void 0);c(this,T,void 0);c(this,R,void 0);u(this,R,new Semaphore({concurrency:1}));const{documentRoot:s="/www/",absoluteUrl:i=typeof location=="object"?location==null?void 0:location.href:""}=r;this.php=t,u(this,P,s);const n=new URL(i);u(this,A,n.hostname),u(this,v,n.port?Number(n.port):n.protocol==="https:"?443:80),u(this,H,(n.protocol||"").replace(":",""));const o=a(this,v)!==443&&a(this,v)!==80;u(this,F,[a(this,A),o?`:${a(this,v)}`:""].join("")),u(this,m,n.pathname.replace(/\/+$/,"")),u(this,T,[`${a(this,H)}://`,a(this,F),a(this,m)].join(""))}pathToInternalUrl(t){return`${this.absoluteUrl}${t}`}internalUrlToPath(t){const r=new URL(t);return r.pathname.startsWith(a(this,m))&&(r.pathname=r.pathname.slice(a(this,m).length)),toRelativeUrl(r)}get isRequestRunning(){return a(this,R).running>0}get absoluteUrl(){return a(this,T)}get documentRoot(){return a(this,P)}async request(t){const r=t.url.startsWith("http://")||t.url.startsWith("https://"),s=new URL(t.url,r?void 0:DEFAULT_BASE_URL),i=removePathPrefix(s.pathname,a(this,m)),n=`${a(this,P)}${i}`;return seemsLikeAPHPRequestHandlerPath(n)?await p(this,N,X).call(this,t,s):p(this,U,Q).call(this,n)}}P=new WeakMap,H=new WeakMap,A=new WeakMap,v=new WeakMap,F=new WeakMap,m=new WeakMap,T=new WeakMap,R=new WeakMap,U=new WeakSet,Q=function(t){if(!this.php.fileExists(t))return new PHPResponse(404,{"x-file-type":["static"]},new TextEncoder().encode("404 File not found"));const r=this.php.readFileAsBuffer(t);return new PHPResponse(200,{"content-length":[`${r.byteLength}`],"content-type":[inferMimeType(t)],"accept-ranges":["bytes"],"cache-control":["public, max-age=0"]},r)},N=new WeakSet,X=async function(t,r){var i,n,o;if(a(this,R).running>0&&((i=t.headers)==null?void 0:i["x-request-issuer"])==="php")return console.warn("Possible deadlock: Called request() before the previous request() have finished. PHP likely issued an HTTP call to itself. Normally this would lead to infinite waiting as Request 1 holds the lock that the Request 2 is waiting to acquire. That's not useful, so PHPRequestHandler will return error 502 instead."),new PHPResponse(502,{},new TextEncoder().encode("502 Bad Gateway"));const s=await a(this,R).acquire();try{this.php.addServerGlobalEntry("REMOTE_ADDR","127.0.0.1"),this.php.addServerGlobalEntry("DOCUMENT_ROOT",a(this,P)),this.php.addServerGlobalEntry("HTTPS",a(this,T).startsWith("https://")?"on":"");let l="GET";const h={host:a(this,F),...normalizeHeaders(t.headers||{})},d=[];if(t.files&&Object.keys(t.files).length){l="POST";for(const S in t.files){const L=t.files[S];d.push({key:S,name:L.name,type:L.type,data:new Uint8Array(await L.arrayBuffer())})}(n=h["content-type"])!=null&&n.startsWith("multipart/form-data")&&(t.formData=parseMultipartFormDataString(t.body||""),h["content-type"]="application/x-www-form-urlencoded",delete t.body)}let f;t.formData!==void 0?(l="POST",h["content-type"]=h["content-type"]||"application/x-www-form-urlencoded",f=new URLSearchParams(t.formData).toString()):f=t.body;let I;try{let S=r.pathname;if((o=t.headers)!=null&&o["x-rewrite-url"])try{S=new URL(t.headers["x-rewrite-url"]).pathname}catch{}I=p(this,M,ee).call(this,S)}catch{return new PHPResponse(404,{},new TextEncoder().encode("404 File not found"))}return await this.php.run({relativeUri:ensurePathPrefix(toRelativeUrl(r),a(this,m)),protocol:a(this,H),method:t.method||l,body:f,fileInfos:d,scriptPath:I,headers:h})}finally{s()}},M=new WeakSet,ee=function(t){let r=removePathPrefix(t,a(this,m));r.includes(".php")?r=r.split(".php")[0]+".php":(r.endsWith("/")||(r+="/"),r.endsWith("index.php")||(r+="index.php"));const s=`${a(this,P)}${r}`;if(this.php.fileExists(s))return s;throw new Error(`File not found: ${s}`)};function parseMultipartFormDataString(e){const t={},r=e.match(/--(.*)\r\n/);if(!r)return t;const s=r[1],i=e.split(`--${s}`);return i.shift(),i.pop(),i.forEach(n=>{const o=n.indexOf(`\r
|
|
36
36
|
\r
|
|
37
|
-
`),l=n.substring(0,o).trim(),p=n.substring(o+4).trim(),d=l.match(/name="([^"]+)"/);if(d){const f=d[1];t[f]=p}}),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 p=typeof l=="object"?l==null?void 0:l.errno:null;if(p in FileErrorCodes){const d=FileErrorCodes[p],f=typeof o[0]=="string"?o[0]:null,P=f!==null?e.replaceAll("{path}",f):e;throw new Error(`${P}: ${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,B,m,g,E,y,k,M,ee,O,te,D,re,q,se,$,ne,j,ie,z,oe,W,ae,G,le,V,ce,J,ue,Y,de;class BasePHP{constructor(e,t){c(this,M);c(this,O);c(this,D);c(this,q);c(this,$);c(this,j);c(this,z);c(this,W);c(this,G);c(this,V);c(this,J);c(this,Y);c(this,S,void 0);c(this,C,void 0);c(this,B,void 0);c(this,m,void 0);c(this,g,void 0);c(this,E,void 0);c(this,y,void 0);c(this,k,void 0);u(this,S,[]),u(this,m,!1),u(this,g,null),u(this,E,{}),u(this,y,new Map),u(this,k,[]),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,k).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,k)){const i=await s(r);if(i)return i}return""},u(this,g,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,B,e)}setPhpIniPath(e){if(a(this,m))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,m))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,m)||(h(this,M,ee).call(this),u(this,m,!0)),h(this,W,ae).call(this,e.scriptPath||""),h(this,D,re).call(this,e.relativeUri||""),h(this,$,ne).call(this,e.method||"GET");const s=normalizeHeaders(e.headers||{}),i=s.host||"example.com:443";if(h(this,q,se).call(this,i,e.protocol||"http"),h(this,j,ie).call(this,s),e.body&&(r=h(this,z,oe).call(this,e.body)),e.fileInfos)for(const o of e.fileInfos)h(this,V,ce).call(this,o);typeof e.code=="string"&&h(this,J,ue).call(this," ?>"+e.code),h(this,G,le).call(this);const n=await h(this,Y,de).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,E)[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,B)&&this.setSapiName(a(this,B)),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,m,!1),u(this,g,null),delete this[__private__dont__use].onMessage,delete this[__private__dont__use]}}S=new WeakMap,C=new WeakMap,B=new WeakMap,m=new WeakMap,g=new WeakMap,E=new WeakMap,y=new WeakMap,k=new WeakMap,M=new WeakSet,ee=function(){if(this.setPhpIniEntry("auto_prepend_file","/tmp/consts.php"),this.fileExists("/tmp/consts.php")||this.writeFile("/tmp/consts.php",`<?php
|
|
37
|
+
`),l=n.substring(0,o).trim(),h=n.substring(o+4).trim(),d=l.match(/name="([^"]+)"/);if(d){const f=d[1];t[f]=h}}),t}function inferMimeType(e){switch(e.split(".").pop()){case"css":return"text/css";case"js":return"application/javascript";case"png":return"image/png";case"jpg":case"jpeg":return"image/jpeg";case"gif":return"image/gif";case"svg":return"image/svg+xml";case"woff":return"font/woff";case"woff2":return"font/woff2";case"ttf":return"font/ttf";case"otf":return"font/otf";case"eot":return"font/eot";case"ico":return"image/x-icon";case"html":return"text/html";case"json":return"application/json";case"xml":return"application/xml";case"txt":case"md":return"text/plain";default:return"application-octet-stream"}}function seemsLikeAPHPRequestHandlerPath(e){return seemsLikeAPHPFile(e)||seemsLikeADirectoryRoot(e)}function seemsLikeAPHPFile(e){return e.endsWith(".php")||e.includes(".php/")}function seemsLikeADirectoryRoot(e){return!e.split("/").pop().includes(".")}const FileErrorCodes={0:"No error occurred. System call completed successfully.",1:"Argument list too long.",2:"Permission denied.",3:"Address in use.",4:"Address not available.",5:"Address family not supported.",6:"Resource unavailable, or operation would block.",7:"Connection already in progress.",8:"Bad file descriptor.",9:"Bad message.",10:"Device or resource busy.",11:"Operation canceled.",12:"No child processes.",13:"Connection aborted.",14:"Connection refused.",15:"Connection reset.",16:"Resource deadlock would occur.",17:"Destination address required.",18:"Mathematics argument out of domain of function.",19:"Reserved.",20:"File exists.",21:"Bad address.",22:"File too large.",23:"Host is unreachable.",24:"Identifier removed.",25:"Illegal byte sequence.",26:"Operation in progress.",27:"Interrupted function.",28:"Invalid argument.",29:"I/O error.",30:"Socket is connected.",31:"There is a directory under that path.",32:"Too many levels of symbolic links.",33:"File descriptor value too large.",34:"Too many links.",35:"Message too large.",36:"Reserved.",37:"Filename too long.",38:"Network is down.",39:"Connection aborted by network.",40:"Network unreachable.",41:"Too many files open in system.",42:"No buffer space available.",43:"No such device.",44:"There is no such file or directory OR the parent directory does not exist.",45:"Executable file format error.",46:"No locks available.",47:"Reserved.",48:"Not enough space.",49:"No message of the desired type.",50:"Protocol not available.",51:"No space left on device.",52:"Function not supported.",53:"The socket is not connected.",54:"Not a directory or a symbolic link to a directory.",55:"Directory not empty.",56:"State not recoverable.",57:"Not a socket.",58:"Not supported, or operation not supported on socket.",59:"Inappropriate I/O control operation.",60:"No such device or address.",61:"Value too large to be stored in data type.",62:"Previous owner died.",63:"Operation not permitted.",64:"Broken pipe.",65:"Protocol error.",66:"Protocol not supported.",67:"Protocol wrong type for socket.",68:"Result too large.",69:"Read-only file system.",70:"Invalid seek.",71:"No such process.",72:"Reserved.",73:"Connection timed out.",74:"Text file busy.",75:"Cross-device link.",76:"Extension: Capabilities insufficient."};function getEmscriptenFsError(e){const t=typeof e=="object"?e==null?void 0:e.errno:null;if(t in FileErrorCodes)return FileErrorCodes[t]}function rethrowFileSystemError(e=""){return function(r,s,i){const n=i.value;i.value=function(...o){try{return n.apply(this,o)}catch(l){const h=typeof l=="object"?l==null?void 0:l.errno:null;if(h in FileErrorCodes){const d=FileErrorCodes[h],f=typeof o[0]=="string"?o[0]:null,I=f!==null?e.replaceAll("{path}",f):e;throw new Error(`${I}: ${d}`,{cause:l})}throw l}}}}const RuntimeId=Symbol("RuntimeId"),loadedRuntimes=new Map;let lastRuntimeId=0;async function loadPHPRuntime(e,t={}){const[r,s,i]=makePromise(),n=e.init(currentJsRuntime,{onAbort(l){i(l),console.error(l)},ENV:{},locateFile:l=>l,...t,noInitialRun:!0,onRuntimeInitialized(){t.onRuntimeInitialized&&t.onRuntimeInitialized(),s()}});await r;const o=++lastRuntimeId;return n.id=o,n.originalExit=n._exit,n._exit=function(l){return loadedRuntimes.delete(o),n.originalExit(l)},n[RuntimeId]=o,loadedRuntimes.set(o,n),o}function getLoadedRuntime(e){return loadedRuntimes.get(e)}const currentJsRuntime=function(){var e;return typeof process<"u"&&((e=process.release)==null?void 0:e.name)==="node"?"NODE":typeof window<"u"?"WEB":typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope?"WORKER":"NODE"}(),makePromise=()=>{const e=[],t=new Promise((r,s)=>{e.push(r,s)});return e.unshift(t),e};var __defProp=Object.defineProperty,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__decorateClass=(e,t,r,s)=>{for(var i=s>1?void 0:s?__getOwnPropDesc(t,r):t,n=e.length-1,o;n>=0;n--)(o=e[n])&&(i=(s?o(t,r,i):o(i))||i);return s&&i&&__defProp(t,r,i),i};const STRING="string",NUMBER="number",__private__dont__use=Symbol("__private__dont__use");var b,C,k,_,w,g,y,B,q,te,O,re,D,se,$,ne,j,ie,z,oe,G,ae,W,le,V,ce,J,ue,Y,de,Z,he;class BasePHP{constructor(e,t){c(this,q);c(this,O);c(this,D);c(this,$);c(this,j);c(this,z);c(this,G);c(this,W);c(this,V);c(this,J);c(this,Y);c(this,Z);c(this,b,void 0);c(this,C,void 0);c(this,k,void 0);c(this,_,void 0);c(this,w,void 0);c(this,g,void 0);c(this,y,void 0);c(this,B,void 0);u(this,b,[]),u(this,_,!1),u(this,w,null),u(this,g,{}),u(this,y,new Map),u(this,B,[]),this.semaphore=new Semaphore({concurrency:1}),e!==void 0&&this.initializeRuntime(e),t&&(this.requestHandler=new PHPBrowser(new PHPRequestHandler(this,t)))}addEventListener(e,t){a(this,y).has(e)||a(this,y).set(e,new Set),a(this,y).get(e).add(t)}removeEventListener(e,t){var r;(r=a(this,y).get(e))==null||r.delete(t)}dispatchEvent(e){const t=a(this,y).get(e.type);if(t)for(const r of t)r(e)}async onMessage(e){a(this,B).push(e)}async setSpawnHandler(handler){typeof handler=="string"&&(handler=createSpawnHandler(eval(handler))),this[__private__dont__use].spawnProcess=handler}get absoluteUrl(){return this.requestHandler.requestHandler.absoluteUrl}get documentRoot(){return this.requestHandler.requestHandler.documentRoot}pathToInternalUrl(e){return this.requestHandler.requestHandler.pathToInternalUrl(e)}internalUrlToPath(e){return this.requestHandler.requestHandler.internalUrlToPath(e)}initializeRuntime(e){if(this[__private__dont__use])throw new Error("PHP runtime already initialized.");const t=getLoadedRuntime(e);if(!t)throw new Error("Invalid PHP runtime id.");this[__private__dont__use]=t,t.onMessage=async r=>{for(const s of a(this,B)){const i=await s(r);if(i)return i}return""},u(this,w,improveWASMErrorReporting(t)),this.dispatchEvent({type:"runtime.initialized"})}async setSapiName(e){if(this[__private__dont__use].ccall("wasm_set_sapi_name",NUMBER,[STRING],[e])!==0)throw new Error("Could not set SAPI name. This can only be done before the PHP WASM module is initialized.Did you already dispatch any requests?");u(this,k,e)}setPhpIniPath(e){if(a(this,_))throw new Error("Cannot set PHP ini path after calling run().");u(this,C,e),this[__private__dont__use].ccall("wasm_set_phpini_path",null,["string"],[e])}setPhpIniEntry(e,t){if(a(this,_))throw new Error("Cannot set PHP ini entries after calling run().");a(this,b).push([e,t])}chdir(e){this[__private__dont__use].FS.chdir(e)}async request(e,t){if(!this.requestHandler)throw new Error("No request handler available.");return this.requestHandler.request(e,t)}async run(e){const t=await this.semaphore.acquire();let r;try{a(this,_)||(p(this,q,te).call(this),u(this,_,!0)),p(this,W,le).call(this,e.scriptPath||""),p(this,D,se).call(this,e.relativeUri||""),p(this,j,ie).call(this,e.method||"GET");const s=normalizeHeaders(e.headers||{}),i=s.host||"example.com:443";if(p(this,$,ne).call(this,i,e.protocol||"http"),p(this,z,oe).call(this,s),e.body&&(r=p(this,G,ae).call(this,e.body)),e.fileInfos)for(const o of e.fileInfos)p(this,J,ue).call(this,o);typeof e.code=="string"&&p(this,Y,de).call(this," ?>"+e.code),p(this,V,ce).call(this);const n=await p(this,Z,he).call(this);if(e.throwOnError&&n.exitCode!==0){const o={stdout:n.text,stderr:n.errors};console.warn("PHP.run() output was:",o);const l=new Error(`PHP.run() failed with exit code ${n.exitCode} and the following output`);throw l.output=o,l}return n}finally{try{r&&this[__private__dont__use].free(r)}finally{t(),this.dispatchEvent({type:"request.end"})}}}addServerGlobalEntry(e,t){a(this,g)[e]=t}defineConstant(e,t){let r={};try{r=JSON.parse(this.fileExists("/tmp/consts.json")&&this.readFileAsText("/tmp/consts.json")||"{}")}catch{}this.writeFile("/tmp/consts.json",JSON.stringify({...r,[e]:t}))}mkdir(e){this[__private__dont__use].FS.mkdirTree(e)}mkdirTree(e){this.mkdir(e)}readFileAsText(e){return new TextDecoder().decode(this.readFileAsBuffer(e))}readFileAsBuffer(e){return this[__private__dont__use].FS.readFile(e)}writeFile(e,t){this[__private__dont__use].FS.writeFile(e,t)}unlink(e){this[__private__dont__use].FS.unlink(e)}mv(e,t){try{this[__private__dont__use].FS.rename(e,t)}catch(r){const s=getEmscriptenFsError(r);throw s?new Error(`Could not move ${e} to ${t}: ${s}`,{cause:r}):r}}rmdir(e,t={recursive:!0}){t!=null&&t.recursive&&this.listFiles(e).forEach(r=>{const s=`${e}/${r}`;this.isDir(s)?this.rmdir(s,t):this.unlink(s)}),this[__private__dont__use].FS.rmdir(e)}listFiles(e,t={prependPath:!1}){if(!this.fileExists(e))return[];try{const r=this[__private__dont__use].FS.readdir(e).filter(s=>s!=="."&&s!=="..");if(t.prependPath){const s=e.replace(/\/$/,"");return r.map(i=>`${s}/${i}`)}return r}catch(r){return console.error(r,{path:e}),[]}}isDir(e){return this.fileExists(e)?this[__private__dont__use].FS.isDir(this[__private__dont__use].FS.lookupPath(e).node.mode):!1}fileExists(e){try{return this[__private__dont__use].FS.lookupPath(e),!0}catch{return!1}}hotSwapPHPRuntime(e){const t=this[__private__dont__use].FS;try{this.exit()}catch{}if(this.initializeRuntime(e),a(this,C)&&this.setPhpIniPath(a(this,C)),a(this,k)&&this.setSapiName(a(this,k)),this.requestHandler){const r=this.documentRoot;recreateMemFS(this[__private__dont__use].FS,t,r)}}exit(e=0){this.dispatchEvent({type:"runtime.beforedestroy"});try{this[__private__dont__use]._exit(e)}catch{}u(this,_,!1),u(this,w,null),delete this[__private__dont__use].onMessage,delete this[__private__dont__use]}}b=new WeakMap,C=new WeakMap,k=new WeakMap,_=new WeakMap,w=new WeakMap,g=new WeakMap,y=new WeakMap,B=new WeakMap,q=new WeakSet,te=function(){if(this.setPhpIniEntry("auto_prepend_file","/tmp/consts.php"),this.fileExists("/tmp/consts.php")||this.writeFile("/tmp/consts.php",`<?php
|
|
38
38
|
if(file_exists('/tmp/consts.json')) {
|
|
39
39
|
$consts = json_decode(file_get_contents('/tmp/consts.json'), true);
|
|
40
40
|
foreach ($consts as $const => $value) {
|
|
@@ -42,7 +42,7 @@ ${bold} WASM ERROR${reset}${redBg}`);for(const t of e.split(`
|
|
|
42
42
|
define($const, $value);
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
}`),a(this,
|
|
45
|
+
}`),a(this,b).length>0){const e=a(this,b).map(([t,r])=>`${t}=${r}`).join(`
|
|
46
46
|
`)+`
|
|
47
47
|
|
|
48
|
-
`;this[__private__dont__use].ccall("wasm_set_phpini_entries",null,[STRING],[e])}this[__private__dont__use].ccall("php_wasm_init",null,[],[])},O=new WeakSet,
|
|
48
|
+
`;this[__private__dont__use].ccall("wasm_set_phpini_entries",null,[STRING],[e])}this[__private__dont__use].ccall("php_wasm_init",null,[],[])},O=new WeakSet,re=function(){const e="/tmp/headers.json";if(!this.fileExists(e))throw new Error("SAPI Error: Could not find response headers file.");const t=JSON.parse(this.readFileAsText(e)),r={};for(const s of t.headers){if(!s.includes(": "))continue;const i=s.indexOf(": "),n=s.substring(0,i).toLowerCase(),o=s.substring(i+2);n in r||(r[n]=[]),r[n].push(o)}return{headers:r,httpStatusCode:t.status}},D=new WeakSet,se=function(e){if(this[__private__dont__use].ccall("wasm_set_request_uri",null,[STRING],[e]),e.includes("?")){const t=e.substring(e.indexOf("?")+1);this[__private__dont__use].ccall("wasm_set_query_string",null,[STRING],[t])}},$=new WeakSet,ne=function(e,t){this[__private__dont__use].ccall("wasm_set_request_host",null,[STRING],[e]);let r;try{r=parseInt(new URL(e).port,10)}catch{}(!r||isNaN(r)||r===80)&&(r=t==="https"?443:80),this[__private__dont__use].ccall("wasm_set_request_port",null,[NUMBER],[r]),(t==="https"||!t&&r===443)&&this.addServerGlobalEntry("HTTPS","on")},j=new WeakSet,ie=function(e){this[__private__dont__use].ccall("wasm_set_request_method",null,[STRING],[e])},z=new WeakSet,oe=function(e){e.cookie&&this[__private__dont__use].ccall("wasm_set_cookies",null,[STRING],[e.cookie]),e["content-type"]&&this[__private__dont__use].ccall("wasm_set_content_type",null,[STRING],[e["content-type"]]),e["content-length"]&&this[__private__dont__use].ccall("wasm_set_content_length",null,[NUMBER],[parseInt(e["content-length"],10)]);for(const t in e){let r="HTTP_";["content-type","content-length"].includes(t.toLowerCase())&&(r=""),this.addServerGlobalEntry(`${r}${t.toUpperCase().replace(/-/g,"_")}`,e[t])}},G=new WeakSet,ae=function(e){const t=this[__private__dont__use].lengthBytesUTF8(e),r=this[__private__dont__use].malloc(t+1);if(!r)throw new Error("Could not allocate memory for the request body.");return this[__private__dont__use].stringToUTF8(e,r,t+1),this[__private__dont__use].ccall("wasm_set_request_body",null,[NUMBER],[r]),this[__private__dont__use].ccall("wasm_set_content_length",null,[NUMBER],[new TextEncoder().encode(e).length]),r},W=new WeakSet,le=function(e){this[__private__dont__use].ccall("wasm_set_path_translated",null,[STRING],[e])},V=new WeakSet,ce=function(){for(const e in a(this,g))this[__private__dont__use].ccall("wasm_add_SERVER_entry",null,[STRING,STRING],[e,a(this,g)[e]])},J=new WeakSet,ue=function(e){const{key:t,name:r,type:s,data:i}=e,n=`/tmp/${Math.random().toFixed(20)}`;this.writeFile(n,i);const o=0;this[__private__dont__use].ccall("wasm_add_uploaded_file",null,[STRING,STRING,STRING,STRING,NUMBER,NUMBER],[t,r,s,n,o,i.byteLength])},Y=new WeakSet,de=function(e){this[__private__dont__use].ccall("wasm_set_php_code",null,[STRING],[e])},Z=new WeakSet,he=async function(){var i;let e,t;try{e=await new Promise((n,o)=>{var h;t=d=>{const f=new Error("Rethrown");f.cause=d.error,f.betterMessage=d.message,o(f)},(h=a(this,w))==null||h.addEventListener("error",t);const l=this[__private__dont__use].ccall("wasm_sapi_handle_request",NUMBER,[],[],{async:!0});return l instanceof Promise?l.then(n,o):n(l)})}catch(n){for(const d in this)typeof this[d]=="function"&&(this[d]=()=>{throw new Error("PHP runtime has crashed – see the earlier error for details.")});this.functionsMaybeMissingFromAsyncify=getFunctionsMaybeMissingFromAsyncify();const o=n,l="betterMessage"in o?o.betterMessage:o.message,h=new Error(l);throw h.cause=o,h}finally{(i=a(this,w))==null||i.removeEventListener("error",t),u(this,g,{})}const{headers:r,httpStatusCode:s}=p(this,O,re).call(this);return new PHPResponse(s,r,this.readFileAsBuffer("/tmp/stdout"),this.readFileAsText("/tmp/stderr"),e)};__decorateClass([rethrowFileSystemError('Could not create directory "{path}"')],BasePHP.prototype,"mkdir",1);__decorateClass([rethrowFileSystemError('Could not create directory "{path}"')],BasePHP.prototype,"mkdirTree",1);__decorateClass([rethrowFileSystemError('Could not read "{path}"')],BasePHP.prototype,"readFileAsText",1);__decorateClass([rethrowFileSystemError('Could not read "{path}"')],BasePHP.prototype,"readFileAsBuffer",1);__decorateClass([rethrowFileSystemError('Could not write to "{path}"')],BasePHP.prototype,"writeFile",1);__decorateClass([rethrowFileSystemError('Could not unlink "{path}"')],BasePHP.prototype,"unlink",1);__decorateClass([rethrowFileSystemError('Could not remove directory "{path}"')],BasePHP.prototype,"rmdir",1);__decorateClass([rethrowFileSystemError('Could not list files in "{path}"')],BasePHP.prototype,"listFiles",1);__decorateClass([rethrowFileSystemError('Could not stat "{path}"')],BasePHP.prototype,"isDir",1);__decorateClass([rethrowFileSystemError('Could not stat "{path}"')],BasePHP.prototype,"fileExists",1);function normalizeHeaders(e){const t={};for(const r in e)t[r.toLowerCase()]=e[r];return t}function recreateMemFS(e,t,r){let s;try{s=t.lookupPath(r)}catch{return}if(!("contents"in s.node))return;try{e=e.lookupPath(r);return}catch{}if(!t.isDir(s.node.mode)){e.writeFile(r,t.readFile(r));return}e.mkdirTree(r);const i=t.readdir(r).filter(n=>n!=="."&&n!=="..");for(const n of i)recreateMemFS(e,t,joinPaths(r,n))}function isLocalPHP(e){return!(e instanceof BasePHP)}function isRemotePHP(e){return!isLocalPHP(e)}function rotatePHPRuntime({php:e,recreateRuntime:t,maxRequests:r}){let s=0;async function i(){if(++s<r)return;s=0;const n=await e.semaphore.acquire();try{e.hotSwapPHPRuntime(await t())}finally{n()}}return e.addEventListener("request.end",i),function(){e.removeEventListener("request.end",i)}}async function writeFiles(e,t,r,{rmRoot:s=!1}={}){s&&await e.isDir(t)&&await e.rmdir(t,{recursive:!0});for(const[i,n]of Object.entries(r)){const o=joinPaths(t,i);await e.fileExists(dirname(o))||await e.mkdir(dirname(o)),await e.writeFile(o,n)}}exports.BasePHP=BasePHP;exports.DEFAULT_BASE_URL=DEFAULT_BASE_URL;exports.LatestSupportedPHPVersion=LatestSupportedPHPVersion;exports.PHPBrowser=PHPBrowser;exports.PHPRequestHandler=PHPRequestHandler;exports.PHPResponse=PHPResponse;exports.SupportedPHPExtensionBundles=SupportedPHPExtensionBundles;exports.SupportedPHPExtensionsList=SupportedPHPExtensionsList;exports.SupportedPHPVersions=SupportedPHPVersions;exports.SupportedPHPVersionsList=SupportedPHPVersionsList;exports.UnhandledRejectionsTarget=UnhandledRejectionsTarget;exports.__private__dont__use=__private__dont__use;exports.ensurePathPrefix=ensurePathPrefix;exports.isExitCodeZero=isExitCodeZero;exports.isLocalPHP=isLocalPHP;exports.isRemotePHP=isRemotePHP;exports.iterateFiles=iteratePhpFiles;exports.loadPHPRuntime=loadPHPRuntime;exports.removePathPrefix=removePathPrefix;exports.rethrowFileSystemError=rethrowFileSystemError;exports.rotatePHPRuntime=rotatePHPRuntime;exports.toRelativeUrl=toRelativeUrl;exports.writeFiles=writeFiles;exports.writeFilesStreamToPhp=writeFilesStreamToPhp;
|
package/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
var
|
|
1
|
+
var K = (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) => (K(e, t, "read from private field"), r ? r.call(e) : t.get(e)), c = (e, t, r) => {
|
|
6
6
|
if (t.has(e))
|
|
7
7
|
throw TypeError("Cannot add the same private member more than once");
|
|
8
8
|
t instanceof WeakSet ? t.add(e) : t.set(e, r);
|
|
9
|
-
}, u = (e, t, r, s) => (
|
|
10
|
-
var
|
|
9
|
+
}, u = (e, t, r, s) => (K(e, t, "write to private field"), s ? s.call(e, r) : t.set(e, r), r);
|
|
10
|
+
var f = (e, t, r) => (K(e, t, "access private method"), r);
|
|
11
11
|
if (typeof File > "u") {
|
|
12
12
|
class e extends Blob {
|
|
13
13
|
constructor(r, s, i) {
|
|
@@ -67,6 +67,9 @@ if (typeof CustomEvent > "u") {
|
|
|
67
67
|
}
|
|
68
68
|
globalThis.CustomEvent = e;
|
|
69
69
|
}
|
|
70
|
+
typeof crypto > "u" && import("./__vite-browser-external-2447137e.js").then((e) => {
|
|
71
|
+
global.crypto = e;
|
|
72
|
+
});
|
|
70
73
|
const kError = Symbol("error"), kMessage = Symbol("message");
|
|
71
74
|
class ErrorEvent2 extends Event {
|
|
72
75
|
/**
|
|
@@ -468,8 +471,8 @@ async function* iteratePhpFiles(e, t, {
|
|
|
468
471
|
if (!o)
|
|
469
472
|
return;
|
|
470
473
|
const l = await e.listFiles(o);
|
|
471
|
-
for (const
|
|
472
|
-
const d = `${o}/${
|
|
474
|
+
for (const h of l) {
|
|
475
|
+
const d = `${o}/${h}`;
|
|
473
476
|
if (i.includes(d.substring(t.length + 1)))
|
|
474
477
|
continue;
|
|
475
478
|
await e.isDir(d) ? n.push(d) : yield new StreamedFile(
|
|
@@ -546,16 +549,16 @@ const SupportedPHPVersions = [
|
|
|
546
549
|
], SupportedPHPExtensionBundles = {
|
|
547
550
|
"kitchen-sink": SupportedPHPExtensionsList
|
|
548
551
|
};
|
|
549
|
-
var
|
|
552
|
+
var E, H;
|
|
550
553
|
class PHPBrowser {
|
|
551
554
|
/**
|
|
552
555
|
* @param server - The PHP server to browse.
|
|
553
556
|
* @param config - The browser configuration.
|
|
554
557
|
*/
|
|
555
558
|
constructor(t, r = {}) {
|
|
556
|
-
c(this,
|
|
557
|
-
c(this,
|
|
558
|
-
this.requestHandler = t, u(this,
|
|
559
|
+
c(this, E, void 0);
|
|
560
|
+
c(this, H, void 0);
|
|
561
|
+
this.requestHandler = t, u(this, E, {}), u(this, H, {
|
|
559
562
|
handleRedirects: !1,
|
|
560
563
|
maxRedirects: 4,
|
|
561
564
|
...r
|
|
@@ -583,7 +586,7 @@ class PHPBrowser {
|
|
|
583
586
|
cookie: this.serializeCookies()
|
|
584
587
|
}
|
|
585
588
|
});
|
|
586
|
-
if (s.headers["set-cookie"] && this.setCookies(s.headers["set-cookie"]), a(this,
|
|
589
|
+
if (s.headers["set-cookie"] && this.setCookies(s.headers["set-cookie"]), a(this, H).handleRedirects && s.headers.location && r < a(this, H).maxRedirects) {
|
|
587
590
|
const i = new URL(
|
|
588
591
|
s.headers.location[0],
|
|
589
592
|
this.requestHandler.absoluteUrl
|
|
@@ -621,19 +624,19 @@ class PHPBrowser {
|
|
|
621
624
|
if (!r.includes("="))
|
|
622
625
|
continue;
|
|
623
626
|
const s = r.indexOf("="), i = r.substring(0, s), n = r.substring(s + 1).split(";")[0];
|
|
624
|
-
a(this,
|
|
627
|
+
a(this, E)[i] = n;
|
|
625
628
|
} catch (s) {
|
|
626
629
|
console.error(s);
|
|
627
630
|
}
|
|
628
631
|
}
|
|
629
632
|
serializeCookies() {
|
|
630
633
|
const t = [];
|
|
631
|
-
for (const r in a(this,
|
|
632
|
-
t.push(`${r}=${a(this,
|
|
634
|
+
for (const r in a(this, E))
|
|
635
|
+
t.push(`${r}=${a(this, E)[r]}`);
|
|
633
636
|
return t.join("; ");
|
|
634
637
|
}
|
|
635
638
|
}
|
|
636
|
-
|
|
639
|
+
E = new WeakMap(), H = new WeakMap();
|
|
637
640
|
const DEFAULT_BASE_URL = "http://example.com";
|
|
638
641
|
function toRelativeUrl(e) {
|
|
639
642
|
return e.toString().substring(e.origin.length);
|
|
@@ -644,7 +647,7 @@ function removePathPrefix(e, t) {
|
|
|
644
647
|
function ensurePathPrefix(e, t) {
|
|
645
648
|
return !t || e.startsWith(t) ? e : t + e;
|
|
646
649
|
}
|
|
647
|
-
var
|
|
650
|
+
var P, x, A, v, F, m, T, R, L, Q, N, X, M, ee;
|
|
648
651
|
class PHPRequestHandler {
|
|
649
652
|
/**
|
|
650
653
|
* @param php - The PHP instance.
|
|
@@ -657,7 +660,7 @@ class PHPRequestHandler {
|
|
|
657
660
|
* @param fsPath - Absolute path of the static file to serve.
|
|
658
661
|
* @returns The response.
|
|
659
662
|
*/
|
|
660
|
-
c(this,
|
|
663
|
+
c(this, L);
|
|
661
664
|
/**
|
|
662
665
|
* Runs the requested PHP file with all the request and $_SERVER
|
|
663
666
|
* superglobals populated.
|
|
@@ -665,7 +668,7 @@ class PHPRequestHandler {
|
|
|
665
668
|
* @param request - The request.
|
|
666
669
|
* @returns The response.
|
|
667
670
|
*/
|
|
668
|
-
c(this,
|
|
671
|
+
c(this, N);
|
|
669
672
|
/**
|
|
670
673
|
* Resolve the requested path to the filesystem path of the requested PHP file.
|
|
671
674
|
*
|
|
@@ -675,31 +678,31 @@ class PHPRequestHandler {
|
|
|
675
678
|
* @throws {Error} If the requested path doesn't exist.
|
|
676
679
|
* @returns The resolved filesystem path.
|
|
677
680
|
*/
|
|
678
|
-
c(this,
|
|
679
|
-
c(this,
|
|
681
|
+
c(this, M);
|
|
682
|
+
c(this, P, void 0);
|
|
680
683
|
c(this, x, void 0);
|
|
681
684
|
c(this, A, void 0);
|
|
682
|
-
c(this,
|
|
683
|
-
c(this, H, void 0);
|
|
684
|
-
c(this, _, void 0);
|
|
685
|
+
c(this, v, void 0);
|
|
685
686
|
c(this, F, void 0);
|
|
687
|
+
c(this, m, void 0);
|
|
686
688
|
c(this, T, void 0);
|
|
687
|
-
|
|
689
|
+
c(this, R, void 0);
|
|
690
|
+
u(this, R, new Semaphore({ concurrency: 1 }));
|
|
688
691
|
const {
|
|
689
692
|
documentRoot: s = "/www/",
|
|
690
693
|
absoluteUrl: i = typeof location == "object" ? location == null ? void 0 : location.href : ""
|
|
691
694
|
} = r;
|
|
692
|
-
this.php = t, u(this,
|
|
695
|
+
this.php = t, u(this, P, s);
|
|
693
696
|
const n = new URL(i);
|
|
694
|
-
u(this, A, n.hostname), u(this,
|
|
695
|
-
const o = a(this,
|
|
696
|
-
u(this,
|
|
697
|
+
u(this, A, n.hostname), u(this, v, n.port ? Number(n.port) : n.protocol === "https:" ? 443 : 80), u(this, x, (n.protocol || "").replace(":", ""));
|
|
698
|
+
const o = a(this, v) !== 443 && a(this, v) !== 80;
|
|
699
|
+
u(this, F, [
|
|
697
700
|
a(this, A),
|
|
698
|
-
o ? `:${a(this,
|
|
699
|
-
].join("")), u(this,
|
|
701
|
+
o ? `:${a(this, v)}` : ""
|
|
702
|
+
].join("")), u(this, m, n.pathname.replace(/\/+$/, "")), u(this, T, [
|
|
700
703
|
`${a(this, x)}://`,
|
|
701
|
-
a(this,
|
|
702
|
-
a(this,
|
|
704
|
+
a(this, F),
|
|
705
|
+
a(this, m)
|
|
703
706
|
].join(""));
|
|
704
707
|
}
|
|
705
708
|
/** @inheritDoc */
|
|
@@ -709,18 +712,18 @@ class PHPRequestHandler {
|
|
|
709
712
|
/** @inheritDoc */
|
|
710
713
|
internalUrlToPath(t) {
|
|
711
714
|
const r = new URL(t);
|
|
712
|
-
return r.pathname.startsWith(a(this,
|
|
715
|
+
return r.pathname.startsWith(a(this, m)) && (r.pathname = r.pathname.slice(a(this, m).length)), toRelativeUrl(r);
|
|
713
716
|
}
|
|
714
717
|
get isRequestRunning() {
|
|
715
|
-
return a(this,
|
|
718
|
+
return a(this, R).running > 0;
|
|
716
719
|
}
|
|
717
720
|
/** @inheritDoc */
|
|
718
721
|
get absoluteUrl() {
|
|
719
|
-
return a(this,
|
|
722
|
+
return a(this, T);
|
|
720
723
|
}
|
|
721
724
|
/** @inheritDoc */
|
|
722
725
|
get documentRoot() {
|
|
723
|
-
return a(this,
|
|
726
|
+
return a(this, P);
|
|
724
727
|
}
|
|
725
728
|
/** @inheritDoc */
|
|
726
729
|
async request(t) {
|
|
@@ -729,12 +732,12 @@ class PHPRequestHandler {
|
|
|
729
732
|
r ? void 0 : DEFAULT_BASE_URL
|
|
730
733
|
), i = removePathPrefix(
|
|
731
734
|
s.pathname,
|
|
732
|
-
a(this,
|
|
733
|
-
), n = `${a(this,
|
|
734
|
-
return seemsLikeAPHPRequestHandlerPath(n) ? await
|
|
735
|
+
a(this, m)
|
|
736
|
+
), n = `${a(this, P)}${i}`;
|
|
737
|
+
return seemsLikeAPHPRequestHandlerPath(n) ? await f(this, N, X).call(this, t, s) : f(this, L, Q).call(this, n);
|
|
735
738
|
}
|
|
736
739
|
}
|
|
737
|
-
|
|
740
|
+
P = new WeakMap(), x = new WeakMap(), A = new WeakMap(), v = new WeakMap(), F = new WeakMap(), m = new WeakMap(), T = new WeakMap(), R = new WeakMap(), L = new WeakSet(), Q = function(t) {
|
|
738
741
|
if (!this.php.fileExists(t))
|
|
739
742
|
return new PHPResponse(
|
|
740
743
|
404,
|
|
@@ -759,49 +762,57 @@ w = new WeakMap(), x = new WeakMap(), A = new WeakMap(), R = new WeakMap(), H =
|
|
|
759
762
|
},
|
|
760
763
|
r
|
|
761
764
|
);
|
|
762
|
-
},
|
|
763
|
-
var i, n;
|
|
764
|
-
|
|
765
|
+
}, N = new WeakSet(), X = async function(t, r) {
|
|
766
|
+
var i, n, o;
|
|
767
|
+
if (a(this, R).running > 0 && ((i = t.headers) == null ? void 0 : i["x-request-issuer"]) === "php")
|
|
768
|
+
return console.warn(
|
|
769
|
+
"Possible deadlock: Called request() before the previous request() have finished. PHP likely issued an HTTP call to itself. Normally this would lead to infinite waiting as Request 1 holds the lock that the Request 2 is waiting to acquire. That's not useful, so PHPRequestHandler will return error 502 instead."
|
|
770
|
+
), new PHPResponse(
|
|
771
|
+
502,
|
|
772
|
+
{},
|
|
773
|
+
new TextEncoder().encode("502 Bad Gateway")
|
|
774
|
+
);
|
|
775
|
+
const s = await a(this, R).acquire();
|
|
765
776
|
try {
|
|
766
|
-
this.php.addServerGlobalEntry("REMOTE_ADDR", "127.0.0.1"), this.php.addServerGlobalEntry("DOCUMENT_ROOT", a(this,
|
|
777
|
+
this.php.addServerGlobalEntry("REMOTE_ADDR", "127.0.0.1"), this.php.addServerGlobalEntry("DOCUMENT_ROOT", a(this, P)), this.php.addServerGlobalEntry(
|
|
767
778
|
"HTTPS",
|
|
768
|
-
a(this,
|
|
779
|
+
a(this, T).startsWith("https://") ? "on" : ""
|
|
769
780
|
);
|
|
770
|
-
let
|
|
771
|
-
const
|
|
772
|
-
host: a(this,
|
|
781
|
+
let l = "GET";
|
|
782
|
+
const h = {
|
|
783
|
+
host: a(this, F),
|
|
773
784
|
...normalizeHeaders(t.headers || {})
|
|
774
|
-
},
|
|
785
|
+
}, d = [];
|
|
775
786
|
if (t.files && Object.keys(t.files).length) {
|
|
776
|
-
|
|
777
|
-
for (const
|
|
778
|
-
const
|
|
779
|
-
|
|
780
|
-
key:
|
|
781
|
-
name:
|
|
782
|
-
type:
|
|
783
|
-
data: new Uint8Array(await
|
|
787
|
+
l = "POST";
|
|
788
|
+
for (const S in t.files) {
|
|
789
|
+
const U = t.files[S];
|
|
790
|
+
d.push({
|
|
791
|
+
key: S,
|
|
792
|
+
name: U.name,
|
|
793
|
+
type: U.type,
|
|
794
|
+
data: new Uint8Array(await U.arrayBuffer())
|
|
784
795
|
});
|
|
785
796
|
}
|
|
786
|
-
(
|
|
797
|
+
(n = h["content-type"]) != null && n.startsWith("multipart/form-data") && (t.formData = parseMultipartFormDataString(
|
|
787
798
|
t.body || ""
|
|
788
|
-
),
|
|
799
|
+
), h["content-type"] = "application/x-www-form-urlencoded", delete t.body);
|
|
789
800
|
}
|
|
790
|
-
let
|
|
791
|
-
t.formData !== void 0 ? (
|
|
801
|
+
let p;
|
|
802
|
+
t.formData !== void 0 ? (l = "POST", h["content-type"] = h["content-type"] || "application/x-www-form-urlencoded", p = new URLSearchParams(
|
|
792
803
|
t.formData
|
|
793
|
-
).toString()) :
|
|
794
|
-
let
|
|
804
|
+
).toString()) : p = t.body;
|
|
805
|
+
let I;
|
|
795
806
|
try {
|
|
796
|
-
let
|
|
797
|
-
if ((
|
|
807
|
+
let S = r.pathname;
|
|
808
|
+
if ((o = t.headers) != null && o["x-rewrite-url"])
|
|
798
809
|
try {
|
|
799
|
-
|
|
810
|
+
S = new URL(
|
|
800
811
|
t.headers["x-rewrite-url"]
|
|
801
812
|
).pathname;
|
|
802
813
|
} catch {
|
|
803
814
|
}
|
|
804
|
-
|
|
815
|
+
I = f(this, M, ee).call(this, S);
|
|
805
816
|
} catch {
|
|
806
817
|
return new PHPResponse(
|
|
807
818
|
404,
|
|
@@ -812,22 +823,22 @@ w = new WeakMap(), x = new WeakMap(), A = new WeakMap(), R = new WeakMap(), H =
|
|
|
812
823
|
return await this.php.run({
|
|
813
824
|
relativeUri: ensurePathPrefix(
|
|
814
825
|
toRelativeUrl(r),
|
|
815
|
-
a(this,
|
|
826
|
+
a(this, m)
|
|
816
827
|
),
|
|
817
828
|
protocol: a(this, x),
|
|
818
|
-
method: t.method ||
|
|
819
|
-
body:
|
|
820
|
-
fileInfos:
|
|
821
|
-
scriptPath:
|
|
822
|
-
headers:
|
|
829
|
+
method: t.method || l,
|
|
830
|
+
body: p,
|
|
831
|
+
fileInfos: d,
|
|
832
|
+
scriptPath: I,
|
|
833
|
+
headers: h
|
|
823
834
|
});
|
|
824
835
|
} finally {
|
|
825
836
|
s();
|
|
826
837
|
}
|
|
827
|
-
},
|
|
828
|
-
let r = removePathPrefix(t, a(this,
|
|
838
|
+
}, M = new WeakSet(), ee = function(t) {
|
|
839
|
+
let r = removePathPrefix(t, a(this, m));
|
|
829
840
|
r.includes(".php") ? r = r.split(".php")[0] + ".php" : (r.endsWith("/") || (r += "/"), r.endsWith("index.php") || (r += "index.php"));
|
|
830
|
-
const s = `${a(this,
|
|
841
|
+
const s = `${a(this, P)}${r}`;
|
|
831
842
|
if (this.php.fileExists(s))
|
|
832
843
|
return s;
|
|
833
844
|
throw new Error(`File not found: ${s}`);
|
|
@@ -840,10 +851,10 @@ function parseMultipartFormDataString(e) {
|
|
|
840
851
|
return i.shift(), i.pop(), i.forEach((n) => {
|
|
841
852
|
const o = n.indexOf(`\r
|
|
842
853
|
\r
|
|
843
|
-
`), l = n.substring(0, o).trim(),
|
|
854
|
+
`), l = n.substring(0, o).trim(), h = n.substring(o + 4).trim(), d = l.match(/name="([^"]+)"/);
|
|
844
855
|
if (d) {
|
|
845
|
-
const
|
|
846
|
-
t[
|
|
856
|
+
const p = d[1];
|
|
857
|
+
t[p] = h;
|
|
847
858
|
}
|
|
848
859
|
}), t;
|
|
849
860
|
}
|
|
@@ -987,10 +998,10 @@ function rethrowFileSystemError(e = "") {
|
|
|
987
998
|
try {
|
|
988
999
|
return n.apply(this, o);
|
|
989
1000
|
} catch (l) {
|
|
990
|
-
const
|
|
991
|
-
if (
|
|
992
|
-
const d = FileErrorCodes[
|
|
993
|
-
throw new Error(`${
|
|
1001
|
+
const h = typeof l == "object" ? l == null ? void 0 : l.errno : null;
|
|
1002
|
+
if (h in FileErrorCodes) {
|
|
1003
|
+
const d = FileErrorCodes[h], p = typeof o[0] == "string" ? o[0] : null, I = p !== null ? e.replaceAll("{path}", p) : e;
|
|
1004
|
+
throw new Error(`${I}: ${d}`, {
|
|
994
1005
|
cause: l
|
|
995
1006
|
});
|
|
996
1007
|
}
|
|
@@ -1041,7 +1052,7 @@ var __defProp = Object.defineProperty, __getOwnPropDesc = Object.getOwnPropertyD
|
|
|
1041
1052
|
return s && i && __defProp(t, r, i), i;
|
|
1042
1053
|
};
|
|
1043
1054
|
const STRING = "string", NUMBER = "number", __private__dont__use = Symbol("__private__dont__use");
|
|
1044
|
-
var b, C, k,
|
|
1055
|
+
var b, C, k, _, w, g, y, B, q, te, O, re, D, se, $, ne, j, ie, z, oe, G, ae, W, le, V, ce, J, ue, Y, de, Z, he;
|
|
1045
1056
|
class BasePHP {
|
|
1046
1057
|
/**
|
|
1047
1058
|
* Initializes a PHP runtime.
|
|
@@ -1051,15 +1062,15 @@ class BasePHP {
|
|
|
1051
1062
|
* @param serverOptions - Optional. Options for the PHPRequestHandler. If undefined, no request handler will be initialized.
|
|
1052
1063
|
*/
|
|
1053
1064
|
constructor(e, t) {
|
|
1054
|
-
c(this,
|
|
1065
|
+
c(this, q);
|
|
1055
1066
|
c(this, O);
|
|
1056
1067
|
c(this, D);
|
|
1057
1068
|
c(this, $);
|
|
1058
|
-
c(this, q);
|
|
1059
1069
|
c(this, j);
|
|
1060
1070
|
c(this, z);
|
|
1061
|
-
c(this, W);
|
|
1062
1071
|
c(this, G);
|
|
1072
|
+
c(this, W);
|
|
1073
|
+
c(this, V);
|
|
1063
1074
|
/**
|
|
1064
1075
|
* Adds file information to $_FILES superglobal in PHP.
|
|
1065
1076
|
*
|
|
@@ -1069,18 +1080,18 @@ class BasePHP {
|
|
|
1069
1080
|
*
|
|
1070
1081
|
* @param fileInfo - File details
|
|
1071
1082
|
*/
|
|
1072
|
-
c(this, V);
|
|
1073
1083
|
c(this, J);
|
|
1074
1084
|
c(this, Y);
|
|
1085
|
+
c(this, Z);
|
|
1075
1086
|
c(this, b, void 0);
|
|
1076
1087
|
c(this, C, void 0);
|
|
1077
1088
|
c(this, k, void 0);
|
|
1078
|
-
c(this,
|
|
1089
|
+
c(this, _, void 0);
|
|
1090
|
+
c(this, w, void 0);
|
|
1079
1091
|
c(this, g, void 0);
|
|
1080
|
-
c(this, E, void 0);
|
|
1081
1092
|
c(this, y, void 0);
|
|
1082
1093
|
c(this, B, void 0);
|
|
1083
|
-
u(this, b, []), u(this,
|
|
1094
|
+
u(this, b, []), u(this, _, !1), u(this, w, null), u(this, g, {}), u(this, y, /* @__PURE__ */ new Map()), u(this, B, []), this.semaphore = new Semaphore({ concurrency: 1 }), e !== void 0 && this.initializeRuntime(e), t && (this.requestHandler = new PHPBrowser(
|
|
1084
1095
|
new PHPRequestHandler(this, t)
|
|
1085
1096
|
));
|
|
1086
1097
|
}
|
|
@@ -1136,7 +1147,7 @@ class BasePHP {
|
|
|
1136
1147
|
return i;
|
|
1137
1148
|
}
|
|
1138
1149
|
return "";
|
|
1139
|
-
}, u(this,
|
|
1150
|
+
}, u(this, w, improveWASMErrorReporting(t)), this.dispatchEvent({
|
|
1140
1151
|
type: "runtime.initialized"
|
|
1141
1152
|
});
|
|
1142
1153
|
}
|
|
@@ -1155,7 +1166,7 @@ class BasePHP {
|
|
|
1155
1166
|
}
|
|
1156
1167
|
/** @inheritDoc */
|
|
1157
1168
|
setPhpIniPath(e) {
|
|
1158
|
-
if (a(this,
|
|
1169
|
+
if (a(this, _))
|
|
1159
1170
|
throw new Error("Cannot set PHP ini path after calling run().");
|
|
1160
1171
|
u(this, C, e), this[__private__dont__use].ccall(
|
|
1161
1172
|
"wasm_set_phpini_path",
|
|
@@ -1166,7 +1177,7 @@ class BasePHP {
|
|
|
1166
1177
|
}
|
|
1167
1178
|
/** @inheritDoc */
|
|
1168
1179
|
setPhpIniEntry(e, t) {
|
|
1169
|
-
if (a(this,
|
|
1180
|
+
if (a(this, _))
|
|
1170
1181
|
throw new Error("Cannot set PHP ini entries after calling run().");
|
|
1171
1182
|
a(this, b).push([e, t]);
|
|
1172
1183
|
}
|
|
@@ -1185,13 +1196,13 @@ class BasePHP {
|
|
|
1185
1196
|
const t = await this.semaphore.acquire();
|
|
1186
1197
|
let r;
|
|
1187
1198
|
try {
|
|
1188
|
-
a(this,
|
|
1199
|
+
a(this, _) || (f(this, q, te).call(this), u(this, _, !0)), f(this, W, le).call(this, e.scriptPath || ""), f(this, D, se).call(this, e.relativeUri || ""), f(this, j, ie).call(this, e.method || "GET");
|
|
1189
1200
|
const s = normalizeHeaders(e.headers || {}), i = s.host || "example.com:443";
|
|
1190
|
-
if (
|
|
1201
|
+
if (f(this, $, ne).call(this, i, e.protocol || "http"), f(this, z, oe).call(this, s), e.body && (r = f(this, G, ae).call(this, e.body)), e.fileInfos)
|
|
1191
1202
|
for (const o of e.fileInfos)
|
|
1192
|
-
|
|
1193
|
-
typeof e.code == "string" &&
|
|
1194
|
-
const n = await
|
|
1203
|
+
f(this, J, ue).call(this, o);
|
|
1204
|
+
typeof e.code == "string" && f(this, Y, de).call(this, " ?>" + e.code), f(this, V, ce).call(this);
|
|
1205
|
+
const n = await f(this, Z, he).call(this);
|
|
1195
1206
|
if (e.throwOnError && n.exitCode !== 0) {
|
|
1196
1207
|
const o = {
|
|
1197
1208
|
stdout: n.text,
|
|
@@ -1215,7 +1226,7 @@ class BasePHP {
|
|
|
1215
1226
|
}
|
|
1216
1227
|
}
|
|
1217
1228
|
addServerGlobalEntry(e, t) {
|
|
1218
|
-
a(this,
|
|
1229
|
+
a(this, g)[e] = t;
|
|
1219
1230
|
}
|
|
1220
1231
|
defineConstant(e, t) {
|
|
1221
1232
|
let r = {};
|
|
@@ -1324,10 +1335,10 @@ class BasePHP {
|
|
|
1324
1335
|
this[__private__dont__use]._exit(e);
|
|
1325
1336
|
} catch {
|
|
1326
1337
|
}
|
|
1327
|
-
u(this,
|
|
1338
|
+
u(this, _, !1), u(this, w, null), delete this[__private__dont__use].onMessage, delete this[__private__dont__use];
|
|
1328
1339
|
}
|
|
1329
1340
|
}
|
|
1330
|
-
b = new WeakMap(), C = new WeakMap(), k = new WeakMap(),
|
|
1341
|
+
b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), _ = new WeakMap(), w = new WeakMap(), g = new WeakMap(), y = new WeakMap(), B = new WeakMap(), q = new WeakSet(), te = function() {
|
|
1331
1342
|
if (this.setPhpIniEntry("auto_prepend_file", "/tmp/consts.php"), this.fileExists("/tmp/consts.php") || this.writeFile(
|
|
1332
1343
|
"/tmp/consts.php",
|
|
1333
1344
|
`<?php
|
|
@@ -1352,7 +1363,7 @@ b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), m = new WeakMap(), g =
|
|
|
1352
1363
|
);
|
|
1353
1364
|
}
|
|
1354
1365
|
this[__private__dont__use].ccall("php_wasm_init", null, [], []);
|
|
1355
|
-
}, O = new WeakSet(),
|
|
1366
|
+
}, O = new WeakSet(), re = function() {
|
|
1356
1367
|
const e = "/tmp/headers.json";
|
|
1357
1368
|
if (!this.fileExists(e))
|
|
1358
1369
|
throw new Error(
|
|
@@ -1369,7 +1380,7 @@ b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), m = new WeakMap(), g =
|
|
|
1369
1380
|
headers: r,
|
|
1370
1381
|
httpStatusCode: t.status
|
|
1371
1382
|
};
|
|
1372
|
-
}, D = new WeakSet(),
|
|
1383
|
+
}, D = new WeakSet(), se = function(e) {
|
|
1373
1384
|
if (this[__private__dont__use].ccall(
|
|
1374
1385
|
"wasm_set_request_uri",
|
|
1375
1386
|
null,
|
|
@@ -1384,7 +1395,7 @@ b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), m = new WeakMap(), g =
|
|
|
1384
1395
|
[t]
|
|
1385
1396
|
);
|
|
1386
1397
|
}
|
|
1387
|
-
}, $ = new WeakSet(),
|
|
1398
|
+
}, $ = new WeakSet(), ne = function(e, t) {
|
|
1388
1399
|
this[__private__dont__use].ccall(
|
|
1389
1400
|
"wasm_set_request_host",
|
|
1390
1401
|
null,
|
|
@@ -1402,14 +1413,14 @@ b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), m = new WeakMap(), g =
|
|
|
1402
1413
|
[NUMBER],
|
|
1403
1414
|
[r]
|
|
1404
1415
|
), (t === "https" || !t && r === 443) && this.addServerGlobalEntry("HTTPS", "on");
|
|
1405
|
-
},
|
|
1416
|
+
}, j = new WeakSet(), ie = function(e) {
|
|
1406
1417
|
this[__private__dont__use].ccall(
|
|
1407
1418
|
"wasm_set_request_method",
|
|
1408
1419
|
null,
|
|
1409
1420
|
[STRING],
|
|
1410
1421
|
[e]
|
|
1411
1422
|
);
|
|
1412
|
-
},
|
|
1423
|
+
}, z = new WeakSet(), oe = function(e) {
|
|
1413
1424
|
e.cookie && this[__private__dont__use].ccall(
|
|
1414
1425
|
"wasm_set_cookies",
|
|
1415
1426
|
null,
|
|
@@ -1433,7 +1444,7 @@ b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), m = new WeakMap(), g =
|
|
|
1433
1444
|
e[t]
|
|
1434
1445
|
);
|
|
1435
1446
|
}
|
|
1436
|
-
},
|
|
1447
|
+
}, G = new WeakSet(), ae = function(e) {
|
|
1437
1448
|
const t = this[__private__dont__use].lengthBytesUTF8(e), r = this[__private__dont__use].malloc(t + 1);
|
|
1438
1449
|
if (!r)
|
|
1439
1450
|
throw new Error("Could not allocate memory for the request body.");
|
|
@@ -1452,22 +1463,22 @@ b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), m = new WeakMap(), g =
|
|
|
1452
1463
|
[NUMBER],
|
|
1453
1464
|
[new TextEncoder().encode(e).length]
|
|
1454
1465
|
), r;
|
|
1455
|
-
}, W = new WeakSet(),
|
|
1466
|
+
}, W = new WeakSet(), le = function(e) {
|
|
1456
1467
|
this[__private__dont__use].ccall(
|
|
1457
1468
|
"wasm_set_path_translated",
|
|
1458
1469
|
null,
|
|
1459
1470
|
[STRING],
|
|
1460
1471
|
[e]
|
|
1461
1472
|
);
|
|
1462
|
-
},
|
|
1463
|
-
for (const e in a(this,
|
|
1473
|
+
}, V = new WeakSet(), ce = function() {
|
|
1474
|
+
for (const e in a(this, g))
|
|
1464
1475
|
this[__private__dont__use].ccall(
|
|
1465
1476
|
"wasm_add_SERVER_entry",
|
|
1466
1477
|
null,
|
|
1467
1478
|
[STRING, STRING],
|
|
1468
|
-
[e, a(this,
|
|
1479
|
+
[e, a(this, g)[e]]
|
|
1469
1480
|
);
|
|
1470
|
-
},
|
|
1481
|
+
}, J = new WeakSet(), ue = function(e) {
|
|
1471
1482
|
const { key: t, name: r, type: s, data: i } = e, n = `/tmp/${Math.random().toFixed(20)}`;
|
|
1472
1483
|
this.writeFile(n, i);
|
|
1473
1484
|
const o = 0;
|
|
@@ -1477,23 +1488,23 @@ b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), m = new WeakMap(), g =
|
|
|
1477
1488
|
[STRING, STRING, STRING, STRING, NUMBER, NUMBER],
|
|
1478
1489
|
[t, r, s, n, o, i.byteLength]
|
|
1479
1490
|
);
|
|
1480
|
-
},
|
|
1491
|
+
}, Y = new WeakSet(), de = function(e) {
|
|
1481
1492
|
this[__private__dont__use].ccall(
|
|
1482
1493
|
"wasm_set_php_code",
|
|
1483
1494
|
null,
|
|
1484
1495
|
[STRING],
|
|
1485
1496
|
[e]
|
|
1486
1497
|
);
|
|
1487
|
-
},
|
|
1498
|
+
}, Z = new WeakSet(), he = async function() {
|
|
1488
1499
|
var i;
|
|
1489
1500
|
let e, t;
|
|
1490
1501
|
try {
|
|
1491
1502
|
e = await new Promise((n, o) => {
|
|
1492
|
-
var
|
|
1503
|
+
var h;
|
|
1493
1504
|
t = (d) => {
|
|
1494
|
-
const
|
|
1495
|
-
|
|
1496
|
-
}, (
|
|
1505
|
+
const p = new Error("Rethrown");
|
|
1506
|
+
p.cause = d.error, p.betterMessage = d.message, o(p);
|
|
1507
|
+
}, (h = a(this, w)) == null || h.addEventListener(
|
|
1497
1508
|
"error",
|
|
1498
1509
|
t
|
|
1499
1510
|
);
|
|
@@ -1514,12 +1525,12 @@ b = new WeakMap(), C = new WeakMap(), k = new WeakMap(), m = new WeakMap(), g =
|
|
|
1514
1525
|
);
|
|
1515
1526
|
});
|
|
1516
1527
|
this.functionsMaybeMissingFromAsyncify = getFunctionsMaybeMissingFromAsyncify();
|
|
1517
|
-
const o = n, l = "betterMessage" in o ? o.betterMessage : o.message,
|
|
1518
|
-
throw
|
|
1528
|
+
const o = n, l = "betterMessage" in o ? o.betterMessage : o.message, h = new Error(l);
|
|
1529
|
+
throw h.cause = o, h;
|
|
1519
1530
|
} finally {
|
|
1520
|
-
(i = a(this,
|
|
1531
|
+
(i = a(this, w)) == null || i.removeEventListener("error", t), u(this, g, {});
|
|
1521
1532
|
}
|
|
1522
|
-
const { headers: r, httpStatusCode: s } =
|
|
1533
|
+
const { headers: r, httpStatusCode: s } = f(this, O, re).call(this);
|
|
1523
1534
|
return new PHPResponse(
|
|
1524
1535
|
s,
|
|
1525
1536
|
r,
|
|
@@ -1614,6 +1625,13 @@ function rotatePHPRuntime({
|
|
|
1614
1625
|
e.removeEventListener("request.end", i);
|
|
1615
1626
|
};
|
|
1616
1627
|
}
|
|
1628
|
+
async function writeFiles(e, t, r, { rmRoot: s = !1 } = {}) {
|
|
1629
|
+
s && await e.isDir(t) && await e.rmdir(t, { recursive: !0 });
|
|
1630
|
+
for (const [i, n] of Object.entries(r)) {
|
|
1631
|
+
const o = joinPaths(t, i);
|
|
1632
|
+
await e.fileExists(dirname(o)) || await e.mkdir(dirname(o)), await e.writeFile(o, n);
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1617
1635
|
export {
|
|
1618
1636
|
BasePHP,
|
|
1619
1637
|
DEFAULT_BASE_URL,
|
|
@@ -1637,5 +1655,6 @@ export {
|
|
|
1637
1655
|
rethrowFileSystemError,
|
|
1638
1656
|
rotatePHPRuntime,
|
|
1639
1657
|
toRelativeUrl,
|
|
1658
|
+
writeFiles,
|
|
1640
1659
|
writeFilesStreamToPhp
|
|
1641
1660
|
};
|
package/lib/index.d.ts
CHANGED
|
@@ -21,5 +21,6 @@ export { PHPRequestHandler } from './php-request-handler';
|
|
|
21
21
|
export type { PHPBrowserConfiguration } from './php-browser';
|
|
22
22
|
export { PHPBrowser } from './php-browser';
|
|
23
23
|
export { rotatePHPRuntime } from './rotate-php-runtime';
|
|
24
|
+
export { writeFiles } from './write-files';
|
|
24
25
|
export { DEFAULT_BASE_URL, ensurePathPrefix, removePathPrefix, toRelativeUrl, } from './urls';
|
|
25
26
|
export { isExitCodeZero } from './is-exit-code-zero';
|
package/lib/universal-php.d.ts
CHANGED
|
@@ -169,7 +169,7 @@ export interface IsomorphicLocalPHP extends RequestHandler {
|
|
|
169
169
|
* @param key - The name of the constant.
|
|
170
170
|
* @param value - The value of the constant.
|
|
171
171
|
*/
|
|
172
|
-
defineConstant(key: string, value: string | number | null): void;
|
|
172
|
+
defineConstant(key: string, value: boolean | string | number | null): void;
|
|
173
173
|
/**
|
|
174
174
|
* Adds an event listener for a PHP event.
|
|
175
175
|
* @param eventType - The type of event to listen for.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { UniversalPHP } from './universal-php';
|
|
2
|
+
export interface WriteFilesOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Whether to wipe out the contents of the
|
|
5
|
+
* root directory before writing the new files.
|
|
6
|
+
*/
|
|
7
|
+
rmRoot?: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Writes multiple files to a specified directory in the Playground
|
|
11
|
+
* filesystem.
|
|
12
|
+
*
|
|
13
|
+
* @example ```ts
|
|
14
|
+
* await writeFiles(php, '/test', {
|
|
15
|
+
* 'file.txt': 'file',
|
|
16
|
+
* 'sub/file.txt': 'file',
|
|
17
|
+
* 'sub1/sub2/file.txt': 'file',
|
|
18
|
+
* });
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @param php
|
|
22
|
+
* @param root
|
|
23
|
+
* @param newFiles
|
|
24
|
+
* @param options
|
|
25
|
+
*/
|
|
26
|
+
export declare function writeFiles(php: UniversalPHP, root: string, newFiles: Record<string, Uint8Array | string>, { rmRoot }?: WriteFilesOptions): Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@php-wasm/universal",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
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": "171b22b853786b8912d9624ea064eaa1e985e96b",
|
|
40
40
|
"engines": {
|
|
41
41
|
"node": ">=18.18.2",
|
|
42
42
|
"npm": ">=8.11.0"
|