@php-wasm/fs-journal 0.6.7 → 0.6.9

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.
Files changed (3) hide show
  1. package/index.cjs +8 -8
  2. package/index.js +164 -157
  3. package/package.json +2 -2
package/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var Y=(e,t,r)=>{if(!t.has(e))throw TypeError("Cannot "+r)};var a=(e,t,r)=>(Y(e,t,"read from private field"),r?r.call(e):t.get(e)),u=(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)},p=(e,t,r,s)=>(Y(e,t,"write to private field"),s?s.call(e,r):t.set(e,r),r);var f=(e,t,r)=>(Y(e,t,"access private method"),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});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"}();if(currentJsRuntime==="NODE"){let e=function(r){return new Promise(function(s,n){r.onload=r.onerror=function(i){r.onload=r.onerror=null,i.type==="load"?s(r.result):n(new Error("Failed to read the blob/file"))}})},t=function(){const r=new Uint8Array([1,2,3,4]),n=new File([r],"test").stream();try{return n.getReader({mode:"byob"}),!0}catch{return!1}};if(typeof File>"u"){class r extends Blob{constructor(n,i,o){super(n);let l;o!=null&&o.lastModified&&(l=new Date),(!l||isNaN(l.getFullYear()))&&(l=new Date),this.lastModifiedDate=l,this.lastModified=l.getMilliseconds(),this.name=i||""}}global.File=r}typeof Blob.prototype.arrayBuffer>"u"&&(Blob.prototype.arrayBuffer=function(){const s=new FileReader;return s.readAsArrayBuffer(this),e(s)}),typeof Blob.prototype.text>"u"&&(Blob.prototype.text=function(){const s=new FileReader;return s.readAsText(this),e(s)}),(typeof Blob.prototype.stream>"u"||!t())&&(Blob.prototype.stream=function(){let r=0;const s=this;return new ReadableStream({type:"bytes",autoAllocateChunkSize:512*1024,async pull(n){const i=n.byobRequest.view,l=await s.slice(r,r+i.byteLength).arrayBuffer(),c=new Uint8Array(l);new Uint8Array(i.buffer).set(c);const h=c.byteLength;n.byobRequest.respond(h),r+=h,r>=s.size&&n.close()}})})}if(currentJsRuntime==="NODE"&&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+=`
1
+ "use strict";var Y=(e,t,r)=>{if(!t.has(e))throw TypeError("Cannot "+r)};var l=(e,t,r)=>(Y(e,t,"read from private field"),r?r.call(e):t.get(e)),u=(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)=>(Y(e,t,"write to private field"),s?s.call(e,r):t.set(e,r),r);var f=(e,t,r)=>(Y(e,t,"access private method"),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});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"}();if(currentJsRuntime==="NODE"){let e=function(r){return new Promise(function(s,n){r.onload=r.onerror=function(i){r.onload=r.onerror=null,i.type==="load"?s(r.result):n(new Error("Failed to read the blob/file"))}})},t=function(){const r=new Uint8Array([1,2,3,4]),n=new File([r],"test").stream();try{return n.getReader({mode:"byob"}),!0}catch{return!1}};if(typeof File>"u"){class r extends Blob{constructor(n,i,o){super(n);let a;o!=null&&o.lastModified&&(a=new Date),(!a||isNaN(a.getFullYear()))&&(a=new Date),this.lastModifiedDate=a,this.lastModified=a.getMilliseconds(),this.name=i||""}}global.File=r}typeof Blob.prototype.arrayBuffer>"u"&&(Blob.prototype.arrayBuffer=function(){const s=new FileReader;return s.readAsArrayBuffer(this),e(s)}),typeof Blob.prototype.text>"u"&&(Blob.prototype.text=function(){const s=new FileReader;return s.readAsText(this),e(s)}),(typeof Blob.prototype.stream>"u"||!t())&&(Blob.prototype.stream=function(){let r=0;const s=this;return new ReadableStream({type:"bytes",autoAllocateChunkSize:512*1024,async pull(n){const i=n.byobRequest.view,a=await s.slice(r,r+i.byteLength).arrayBuffer(),c=new Uint8Array(a);new Uint8Array(i.buffer).set(c);const d=c.byteLength;n.byobRequest.respond(d),r+=d,r>=s.size&&n.close()}})})}if(currentJsRuntime==="NODE"&&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 a=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:a}));return}throw isExitCodeZero(o)||showCriticalErrorBox(a),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,13 +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$1(t),!t&&!r&&(t="."),t&&s&&(t+="/"),t}function basename(e){if(e==="/")return"/";e=normalizePath$1(e);const t=e.lastIndexOf("/");return t===-1?e:e.substr(t+1)}function normalizePath$1(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 splitShellCommand(e){let s=0,n="";const i=[];let o="";for(let l=0;l<e.length;l++){const c=e[l];c==="\\"?((e[l+1]==='"'||e[l+1]==="'")&&l++,o+=e[l]):s===0?c==='"'||c==="'"?(s=1,n=c):c.match(/\s/)?(o.trim().length&&i.push(o.trim()),o=c):i.length&&!o?o=i.pop()+c:o+=c:s===1&&(c===n?(s=0,n=""):o+=c)}return o&&i.push(o.trim()),i}function createSpawnHandler(e){return function(t,r=[],s={}){const n=new ChildProcess,i=new ProcessApi(n);return setTimeout(async()=>{let o=[];if(r.length)o=[t,...r];else if(typeof t=="string")o=splitShellCommand(t);else if(Array.isArray(t))o=t;else throw new Error("Invalid command ",t);await e(o,i,s),n.emit("spawn",!0)}),n}}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)}stdoutEnd(){this.childProcess.stdout.emit("end",{})}stderr(t){typeof t=="string"&&(t=new TextEncoder().encode(t)),this.childProcess.stderr.emit("data",t)}stderrEnd(){this.childProcess.stderr.emit("end",{})}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)}}}}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]);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)}}var v,T;class PHPBrowser{constructor(t,r={}){u(this,v,void 0);u(this,T,void 0);this.requestHandler=t,p(this,v,{}),p(this,T,{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,T).handleRedirects&&s.headers.location&&r<a(this,T).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,v)[n]=i}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,T=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[c,h]of Object.entries(e))n.push(`--${t}\r
36
- `),n.push(`Content-Disposition: form-data; name="${c}"`),h instanceof File&&n.push(`; filename="${h.name}"`),n.push(`\r
37
- `),h instanceof File&&(n.push("Content-Type: application/octet-stream"),n.push(`\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$1(t),!t&&!r&&(t="."),t&&s&&(t+="/"),t}function basename(e){if(e==="/")return"/";e=normalizePath$1(e);const t=e.lastIndexOf("/");return t===-1?e:e.substr(t+1)}function normalizePath$1(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 splitShellCommand(e){let s=0,n="";const i=[];let o="";for(let a=0;a<e.length;a++){const c=e[a];c==="\\"?((e[a+1]==='"'||e[a+1]==="'")&&a++,o+=e[a]):s===0?c==='"'||c==="'"?(s=1,n=c):c.match(/\s/)?(o.trim().length&&i.push(o.trim()),o=c):i.length&&!o?o=i.pop()+c:o+=c:s===1&&(c===n?(s=0,n=""):o+=c)}return o&&i.push(o.trim()),i}function createSpawnHandler(e){return function(t,r=[],s={}){const n=new ChildProcess,i=new ProcessApi(n);return setTimeout(async()=>{let o=[];if(r.length)o=[t,...r];else if(typeof t=="string")o=splitShellCommand(t);else if(Array.isArray(t))o=t;else throw new Error("Invalid command ",t);await e(o,i,s),n.emit("spawn",!0)}),n}}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)}stdoutEnd(){this.childProcess.stdout.emit("end",{})}stderr(t){typeof t=="string"&&(t=new TextEncoder().encode(t)),this.childProcess.stderr.emit("data",t)}stderrEnd(){this.childProcess.stderr.emit("end",{})}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)}}}}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]);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)}}var v,T;class PHPBrowser{constructor(t,r={}){u(this,v,void 0);u(this,T,void 0);this.requestHandler=t,h(this,v,{}),h(this,T,{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"]),l(this,T).handleRedirects&&s.headers.location&&r<l(this,T).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];l(this,v)[n]=i}catch(s){console.error(s)}}serializeCookies(){const t=[];for(const r in l(this,v))t.push(`${r}=${l(this,v)[r]}`);return t.join("; ")}}v=new WeakMap,T=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[c,d]of Object.entries(e))n.push(`--${t}\r
36
+ `),n.push(`Content-Disposition: form-data; name="${c}"`),d instanceof File&&n.push(`; filename="${d.name}"`),n.push(`\r
37
+ `),d instanceof File&&(n.push("Content-Type: application/octet-stream"),n.push(`\r
38
38
  `)),n.push(`\r
39
- `),h instanceof File?n.push(await fileToUint8Array(h)):n.push(h),n.push(`\r
39
+ `),d instanceof File?n.push(await fileToUint8Array(d)):n.push(d),n.push(`\r
40
40
  `);n.push(`--${t}--\r
41
- `);const i=n.reduce((c,h)=>c+h.length,0),o=new Uint8Array(i);let l=0;for(const c of n)o.set(typeof c=="string"?s.encode(c):c,l),l+=c.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 y,F,N,b,x,m,C,R,O,K,I,Z,U,X;class PHPRequestHandler{constructor(t,r={}){u(this,O);u(this,I);u(this,U);u(this,y,void 0);u(this,F,void 0);u(this,N,void 0);u(this,b,void 0);u(this,x,void 0);u(this,m,void 0);u(this,C,void 0);u(this,R,void 0);p(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,p(this,y,s);const i=new URL(n);p(this,N,i.hostname),p(this,b,i.port?Number(i.port):i.protocol==="https:"?443:80),p(this,F,(i.protocol||"").replace(":",""));const o=a(this,b)!==443&&a(this,b)!==80;p(this,x,[a(this,N),o?`:${a(this,b)}`:""].join("")),p(this,m,i.pathname.replace(/\/+$/,"")),p(this,C,[`${a(this,F)}://`,a(this,x),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,C)}get documentRoot(){return a(this,y)}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,m)),i=`${a(this,y)}${n}`;return seemsLikeAPHPRequestHandlerPath(i)?await f(this,I,Z).call(this,t,s):f(this,O,K).call(this,i)}}y=new WeakMap,F=new WeakMap,N=new WeakMap,b=new WeakMap,x=new WeakMap,m=new WeakMap,C=new WeakMap,R=new WeakMap,O=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)},I=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,y)),this.php.addServerGlobalEntry("HTTPS",a(this,C).startsWith("https://")?"on":"");let o="GET";const l={host:a(this,x),...normalizeHeaders(t.headers||{})};let c=t.body;if(typeof c=="object"&&!(c instanceof Uint8Array)){o="POST";const{bytes:d,contentType:_}=await encodeAsMultipart(c);c=d,l["content-type"]=_}let h;try{let d=r.pathname;if((i=t.headers)!=null&&i["x-rewrite-url"])try{d=new URL(t.headers["x-rewrite-url"]).pathname}catch{}h=f(this,U,X).call(this,d)}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,F),method:t.method||o,body:c,scriptPath:h,headers:l})}finally{s()}},U=new WeakSet,X=function(t){let r=removePathPrefix(t,a(this,m));r.includes(".php")?r=r.split(".php")[0]+".php":this.php.isDir(`${a(this,y)}${r}`)?(r.endsWith("/")||(r=`${r}/`),r=`${r}index.php`):r="/index.php";const s=`${a(this,y)}${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 c=typeof l=="object"?l==null?void 0:l.errno:null;if(c in FileErrorCodes){const h=FileErrorCodes[c],d=typeof o[0]=="string"?o[0]:null,_=d!==null?e.replaceAll("{path}",d):e;throw new Error(`${_}: ${h}`,{cause:l})}throw l}}}}const loadedRuntimes=new Map;function getLoadedRuntime(e){return loadedRuntimes.get(e)}(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"})();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 S,k,A,E,g,P,w,H,M,ee,B,te,L,re,D,se,$,ne,q,ie,W,oe,j,ae,z,le,G,ce,J,ue,Q,de;class BasePHP{constructor(e,t){u(this,M);u(this,B);u(this,L);u(this,D);u(this,$);u(this,q);u(this,W);u(this,j);u(this,z);u(this,G);u(this,J);u(this,Q);u(this,S,void 0);u(this,k,void 0);u(this,A,void 0);u(this,E,void 0);u(this,g,void 0);u(this,P,void 0);u(this,w,void 0);u(this,H,void 0);p(this,S,[]),p(this,E,!1),p(this,g,null),p(this,P,{}),p(this,w,new Map),p(this,H,[]),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,w).has(e)||a(this,w).set(e,new Set),a(this,w).get(e).add(t)}removeEventListener(e,t){var r;(r=a(this,w).get(e))==null||r.delete(t)}dispatchEvent(e){const t=a(this,w).get(e.type);if(t)for(const r of t)r(e)}async onMessage(e){a(this,H).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,H)){const n=await s(r);if(n)return n}return""},p(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?");p(this,A,e)}setPhpIniPath(e){if(a(this,E))throw new Error("Cannot set PHP ini path after calling run().");p(this,k,e),this[__private__dont__use].ccall("wasm_set_phpini_path",null,["string"],[e])}setPhpIniEntry(e,t){if(a(this,E))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{if(a(this,E)||(f(this,M,ee).call(this),p(this,E,!0)),e.scriptPath&&!this.fileExists(e.scriptPath))throw new Error(`The script path "${e.scriptPath}" does not exist.`);f(this,j,ae).call(this,e.scriptPath||""),f(this,L,re).call(this,e.relativeUri||""),f(this,$,ne).call(this,e.method||"GET");const s=normalizeHeaders(e.headers||{}),n=s.host||"example.com:443";f(this,D,se).call(this,n,e.protocol||"http"),f(this,q,ie).call(this,s),e.body&&(r=f(this,W,oe).call(this,e.body)),typeof e.code=="string"&&f(this,J,ue).call(this," ?>"+e.code),f(this,z,le).call(this);const i=e.env||{};for(const l in i)f(this,G,ce).call(this,l,i[l]);const o=await f(this,Q,de).call(this);if(e.throwOnError&&o.exitCode!==0){const l={stdout:o.text,stderr:o.errors};console.warn("PHP.run() output was:",l);const c=new Error(`PHP.run() failed with exit code ${o.exitCode} and the following output: `+o.errors);throw c.output=l,console.error(c),c}return o}finally{try{r&&this[__private__dont__use].free(r)}finally{t(),this.dispatchEvent({type:"request.end"})}}}addServerGlobalEntry(e,t){a(this,P)[e]=t}defineConstant(e,t){let r={};try{r=JSON.parse(this.fileExists("/internal/consts.json")&&this.readFileAsText("/internal/consts.json")||"{}")}catch{}this.writeFile("/internal/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,k)&&this.setPhpIniPath(a(this,k)),a(this,A)&&this.setSapiName(a(this,A)),this.requestHandler){const r=this.documentRoot;copyFS(t,this[__private__dont__use].FS,r)}}exit(e=0){this.dispatchEvent({type:"runtime.beforedestroy"});try{this[__private__dont__use]._exit(e)}catch{}p(this,E,!1),p(this,g,null),delete this[__private__dont__use].onMessage,delete this[__private__dont__use]}}S=new WeakMap,k=new WeakMap,A=new WeakMap,E=new WeakMap,g=new WeakMap,P=new WeakMap,w=new WeakMap,H=new WeakMap,M=new WeakSet,ee=function(){if(this.setPhpIniEntry("auto_prepend_file","/internal/consts.php"),this.fileExists("/internal/consts.php")||this.writeFile("/internal/consts.php",`<?php
41
+ `);const i=n.reduce((c,d)=>c+d.length,0),o=new Uint8Array(i);let a=0;for(const c of n)o.set(typeof c=="string"?s.encode(c):c,a),a+=c.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 m,F,N,R,x,_,C,b,O,K,I,Z,M,X;class PHPRequestHandler{constructor(t,r={}){u(this,O);u(this,I);u(this,M);u(this,m,void 0);u(this,F,void 0);u(this,N,void 0);u(this,R,void 0);u(this,x,void 0);u(this,_,void 0);u(this,C,void 0);u(this,b,void 0);h(this,b,new Semaphore({concurrency:1}));const{documentRoot:s="/www/",absoluteUrl:n=typeof location=="object"?location==null?void 0:location.href:"",rewriteRules:i=[]}=r;this.php=t,h(this,m,s);const o=new URL(n);h(this,N,o.hostname),h(this,R,o.port?Number(o.port):o.protocol==="https:"?443:80),h(this,F,(o.protocol||"").replace(":",""));const a=l(this,R)!==443&&l(this,R)!==80;h(this,x,[l(this,N),a?`:${l(this,R)}`:""].join("")),h(this,_,o.pathname.replace(/\/+$/,"")),h(this,C,[`${l(this,F)}://`,l(this,x),l(this,_)].join("")),this.rewriteRules=i}pathToInternalUrl(t){return`${this.absoluteUrl}${t}`}internalUrlToPath(t){const r=new URL(t);return r.pathname.startsWith(l(this,_))&&(r.pathname=r.pathname.slice(l(this,_).length)),toRelativeUrl(r)}get isRequestRunning(){return l(this,b).running>0}get absoluteUrl(){return l(this,C)}get documentRoot(){return l(this,m)}async request(t){const r=t.url.startsWith("http://")||t.url.startsWith("https://"),s=new URL(t.url.split("#")[0],r?void 0:DEFAULT_BASE_URL),n=applyRewriteRules(removePathPrefix(s.pathname,l(this,_)),this.rewriteRules),i=`${l(this,m)}${n}`;return seemsLikeAPHPRequestHandlerPath(i)?await f(this,I,Z).call(this,t,s):f(this,O,K).call(this,i)}}m=new WeakMap,F=new WeakMap,N=new WeakMap,R=new WeakMap,x=new WeakMap,_=new WeakMap,C=new WeakMap,b=new WeakMap,O=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)},I=new WeakSet,Z=async function(t,r){var n;if(l(this,b).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 l(this,b).acquire();try{this.php.addServerGlobalEntry("REMOTE_ADDR","127.0.0.1"),this.php.addServerGlobalEntry("DOCUMENT_ROOT",l(this,m)),this.php.addServerGlobalEntry("HTTPS",l(this,C).startsWith("https://")?"on":"");let i="GET";const o={host:l(this,x),...normalizeHeaders(t.headers||{})};let a=t.body;if(typeof a=="object"&&!(a instanceof Uint8Array)){i="POST";const{bytes:d,contentType:p}=await encodeAsMultipart(a);a=d,o["content-type"]=p}let c;try{c=f(this,M,X).call(this,r.pathname)}catch{return new PHPResponse(404,{},new TextEncoder().encode("404 File not found"))}return await this.php.run({relativeUri:ensurePathPrefix(toRelativeUrl(r),l(this,_)),protocol:l(this,F),method:t.method||i,body:a,scriptPath:c,headers:o})}finally{s()}},M=new WeakSet,X=function(t){let r=removePathPrefix(t,l(this,_));r=applyRewriteRules(r,this.rewriteRules),r.includes(".php")?r=r.split(".php")[0]+".php":this.php.isDir(`${l(this,m)}${r}`)?(r.endsWith("/")||(r=`${r}/`),r=`${r}index.php`):r="/index.php";const s=`${l(this,m)}${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(".")}function applyRewriteRules(e,t){for(const r of t)if(new RegExp(r.match).test(e))return e.replace(r.match,r.replacement);return e}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(a){const c=typeof a=="object"?a==null?void 0:a.errno:null;if(c in FileErrorCodes){const d=FileErrorCodes[c],p=typeof o[0]=="string"?o[0]:null,P=p!==null?e.replaceAll("{path}",p):e;throw new Error(`${P}: ${d}`,{cause:a})}throw a}}}}const loadedRuntimes=new Map;function getLoadedRuntime(e){return loadedRuntimes.get(e)}(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"})();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 S,k,A,y,w,g,E,H,U,ee,B,te,L,re,D,se,$,ne,q,ie,W,oe,j,ae,z,le,G,ce,J,ue,Q,de;class BasePHP{constructor(e,t){u(this,U);u(this,B);u(this,L);u(this,D);u(this,$);u(this,q);u(this,W);u(this,j);u(this,z);u(this,G);u(this,J);u(this,Q);u(this,S,void 0);u(this,k,void 0);u(this,A,void 0);u(this,y,void 0);u(this,w,void 0);u(this,g,void 0);u(this,E,void 0);u(this,H,void 0);h(this,S,[]),h(this,y,!1),h(this,w,null),h(this,g,{}),h(this,E,new Map),h(this,H,[]),this.semaphore=new Semaphore({concurrency:1}),e!==void 0&&this.initializeRuntime(e),t&&(this.requestHandler=new PHPBrowser(new PHPRequestHandler(this,t)))}addEventListener(e,t){l(this,E).has(e)||l(this,E).set(e,new Set),l(this,E).get(e).add(t)}removeEventListener(e,t){var r;(r=l(this,E).get(e))==null||r.delete(t)}dispatchEvent(e){const t=l(this,E).get(e.type);if(t)for(const r of t)r(e)}async onMessage(e){l(this,H).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 l(this,H)){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(l(this,y))throw new Error("Cannot set PHP ini path after calling run().");h(this,k,e),this[__private__dont__use].ccall("wasm_set_phpini_path",null,["string"],[e])}setPhpIniEntry(e,t){if(l(this,y))throw new Error("Cannot set PHP ini entries after calling run().");l(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{if(l(this,y)||(f(this,U,ee).call(this),h(this,y,!0)),e.scriptPath&&!this.fileExists(e.scriptPath))throw new Error(`The script path "${e.scriptPath}" does not exist.`);f(this,j,ae).call(this,e.scriptPath||""),f(this,L,re).call(this,e.relativeUri||""),f(this,$,ne).call(this,e.method||"GET");const s=normalizeHeaders(e.headers||{}),n=s.host||"example.com:443";f(this,D,se).call(this,n,e.protocol||"http"),f(this,q,ie).call(this,s),e.body&&(r=f(this,W,oe).call(this,e.body)),typeof e.code=="string"&&f(this,J,ue).call(this," ?>"+e.code),f(this,z,le).call(this);const i=e.env||{};for(const a in i)f(this,G,ce).call(this,a,i[a]);const o=await f(this,Q,de).call(this);if(o.exitCode!==0){const a={stdout:o.text,stderr:o.errors};console.warn("PHP.run() output was:",a);const c=new Error(`PHP.run() failed with exit code ${o.exitCode} and the following output: `+o.errors);throw c.output=a,c.source="request",console.error(c),c}return o}catch(s){throw this.dispatchEvent({type:"request.error",error:s,source:s.source??"php-wasm"}),s}finally{try{r&&this[__private__dont__use].free(r)}finally{t(),this.dispatchEvent({type:"request.end"})}}}addServerGlobalEntry(e,t){l(this,g)[e]=t}defineConstant(e,t){let r={};try{r=JSON.parse(this.fileExists("/internal/consts.json")&&this.readFileAsText("/internal/consts.json")||"{}")}catch{}this.writeFile("/internal/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),l(this,k)&&this.setPhpIniPath(l(this,k)),l(this,A)&&this.setSapiName(l(this,A)),this.requestHandler){const r=this.documentRoot;copyFS(t,this[__private__dont__use].FS,r)}}exit(e=0){this.dispatchEvent({type:"runtime.beforedestroy"});try{this[__private__dont__use]._exit(e)}catch{}h(this,y,!1),h(this,w,null),delete this[__private__dont__use].onMessage,delete this[__private__dont__use]}}S=new WeakMap,k=new WeakMap,A=new WeakMap,y=new WeakMap,w=new WeakMap,g=new WeakMap,E=new WeakMap,H=new WeakMap,U=new WeakSet,ee=function(){if(this.setPhpIniEntry("auto_prepend_file","/internal/consts.php"),this.fileExists("/internal/consts.php")||this.writeFile("/internal/consts.php",`<?php
42
42
  if(file_exists('/internal/consts.json')) {
43
43
  $consts = json_decode(file_get_contents('/internal/consts.json'), true);
44
44
  foreach ($consts as $const => $value) {
@@ -46,7 +46,7 @@ ${bold} WASM ERROR${reset}${redBg}`);for(const t of e.split(`
46
46
  define($const, $value);
47
47
  }
48
48
  }
49
- }`),a(this,S).length>0){const e=a(this,S).map(([t,r])=>`${t}=${r}`).join(`
49
+ }`),l(this,S).length>0){const e=l(this,S).map(([t,r])=>`${t}=${r}`).join(`
50
50
  `)+`
51
51
 
52
- `;this[__private__dont__use].ccall("wasm_set_phpini_entries",null,[STRING],[e])}this[__private__dont__use].ccall("php_wasm_init",null,[],[])},B=new WeakSet,te=function(){const e="/internal/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}},L=new WeakSet,re=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])}},D=new WeakSet,se=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")},$=new WeakSet,ne=function(e){this[__private__dont__use].ccall("wasm_set_request_method",null,[STRING],[e])},q=new WeakSet,ie=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])}},W=new WeakSet,oe=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},j=new WeakSet,ae=function(e){this[__private__dont__use].ccall("wasm_set_path_translated",null,[STRING],[e])},z=new WeakSet,le=function(){for(const e in a(this,P))this[__private__dont__use].ccall("wasm_add_SERVER_entry",null,[STRING,STRING],[e,a(this,P)[e]])},G=new WeakSet,ce=function(e,t){this[__private__dont__use].ccall("wasm_add_ENV_entry",null,[STRING,STRING],[e,t])},J=new WeakSet,ue=function(e){this[__private__dont__use].ccall("wasm_set_php_code",null,[STRING],[e])},Q=new WeakSet,de=async function(){var n;let e,t;try{e=await new Promise((i,o)=>{var c;t=h=>{console.error(h),console.error(h.error);const d=new Error("Rethrown");d.cause=h.error,d.betterMessage=h.message,o(d)},(c=a(this,g))==null||c.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 h in this)typeof this[h]=="function"&&(this[h]=()=>{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,c=new Error(l);throw c.cause=o,console.error(c),c}finally{(n=a(this,g))==null||n.removeEventListener("error",t),p(this,P,{})}const{headers:r,httpStatusCode:s}=f(this,B,te).call(this);return new PHPResponse(s,r,this.readFileAsBuffer("/internal/stdout"),this.readFileAsText("/internal/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 copyFS(e,t,r){let s;try{s=e.lookupPath(r)}catch{return}if(!("contents"in s.node))return;if(!e.isDir(s.node.mode)){t.writeFile(r,e.readFile(r));return}t.mkdirTree(r);const n=e.readdir(r).filter(i=>i!=="."&&i!=="..");for(const i of n)copyFS(e,t,joinPaths(r,i))}function journalFSEvents(e,t,r=()=>{}){function s(){t=normalizePath(t);const i=e[__private__dont__use].FS,o=createFSHooks(i,d=>{if(d.path.startsWith(t))r(d);else if(d.operation==="RENAME"&&d.toPath.startsWith(t))for(const _ of recordExistingPath(e,d.path,d.toPath))r(_)}),l={};for(const[d]of Object.entries(o))l[d]=i[d];function c(){for(const[d,_]of Object.entries(o))i[d]=function(...V){return _(...V),l[d].apply(this,V)}}function h(){for(const[d,_]of Object.entries(l))e[__private__dont__use].FS[d]=_}e[__private__dont__use].journal={bind:c,unbind:h},c()}e.addEventListener("runtime.initialized",s),e[__private__dont__use]&&s();function n(){e[__private__dont__use].journal.unbind(),delete e[__private__dont__use].journal}return e.addEventListener("runtime.beforedestroy",n),function(){return e.removeEventListener("runtime.initialized",s),e.removeEventListener("runtime.beforedestroy",n),e[__private__dont__use].journal.unbind()}}const createFSHooks=(e,t=()=>{})=>({write(r){t({operation:"WRITE",path:r.path,nodeType:"file"})},truncate(r){let s;typeof r=="string"?s=e.lookupPath(r,{follow:!0}).node:s=r,t({operation:"WRITE",path:e.getPath(s),nodeType:"file"})},unlink(r){t({operation:"DELETE",path:r,nodeType:"file"})},mknod(r,s){e.isFile(s)&&t({operation:"CREATE",path:r,nodeType:"file"})},mkdir(r){t({operation:"CREATE",path:r,nodeType:"directory"})},rmdir(r){t({operation:"DELETE",path:r,nodeType:"directory"})},rename(r,s){try{const n=e.lookupPath(r,{follow:!0}),i=e.lookupPath(s,{parent:!0}).path;t({operation:"RENAME",nodeType:e.isDir(n.node.mode)?"directory":"file",path:n.path,toPath:joinPaths(i,basename(s))})}catch{}}});function replayFSJournal(e,t){e[__private__dont__use].journal.unbind();try{for(const r of t)r.operation==="CREATE"?r.nodeType==="file"?e.writeFile(r.path," "):e.mkdir(r.path):r.operation==="DELETE"?r.nodeType==="file"?e.unlink(r.path):e.rmdir(r.path):r.operation==="WRITE"?e.writeFile(r.path,r.data):r.operation==="RENAME"&&e.mv(r.path,r.toPath)}finally{e[__private__dont__use].journal.bind()}}function*recordExistingPath(e,t,r){if(e.isDir(t)){yield{operation:"CREATE",path:r,nodeType:"directory"};for(const s of e.listFiles(t))yield*recordExistingPath(e,joinPaths(t,s),joinPaths(r,s))}else yield{operation:"CREATE",path:r,nodeType:"file"},yield{operation:"WRITE",nodeType:"file",path:r}}function normalizePath(e){return e.replace(/\/$/,"").replace(/\/\/+/g,"/")}function normalizeFilesystemOperations(e){const t={};for(let r=e.length-1;r>=0;r--){for(let s=r-1;s>=0;s--){const n=checkRelationship(e[r],e[s]);if(n==="none")continue;const i=e[r],o=e[s];if(i.operation==="RENAME"&&o.operation==="RENAME"){console.warn("[FS Journal] Normalizing a double rename is not yet supported:",{current:i,last:o});continue}(o.operation==="CREATE"||o.operation==="WRITE")&&(i.operation==="RENAME"?n==="same_node"?(t[s]=[],t[r]=[{...o,path:i.toPath},...t[r]||[]]):n==="descendant"&&(t[s]=[],t[r]=[{...o,path:joinPaths(i.toPath,o.path.substring(i.path.length))},...t[r]||[]]):i.operation==="WRITE"&&n==="same_node"?t[s]=[]:i.operation==="DELETE"&&n==="same_node"&&(t[s]=[],t[r]=[]))}if(Object.entries(t).length>0){const s=e.flatMap((n,i)=>i in t?t[i]:[n]);return normalizeFilesystemOperations(s)}}return e}function checkRelationship(e,t){const r=e.path,s=e.operation!=="WRITE"&&e.nodeType==="directory",n=t.operation!=="WRITE"&&t.nodeType==="directory",i=t.operation==="RENAME"?t.toPath:t.path;return i===r?"same_node":n&&r.startsWith(i+"/")?"ancestor":s&&i.startsWith(r+"/")?"descendant":"none"}async function hydrateUpdateFileOps(e,t){const s=t.filter(n=>n.operation==="WRITE").map(n=>hydrateOp(e,n));return await Promise.all(s),t}const hydrateLock=new Semaphore({concurrency:15});async function hydrateOp(e,t){const r=await hydrateLock.acquire();try{t.data=await e.readFileAsBuffer(t.path)}catch(s){console.warn(`Journal failed to hydrate a file on flush: the path ${t.path} no longer exists`),console.error(s)}r()}exports.hydrateUpdateFileOps=hydrateUpdateFileOps;exports.journalFSEvents=journalFSEvents;exports.normalizeFilesystemOperations=normalizeFilesystemOperations;exports.replayFSJournal=replayFSJournal;
52
+ `;this[__private__dont__use].ccall("wasm_set_phpini_entries",null,[STRING],[e])}this[__private__dont__use].ccall("php_wasm_init",null,[],[])},B=new WeakSet,te=function(){const e="/internal/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}},L=new WeakSet,re=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])}},D=new WeakSet,se=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")},$=new WeakSet,ne=function(e){this[__private__dont__use].ccall("wasm_set_request_method",null,[STRING],[e])},q=new WeakSet,ie=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])}},W=new WeakSet,oe=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},j=new WeakSet,ae=function(e){this[__private__dont__use].ccall("wasm_set_path_translated",null,[STRING],[e])},z=new WeakSet,le=function(){for(const e in l(this,g))this[__private__dont__use].ccall("wasm_add_SERVER_entry",null,[STRING,STRING],[e,l(this,g)[e]])},G=new WeakSet,ce=function(e,t){this[__private__dont__use].ccall("wasm_add_ENV_entry",null,[STRING,STRING],[e,t])},J=new WeakSet,ue=function(e){this[__private__dont__use].ccall("wasm_set_php_code",null,[STRING],[e])},Q=new WeakSet,de=async function(){var n;let e,t;try{e=await new Promise((i,o)=>{var c;t=d=>{console.error(d),console.error(d.error);const p=new Error("Rethrown");p.cause=d.error,p.betterMessage=d.message,o(p)},(c=l(this,w))==null||c.addEventListener("error",t);const a=this[__private__dont__use].ccall("wasm_sapi_handle_request",NUMBER,[],[],{async:!0});return a instanceof Promise?a.then(i,o):i(a)})}catch(i){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=i,a="betterMessage"in o?o.betterMessage:o.message,c=new Error(a);throw c.cause=o,console.error(c),c}finally{(n=l(this,w))==null||n.removeEventListener("error",t),h(this,g,{})}const{headers:r,httpStatusCode:s}=f(this,B,te).call(this);return new PHPResponse(s,r,this.readFileAsBuffer("/internal/stdout"),this.readFileAsText("/internal/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 copyFS(e,t,r){let s;try{s=e.lookupPath(r)}catch{return}if(!("contents"in s.node))return;if(!e.isDir(s.node.mode)){t.writeFile(r,e.readFile(r));return}t.mkdirTree(r);const n=e.readdir(r).filter(i=>i!=="."&&i!=="..");for(const i of n)copyFS(e,t,joinPaths(r,i))}function journalFSEvents(e,t,r=()=>{}){function s(){t=normalizePath(t);const i=e[__private__dont__use].FS,o=createFSHooks(i,p=>{if(p.path.startsWith(t))r(p);else if(p.operation==="RENAME"&&p.toPath.startsWith(t))for(const P of recordExistingPath(e,p.path,p.toPath))r(P)}),a={};for(const[p]of Object.entries(o))a[p]=i[p];function c(){for(const[p,P]of Object.entries(o))i[p]=function(...V){return P(...V),a[p].apply(this,V)}}function d(){for(const[p,P]of Object.entries(a))e[__private__dont__use].FS[p]=P}e[__private__dont__use].journal={bind:c,unbind:d},c()}e.addEventListener("runtime.initialized",s),e[__private__dont__use]&&s();function n(){e[__private__dont__use].journal.unbind(),delete e[__private__dont__use].journal}return e.addEventListener("runtime.beforedestroy",n),function(){return e.removeEventListener("runtime.initialized",s),e.removeEventListener("runtime.beforedestroy",n),e[__private__dont__use].journal.unbind()}}const createFSHooks=(e,t=()=>{})=>({write(r){t({operation:"WRITE",path:r.path,nodeType:"file"})},truncate(r){let s;typeof r=="string"?s=e.lookupPath(r,{follow:!0}).node:s=r,t({operation:"WRITE",path:e.getPath(s),nodeType:"file"})},unlink(r){t({operation:"DELETE",path:r,nodeType:"file"})},mknod(r,s){e.isFile(s)&&t({operation:"CREATE",path:r,nodeType:"file"})},mkdir(r){t({operation:"CREATE",path:r,nodeType:"directory"})},rmdir(r){t({operation:"DELETE",path:r,nodeType:"directory"})},rename(r,s){try{const n=e.lookupPath(r,{follow:!0}),i=e.lookupPath(s,{parent:!0}).path;t({operation:"RENAME",nodeType:e.isDir(n.node.mode)?"directory":"file",path:n.path,toPath:joinPaths(i,basename(s))})}catch{}}});function replayFSJournal(e,t){e[__private__dont__use].journal.unbind();try{for(const r of t)r.operation==="CREATE"?r.nodeType==="file"?e.writeFile(r.path," "):e.mkdir(r.path):r.operation==="DELETE"?r.nodeType==="file"?e.unlink(r.path):e.rmdir(r.path):r.operation==="WRITE"?e.writeFile(r.path,r.data):r.operation==="RENAME"&&e.mv(r.path,r.toPath)}finally{e[__private__dont__use].journal.bind()}}function*recordExistingPath(e,t,r){if(e.isDir(t)){yield{operation:"CREATE",path:r,nodeType:"directory"};for(const s of e.listFiles(t))yield*recordExistingPath(e,joinPaths(t,s),joinPaths(r,s))}else yield{operation:"CREATE",path:r,nodeType:"file"},yield{operation:"WRITE",nodeType:"file",path:r}}function normalizePath(e){return e.replace(/\/$/,"").replace(/\/\/+/g,"/")}function normalizeFilesystemOperations(e){const t={};for(let r=e.length-1;r>=0;r--){for(let s=r-1;s>=0;s--){const n=checkRelationship(e[r],e[s]);if(n==="none")continue;const i=e[r],o=e[s];if(i.operation==="RENAME"&&o.operation==="RENAME"){console.warn("[FS Journal] Normalizing a double rename is not yet supported:",{current:i,last:o});continue}(o.operation==="CREATE"||o.operation==="WRITE")&&(i.operation==="RENAME"?n==="same_node"?(t[s]=[],t[r]=[{...o,path:i.toPath},...t[r]||[]]):n==="descendant"&&(t[s]=[],t[r]=[{...o,path:joinPaths(i.toPath,o.path.substring(i.path.length))},...t[r]||[]]):i.operation==="WRITE"&&n==="same_node"?t[s]=[]:i.operation==="DELETE"&&n==="same_node"&&(t[s]=[],t[r]=[]))}if(Object.entries(t).length>0){const s=e.flatMap((n,i)=>i in t?t[i]:[n]);return normalizeFilesystemOperations(s)}}return e}function checkRelationship(e,t){const r=e.path,s=e.operation!=="WRITE"&&e.nodeType==="directory",n=t.operation!=="WRITE"&&t.nodeType==="directory",i=t.operation==="RENAME"?t.toPath:t.path;return i===r?"same_node":n&&r.startsWith(i+"/")?"ancestor":s&&i.startsWith(r+"/")?"descendant":"none"}async function hydrateUpdateFileOps(e,t){const s=t.filter(n=>n.operation==="WRITE").map(n=>hydrateOp(e,n));return await Promise.all(s),t}const hydrateLock=new Semaphore({concurrency:15});async function hydrateOp(e,t){const r=await hydrateLock.acquire();try{t.data=await e.readFileAsBuffer(t.path)}catch(s){console.warn(`Journal failed to hydrate a file on flush: the path ${t.path} no longer exists`),console.error(s)}r()}exports.hydrateUpdateFileOps=hydrateUpdateFileOps;exports.journalFSEvents=journalFSEvents;exports.normalizeFilesystemOperations=normalizeFilesystemOperations;exports.replayFSJournal=replayFSJournal;
package/index.js CHANGED
@@ -2,11 +2,11 @@ var Y = (e, t, r) => {
2
2
  if (!t.has(e))
3
3
  throw TypeError("Cannot " + r);
4
4
  };
5
- var a = (e, t, r) => (Y(e, t, "read from private field"), r ? r.call(e) : t.get(e)), u = (e, t, r) => {
5
+ var l = (e, t, r) => (Y(e, t, "read from private field"), r ? r.call(e) : t.get(e)), u = (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
- }, p = (e, t, r, s) => (Y(e, t, "write to private field"), s ? s.call(e, r) : t.set(e, r), r);
9
+ }, h = (e, t, r, s) => (Y(e, t, "write to private field"), s ? s.call(e, r) : t.set(e, r), r);
10
10
  var f = (e, t, r) => (Y(e, t, "access private method"), r);
11
11
  const currentJsRuntime = function() {
12
12
  var e;
@@ -35,8 +35,8 @@ if (currentJsRuntime === "NODE") {
35
35
  class r extends Blob {
36
36
  constructor(n, i, o) {
37
37
  super(n);
38
- let l;
39
- o != null && o.lastModified && (l = /* @__PURE__ */ new Date()), (!l || isNaN(l.getFullYear())) && (l = /* @__PURE__ */ new Date()), this.lastModifiedDate = l, this.lastModified = l.getMilliseconds(), this.name = i || "";
38
+ let a;
39
+ o != null && o.lastModified && (a = /* @__PURE__ */ new Date()), (!a || isNaN(a.getFullYear())) && (a = /* @__PURE__ */ new Date()), this.lastModifiedDate = a, this.lastModified = a.getMilliseconds(), this.name = i || "";
40
40
  }
41
41
  }
42
42
  global.File = r;
@@ -56,13 +56,13 @@ if (currentJsRuntime === "NODE") {
56
56
  // this if needed.
57
57
  autoAllocateChunkSize: 512 * 1024,
58
58
  async pull(n) {
59
- const i = n.byobRequest.view, l = await s.slice(
59
+ const i = n.byobRequest.view, a = await s.slice(
60
60
  r,
61
61
  r + i.byteLength
62
- ).arrayBuffer(), c = new Uint8Array(l);
62
+ ).arrayBuffer(), c = new Uint8Array(a);
63
63
  new Uint8Array(i.buffer).set(c);
64
- const h = c.byteLength;
65
- n.byobRequest.respond(h), r += h, r >= s.size && n.close();
64
+ const d = c.byteLength;
65
+ n.byobRequest.respond(d), r += d, r >= s.size && n.close();
66
66
  }
67
67
  });
68
68
  });
@@ -131,7 +131,7 @@ function improveWASMErrorReporting(e) {
131
131
  } catch (o) {
132
132
  if (!(o instanceof Error))
133
133
  throw o;
134
- const l = clarifyErrorMessage(
134
+ const a = clarifyErrorMessage(
135
135
  o,
136
136
  (i = e.lastAsyncifyStackSource) == null ? void 0 : i.stack
137
137
  );
@@ -139,12 +139,12 @@ function improveWASMErrorReporting(e) {
139
139
  t.dispatchEvent(
140
140
  new ErrorEvent("error", {
141
141
  error: o,
142
- message: l
142
+ message: a
143
143
  })
144
144
  );
145
145
  return;
146
146
  }
147
- throw isExitCodeZero(o) || showCriticalErrorBox(l), o;
147
+ throw isExitCodeZero(o) || showCriticalErrorBox(a), o;
148
148
  }
149
149
  };
150
150
  }
@@ -288,9 +288,9 @@ function splitShellCommand(e) {
288
288
  let s = 0, n = "";
289
289
  const i = [];
290
290
  let o = "";
291
- for (let l = 0; l < e.length; l++) {
292
- const c = e[l];
293
- c === "\\" ? ((e[l + 1] === '"' || e[l + 1] === "'") && l++, o += e[l]) : s === 0 ? c === '"' || c === "'" ? (s = 1, n = c) : c.match(/\s/) ? (o.trim().length && i.push(o.trim()), o = c) : i.length && !o ? o = i.pop() + c : o += c : s === 1 && (c === n ? (s = 0, n = "") : o += c);
291
+ for (let a = 0; a < e.length; a++) {
292
+ const c = e[a];
293
+ c === "\\" ? ((e[a + 1] === '"' || e[a + 1] === "'") && a++, o += e[a]) : s === 0 ? c === '"' || c === "'" ? (s = 1, n = c) : c.match(/\s/) ? (o.trim().length && i.push(o.trim()), o = c) : i.length && !o ? o = i.pop() + c : o += c : s === 1 && (c === n ? (s = 0, n = "") : o += c);
294
294
  }
295
295
  return o && i.push(o.trim()), i;
296
296
  }
@@ -422,7 +422,7 @@ class PHPBrowser {
422
422
  constructor(t, r = {}) {
423
423
  u(this, v, void 0);
424
424
  u(this, T, void 0);
425
- this.requestHandler = t, p(this, v, {}), p(this, T, {
425
+ this.requestHandler = t, h(this, v, {}), h(this, T, {
426
426
  handleRedirects: !1,
427
427
  maxRedirects: 4,
428
428
  ...r
@@ -450,7 +450,7 @@ class PHPBrowser {
450
450
  cookie: this.serializeCookies()
451
451
  }
452
452
  });
453
- if (s.headers["set-cookie"] && this.setCookies(s.headers["set-cookie"]), a(this, T).handleRedirects && s.headers.location && r < a(this, T).maxRedirects) {
453
+ if (s.headers["set-cookie"] && this.setCookies(s.headers["set-cookie"]), l(this, T).handleRedirects && s.headers.location && r < l(this, T).maxRedirects) {
454
454
  const n = new URL(
455
455
  s.headers.location[0],
456
456
  this.requestHandler.absoluteUrl
@@ -488,15 +488,15 @@ class PHPBrowser {
488
488
  if (!r.includes("="))
489
489
  continue;
490
490
  const s = r.indexOf("="), n = r.substring(0, s), i = r.substring(s + 1).split(";")[0];
491
- a(this, v)[n] = i;
491
+ l(this, v)[n] = i;
492
492
  } catch (s) {
493
493
  console.error(s);
494
494
  }
495
495
  }
496
496
  serializeCookies() {
497
497
  const t = [];
498
- for (const r in a(this, v))
499
- t.push(`${r}=${a(this, v)[r]}`);
498
+ for (const r in l(this, v))
499
+ t.push(`${r}=${l(this, v)[r]}`);
500
500
  return t.join("; ");
501
501
  }
502
502
  }
@@ -513,22 +513,22 @@ function ensurePathPrefix(e, t) {
513
513
  }
514
514
  async function encodeAsMultipart(e) {
515
515
  const t = `----${Math.random().toString(36).slice(2)}`, r = `multipart/form-data; boundary=${t}`, s = new TextEncoder(), n = [];
516
- for (const [c, h] of Object.entries(e))
516
+ for (const [c, d] of Object.entries(e))
517
517
  n.push(`--${t}\r
518
- `), n.push(`Content-Disposition: form-data; name="${c}"`), h instanceof File && n.push(`; filename="${h.name}"`), n.push(`\r
519
- `), h instanceof File && (n.push("Content-Type: application/octet-stream"), n.push(`\r
518
+ `), n.push(`Content-Disposition: form-data; name="${c}"`), d instanceof File && n.push(`; filename="${d.name}"`), n.push(`\r
519
+ `), d instanceof File && (n.push("Content-Type: application/octet-stream"), n.push(`\r
520
520
  `)), n.push(`\r
521
- `), h instanceof File ? n.push(await fileToUint8Array(h)) : n.push(h), n.push(`\r
521
+ `), d instanceof File ? n.push(await fileToUint8Array(d)) : n.push(d), n.push(`\r
522
522
  `);
523
523
  n.push(`--${t}--\r
524
524
  `);
525
- const i = n.reduce((c, h) => c + h.length, 0), o = new Uint8Array(i);
526
- let l = 0;
525
+ const i = n.reduce((c, d) => c + d.length, 0), o = new Uint8Array(i);
526
+ let a = 0;
527
527
  for (const c of n)
528
528
  o.set(
529
529
  typeof c == "string" ? s.encode(c) : c,
530
- l
531
- ), l += c.length;
530
+ a
531
+ ), a += c.length;
532
532
  return { bytes: o, contentType: r };
533
533
  }
534
534
  function fileToUint8Array(e) {
@@ -539,7 +539,7 @@ function fileToUint8Array(e) {
539
539
  }, r.readAsArrayBuffer(e);
540
540
  });
541
541
  }
542
- var y, F, N, b, x, m, C, R, I, K, O, Z, U, X;
542
+ var m, F, N, R, x, _, C, b, I, K, O, Z, M, X;
543
543
  class PHPRequestHandler {
544
544
  /**
545
545
  * @param php - The PHP instance.
@@ -570,32 +570,33 @@ class PHPRequestHandler {
570
570
  * @throws {Error} If the requested path doesn't exist.
571
571
  * @returns The resolved filesystem path.
572
572
  */
573
- u(this, U);
574
- u(this, y, void 0);
573
+ u(this, M);
574
+ u(this, m, void 0);
575
575
  u(this, F, void 0);
576
576
  u(this, N, void 0);
577
- u(this, b, void 0);
577
+ u(this, R, void 0);
578
578
  u(this, x, void 0);
579
- u(this, m, void 0);
579
+ u(this, _, void 0);
580
580
  u(this, C, void 0);
581
- u(this, R, void 0);
582
- p(this, R, new Semaphore({ concurrency: 1 }));
581
+ u(this, b, void 0);
582
+ h(this, b, new Semaphore({ concurrency: 1 }));
583
583
  const {
584
584
  documentRoot: s = "/www/",
585
- absoluteUrl: n = typeof location == "object" ? location == null ? void 0 : location.href : ""
585
+ absoluteUrl: n = typeof location == "object" ? location == null ? void 0 : location.href : "",
586
+ rewriteRules: i = []
586
587
  } = r;
587
- this.php = t, p(this, y, s);
588
- const i = new URL(n);
589
- p(this, N, i.hostname), p(this, b, i.port ? Number(i.port) : i.protocol === "https:" ? 443 : 80), p(this, F, (i.protocol || "").replace(":", ""));
590
- const o = a(this, b) !== 443 && a(this, b) !== 80;
591
- p(this, x, [
592
- a(this, N),
593
- o ? `:${a(this, b)}` : ""
594
- ].join("")), p(this, m, i.pathname.replace(/\/+$/, "")), p(this, C, [
595
- `${a(this, F)}://`,
596
- a(this, x),
597
- a(this, m)
598
- ].join(""));
588
+ this.php = t, h(this, m, s);
589
+ const o = new URL(n);
590
+ h(this, N, o.hostname), h(this, R, o.port ? Number(o.port) : o.protocol === "https:" ? 443 : 80), h(this, F, (o.protocol || "").replace(":", ""));
591
+ const a = l(this, R) !== 443 && l(this, R) !== 80;
592
+ h(this, x, [
593
+ l(this, N),
594
+ a ? `:${l(this, R)}` : ""
595
+ ].join("")), h(this, _, o.pathname.replace(/\/+$/, "")), h(this, C, [
596
+ `${l(this, F)}://`,
597
+ l(this, x),
598
+ l(this, _)
599
+ ].join("")), this.rewriteRules = i;
599
600
  }
600
601
  /** @inheritDoc */
601
602
  pathToInternalUrl(t) {
@@ -604,32 +605,33 @@ class PHPRequestHandler {
604
605
  /** @inheritDoc */
605
606
  internalUrlToPath(t) {
606
607
  const r = new URL(t);
607
- return r.pathname.startsWith(a(this, m)) && (r.pathname = r.pathname.slice(a(this, m).length)), toRelativeUrl(r);
608
+ return r.pathname.startsWith(l(this, _)) && (r.pathname = r.pathname.slice(l(this, _).length)), toRelativeUrl(r);
608
609
  }
609
610
  get isRequestRunning() {
610
- return a(this, R).running > 0;
611
+ return l(this, b).running > 0;
611
612
  }
612
613
  /** @inheritDoc */
613
614
  get absoluteUrl() {
614
- return a(this, C);
615
+ return l(this, C);
615
616
  }
616
617
  /** @inheritDoc */
617
618
  get documentRoot() {
618
- return a(this, y);
619
+ return l(this, m);
619
620
  }
620
621
  /** @inheritDoc */
621
622
  async request(t) {
622
623
  const r = t.url.startsWith("http://") || t.url.startsWith("https://"), s = new URL(
623
- t.url,
624
+ // Remove the hash part of the URL as it's not meant for the server.
625
+ t.url.split("#")[0],
624
626
  r ? void 0 : DEFAULT_BASE_URL
625
- ), n = removePathPrefix(
626
- s.pathname,
627
- a(this, m)
628
- ), i = `${a(this, y)}${n}`;
627
+ ), n = applyRewriteRules(
628
+ removePathPrefix(s.pathname, l(this, _)),
629
+ this.rewriteRules
630
+ ), i = `${l(this, m)}${n}`;
629
631
  return seemsLikeAPHPRequestHandlerPath(i) ? await f(this, O, Z).call(this, t, s) : f(this, I, K).call(this, i);
630
632
  }
631
633
  }
632
- y = new WeakMap(), F = new WeakMap(), N = new WeakMap(), b = new WeakMap(), x = new WeakMap(), m = new WeakMap(), C = new WeakMap(), R = new WeakMap(), I = new WeakSet(), K = function(t) {
634
+ m = new WeakMap(), F = new WeakMap(), N = new WeakMap(), R = new WeakMap(), x = new WeakMap(), _ = new WeakMap(), C = new WeakMap(), b = new WeakMap(), I = new WeakSet(), K = function(t) {
633
635
  if (!this.php.fileExists(t))
634
636
  return new PHPResponse(
635
637
  404,
@@ -655,8 +657,8 @@ y = new WeakMap(), F = new WeakMap(), N = new WeakMap(), b = new WeakMap(), x =
655
657
  r
656
658
  );
657
659
  }, O = new WeakSet(), Z = async function(t, r) {
658
- var n, i;
659
- if (a(this, R).running > 0 && ((n = t.headers) == null ? void 0 : n["x-request-issuer"]) === "php")
660
+ var n;
661
+ if (l(this, b).running > 0 && ((n = t.headers) == null ? void 0 : n["x-request-issuer"]) === "php")
660
662
  return console.warn(
661
663
  "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."
662
664
  ), new PHPResponse(
@@ -664,34 +666,26 @@ y = new WeakMap(), F = new WeakMap(), N = new WeakMap(), b = new WeakMap(), x =
664
666
  {},
665
667
  new TextEncoder().encode("502 Bad Gateway")
666
668
  );
667
- const s = await a(this, R).acquire();
669
+ const s = await l(this, b).acquire();
668
670
  try {
669
- this.php.addServerGlobalEntry("REMOTE_ADDR", "127.0.0.1"), this.php.addServerGlobalEntry("DOCUMENT_ROOT", a(this, y)), this.php.addServerGlobalEntry(
671
+ this.php.addServerGlobalEntry("REMOTE_ADDR", "127.0.0.1"), this.php.addServerGlobalEntry("DOCUMENT_ROOT", l(this, m)), this.php.addServerGlobalEntry(
670
672
  "HTTPS",
671
- a(this, C).startsWith("https://") ? "on" : ""
673
+ l(this, C).startsWith("https://") ? "on" : ""
672
674
  );
673
- let o = "GET";
674
- const l = {
675
- host: a(this, x),
675
+ let i = "GET";
676
+ const o = {
677
+ host: l(this, x),
676
678
  ...normalizeHeaders(t.headers || {})
677
679
  };
678
- let c = t.body;
679
- if (typeof c == "object" && !(c instanceof Uint8Array)) {
680
- o = "POST";
681
- const { bytes: d, contentType: _ } = await encodeAsMultipart(c);
682
- c = d, l["content-type"] = _;
680
+ let a = t.body;
681
+ if (typeof a == "object" && !(a instanceof Uint8Array)) {
682
+ i = "POST";
683
+ const { bytes: d, contentType: p } = await encodeAsMultipart(a);
684
+ a = d, o["content-type"] = p;
683
685
  }
684
- let h;
686
+ let c;
685
687
  try {
686
- let d = r.pathname;
687
- if ((i = t.headers) != null && i["x-rewrite-url"])
688
- try {
689
- d = new URL(
690
- t.headers["x-rewrite-url"]
691
- ).pathname;
692
- } catch {
693
- }
694
- h = f(this, U, X).call(this, d);
688
+ c = f(this, M, X).call(this, r.pathname);
695
689
  } catch {
696
690
  return new PHPResponse(
697
691
  404,
@@ -702,21 +696,21 @@ y = new WeakMap(), F = new WeakMap(), N = new WeakMap(), b = new WeakMap(), x =
702
696
  return await this.php.run({
703
697
  relativeUri: ensurePathPrefix(
704
698
  toRelativeUrl(r),
705
- a(this, m)
699
+ l(this, _)
706
700
  ),
707
- protocol: a(this, F),
708
- method: t.method || o,
709
- body: c,
710
- scriptPath: h,
711
- headers: l
701
+ protocol: l(this, F),
702
+ method: t.method || i,
703
+ body: a,
704
+ scriptPath: c,
705
+ headers: o
712
706
  });
713
707
  } finally {
714
708
  s();
715
709
  }
716
- }, U = new WeakSet(), X = function(t) {
717
- let r = removePathPrefix(t, a(this, m));
718
- r.includes(".php") ? r = r.split(".php")[0] + ".php" : this.php.isDir(`${a(this, y)}${r}`) ? (r.endsWith("/") || (r = `${r}/`), r = `${r}index.php`) : r = "/index.php";
719
- const s = `${a(this, y)}${r}`;
710
+ }, M = new WeakSet(), X = function(t) {
711
+ let r = removePathPrefix(t, l(this, _));
712
+ r = applyRewriteRules(r, this.rewriteRules), r.includes(".php") ? r = r.split(".php")[0] + ".php" : this.php.isDir(`${l(this, m)}${r}`) ? (r.endsWith("/") || (r = `${r}/`), r = `${r}index.php`) : r = "/index.php";
713
+ const s = `${l(this, m)}${r}`;
720
714
  if (this.php.fileExists(s))
721
715
  return s;
722
716
  throw new Error(`File not found: ${s}`);
@@ -770,6 +764,12 @@ function seemsLikeAPHPFile(e) {
770
764
  function seemsLikeADirectoryRoot(e) {
771
765
  return !e.split("/").pop().includes(".");
772
766
  }
767
+ function applyRewriteRules(e, t) {
768
+ for (const r of t)
769
+ if (new RegExp(r.match).test(e))
770
+ return e.replace(r.match, r.replacement);
771
+ return e;
772
+ }
773
773
  const FileErrorCodes = {
774
774
  0: "No error occurred. System call completed successfully.",
775
775
  1: "Argument list too long.",
@@ -860,15 +860,15 @@ function rethrowFileSystemError(e = "") {
860
860
  n.value = function(...o) {
861
861
  try {
862
862
  return i.apply(this, o);
863
- } catch (l) {
864
- const c = typeof l == "object" ? l == null ? void 0 : l.errno : null;
863
+ } catch (a) {
864
+ const c = typeof a == "object" ? a == null ? void 0 : a.errno : null;
865
865
  if (c in FileErrorCodes) {
866
- const h = FileErrorCodes[c], d = typeof o[0] == "string" ? o[0] : null, _ = d !== null ? e.replaceAll("{path}", d) : e;
867
- throw new Error(`${_}: ${h}`, {
868
- cause: l
866
+ const d = FileErrorCodes[c], p = typeof o[0] == "string" ? o[0] : null, P = p !== null ? e.replaceAll("{path}", p) : e;
867
+ throw new Error(`${P}: ${d}`, {
868
+ cause: a
869
869
  });
870
870
  }
871
- throw l;
871
+ throw a;
872
872
  }
873
873
  };
874
874
  };
@@ -887,7 +887,7 @@ var __defProp = Object.defineProperty, __getOwnPropDesc = Object.getOwnPropertyD
887
887
  return s && n && __defProp(t, r, n), n;
888
888
  };
889
889
  const STRING = "string", NUMBER = "number", __private__dont__use = Symbol("__private__dont__use");
890
- var S, k, A, E, g, P, w, H, M, ee, B, te, L, re, D, se, $, ne, q, ie, W, oe, j, ae, z, le, G, ce, J, ue, Q, de;
890
+ var S, k, A, y, w, g, E, H, U, ee, B, te, L, re, D, se, $, ne, q, ie, W, oe, j, ae, z, le, G, ce, J, ue, Q, de;
891
891
  class BasePHP {
892
892
  /**
893
893
  * Initializes a PHP runtime.
@@ -897,7 +897,7 @@ class BasePHP {
897
897
  * @param serverOptions - Optional. Options for the PHPRequestHandler. If undefined, no request handler will be initialized.
898
898
  */
899
899
  constructor(e, t) {
900
- u(this, M);
900
+ u(this, U);
901
901
  u(this, B);
902
902
  u(this, L);
903
903
  u(this, D);
@@ -912,31 +912,31 @@ class BasePHP {
912
912
  u(this, S, void 0);
913
913
  u(this, k, void 0);
914
914
  u(this, A, void 0);
915
- u(this, E, void 0);
916
- u(this, g, void 0);
917
- u(this, P, void 0);
915
+ u(this, y, void 0);
918
916
  u(this, w, void 0);
917
+ u(this, g, void 0);
918
+ u(this, E, void 0);
919
919
  u(this, H, void 0);
920
- p(this, S, []), p(this, E, !1), p(this, g, null), p(this, P, {}), p(this, w, /* @__PURE__ */ new Map()), p(this, H, []), this.semaphore = new Semaphore({ concurrency: 1 }), e !== void 0 && this.initializeRuntime(e), t && (this.requestHandler = new PHPBrowser(
920
+ h(this, S, []), h(this, y, !1), h(this, w, null), h(this, g, {}), h(this, E, /* @__PURE__ */ new Map()), h(this, H, []), this.semaphore = new Semaphore({ concurrency: 1 }), e !== void 0 && this.initializeRuntime(e), t && (this.requestHandler = new PHPBrowser(
921
921
  new PHPRequestHandler(this, t)
922
922
  ));
923
923
  }
924
924
  addEventListener(e, t) {
925
- a(this, w).has(e) || a(this, w).set(e, /* @__PURE__ */ new Set()), a(this, w).get(e).add(t);
925
+ l(this, E).has(e) || l(this, E).set(e, /* @__PURE__ */ new Set()), l(this, E).get(e).add(t);
926
926
  }
927
927
  removeEventListener(e, t) {
928
928
  var r;
929
- (r = a(this, w).get(e)) == null || r.delete(t);
929
+ (r = l(this, E).get(e)) == null || r.delete(t);
930
930
  }
931
931
  dispatchEvent(e) {
932
- const t = a(this, w).get(e.type);
932
+ const t = l(this, E).get(e.type);
933
933
  if (t)
934
934
  for (const r of t)
935
935
  r(e);
936
936
  }
937
937
  /** @inheritDoc */
938
938
  async onMessage(e) {
939
- a(this, H).push(e);
939
+ l(this, H).push(e);
940
940
  }
941
941
  /** @inheritDoc */
942
942
  async setSpawnHandler(handler) {
@@ -967,13 +967,13 @@ class BasePHP {
967
967
  if (!t)
968
968
  throw new Error("Invalid PHP runtime id.");
969
969
  this[__private__dont__use] = t, t.onMessage = async (r) => {
970
- for (const s of a(this, H)) {
970
+ for (const s of l(this, H)) {
971
971
  const n = await s(r);
972
972
  if (n)
973
973
  return n;
974
974
  }
975
975
  return "";
976
- }, p(this, g, improveWASMErrorReporting(t)), this.dispatchEvent({
976
+ }, h(this, w, improveWASMErrorReporting(t)), this.dispatchEvent({
977
977
  type: "runtime.initialized"
978
978
  });
979
979
  }
@@ -988,13 +988,13 @@ class BasePHP {
988
988
  throw new Error(
989
989
  "Could not set SAPI name. This can only be done before the PHP WASM module is initialized.Did you already dispatch any requests?"
990
990
  );
991
- p(this, A, e);
991
+ h(this, A, e);
992
992
  }
993
993
  /** @inheritDoc */
994
994
  setPhpIniPath(e) {
995
- if (a(this, E))
995
+ if (l(this, y))
996
996
  throw new Error("Cannot set PHP ini path after calling run().");
997
- p(this, k, e), this[__private__dont__use].ccall(
997
+ h(this, k, e), this[__private__dont__use].ccall(
998
998
  "wasm_set_phpini_path",
999
999
  null,
1000
1000
  ["string"],
@@ -1003,9 +1003,9 @@ class BasePHP {
1003
1003
  }
1004
1004
  /** @inheritDoc */
1005
1005
  setPhpIniEntry(e, t) {
1006
- if (a(this, E))
1006
+ if (l(this, y))
1007
1007
  throw new Error("Cannot set PHP ini entries after calling run().");
1008
- a(this, S).push([e, t]);
1008
+ l(this, S).push([e, t]);
1009
1009
  }
1010
1010
  /** @inheritDoc */
1011
1011
  chdir(e) {
@@ -1022,7 +1022,7 @@ class BasePHP {
1022
1022
  const t = await this.semaphore.acquire();
1023
1023
  let r;
1024
1024
  try {
1025
- if (a(this, E) || (f(this, M, ee).call(this), p(this, E, !0)), e.scriptPath && !this.fileExists(e.scriptPath))
1025
+ if (l(this, y) || (f(this, U, ee).call(this), h(this, y, !0)), e.scriptPath && !this.fileExists(e.scriptPath))
1026
1026
  throw new Error(
1027
1027
  `The script path "${e.scriptPath}" does not exist.`
1028
1028
  );
@@ -1030,21 +1030,28 @@ class BasePHP {
1030
1030
  const s = normalizeHeaders(e.headers || {}), n = s.host || "example.com:443";
1031
1031
  f(this, D, se).call(this, n, e.protocol || "http"), f(this, q, ie).call(this, s), e.body && (r = f(this, W, oe).call(this, e.body)), typeof e.code == "string" && f(this, J, ue).call(this, " ?>" + e.code), f(this, z, le).call(this);
1032
1032
  const i = e.env || {};
1033
- for (const l in i)
1034
- f(this, G, ce).call(this, l, i[l]);
1033
+ for (const a in i)
1034
+ f(this, G, ce).call(this, a, i[a]);
1035
1035
  const o = await f(this, Q, de).call(this);
1036
- if (e.throwOnError && o.exitCode !== 0) {
1037
- const l = {
1036
+ if (o.exitCode !== 0) {
1037
+ const a = {
1038
1038
  stdout: o.text,
1039
1039
  stderr: o.errors
1040
1040
  };
1041
- console.warn("PHP.run() output was:", l);
1041
+ console.warn("PHP.run() output was:", a);
1042
1042
  const c = new Error(
1043
1043
  `PHP.run() failed with exit code ${o.exitCode} and the following output: ` + o.errors
1044
1044
  );
1045
- throw c.output = l, console.error(c), c;
1045
+ throw c.output = a, c.source = "request", console.error(c), c;
1046
1046
  }
1047
1047
  return o;
1048
+ } catch (s) {
1049
+ throw this.dispatchEvent({
1050
+ type: "request.error",
1051
+ error: s,
1052
+ // Distinguish between PHP request and PHP-wasm errors
1053
+ source: s.source ?? "php-wasm"
1054
+ }), s;
1048
1055
  } finally {
1049
1056
  try {
1050
1057
  r && this[__private__dont__use].free(r);
@@ -1056,7 +1063,7 @@ class BasePHP {
1056
1063
  }
1057
1064
  }
1058
1065
  addServerGlobalEntry(e, t) {
1059
- a(this, P)[e] = t;
1066
+ l(this, g)[e] = t;
1060
1067
  }
1061
1068
  defineConstant(e, t) {
1062
1069
  let r = {};
@@ -1152,7 +1159,7 @@ class BasePHP {
1152
1159
  this.exit();
1153
1160
  } catch {
1154
1161
  }
1155
- if (this.initializeRuntime(e), a(this, k) && this.setPhpIniPath(a(this, k)), a(this, A) && this.setSapiName(a(this, A)), this.requestHandler) {
1162
+ if (this.initializeRuntime(e), l(this, k) && this.setPhpIniPath(l(this, k)), l(this, A) && this.setSapiName(l(this, A)), this.requestHandler) {
1156
1163
  const r = this.documentRoot;
1157
1164
  copyFS(t, this[__private__dont__use].FS, r);
1158
1165
  }
@@ -1165,10 +1172,10 @@ class BasePHP {
1165
1172
  this[__private__dont__use]._exit(e);
1166
1173
  } catch {
1167
1174
  }
1168
- p(this, E, !1), p(this, g, null), delete this[__private__dont__use].onMessage, delete this[__private__dont__use];
1175
+ h(this, y, !1), h(this, w, null), delete this[__private__dont__use].onMessage, delete this[__private__dont__use];
1169
1176
  }
1170
1177
  }
1171
- S = new WeakMap(), k = new WeakMap(), A = new WeakMap(), E = new WeakMap(), g = new WeakMap(), P = new WeakMap(), w = new WeakMap(), H = new WeakMap(), M = new WeakSet(), ee = function() {
1178
+ S = new WeakMap(), k = new WeakMap(), A = new WeakMap(), y = new WeakMap(), w = new WeakMap(), g = new WeakMap(), E = new WeakMap(), H = new WeakMap(), U = new WeakSet(), ee = function() {
1172
1179
  if (this.setPhpIniEntry("auto_prepend_file", "/internal/consts.php"), this.fileExists("/internal/consts.php") || this.writeFile(
1173
1180
  "/internal/consts.php",
1174
1181
  `<?php
@@ -1180,8 +1187,8 @@ S = new WeakMap(), k = new WeakMap(), A = new WeakMap(), E = new WeakMap(), g =
1180
1187
  }
1181
1188
  }
1182
1189
  }`
1183
- ), a(this, S).length > 0) {
1184
- const e = a(this, S).map(([t, r]) => `${t}=${r}`).join(`
1190
+ ), l(this, S).length > 0) {
1191
+ const e = l(this, S).map(([t, r]) => `${t}=${r}`).join(`
1185
1192
  `) + `
1186
1193
 
1187
1194
  `;
@@ -1305,12 +1312,12 @@ S = new WeakMap(), k = new WeakMap(), A = new WeakMap(), E = new WeakMap(), g =
1305
1312
  [e]
1306
1313
  );
1307
1314
  }, z = new WeakSet(), le = function() {
1308
- for (const e in a(this, P))
1315
+ for (const e in l(this, g))
1309
1316
  this[__private__dont__use].ccall(
1310
1317
  "wasm_add_SERVER_entry",
1311
1318
  null,
1312
1319
  [STRING, STRING],
1313
- [e, a(this, P)[e]]
1320
+ [e, l(this, g)[e]]
1314
1321
  );
1315
1322
  }, G = new WeakSet(), ce = function(e, t) {
1316
1323
  this[__private__dont__use].ccall(
@@ -1332,35 +1339,35 @@ S = new WeakMap(), k = new WeakMap(), A = new WeakMap(), E = new WeakMap(), g =
1332
1339
  try {
1333
1340
  e = await new Promise((i, o) => {
1334
1341
  var c;
1335
- t = (h) => {
1336
- console.error(h), console.error(h.error);
1337
- const d = new Error("Rethrown");
1338
- d.cause = h.error, d.betterMessage = h.message, o(d);
1339
- }, (c = a(this, g)) == null || c.addEventListener(
1342
+ t = (d) => {
1343
+ console.error(d), console.error(d.error);
1344
+ const p = new Error("Rethrown");
1345
+ p.cause = d.error, p.betterMessage = d.message, o(p);
1346
+ }, (c = l(this, w)) == null || c.addEventListener(
1340
1347
  "error",
1341
1348
  t
1342
1349
  );
1343
- const l = this[__private__dont__use].ccall(
1350
+ const a = this[__private__dont__use].ccall(
1344
1351
  "wasm_sapi_handle_request",
1345
1352
  NUMBER,
1346
1353
  [],
1347
1354
  [],
1348
1355
  { async: !0 }
1349
1356
  );
1350
- return l instanceof Promise ? l.then(i, o) : i(l);
1357
+ return a instanceof Promise ? a.then(i, o) : i(a);
1351
1358
  });
1352
1359
  } catch (i) {
1353
- for (const h in this)
1354
- typeof this[h] == "function" && (this[h] = () => {
1360
+ for (const d in this)
1361
+ typeof this[d] == "function" && (this[d] = () => {
1355
1362
  throw new Error(
1356
1363
  "PHP runtime has crashed – see the earlier error for details."
1357
1364
  );
1358
1365
  });
1359
1366
  this.functionsMaybeMissingFromAsyncify = getFunctionsMaybeMissingFromAsyncify();
1360
- const o = i, l = "betterMessage" in o ? o.betterMessage : o.message, c = new Error(l);
1367
+ const o = i, a = "betterMessage" in o ? o.betterMessage : o.message, c = new Error(a);
1361
1368
  throw c.cause = o, console.error(c), c;
1362
1369
  } finally {
1363
- (n = a(this, g)) == null || n.removeEventListener("error", t), p(this, P, {});
1370
+ (n = l(this, w)) == null || n.removeEventListener("error", t), h(this, g, {});
1364
1371
  }
1365
1372
  const { headers: r, httpStatusCode: s } = f(this, B, te).call(this);
1366
1373
  return new PHPResponse(
@@ -1429,32 +1436,32 @@ function journalFSEvents(e, t, r = () => {
1429
1436
  }) {
1430
1437
  function s() {
1431
1438
  t = normalizePath(t);
1432
- const i = e[__private__dont__use].FS, o = createFSHooks(i, (d) => {
1433
- if (d.path.startsWith(t))
1434
- r(d);
1435
- else if (d.operation === "RENAME" && d.toPath.startsWith(t))
1436
- for (const _ of recordExistingPath(
1439
+ const i = e[__private__dont__use].FS, o = createFSHooks(i, (p) => {
1440
+ if (p.path.startsWith(t))
1441
+ r(p);
1442
+ else if (p.operation === "RENAME" && p.toPath.startsWith(t))
1443
+ for (const P of recordExistingPath(
1437
1444
  e,
1438
- d.path,
1439
- d.toPath
1445
+ p.path,
1446
+ p.toPath
1440
1447
  ))
1441
- r(_);
1442
- }), l = {};
1443
- for (const [d] of Object.entries(o))
1444
- l[d] = i[d];
1448
+ r(P);
1449
+ }), a = {};
1450
+ for (const [p] of Object.entries(o))
1451
+ a[p] = i[p];
1445
1452
  function c() {
1446
- for (const [d, _] of Object.entries(o))
1447
- i[d] = function(...V) {
1448
- return _(...V), l[d].apply(this, V);
1453
+ for (const [p, P] of Object.entries(o))
1454
+ i[p] = function(...V) {
1455
+ return P(...V), a[p].apply(this, V);
1449
1456
  };
1450
1457
  }
1451
- function h() {
1452
- for (const [d, _] of Object.entries(l))
1453
- e[__private__dont__use].FS[d] = _;
1458
+ function d() {
1459
+ for (const [p, P] of Object.entries(a))
1460
+ e[__private__dont__use].FS[p] = P;
1454
1461
  }
1455
1462
  e[__private__dont__use].journal = {
1456
1463
  bind: c,
1457
- unbind: h
1464
+ unbind: d
1458
1465
  }, c();
1459
1466
  }
1460
1467
  e.addEventListener("runtime.initialized", s), e[__private__dont__use] && s();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@php-wasm/fs-journal",
3
- "version": "0.6.7",
3
+ "version": "0.6.9",
4
4
  "description": "Bindings to journal the PHP filesystem",
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": "c4c52563eee8997b94cd4a0875e10fb5d8ccda42",
39
+ "gitHead": "f6b98ad6d05617ee8cb1234c21318fdde17a6e56",
40
40
  "engines": {
41
41
  "node": ">=18.18.2",
42
42
  "npm": ">=8.11.0"