@php-wasm/fs-journal 0.6.2 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs +9 -5
- package/index.js +261 -281
- package/package.json +2 -2
package/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var Y=(e,t,r)=>{if(!t.has(e))throw TypeError("Cannot "+r)};var o=(e,t,r)=>(Y(e,t,"read from private field"),r?r.call(e):t.get(e)),l=(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"});if(typeof File>"u"){class e extends Blob{constructor(r,s,n){super(r);let i;n!=null&&n.lastModified&&(i=new Date),(!i||isNaN(i.getFullYear()))&&(i=new Date),this.lastModifiedDate=i,this.lastModified=i.getMilliseconds(),this.name=s||""}}global.File=e}function asPromise(e){return new Promise(function(t,r){e.onload=e.onerror=function(s){e.onload=e.onerror=null,s.type==="load"?t(e.result):r(new Error("Failed to read the blob/file"))}})}typeof Blob.prototype.arrayBuffer>"u"&&(Blob.prototype.arrayBuffer=function(){const t=new FileReader;return t.readAsArrayBuffer(this),asPromise(t)});typeof Blob.prototype.text>"u"&&(Blob.prototype.text=function(){const t=new FileReader;return t.readAsText(this),asPromise(t)});function isByobSupported(){const e=new Uint8Array([1,2,3,4]),r=new File([e],"test").stream();try{return r.getReader({mode:"byob"}),!0}catch{return!1}}(typeof Blob.prototype.stream>"u"||!isByobSupported())&&(Blob.prototype.stream=function(){let e=0;const t=this;return new ReadableStream({type:"bytes",autoAllocateChunkSize:512*1024,async pull(r){const s=r.byobRequest.view,i=await t.slice(e,e+s.byteLength).arrayBuffer(),a=new Uint8Array(i);new Uint8Array(s.buffer).set(a);const c=a.byteLength;r.byobRequest.respond(c),e+=c,e>=t.size&&r.close()}})});if(typeof CustomEvent>"u"){class e extends Event{constructor(r,s={}){super(r,s),this.detail=s.detail}initCustomEvent(){}}globalThis.CustomEvent=e}const kError=Symbol("error"),kMessage=Symbol("message");class ErrorEvent2 extends Event{constructor(t,r={}){super(t),this[kError]=r.error===void 0?null:r.error,this[kMessage]=r.message===void 0?"":r.message}get error(){return this[kError]}get message(){return this[kMessage]}}Object.defineProperty(ErrorEvent2.prototype,"error",{enumerable:!0});Object.defineProperty(ErrorEvent2.prototype,"message",{enumerable:!0});const ErrorEvent=typeof globalThis.ErrorEvent=="function"?globalThis.ErrorEvent:ErrorEvent2;function isExitCodeZero(e){return e instanceof Error?"exitCode"in e&&(e==null?void 0:e.exitCode)===0||(e==null?void 0:e.name)==="ExitStatus"&&"status"in e&&e.status===0:!1}class UnhandledRejectionsTarget extends EventTarget{constructor(){super(...arguments),this.listenersCount=0}addEventListener(t,r){++this.listenersCount,super.addEventListener(t,r)}removeEventListener(t,r){--this.listenersCount,super.removeEventListener(t,r)}hasListeners(){return this.listenersCount>0}}function improveWASMErrorReporting(e){e.asm={...e.asm};const t=new UnhandledRejectionsTarget;for(const r in e.asm)if(typeof e.asm[r]=="function"){const s=e.asm[r];e.asm[r]=function(...n){var i;try{return s(...n)}catch(a){if(!(a instanceof Error))throw a;const c=clarifyErrorMessage(a,(i=e.lastAsyncifyStackSource)==null?void 0:i.stack);if(e.lastAsyncifyStackSource&&(a.cause=e.lastAsyncifyStackSource),t.hasListeners()){t.dispatchEvent(new ErrorEvent("error",{error:a,message:c}));return}throw isExitCodeZero(a)||showCriticalErrorBox(c),a}}}return t}let functionsMaybeMissingFromAsyncify=[];function getFunctionsMaybeMissingFromAsyncify(){return functionsMaybeMissingFromAsyncify}function clarifyErrorMessage(e,t){if(e.message==="unreachable"){let r=UNREACHABLE_ERROR;t||(r+=`
|
|
2
2
|
|
|
3
3
|
This stack trace is lacking. For a better one initialize
|
|
4
4
|
the PHP runtime with { debug: true }, e.g. PHPNode.load('8.1', { debug: true }).
|
|
@@ -32,9 +32,13 @@ CLI option:
|
|
|
32
32
|
${eol}
|
|
33
33
|
${bold} WASM ERROR${reset}${redBg}`);for(const t of e.split(`
|
|
34
34
|
`))console.log(`${eol} ${t} `);console.log(`${reset}`)}}function extractPHPFunctionsFromStack(e){try{const t=e.split(`
|
|
35
|
-
`).slice(1).map(r=>{const s=r.trim().substring(3).split(" ");return{fn:s.length>=2?s[0]:"<unknown>",isWasm:r.includes("wasm://")}}).filter(({fn:r,isWasm:s})=>s&&!r.startsWith("dynCall_")&&!r.startsWith("invoke_")).map(({fn:r})=>r);return Array.from(new Set(t))}catch{return[]}}class Semaphore{constructor({concurrency:t}){this._running=0,this.concurrency=t,this.queue=[]}get running(){return this._running}async acquire(){for(;;)if(this._running>=this.concurrency)await new Promise(t=>this.queue.push(t));else{this._running++;let t=!1;return()=>{t||(t=!0,this._running--,this.queue.length>0&&this.queue.shift()())}}}async run(t){const r=await this.acquire();try{return await t()}finally{r()}}}function joinPaths(...e){let t=e.join("/");const r=t[0]==="/",s=t.substring(t.length-1)==="/";return t=normalizePath$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
|
|
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 createSpawnHandler(e){return function(t){const r=new ChildProcess,s=new ProcessApi(r);return setTimeout(async()=>{await e(t,s),r.emit("spawn",!0)}),r}}class EventEmitter{constructor(){this.listeners={}}emit(t,r){this.listeners[t]&&this.listeners[t].forEach(function(s){s(r)})}on(t,r){this.listeners[t]||(this.listeners[t]=[]),this.listeners[t].push(r)}}class ProcessApi extends EventEmitter{constructor(t){super(),this.childProcess=t,this.exited=!1,this.stdinData=[],t.on("stdin",r=>{this.stdinData?this.stdinData.push(r.slice()):this.emit("stdin",r)})}stdout(t){typeof t=="string"&&(t=new TextEncoder().encode(t)),this.childProcess.stdout.emit("data",t)}stderr(t){typeof t=="string"&&(t=new TextEncoder().encode(t)),this.childProcess.stderr.emit("data",t)}exit(t){this.exited||(this.exited=!0,this.childProcess.emit("exit",t))}flushStdin(){if(this.stdinData)for(let t=0;t<this.stdinData.length;t++)this.emit("stdin",this.stdinData[t]);this.stdinData=null}}let lastPid=9743;class ChildProcess extends EventEmitter{constructor(t=lastPid++){super(),this.pid=t,this.stdout=new EventEmitter,this.stderr=new EventEmitter;const r=this;this.stdin={write:s=>{r.emit("stdin",s)}}}}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={}){l(this,v,void 0);l(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"]),o(this,T).handleRedirects&&s.headers.location&&r<o(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];o(this,v)[n]=i}catch(s){console.error(s)}}serializeCookies(){const t=[];for(const r in o(this,v))t.push(`${r}=${o(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[d,p]of Object.entries(e))n.push(`--${t}\r
|
|
36
|
+
`),n.push(`Content-Disposition: form-data; name="${d}"`),p instanceof File&&n.push(`; filename="${p.name}"`),n.push(`\r
|
|
37
|
+
`),p instanceof File&&n.push("Content-Type: application/octet-stream"),n.push(`\r
|
|
36
38
|
\r
|
|
37
|
-
`),c=n.substring(0,o).trim(),h=n.substring(o+4).trim(),f=c.match(/name="([^"]+)"/);if(f){const u=f[1];t[u]=h}}),t}function inferMimeType(e){switch(e.split(".").pop()){case"css":return"text/css";case"js":return"application/javascript";case"png":return"image/png";case"jpg":case"jpeg":return"image/jpeg";case"gif":return"image/gif";case"svg":return"image/svg+xml";case"woff":return"font/woff";case"woff2":return"font/woff2";case"ttf":return"font/ttf";case"otf":return"font/otf";case"eot":return"font/eot";case"ico":return"image/x-icon";case"html":return"text/html";case"json":return"application/json";case"xml":return"application/xml";case"txt":case"md":return"text/plain";default:return"application-octet-stream"}}function seemsLikeAPHPRequestHandlerPath(e){return seemsLikeAPHPFile(e)||seemsLikeADirectoryRoot(e)}function seemsLikeAPHPFile(e){return e.endsWith(".php")||e.includes(".php/")}function seemsLikeADirectoryRoot(e){return!e.split("/").pop().includes(".")}const FileErrorCodes={0:"No error occurred. System call completed successfully.",1:"Argument list too long.",2:"Permission denied.",3:"Address in use.",4:"Address not available.",5:"Address family not supported.",6:"Resource unavailable, or operation would block.",7:"Connection already in progress.",8:"Bad file descriptor.",9:"Bad message.",10:"Device or resource busy.",11:"Operation canceled.",12:"No child processes.",13:"Connection aborted.",14:"Connection refused.",15:"Connection reset.",16:"Resource deadlock would occur.",17:"Destination address required.",18:"Mathematics argument out of domain of function.",19:"Reserved.",20:"File exists.",21:"Bad address.",22:"File too large.",23:"Host is unreachable.",24:"Identifier removed.",25:"Illegal byte sequence.",26:"Operation in progress.",27:"Interrupted function.",28:"Invalid argument.",29:"I/O error.",30:"Socket is connected.",31:"There is a directory under that path.",32:"Too many levels of symbolic links.",33:"File descriptor value too large.",34:"Too many links.",35:"Message too large.",36:"Reserved.",37:"Filename too long.",38:"Network is down.",39:"Connection aborted by network.",40:"Network unreachable.",41:"Too many files open in system.",42:"No buffer space available.",43:"No such device.",44:"There is no such file or directory OR the parent directory does not exist.",45:"Executable file format error.",46:"No locks available.",47:"Reserved.",48:"Not enough space.",49:"No message of the desired type.",50:"Protocol not available.",51:"No space left on device.",52:"Function not supported.",53:"The socket is not connected.",54:"Not a directory or a symbolic link to a directory.",55:"Directory not empty.",56:"State not recoverable.",57:"Not a socket.",58:"Not supported, or operation not supported on socket.",59:"Inappropriate I/O control operation.",60:"No such device or address.",61:"Value too large to be stored in data type.",62:"Previous owner died.",63:"Operation not permitted.",64:"Broken pipe.",65:"Protocol error.",66:"Protocol not supported.",67:"Protocol wrong type for socket.",68:"Result too large.",69:"Read-only file system.",70:"Invalid seek.",71:"No such process.",72:"Reserved.",73:"Connection timed out.",74:"Text file busy.",75:"Cross-device link.",76:"Extension: Capabilities insufficient."};function getEmscriptenFsError(e){const t=typeof e=="object"?e==null?void 0:e.errno:null;if(t in FileErrorCodes)return FileErrorCodes[t]}function rethrowFileSystemError(e=""){return function(r,s,i){const n=i.value;i.value=function(...o){try{return n.apply(this,o)}catch(c){const h=typeof c=="object"?c==null?void 0:c.errno:null;if(h in FileErrorCodes){const f=FileErrorCodes[h],u=typeof o[0]=="string"?o[0]:null,_=u!==null?e.replaceAll("{path}",u):e;throw new Error(`${_}: ${f}`,{cause:c})}throw c}}}}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 i=s>1?void 0:s?__getOwnPropDesc(t,r):t,n=e.length-1,o;n>=0;n--)(o=e[n])&&(i=(s?o(t,r,i):o(i))||i);return s&&i&&__defProp(t,r,i),i};const STRING="string",NUMBER="number",__private__dont__use=Symbol("__private__dont__use");var T,H,A,w,P,v,g,I,U,te,D,re,$,se,q,ne,W,ie,j,oe,z,ae,G,le,J,ce,Y,ue,V,de,K,he;class BasePHP{constructor(e,t){l(this,U);l(this,D);l(this,$);l(this,q);l(this,W);l(this,j);l(this,z);l(this,G);l(this,J);l(this,Y);l(this,V);l(this,K);l(this,T,void 0);l(this,H,void 0);l(this,A,void 0);l(this,w,void 0);l(this,P,void 0);l(this,v,void 0);l(this,g,void 0);l(this,I,void 0);d(this,T,[]),d(this,w,!1),d(this,P,null),d(this,v,{}),d(this,g,new Map),d(this,I,[]),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,g).has(e)||a(this,g).set(e,new Set),a(this,g).get(e).add(t)}removeEventListener(e,t){var r;(r=a(this,g).get(e))==null||r.delete(t)}dispatchEvent(e){const t=a(this,g).get(e.type);if(t)for(const r of t)r(e)}async onMessage(e){a(this,I).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,I)){const i=await s(r);if(i)return i}return""},d(this,P,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?");d(this,A,e)}setPhpIniPath(e){if(a(this,w))throw new Error("Cannot set PHP ini path after calling run().");d(this,H,e),this[__private__dont__use].ccall("wasm_set_phpini_path",null,["string"],[e])}setPhpIniEntry(e,t){if(a(this,w))throw new Error("Cannot set PHP ini entries after calling run().");a(this,T).push([e,t])}chdir(e){this[__private__dont__use].FS.chdir(e)}async request(e,t){if(!this.requestHandler)throw new Error("No request handler available.");return this.requestHandler.request(e,t)}async run(e){const t=await this.semaphore.acquire();let r;try{a(this,w)||(p(this,U,te).call(this),d(this,w,!0)),p(this,G,le).call(this,e.scriptPath||""),p(this,$,se).call(this,e.relativeUri||""),p(this,W,ie).call(this,e.method||"GET");const s=normalizeHeaders(e.headers||{}),i=s.host||"example.com:443";if(p(this,q,ne).call(this,i,e.protocol||"http"),p(this,j,oe).call(this,s),e.body&&(r=p(this,z,ae).call(this,e.body)),e.fileInfos)for(const o of e.fileInfos)p(this,Y,ue).call(this,o);typeof e.code=="string"&&p(this,V,de).call(this," ?>"+e.code),p(this,J,ce).call(this);const n=await p(this,K,he).call(this);if(e.throwOnError&&n.exitCode!==0){const o={stdout:n.text,stderr:n.errors};console.warn("PHP.run() output was:",o);const c=new Error(`PHP.run() failed with exit code ${n.exitCode} and the following output`);throw c.output=o,c}return n}finally{try{r&&this[__private__dont__use].free(r)}finally{t(),this.dispatchEvent({type:"request.end"})}}}addServerGlobalEntry(e,t){a(this,v)[e]=t}defineConstant(e,t){let r={};try{r=JSON.parse(this.fileExists("/tmp/consts.json")&&this.readFileAsText("/tmp/consts.json")||"{}")}catch{}this.writeFile("/tmp/consts.json",JSON.stringify({...r,[e]:t}))}mkdir(e){this[__private__dont__use].FS.mkdirTree(e)}mkdirTree(e){this.mkdir(e)}readFileAsText(e){return new TextDecoder().decode(this.readFileAsBuffer(e))}readFileAsBuffer(e){return this[__private__dont__use].FS.readFile(e)}writeFile(e,t){this[__private__dont__use].FS.writeFile(e,t)}unlink(e){this[__private__dont__use].FS.unlink(e)}mv(e,t){try{this[__private__dont__use].FS.rename(e,t)}catch(r){const s=getEmscriptenFsError(r);throw s?new Error(`Could not move ${e} to ${t}: ${s}`,{cause:r}):r}}rmdir(e,t={recursive:!0}){t!=null&&t.recursive&&this.listFiles(e).forEach(r=>{const s=`${e}/${r}`;this.isDir(s)?this.rmdir(s,t):this.unlink(s)}),this[__private__dont__use].FS.rmdir(e)}listFiles(e,t={prependPath:!1}){if(!this.fileExists(e))return[];try{const r=this[__private__dont__use].FS.readdir(e).filter(s=>s!=="."&&s!=="..");if(t.prependPath){const s=e.replace(/\/$/,"");return r.map(i=>`${s}/${i}`)}return r}catch(r){return console.error(r,{path:e}),[]}}isDir(e){return this.fileExists(e)?this[__private__dont__use].FS.isDir(this[__private__dont__use].FS.lookupPath(e).node.mode):!1}fileExists(e){try{return this[__private__dont__use].FS.lookupPath(e),!0}catch{return!1}}hotSwapPHPRuntime(e){const t=this[__private__dont__use].FS;try{this.exit()}catch{}if(this.initializeRuntime(e),a(this,H)&&this.setPhpIniPath(a(this,H)),a(this,A)&&this.setSapiName(a(this,A)),this.requestHandler){const r=this.documentRoot;recreateMemFS(this[__private__dont__use].FS,t,r)}}exit(e=0){this.dispatchEvent({type:"runtime.beforedestroy"});try{this[__private__dont__use]._exit(e)}catch{}d(this,w,!1),d(this,P,null),delete this[__private__dont__use].onMessage,delete this[__private__dont__use]}}T=new WeakMap,H=new WeakMap,A=new WeakMap,w=new WeakMap,P=new WeakMap,v=new WeakMap,g=new WeakMap,I=new WeakMap,U=new WeakSet,te=function(){if(this.setPhpIniEntry("auto_prepend_file","/tmp/consts.php"),this.fileExists("/tmp/consts.php")||this.writeFile("/tmp/consts.php",`<?php
|
|
39
|
+
`),p instanceof File?n.push(await fileToUint8Array(p)):n.push(p),n.push(`\r
|
|
40
|
+
`);n.push(`--${t}--\r
|
|
41
|
+
`);const i=n.reduce((d,p)=>d+p.length,0),a=new Uint8Array(i);let c=0;for(const d of n)a.set(typeof d=="string"?s.encode(d):d,c),c+=d.length;return{bytes:a,contentType:r}}function fileToUint8Array(e){return new Promise(t=>{const r=new FileReader;r.onload=()=>{t(new Uint8Array(r.result))},r.readAsArrayBuffer(e)})}var w,F,I,b,x,m,C,R,M,K,N,Z,B,Q;class PHPRequestHandler{constructor(t,r={}){l(this,M);l(this,N);l(this,B);l(this,w,void 0);l(this,F,void 0);l(this,I,void 0);l(this,b,void 0);l(this,x,void 0);l(this,m,void 0);l(this,C,void 0);l(this,R,void 0);h(this,R,new Semaphore({concurrency:1}));const{documentRoot:s="/www/",absoluteUrl:n=typeof location=="object"?location==null?void 0:location.href:""}=r;this.php=t,h(this,w,s);const i=new URL(n);h(this,I,i.hostname),h(this,b,i.port?Number(i.port):i.protocol==="https:"?443:80),h(this,F,(i.protocol||"").replace(":",""));const a=o(this,b)!==443&&o(this,b)!==80;h(this,x,[o(this,I),a?`:${o(this,b)}`:""].join("")),h(this,m,i.pathname.replace(/\/+$/,"")),h(this,C,[`${o(this,F)}://`,o(this,x),o(this,m)].join(""))}pathToInternalUrl(t){return`${this.absoluteUrl}${t}`}internalUrlToPath(t){const r=new URL(t);return r.pathname.startsWith(o(this,m))&&(r.pathname=r.pathname.slice(o(this,m).length)),toRelativeUrl(r)}get isRequestRunning(){return o(this,R).running>0}get absoluteUrl(){return o(this,C)}get documentRoot(){return o(this,w)}async request(t){const r=t.url.startsWith("http://")||t.url.startsWith("https://"),s=new URL(t.url,r?void 0:DEFAULT_BASE_URL),n=removePathPrefix(s.pathname,o(this,m)),i=`${o(this,w)}${n}`;return seemsLikeAPHPRequestHandlerPath(i)?await f(this,N,Z).call(this,t,s):f(this,M,K).call(this,i)}}w=new WeakMap,F=new WeakMap,I=new WeakMap,b=new WeakMap,x=new WeakMap,m=new WeakMap,C=new WeakMap,R=new WeakMap,M=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)},N=new WeakSet,Z=async function(t,r){var n,i;if(o(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 o(this,R).acquire();try{this.php.addServerGlobalEntry("REMOTE_ADDR","127.0.0.1"),this.php.addServerGlobalEntry("DOCUMENT_ROOT",o(this,w)),this.php.addServerGlobalEntry("HTTPS",o(this,C).startsWith("https://")?"on":"");let a="GET";const c={host:o(this,x),...normalizeHeaders(t.headers||{})};let d=t.body;if(typeof d=="object"&&!(d instanceof Uint8Array)){a="POST";const{bytes:u,contentType:_}=await encodeAsMultipart(d);d=u,c["content-type"]=_}let p;try{let u=r.pathname;if((i=t.headers)!=null&&i["x-rewrite-url"])try{u=new URL(t.headers["x-rewrite-url"]).pathname}catch{}p=f(this,B,Q).call(this,u)}catch{return new PHPResponse(404,{},new TextEncoder().encode("404 File not found"))}return await this.php.run({relativeUri:ensurePathPrefix(toRelativeUrl(r),o(this,m)),protocol:o(this,F),method:t.method||a,body:d,scriptPath:p,headers:c})}finally{s()}},B=new WeakSet,Q=function(t){let r=removePathPrefix(t,o(this,m));r.includes(".php")?r=r.split(".php")[0]+".php":(r.endsWith("/")||(r+="/"),r.endsWith("index.php")||(r+="index.php"));const s=`${o(this,w)}${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(...a){try{return i.apply(this,a)}catch(c){const d=typeof c=="object"?c==null?void 0:c.errno:null;if(d in FileErrorCodes){const p=FileErrorCodes[d],u=typeof a[0]=="string"?a[0]:null,_=u!==null?e.replaceAll("{path}",u):e;throw new Error(`${_}: ${p}`,{cause:c})}throw c}}}}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,a;i>=0;i--)(a=e[i])&&(n=(s?a(t,r,n):a(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,E,P,g,H,L,X,O,ee,U,te,q,re,$,se,D,ne,j,ie,W,oe,z,ae,G,le,J,ce;class BasePHP{constructor(e,t){l(this,L);l(this,O);l(this,U);l(this,q);l(this,$);l(this,D);l(this,j);l(this,W);l(this,z);l(this,G);l(this,J);l(this,S,void 0);l(this,k,void 0);l(this,A,void 0);l(this,y,void 0);l(this,E,void 0);l(this,P,void 0);l(this,g,void 0);l(this,H,void 0);h(this,S,[]),h(this,y,!1),h(this,E,null),h(this,P,{}),h(this,g,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){o(this,g).has(e)||o(this,g).set(e,new Set),o(this,g).get(e).add(t)}removeEventListener(e,t){var r;(r=o(this,g).get(e))==null||r.delete(t)}dispatchEvent(e){const t=o(this,g).get(e.type);if(t)for(const r of t)r(e)}async onMessage(e){o(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 o(this,H)){const n=await s(r);if(n)return n}return""},h(this,E,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(o(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(o(this,y))throw new Error("Cannot set PHP ini entries after calling run().");o(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{o(this,y)||(f(this,L,X).call(this),h(this,y,!0)),f(this,W,oe).call(this,e.scriptPath||""),f(this,U,te).call(this,e.relativeUri||""),f(this,$,se).call(this,e.method||"GET");const s=normalizeHeaders(e.headers||{}),n=s.host||"example.com:443";f(this,q,re).call(this,n,e.protocol||"http"),f(this,D,ne).call(this,s),e.body&&(r=f(this,j,ie).call(this,e.body)),typeof e.code=="string"&&f(this,G,le).call(this," ?>"+e.code),f(this,z,ae).call(this);const i=await f(this,J,ce).call(this);if(e.throwOnError&&i.exitCode!==0){const a={stdout:i.text,stderr:i.errors};console.warn("PHP.run() output was:",a);const c=new Error(`PHP.run() failed with exit code ${i.exitCode} and the following output`);throw c.output=a,c}return i}finally{try{r&&this[__private__dont__use].free(r)}finally{t(),this.dispatchEvent({type:"request.end"})}}}addServerGlobalEntry(e,t){o(this,P)[e]=t}defineConstant(e,t){let r={};try{r=JSON.parse(this.fileExists("/tmp/consts.json")&&this.readFileAsText("/tmp/consts.json")||"{}")}catch{}this.writeFile("/tmp/consts.json",JSON.stringify({...r,[e]:t}))}mkdir(e){this[__private__dont__use].FS.mkdirTree(e)}mkdirTree(e){this.mkdir(e)}readFileAsText(e){return new TextDecoder().decode(this.readFileAsBuffer(e))}readFileAsBuffer(e){return this[__private__dont__use].FS.readFile(e)}writeFile(e,t){this[__private__dont__use].FS.writeFile(e,t)}unlink(e){this[__private__dont__use].FS.unlink(e)}mv(e,t){try{this[__private__dont__use].FS.rename(e,t)}catch(r){const s=getEmscriptenFsError(r);throw s?new Error(`Could not move ${e} to ${t}: ${s}`,{cause:r}):r}}rmdir(e,t={recursive:!0}){t!=null&&t.recursive&&this.listFiles(e).forEach(r=>{const s=`${e}/${r}`;this.isDir(s)?this.rmdir(s,t):this.unlink(s)}),this[__private__dont__use].FS.rmdir(e)}listFiles(e,t={prependPath:!1}){if(!this.fileExists(e))return[];try{const r=this[__private__dont__use].FS.readdir(e).filter(s=>s!=="."&&s!=="..");if(t.prependPath){const s=e.replace(/\/$/,"");return r.map(n=>`${s}/${n}`)}return r}catch(r){return console.error(r,{path:e}),[]}}isDir(e){return this.fileExists(e)?this[__private__dont__use].FS.isDir(this[__private__dont__use].FS.lookupPath(e).node.mode):!1}fileExists(e){try{return this[__private__dont__use].FS.lookupPath(e),!0}catch{return!1}}hotSwapPHPRuntime(e){const t=this[__private__dont__use].FS;try{this.exit()}catch{}if(this.initializeRuntime(e),o(this,k)&&this.setPhpIniPath(o(this,k)),o(this,A)&&this.setSapiName(o(this,A)),this.requestHandler){const r=this.documentRoot;recreateMemFS(this[__private__dont__use].FS,t,r)}}exit(e=0){this.dispatchEvent({type:"runtime.beforedestroy"});try{this[__private__dont__use]._exit(e)}catch{}h(this,y,!1),h(this,E,null),delete this[__private__dont__use].onMessage,delete this[__private__dont__use]}}S=new WeakMap,k=new WeakMap,A=new WeakMap,y=new WeakMap,E=new WeakMap,P=new WeakMap,g=new WeakMap,H=new WeakMap,L=new WeakSet,X=function(){if(this.setPhpIniEntry("auto_prepend_file","/tmp/consts.php"),this.fileExists("/tmp/consts.php")||this.writeFile("/tmp/consts.php",`<?php
|
|
38
42
|
if(file_exists('/tmp/consts.json')) {
|
|
39
43
|
$consts = json_decode(file_get_contents('/tmp/consts.json'), true);
|
|
40
44
|
foreach ($consts as $const => $value) {
|
|
@@ -42,7 +46,7 @@ ${bold} WASM ERROR${reset}${redBg}`);for(const t of e.split(`
|
|
|
42
46
|
define($const, $value);
|
|
43
47
|
}
|
|
44
48
|
}
|
|
45
|
-
}`),
|
|
49
|
+
}`),o(this,S).length>0){const e=o(this,S).map(([t,r])=>`${t}=${r}`).join(`
|
|
46
50
|
`)+`
|
|
47
51
|
|
|
48
|
-
`;this[__private__dont__use].ccall("wasm_set_phpini_entries",null,[STRING],[e])}this[__private__dont__use].ccall("php_wasm_init",null,[],[])},
|
|
52
|
+
`;this[__private__dont__use].ccall("wasm_set_phpini_entries",null,[STRING],[e])}this[__private__dont__use].ccall("php_wasm_init",null,[],[])},O=new WeakSet,ee=function(){const e="/tmp/headers.json";if(!this.fileExists(e))throw new Error("SAPI Error: Could not find response headers file.");const t=JSON.parse(this.readFileAsText(e)),r={};for(const s of t.headers){if(!s.includes(": "))continue;const n=s.indexOf(": "),i=s.substring(0,n).toLowerCase(),a=s.substring(n+2);i in r||(r[i]=[]),r[i].push(a)}return{headers:r,httpStatusCode:t.status}},U=new WeakSet,te=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])}},q=new WeakSet,re=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,se=function(e){this[__private__dont__use].ccall("wasm_set_request_method",null,[STRING],[e])},D=new WeakSet,ne=function(e){e.cookie&&this[__private__dont__use].ccall("wasm_set_cookies",null,[STRING],[e.cookie]),e["content-type"]&&this[__private__dont__use].ccall("wasm_set_content_type",null,[STRING],[e["content-type"]]),e["content-length"]&&this[__private__dont__use].ccall("wasm_set_content_length",null,[NUMBER],[parseInt(e["content-length"],10)]);for(const t in e){let r="HTTP_";["content-type","content-length"].includes(t.toLowerCase())&&(r=""),this.addServerGlobalEntry(`${r}${t.toUpperCase().replace(/-/g,"_")}`,e[t])}},j=new WeakSet,ie=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},W=new WeakSet,oe=function(e){this[__private__dont__use].ccall("wasm_set_path_translated",null,[STRING],[e])},z=new WeakSet,ae=function(){for(const e in o(this,P))this[__private__dont__use].ccall("wasm_add_SERVER_entry",null,[STRING,STRING],[e,o(this,P)[e]])},G=new WeakSet,le=function(e){this[__private__dont__use].ccall("wasm_set_php_code",null,[STRING],[e])},J=new WeakSet,ce=async function(){var n;let e,t;try{e=await new Promise((i,a)=>{var d;t=p=>{const u=new Error("Rethrown");u.cause=p.error,u.betterMessage=p.message,a(u)},(d=o(this,E))==null||d.addEventListener("error",t);const c=this[__private__dont__use].ccall("wasm_sapi_handle_request",NUMBER,[],[],{async:!0});return c instanceof Promise?c.then(i,a):i(c)})}catch(i){for(const p in this)typeof this[p]=="function"&&(this[p]=()=>{throw new Error("PHP runtime has crashed – see the earlier error for details.")});this.functionsMaybeMissingFromAsyncify=getFunctionsMaybeMissingFromAsyncify();const a=i,c="betterMessage"in a?a.betterMessage:a.message,d=new Error(c);throw d.cause=a,d}finally{(n=o(this,E))==null||n.removeEventListener("error",t),h(this,P,{})}const{headers:r,httpStatusCode:s}=f(this,O,ee).call(this);return new PHPResponse(s,r,this.readFileAsBuffer("/tmp/stdout"),this.readFileAsText("/tmp/stderr"),e)};__decorateClass([rethrowFileSystemError('Could not create directory "{path}"')],BasePHP.prototype,"mkdir",1);__decorateClass([rethrowFileSystemError('Could not create directory "{path}"')],BasePHP.prototype,"mkdirTree",1);__decorateClass([rethrowFileSystemError('Could not read "{path}"')],BasePHP.prototype,"readFileAsText",1);__decorateClass([rethrowFileSystemError('Could not read "{path}"')],BasePHP.prototype,"readFileAsBuffer",1);__decorateClass([rethrowFileSystemError('Could not write to "{path}"')],BasePHP.prototype,"writeFile",1);__decorateClass([rethrowFileSystemError('Could not unlink "{path}"')],BasePHP.prototype,"unlink",1);__decorateClass([rethrowFileSystemError('Could not remove directory "{path}"')],BasePHP.prototype,"rmdir",1);__decorateClass([rethrowFileSystemError('Could not list files in "{path}"')],BasePHP.prototype,"listFiles",1);__decorateClass([rethrowFileSystemError('Could not stat "{path}"')],BasePHP.prototype,"isDir",1);__decorateClass([rethrowFileSystemError('Could not stat "{path}"')],BasePHP.prototype,"fileExists",1);function normalizeHeaders(e){const t={};for(const r in e)t[r.toLowerCase()]=e[r];return t}function recreateMemFS(e,t,r){let s;try{s=t.lookupPath(r)}catch{return}if(!("contents"in s.node))return;try{e=e.lookupPath(r);return}catch{}if(!t.isDir(s.node.mode)){e.writeFile(r,t.readFile(r));return}e.mkdirTree(r);const n=t.readdir(r).filter(i=>i!=="."&&i!=="..");for(const i of n)recreateMemFS(e,t,joinPaths(r,i))}function journalFSEvents(e,t,r=()=>{}){function s(){t=normalizePath(t);const i=e[__private__dont__use].FS,a=createFSHooks(i,u=>{if(u.path.startsWith(t))r(u);else if(u.operation==="RENAME"&&u.toPath.startsWith(t))for(const _ of recordExistingPath(e,u.path,u.toPath))r(_)}),c={};for(const[u]of Object.entries(a))c[u]=i[u];function d(){for(const[u,_]of Object.entries(a))i[u]=function(...V){return _(...V),c[u].apply(this,V)}}function p(){for(const[u,_]of Object.entries(c))e[__private__dont__use].FS[u]=_}e[__private__dont__use].journal={bind:d,unbind:p},d()}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],a=e[s];if(i.operation==="RENAME"&&a.operation==="RENAME"){console.warn("[FS Journal] Normalizing a double rename is not yet supported:",{current:i,last:a});continue}(a.operation==="CREATE"||a.operation==="WRITE")&&(i.operation==="RENAME"?n==="same_node"?(t[s]=[],t[r]=[{...a,path:i.toPath},...t[r]||[]]):n==="descendant"&&(t[s]=[],t[r]=[{...a,path:joinPaths(i.toPath,a.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
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
var
|
|
1
|
+
var Y = (e, t, r) => {
|
|
2
2
|
if (!t.has(e))
|
|
3
3
|
throw TypeError("Cannot " + r);
|
|
4
4
|
};
|
|
5
|
-
var
|
|
5
|
+
var o = (e, t, r) => (Y(e, t, "read from private field"), r ? r.call(e) : t.get(e)), l = (e, t, r) => {
|
|
6
6
|
if (t.has(e))
|
|
7
7
|
throw TypeError("Cannot add the same private member more than once");
|
|
8
8
|
t instanceof WeakSet ? t.add(e) : t.set(e, r);
|
|
9
|
-
},
|
|
10
|
-
var
|
|
9
|
+
}, h = (e, t, r, s) => (Y(e, t, "write to private field"), s ? s.call(e, r) : t.set(e, r), r);
|
|
10
|
+
var f = (e, t, r) => (Y(e, t, "access private method"), r);
|
|
11
11
|
if (typeof File > "u") {
|
|
12
12
|
class e extends Blob {
|
|
13
|
-
constructor(r, s,
|
|
13
|
+
constructor(r, s, n) {
|
|
14
14
|
super(r);
|
|
15
|
-
let
|
|
16
|
-
|
|
15
|
+
let i;
|
|
16
|
+
n != null && n.lastModified && (i = /* @__PURE__ */ new Date()), (!i || isNaN(i.getFullYear())) && (i = /* @__PURE__ */ new Date()), this.lastModifiedDate = i, this.lastModified = i.getMilliseconds(), this.name = s || "";
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
global.File = e;
|
|
@@ -50,9 +50,9 @@ function isByobSupported() {
|
|
|
50
50
|
// this if needed.
|
|
51
51
|
autoAllocateChunkSize: 512 * 1024,
|
|
52
52
|
async pull(r) {
|
|
53
|
-
const s = r.byobRequest.view,
|
|
54
|
-
new Uint8Array(s.buffer).set(
|
|
55
|
-
const c =
|
|
53
|
+
const s = r.byobRequest.view, i = await t.slice(e, e + s.byteLength).arrayBuffer(), a = new Uint8Array(i);
|
|
54
|
+
new Uint8Array(s.buffer).set(a);
|
|
55
|
+
const c = a.byteLength;
|
|
56
56
|
r.byobRequest.respond(c), e += c, e >= t.size && r.close();
|
|
57
57
|
}
|
|
58
58
|
});
|
|
@@ -114,27 +114,27 @@ function improveWASMErrorReporting(e) {
|
|
|
114
114
|
for (const r in e.asm)
|
|
115
115
|
if (typeof e.asm[r] == "function") {
|
|
116
116
|
const s = e.asm[r];
|
|
117
|
-
e.asm[r] = function(...
|
|
118
|
-
var
|
|
117
|
+
e.asm[r] = function(...n) {
|
|
118
|
+
var i;
|
|
119
119
|
try {
|
|
120
|
-
return s(...
|
|
121
|
-
} catch (
|
|
122
|
-
if (!(
|
|
123
|
-
throw
|
|
120
|
+
return s(...n);
|
|
121
|
+
} catch (a) {
|
|
122
|
+
if (!(a instanceof Error))
|
|
123
|
+
throw a;
|
|
124
124
|
const c = clarifyErrorMessage(
|
|
125
|
-
|
|
126
|
-
(
|
|
125
|
+
a,
|
|
126
|
+
(i = e.lastAsyncifyStackSource) == null ? void 0 : i.stack
|
|
127
127
|
);
|
|
128
|
-
if (e.lastAsyncifyStackSource && (
|
|
128
|
+
if (e.lastAsyncifyStackSource && (a.cause = e.lastAsyncifyStackSource), t.hasListeners()) {
|
|
129
129
|
t.dispatchEvent(
|
|
130
130
|
new ErrorEvent("error", {
|
|
131
|
-
error:
|
|
131
|
+
error: a,
|
|
132
132
|
message: c
|
|
133
133
|
})
|
|
134
134
|
);
|
|
135
135
|
return;
|
|
136
136
|
}
|
|
137
|
-
throw isExitCodeZero(
|
|
137
|
+
throw isExitCodeZero(a) || showCriticalErrorBox(c), a;
|
|
138
138
|
}
|
|
139
139
|
};
|
|
140
140
|
}
|
|
@@ -266,8 +266,8 @@ function normalizePath$1(e) {
|
|
|
266
266
|
function normalizePathsArray(e, t) {
|
|
267
267
|
let r = 0;
|
|
268
268
|
for (let s = e.length - 1; s >= 0; s--) {
|
|
269
|
-
const
|
|
270
|
-
|
|
269
|
+
const n = e[s];
|
|
270
|
+
n === "." ? e.splice(s, 1) : n === ".." ? (e.splice(s, 1), r++) : r && (e.splice(s, 1), r--);
|
|
271
271
|
}
|
|
272
272
|
if (t)
|
|
273
273
|
for (; r; r--)
|
|
@@ -344,8 +344,8 @@ ReadableStream.prototype[Symbol.asyncIterator] || (ReadableStream.prototype[Symb
|
|
|
344
344
|
}, ReadableStream.prototype.iterate = // @ts-ignore
|
|
345
345
|
ReadableStream.prototype[Symbol.asyncIterator]);
|
|
346
346
|
class PHPResponse {
|
|
347
|
-
constructor(t, r, s,
|
|
348
|
-
this.httpStatusCode = t, this.headers = r, this.bytes = s, this.exitCode =
|
|
347
|
+
constructor(t, r, s, n = "", i = 0) {
|
|
348
|
+
this.httpStatusCode = t, this.headers = r, this.bytes = s, this.exitCode = i, this.errors = n;
|
|
349
349
|
}
|
|
350
350
|
static fromRawData(t) {
|
|
351
351
|
return new PHPResponse(
|
|
@@ -378,16 +378,16 @@ class PHPResponse {
|
|
|
378
378
|
return new TextDecoder().decode(this.bytes);
|
|
379
379
|
}
|
|
380
380
|
}
|
|
381
|
-
var
|
|
381
|
+
var v, T;
|
|
382
382
|
class PHPBrowser {
|
|
383
383
|
/**
|
|
384
384
|
* @param server - The PHP server to browse.
|
|
385
385
|
* @param config - The browser configuration.
|
|
386
386
|
*/
|
|
387
387
|
constructor(t, r = {}) {
|
|
388
|
-
l(this,
|
|
389
|
-
l(this,
|
|
390
|
-
this.requestHandler = t,
|
|
388
|
+
l(this, v, void 0);
|
|
389
|
+
l(this, T, void 0);
|
|
390
|
+
this.requestHandler = t, h(this, v, {}), h(this, T, {
|
|
391
391
|
handleRedirects: !1,
|
|
392
392
|
maxRedirects: 4,
|
|
393
393
|
...r
|
|
@@ -415,14 +415,14 @@ class PHPBrowser {
|
|
|
415
415
|
cookie: this.serializeCookies()
|
|
416
416
|
}
|
|
417
417
|
});
|
|
418
|
-
if (s.headers["set-cookie"] && this.setCookies(s.headers["set-cookie"]),
|
|
419
|
-
const
|
|
418
|
+
if (s.headers["set-cookie"] && this.setCookies(s.headers["set-cookie"]), o(this, T).handleRedirects && s.headers.location && r < o(this, T).maxRedirects) {
|
|
419
|
+
const n = new URL(
|
|
420
420
|
s.headers.location[0],
|
|
421
421
|
this.requestHandler.absoluteUrl
|
|
422
422
|
);
|
|
423
423
|
return this.request(
|
|
424
424
|
{
|
|
425
|
-
url:
|
|
425
|
+
url: n.toString(),
|
|
426
426
|
method: "GET",
|
|
427
427
|
headers: {}
|
|
428
428
|
},
|
|
@@ -452,20 +452,20 @@ class PHPBrowser {
|
|
|
452
452
|
try {
|
|
453
453
|
if (!r.includes("="))
|
|
454
454
|
continue;
|
|
455
|
-
const s = r.indexOf("="),
|
|
456
|
-
|
|
455
|
+
const s = r.indexOf("="), n = r.substring(0, s), i = r.substring(s + 1).split(";")[0];
|
|
456
|
+
o(this, v)[n] = i;
|
|
457
457
|
} catch (s) {
|
|
458
458
|
console.error(s);
|
|
459
459
|
}
|
|
460
460
|
}
|
|
461
461
|
serializeCookies() {
|
|
462
462
|
const t = [];
|
|
463
|
-
for (const r in
|
|
464
|
-
t.push(`${r}=${
|
|
463
|
+
for (const r in o(this, v))
|
|
464
|
+
t.push(`${r}=${o(this, v)[r]}`);
|
|
465
465
|
return t.join("; ");
|
|
466
466
|
}
|
|
467
467
|
}
|
|
468
|
-
|
|
468
|
+
v = new WeakMap(), T = new WeakMap();
|
|
469
469
|
const DEFAULT_BASE_URL = "http://example.com";
|
|
470
470
|
function toRelativeUrl(e) {
|
|
471
471
|
return e.toString().substring(e.origin.length);
|
|
@@ -476,7 +476,35 @@ function removePathPrefix(e, t) {
|
|
|
476
476
|
function ensurePathPrefix(e, t) {
|
|
477
477
|
return !t || e.startsWith(t) ? e : t + e;
|
|
478
478
|
}
|
|
479
|
-
|
|
479
|
+
async function encodeAsMultipart(e) {
|
|
480
|
+
const t = `----${Math.random().toString(36).slice(2)}`, r = `multipart/form-data; boundary=${t}`, s = new TextEncoder(), n = [];
|
|
481
|
+
for (const [d, p] of Object.entries(e))
|
|
482
|
+
n.push(`--${t}\r
|
|
483
|
+
`), n.push(`Content-Disposition: form-data; name="${d}"`), p instanceof File && n.push(`; filename="${p.name}"`), n.push(`\r
|
|
484
|
+
`), p instanceof File && n.push("Content-Type: application/octet-stream"), n.push(`\r
|
|
485
|
+
\r
|
|
486
|
+
`), p instanceof File ? n.push(await fileToUint8Array(p)) : n.push(p), n.push(`\r
|
|
487
|
+
`);
|
|
488
|
+
n.push(`--${t}--\r
|
|
489
|
+
`);
|
|
490
|
+
const i = n.reduce((d, p) => d + p.length, 0), a = new Uint8Array(i);
|
|
491
|
+
let c = 0;
|
|
492
|
+
for (const d of n)
|
|
493
|
+
a.set(
|
|
494
|
+
typeof d == "string" ? s.encode(d) : d,
|
|
495
|
+
c
|
|
496
|
+
), c += d.length;
|
|
497
|
+
return { bytes: a, contentType: r };
|
|
498
|
+
}
|
|
499
|
+
function fileToUint8Array(e) {
|
|
500
|
+
return new Promise((t) => {
|
|
501
|
+
const r = new FileReader();
|
|
502
|
+
r.onload = () => {
|
|
503
|
+
t(new Uint8Array(r.result));
|
|
504
|
+
}, r.readAsArrayBuffer(e);
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
var w, F, I, b, x, m, C, R, M, K, N, Z, B, Q;
|
|
480
508
|
class PHPRequestHandler {
|
|
481
509
|
/**
|
|
482
510
|
* @param php - The PHP instance.
|
|
@@ -489,7 +517,7 @@ class PHPRequestHandler {
|
|
|
489
517
|
* @param fsPath - Absolute path of the static file to serve.
|
|
490
518
|
* @returns The response.
|
|
491
519
|
*/
|
|
492
|
-
l(this,
|
|
520
|
+
l(this, M);
|
|
493
521
|
/**
|
|
494
522
|
* Runs the requested PHP file with all the request and $_SERVER
|
|
495
523
|
* superglobals populated.
|
|
@@ -497,7 +525,7 @@ class PHPRequestHandler {
|
|
|
497
525
|
* @param request - The request.
|
|
498
526
|
* @returns The response.
|
|
499
527
|
*/
|
|
500
|
-
l(this,
|
|
528
|
+
l(this, N);
|
|
501
529
|
/**
|
|
502
530
|
* Resolve the requested path to the filesystem path of the requested PHP file.
|
|
503
531
|
*
|
|
@@ -507,31 +535,31 @@ class PHPRequestHandler {
|
|
|
507
535
|
* @throws {Error} If the requested path doesn't exist.
|
|
508
536
|
* @returns The resolved filesystem path.
|
|
509
537
|
*/
|
|
510
|
-
l(this,
|
|
511
|
-
l(this,
|
|
538
|
+
l(this, B);
|
|
539
|
+
l(this, w, void 0);
|
|
540
|
+
l(this, F, void 0);
|
|
541
|
+
l(this, I, void 0);
|
|
542
|
+
l(this, b, void 0);
|
|
512
543
|
l(this, x, void 0);
|
|
513
|
-
l(this, N, void 0);
|
|
514
|
-
l(this, R, void 0);
|
|
515
|
-
l(this, k, void 0);
|
|
516
544
|
l(this, m, void 0);
|
|
517
545
|
l(this, C, void 0);
|
|
518
|
-
l(this,
|
|
519
|
-
|
|
546
|
+
l(this, R, void 0);
|
|
547
|
+
h(this, R, new Semaphore({ concurrency: 1 }));
|
|
520
548
|
const {
|
|
521
549
|
documentRoot: s = "/www/",
|
|
522
|
-
absoluteUrl:
|
|
550
|
+
absoluteUrl: n = typeof location == "object" ? location == null ? void 0 : location.href : ""
|
|
523
551
|
} = r;
|
|
524
|
-
this.php = t,
|
|
525
|
-
const
|
|
526
|
-
|
|
527
|
-
const
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
].join("")),
|
|
532
|
-
`${
|
|
533
|
-
|
|
534
|
-
|
|
552
|
+
this.php = t, h(this, w, s);
|
|
553
|
+
const i = new URL(n);
|
|
554
|
+
h(this, I, i.hostname), h(this, b, i.port ? Number(i.port) : i.protocol === "https:" ? 443 : 80), h(this, F, (i.protocol || "").replace(":", ""));
|
|
555
|
+
const a = o(this, b) !== 443 && o(this, b) !== 80;
|
|
556
|
+
h(this, x, [
|
|
557
|
+
o(this, I),
|
|
558
|
+
a ? `:${o(this, b)}` : ""
|
|
559
|
+
].join("")), h(this, m, i.pathname.replace(/\/+$/, "")), h(this, C, [
|
|
560
|
+
`${o(this, F)}://`,
|
|
561
|
+
o(this, x),
|
|
562
|
+
o(this, m)
|
|
535
563
|
].join(""));
|
|
536
564
|
}
|
|
537
565
|
/** @inheritDoc */
|
|
@@ -541,32 +569,32 @@ class PHPRequestHandler {
|
|
|
541
569
|
/** @inheritDoc */
|
|
542
570
|
internalUrlToPath(t) {
|
|
543
571
|
const r = new URL(t);
|
|
544
|
-
return r.pathname.startsWith(
|
|
572
|
+
return r.pathname.startsWith(o(this, m)) && (r.pathname = r.pathname.slice(o(this, m).length)), toRelativeUrl(r);
|
|
545
573
|
}
|
|
546
574
|
get isRequestRunning() {
|
|
547
|
-
return
|
|
575
|
+
return o(this, R).running > 0;
|
|
548
576
|
}
|
|
549
577
|
/** @inheritDoc */
|
|
550
578
|
get absoluteUrl() {
|
|
551
|
-
return
|
|
579
|
+
return o(this, C);
|
|
552
580
|
}
|
|
553
581
|
/** @inheritDoc */
|
|
554
582
|
get documentRoot() {
|
|
555
|
-
return
|
|
583
|
+
return o(this, w);
|
|
556
584
|
}
|
|
557
585
|
/** @inheritDoc */
|
|
558
586
|
async request(t) {
|
|
559
587
|
const r = t.url.startsWith("http://") || t.url.startsWith("https://"), s = new URL(
|
|
560
588
|
t.url,
|
|
561
589
|
r ? void 0 : DEFAULT_BASE_URL
|
|
562
|
-
),
|
|
590
|
+
), n = removePathPrefix(
|
|
563
591
|
s.pathname,
|
|
564
|
-
|
|
565
|
-
),
|
|
566
|
-
return seemsLikeAPHPRequestHandlerPath(
|
|
592
|
+
o(this, m)
|
|
593
|
+
), i = `${o(this, w)}${n}`;
|
|
594
|
+
return seemsLikeAPHPRequestHandlerPath(i) ? await f(this, N, Z).call(this, t, s) : f(this, M, K).call(this, i);
|
|
567
595
|
}
|
|
568
596
|
}
|
|
569
|
-
|
|
597
|
+
w = new WeakMap(), F = new WeakMap(), I = new WeakMap(), b = new WeakMap(), x = new WeakMap(), m = new WeakMap(), C = new WeakMap(), R = new WeakMap(), M = new WeakSet(), K = function(t) {
|
|
570
598
|
if (!this.php.fileExists(t))
|
|
571
599
|
return new PHPResponse(
|
|
572
600
|
404,
|
|
@@ -591,9 +619,9 @@ E = new WeakMap(), x = new WeakMap(), N = new WeakMap(), R = new WeakMap(), k =
|
|
|
591
619
|
},
|
|
592
620
|
r
|
|
593
621
|
);
|
|
594
|
-
},
|
|
595
|
-
var
|
|
596
|
-
if (
|
|
622
|
+
}, N = new WeakSet(), Z = async function(t, r) {
|
|
623
|
+
var n, i;
|
|
624
|
+
if (o(this, R).running > 0 && ((n = t.headers) == null ? void 0 : n["x-request-issuer"]) === "php")
|
|
597
625
|
return console.warn(
|
|
598
626
|
"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."
|
|
599
627
|
), new PHPResponse(
|
|
@@ -601,47 +629,34 @@ E = new WeakMap(), x = new WeakMap(), N = new WeakMap(), R = new WeakMap(), k =
|
|
|
601
629
|
{},
|
|
602
630
|
new TextEncoder().encode("502 Bad Gateway")
|
|
603
631
|
);
|
|
604
|
-
const s = await
|
|
632
|
+
const s = await o(this, R).acquire();
|
|
605
633
|
try {
|
|
606
|
-
this.php.addServerGlobalEntry("REMOTE_ADDR", "127.0.0.1"), this.php.addServerGlobalEntry("DOCUMENT_ROOT",
|
|
634
|
+
this.php.addServerGlobalEntry("REMOTE_ADDR", "127.0.0.1"), this.php.addServerGlobalEntry("DOCUMENT_ROOT", o(this, w)), this.php.addServerGlobalEntry(
|
|
607
635
|
"HTTPS",
|
|
608
|
-
|
|
636
|
+
o(this, C).startsWith("https://") ? "on" : ""
|
|
609
637
|
);
|
|
610
|
-
let
|
|
611
|
-
const
|
|
612
|
-
host:
|
|
638
|
+
let a = "GET";
|
|
639
|
+
const c = {
|
|
640
|
+
host: o(this, x),
|
|
613
641
|
...normalizeHeaders(t.headers || {})
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
key: y,
|
|
621
|
-
name: M.name,
|
|
622
|
-
type: M.type,
|
|
623
|
-
data: new Uint8Array(await M.arrayBuffer())
|
|
624
|
-
});
|
|
625
|
-
}
|
|
626
|
-
(n = h["content-type"]) != null && n.startsWith("multipart/form-data") && (t.formData = parseMultipartFormDataString(
|
|
627
|
-
t.body || ""
|
|
628
|
-
), h["content-type"] = "application/x-www-form-urlencoded", delete t.body);
|
|
642
|
+
};
|
|
643
|
+
let d = t.body;
|
|
644
|
+
if (typeof d == "object" && !(d instanceof Uint8Array)) {
|
|
645
|
+
a = "POST";
|
|
646
|
+
const { bytes: u, contentType: _ } = await encodeAsMultipart(d);
|
|
647
|
+
d = u, c["content-type"] = _;
|
|
629
648
|
}
|
|
630
|
-
let
|
|
631
|
-
t.formData !== void 0 ? (c = "POST", h["content-type"] = h["content-type"] || "application/x-www-form-urlencoded", u = new URLSearchParams(
|
|
632
|
-
t.formData
|
|
633
|
-
).toString()) : u = t.body;
|
|
634
|
-
let _;
|
|
649
|
+
let p;
|
|
635
650
|
try {
|
|
636
|
-
let
|
|
637
|
-
if ((
|
|
651
|
+
let u = r.pathname;
|
|
652
|
+
if ((i = t.headers) != null && i["x-rewrite-url"])
|
|
638
653
|
try {
|
|
639
|
-
|
|
654
|
+
u = new URL(
|
|
640
655
|
t.headers["x-rewrite-url"]
|
|
641
656
|
).pathname;
|
|
642
657
|
} catch {
|
|
643
658
|
}
|
|
644
|
-
|
|
659
|
+
p = f(this, B, Q).call(this, u);
|
|
645
660
|
} catch {
|
|
646
661
|
return new PHPResponse(
|
|
647
662
|
404,
|
|
@@ -652,41 +667,25 @@ E = new WeakMap(), x = new WeakMap(), N = new WeakMap(), R = new WeakMap(), k =
|
|
|
652
667
|
return await this.php.run({
|
|
653
668
|
relativeUri: ensurePathPrefix(
|
|
654
669
|
toRelativeUrl(r),
|
|
655
|
-
|
|
670
|
+
o(this, m)
|
|
656
671
|
),
|
|
657
|
-
protocol:
|
|
658
|
-
method: t.method ||
|
|
659
|
-
body:
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
headers: h
|
|
672
|
+
protocol: o(this, F),
|
|
673
|
+
method: t.method || a,
|
|
674
|
+
body: d,
|
|
675
|
+
scriptPath: p,
|
|
676
|
+
headers: c
|
|
663
677
|
});
|
|
664
678
|
} finally {
|
|
665
679
|
s();
|
|
666
680
|
}
|
|
667
|
-
},
|
|
668
|
-
let r = removePathPrefix(t,
|
|
681
|
+
}, B = new WeakSet(), Q = function(t) {
|
|
682
|
+
let r = removePathPrefix(t, o(this, m));
|
|
669
683
|
r.includes(".php") ? r = r.split(".php")[0] + ".php" : (r.endsWith("/") || (r += "/"), r.endsWith("index.php") || (r += "index.php"));
|
|
670
|
-
const s = `${
|
|
684
|
+
const s = `${o(this, w)}${r}`;
|
|
671
685
|
if (this.php.fileExists(s))
|
|
672
686
|
return s;
|
|
673
687
|
throw new Error(`File not found: ${s}`);
|
|
674
688
|
};
|
|
675
|
-
function parseMultipartFormDataString(e) {
|
|
676
|
-
const t = {}, r = e.match(/--(.*)\r\n/);
|
|
677
|
-
if (!r)
|
|
678
|
-
return t;
|
|
679
|
-
const s = r[1], i = e.split(`--${s}`);
|
|
680
|
-
return i.shift(), i.pop(), i.forEach((n) => {
|
|
681
|
-
const o = n.indexOf(`\r
|
|
682
|
-
\r
|
|
683
|
-
`), c = n.substring(0, o).trim(), h = n.substring(o + 4).trim(), f = c.match(/name="([^"]+)"/);
|
|
684
|
-
if (f) {
|
|
685
|
-
const u = f[1];
|
|
686
|
-
t[u] = h;
|
|
687
|
-
}
|
|
688
|
-
}), t;
|
|
689
|
-
}
|
|
690
689
|
function inferMimeType(e) {
|
|
691
690
|
switch (e.split(".").pop()) {
|
|
692
691
|
case "css":
|
|
@@ -821,16 +820,16 @@ function getEmscriptenFsError(e) {
|
|
|
821
820
|
return FileErrorCodes[t];
|
|
822
821
|
}
|
|
823
822
|
function rethrowFileSystemError(e = "") {
|
|
824
|
-
return function(r, s,
|
|
825
|
-
const
|
|
826
|
-
|
|
823
|
+
return function(r, s, n) {
|
|
824
|
+
const i = n.value;
|
|
825
|
+
n.value = function(...a) {
|
|
827
826
|
try {
|
|
828
|
-
return
|
|
827
|
+
return i.apply(this, a);
|
|
829
828
|
} catch (c) {
|
|
830
|
-
const
|
|
831
|
-
if (
|
|
832
|
-
const
|
|
833
|
-
throw new Error(`${_}: ${
|
|
829
|
+
const d = typeof c == "object" ? c == null ? void 0 : c.errno : null;
|
|
830
|
+
if (d in FileErrorCodes) {
|
|
831
|
+
const p = FileErrorCodes[d], u = typeof a[0] == "string" ? a[0] : null, _ = u !== null ? e.replaceAll("{path}", u) : e;
|
|
832
|
+
throw new Error(`${_}: ${p}`, {
|
|
834
833
|
cause: c
|
|
835
834
|
});
|
|
836
835
|
}
|
|
@@ -848,12 +847,12 @@ function getLoadedRuntime(e) {
|
|
|
848
847
|
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";
|
|
849
848
|
})();
|
|
850
849
|
var __defProp = Object.defineProperty, __getOwnPropDesc = Object.getOwnPropertyDescriptor, __decorateClass = (e, t, r, s) => {
|
|
851
|
-
for (var
|
|
852
|
-
(
|
|
853
|
-
return s &&
|
|
850
|
+
for (var n = s > 1 ? void 0 : s ? __getOwnPropDesc(t, r) : t, i = e.length - 1, a; i >= 0; i--)
|
|
851
|
+
(a = e[i]) && (n = (s ? a(t, r, n) : a(n)) || n);
|
|
852
|
+
return s && n && __defProp(t, r, n), n;
|
|
854
853
|
};
|
|
855
854
|
const STRING = "string", NUMBER = "number", __private__dont__use = Symbol("__private__dont__use");
|
|
856
|
-
var
|
|
855
|
+
var S, k, A, y, E, P, g, H, L, X, U, ee, O, te, q, re, $, se, D, ne, W, ie, j, oe, z, ae, G, le, J, ce;
|
|
857
856
|
class BasePHP {
|
|
858
857
|
/**
|
|
859
858
|
* Initializes a PHP runtime.
|
|
@@ -863,55 +862,45 @@ class BasePHP {
|
|
|
863
862
|
* @param serverOptions - Optional. Options for the PHPRequestHandler. If undefined, no request handler will be initialized.
|
|
864
863
|
*/
|
|
865
864
|
constructor(e, t) {
|
|
865
|
+
l(this, L);
|
|
866
866
|
l(this, U);
|
|
867
|
-
l(this,
|
|
868
|
-
l(this, $);
|
|
867
|
+
l(this, O);
|
|
869
868
|
l(this, q);
|
|
869
|
+
l(this, $);
|
|
870
|
+
l(this, D);
|
|
870
871
|
l(this, W);
|
|
871
872
|
l(this, j);
|
|
872
873
|
l(this, z);
|
|
873
874
|
l(this, G);
|
|
874
875
|
l(this, J);
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
*
|
|
878
|
-
* In particular:
|
|
879
|
-
* * Creates the file data in the filesystem
|
|
880
|
-
* * Registers the file details in PHP
|
|
881
|
-
*
|
|
882
|
-
* @param fileInfo - File details
|
|
883
|
-
*/
|
|
884
|
-
l(this, Y);
|
|
885
|
-
l(this, V);
|
|
886
|
-
l(this, K);
|
|
887
|
-
l(this, T, void 0);
|
|
888
|
-
l(this, H, void 0);
|
|
876
|
+
l(this, S, void 0);
|
|
877
|
+
l(this, k, void 0);
|
|
889
878
|
l(this, A, void 0);
|
|
890
|
-
l(this,
|
|
879
|
+
l(this, y, void 0);
|
|
880
|
+
l(this, E, void 0);
|
|
891
881
|
l(this, P, void 0);
|
|
892
|
-
l(this, v, void 0);
|
|
893
882
|
l(this, g, void 0);
|
|
894
|
-
l(this,
|
|
895
|
-
|
|
883
|
+
l(this, H, void 0);
|
|
884
|
+
h(this, S, []), h(this, y, !1), h(this, E, null), h(this, P, {}), h(this, g, /* @__PURE__ */ new Map()), h(this, H, []), this.semaphore = new Semaphore({ concurrency: 1 }), e !== void 0 && this.initializeRuntime(e), t && (this.requestHandler = new PHPBrowser(
|
|
896
885
|
new PHPRequestHandler(this, t)
|
|
897
886
|
));
|
|
898
887
|
}
|
|
899
888
|
addEventListener(e, t) {
|
|
900
|
-
|
|
889
|
+
o(this, g).has(e) || o(this, g).set(e, /* @__PURE__ */ new Set()), o(this, g).get(e).add(t);
|
|
901
890
|
}
|
|
902
891
|
removeEventListener(e, t) {
|
|
903
892
|
var r;
|
|
904
|
-
(r =
|
|
893
|
+
(r = o(this, g).get(e)) == null || r.delete(t);
|
|
905
894
|
}
|
|
906
895
|
dispatchEvent(e) {
|
|
907
|
-
const t =
|
|
896
|
+
const t = o(this, g).get(e.type);
|
|
908
897
|
if (t)
|
|
909
898
|
for (const r of t)
|
|
910
899
|
r(e);
|
|
911
900
|
}
|
|
912
901
|
/** @inheritDoc */
|
|
913
902
|
async onMessage(e) {
|
|
914
|
-
|
|
903
|
+
o(this, H).push(e);
|
|
915
904
|
}
|
|
916
905
|
/** @inheritDoc */
|
|
917
906
|
async setSpawnHandler(handler) {
|
|
@@ -942,13 +931,13 @@ class BasePHP {
|
|
|
942
931
|
if (!t)
|
|
943
932
|
throw new Error("Invalid PHP runtime id.");
|
|
944
933
|
this[__private__dont__use] = t, t.onMessage = async (r) => {
|
|
945
|
-
for (const s of
|
|
946
|
-
const
|
|
947
|
-
if (
|
|
948
|
-
return
|
|
934
|
+
for (const s of o(this, H)) {
|
|
935
|
+
const n = await s(r);
|
|
936
|
+
if (n)
|
|
937
|
+
return n;
|
|
949
938
|
}
|
|
950
939
|
return "";
|
|
951
|
-
},
|
|
940
|
+
}, h(this, E, improveWASMErrorReporting(t)), this.dispatchEvent({
|
|
952
941
|
type: "runtime.initialized"
|
|
953
942
|
});
|
|
954
943
|
}
|
|
@@ -963,13 +952,13 @@ class BasePHP {
|
|
|
963
952
|
throw new Error(
|
|
964
953
|
"Could not set SAPI name. This can only be done before the PHP WASM module is initialized.Did you already dispatch any requests?"
|
|
965
954
|
);
|
|
966
|
-
|
|
955
|
+
h(this, A, e);
|
|
967
956
|
}
|
|
968
957
|
/** @inheritDoc */
|
|
969
958
|
setPhpIniPath(e) {
|
|
970
|
-
if (
|
|
959
|
+
if (o(this, y))
|
|
971
960
|
throw new Error("Cannot set PHP ini path after calling run().");
|
|
972
|
-
|
|
961
|
+
h(this, k, e), this[__private__dont__use].ccall(
|
|
973
962
|
"wasm_set_phpini_path",
|
|
974
963
|
null,
|
|
975
964
|
["string"],
|
|
@@ -978,9 +967,9 @@ class BasePHP {
|
|
|
978
967
|
}
|
|
979
968
|
/** @inheritDoc */
|
|
980
969
|
setPhpIniEntry(e, t) {
|
|
981
|
-
if (
|
|
970
|
+
if (o(this, y))
|
|
982
971
|
throw new Error("Cannot set PHP ini entries after calling run().");
|
|
983
|
-
|
|
972
|
+
o(this, S).push([e, t]);
|
|
984
973
|
}
|
|
985
974
|
/** @inheritDoc */
|
|
986
975
|
chdir(e) {
|
|
@@ -997,25 +986,22 @@ class BasePHP {
|
|
|
997
986
|
const t = await this.semaphore.acquire();
|
|
998
987
|
let r;
|
|
999
988
|
try {
|
|
1000
|
-
|
|
1001
|
-
const s = normalizeHeaders(e.headers || {}),
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
const o = {
|
|
1009
|
-
stdout: n.text,
|
|
1010
|
-
stderr: n.errors
|
|
989
|
+
o(this, y) || (f(this, L, X).call(this), h(this, y, !0)), f(this, j, oe).call(this, e.scriptPath || ""), f(this, O, te).call(this, e.relativeUri || ""), f(this, $, se).call(this, e.method || "GET");
|
|
990
|
+
const s = normalizeHeaders(e.headers || {}), n = s.host || "example.com:443";
|
|
991
|
+
f(this, q, re).call(this, n, e.protocol || "http"), f(this, D, ne).call(this, s), e.body && (r = f(this, W, ie).call(this, e.body)), typeof e.code == "string" && f(this, G, le).call(this, " ?>" + e.code), f(this, z, ae).call(this);
|
|
992
|
+
const i = await f(this, J, ce).call(this);
|
|
993
|
+
if (e.throwOnError && i.exitCode !== 0) {
|
|
994
|
+
const a = {
|
|
995
|
+
stdout: i.text,
|
|
996
|
+
stderr: i.errors
|
|
1011
997
|
};
|
|
1012
|
-
console.warn("PHP.run() output was:",
|
|
998
|
+
console.warn("PHP.run() output was:", a);
|
|
1013
999
|
const c = new Error(
|
|
1014
|
-
`PHP.run() failed with exit code ${
|
|
1000
|
+
`PHP.run() failed with exit code ${i.exitCode} and the following output`
|
|
1015
1001
|
);
|
|
1016
|
-
throw c.output =
|
|
1002
|
+
throw c.output = a, c;
|
|
1017
1003
|
}
|
|
1018
|
-
return
|
|
1004
|
+
return i;
|
|
1019
1005
|
} finally {
|
|
1020
1006
|
try {
|
|
1021
1007
|
r && this[__private__dont__use].free(r);
|
|
@@ -1027,7 +1013,7 @@ class BasePHP {
|
|
|
1027
1013
|
}
|
|
1028
1014
|
}
|
|
1029
1015
|
addServerGlobalEntry(e, t) {
|
|
1030
|
-
|
|
1016
|
+
o(this, P)[e] = t;
|
|
1031
1017
|
}
|
|
1032
1018
|
defineConstant(e, t) {
|
|
1033
1019
|
let r = {};
|
|
@@ -1092,7 +1078,7 @@ class BasePHP {
|
|
|
1092
1078
|
);
|
|
1093
1079
|
if (t.prependPath) {
|
|
1094
1080
|
const s = e.replace(/\/$/, "");
|
|
1095
|
-
return r.map((
|
|
1081
|
+
return r.map((n) => `${s}/${n}`);
|
|
1096
1082
|
}
|
|
1097
1083
|
return r;
|
|
1098
1084
|
} catch (r) {
|
|
@@ -1123,7 +1109,7 @@ class BasePHP {
|
|
|
1123
1109
|
this.exit();
|
|
1124
1110
|
} catch {
|
|
1125
1111
|
}
|
|
1126
|
-
if (this.initializeRuntime(e),
|
|
1112
|
+
if (this.initializeRuntime(e), o(this, k) && this.setPhpIniPath(o(this, k)), o(this, A) && this.setSapiName(o(this, A)), this.requestHandler) {
|
|
1127
1113
|
const r = this.documentRoot;
|
|
1128
1114
|
recreateMemFS(this[__private__dont__use].FS, t, r);
|
|
1129
1115
|
}
|
|
@@ -1136,10 +1122,10 @@ class BasePHP {
|
|
|
1136
1122
|
this[__private__dont__use]._exit(e);
|
|
1137
1123
|
} catch {
|
|
1138
1124
|
}
|
|
1139
|
-
|
|
1125
|
+
h(this, y, !1), h(this, E, null), delete this[__private__dont__use].onMessage, delete this[__private__dont__use];
|
|
1140
1126
|
}
|
|
1141
1127
|
}
|
|
1142
|
-
|
|
1128
|
+
S = new WeakMap(), k = new WeakMap(), A = new WeakMap(), y = new WeakMap(), E = new WeakMap(), P = new WeakMap(), g = new WeakMap(), H = new WeakMap(), L = new WeakSet(), X = function() {
|
|
1143
1129
|
if (this.setPhpIniEntry("auto_prepend_file", "/tmp/consts.php"), this.fileExists("/tmp/consts.php") || this.writeFile(
|
|
1144
1130
|
"/tmp/consts.php",
|
|
1145
1131
|
`<?php
|
|
@@ -1151,8 +1137,8 @@ T = new WeakMap(), H = new WeakMap(), A = new WeakMap(), w = new WeakMap(), P =
|
|
|
1151
1137
|
}
|
|
1152
1138
|
}
|
|
1153
1139
|
}`
|
|
1154
|
-
),
|
|
1155
|
-
const e =
|
|
1140
|
+
), o(this, S).length > 0) {
|
|
1141
|
+
const e = o(this, S).map(([t, r]) => `${t}=${r}`).join(`
|
|
1156
1142
|
`) + `
|
|
1157
1143
|
|
|
1158
1144
|
`;
|
|
@@ -1164,7 +1150,7 @@ T = new WeakMap(), H = new WeakMap(), A = new WeakMap(), w = new WeakMap(), P =
|
|
|
1164
1150
|
);
|
|
1165
1151
|
}
|
|
1166
1152
|
this[__private__dont__use].ccall("php_wasm_init", null, [], []);
|
|
1167
|
-
},
|
|
1153
|
+
}, U = new WeakSet(), ee = function() {
|
|
1168
1154
|
const e = "/tmp/headers.json";
|
|
1169
1155
|
if (!this.fileExists(e))
|
|
1170
1156
|
throw new Error(
|
|
@@ -1174,14 +1160,14 @@ T = new WeakMap(), H = new WeakMap(), A = new WeakMap(), w = new WeakMap(), P =
|
|
|
1174
1160
|
for (const s of t.headers) {
|
|
1175
1161
|
if (!s.includes(": "))
|
|
1176
1162
|
continue;
|
|
1177
|
-
const
|
|
1178
|
-
|
|
1163
|
+
const n = s.indexOf(": "), i = s.substring(0, n).toLowerCase(), a = s.substring(n + 2);
|
|
1164
|
+
i in r || (r[i] = []), r[i].push(a);
|
|
1179
1165
|
}
|
|
1180
1166
|
return {
|
|
1181
1167
|
headers: r,
|
|
1182
1168
|
httpStatusCode: t.status
|
|
1183
1169
|
};
|
|
1184
|
-
},
|
|
1170
|
+
}, O = new WeakSet(), te = function(e) {
|
|
1185
1171
|
if (this[__private__dont__use].ccall(
|
|
1186
1172
|
"wasm_set_request_uri",
|
|
1187
1173
|
null,
|
|
@@ -1196,7 +1182,7 @@ T = new WeakMap(), H = new WeakMap(), A = new WeakMap(), w = new WeakMap(), P =
|
|
|
1196
1182
|
[t]
|
|
1197
1183
|
);
|
|
1198
1184
|
}
|
|
1199
|
-
}, q = new WeakSet(),
|
|
1185
|
+
}, q = new WeakSet(), re = function(e, t) {
|
|
1200
1186
|
this[__private__dont__use].ccall(
|
|
1201
1187
|
"wasm_set_request_host",
|
|
1202
1188
|
null,
|
|
@@ -1214,14 +1200,14 @@ T = new WeakMap(), H = new WeakMap(), A = new WeakMap(), w = new WeakMap(), P =
|
|
|
1214
1200
|
[NUMBER],
|
|
1215
1201
|
[r]
|
|
1216
1202
|
), (t === "https" || !t && r === 443) && this.addServerGlobalEntry("HTTPS", "on");
|
|
1217
|
-
},
|
|
1203
|
+
}, $ = new WeakSet(), se = function(e) {
|
|
1218
1204
|
this[__private__dont__use].ccall(
|
|
1219
1205
|
"wasm_set_request_method",
|
|
1220
1206
|
null,
|
|
1221
1207
|
[STRING],
|
|
1222
1208
|
[e]
|
|
1223
1209
|
);
|
|
1224
|
-
},
|
|
1210
|
+
}, D = new WeakSet(), ne = function(e) {
|
|
1225
1211
|
e.cookie && this[__private__dont__use].ccall(
|
|
1226
1212
|
"wasm_set_cookies",
|
|
1227
1213
|
null,
|
|
@@ -1245,67 +1231,61 @@ T = new WeakMap(), H = new WeakMap(), A = new WeakMap(), w = new WeakMap(), P =
|
|
|
1245
1231
|
e[t]
|
|
1246
1232
|
);
|
|
1247
1233
|
}
|
|
1248
|
-
},
|
|
1249
|
-
|
|
1250
|
-
|
|
1234
|
+
}, W = new WeakSet(), ie = function(e) {
|
|
1235
|
+
let t, r;
|
|
1236
|
+
typeof e == "string" ? (console.warn(
|
|
1237
|
+
"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"
|
|
1238
|
+
), r = this[__private__dont__use].lengthBytesUTF8(e), t = r + 1) : (r = e.byteLength, t = e.byteLength);
|
|
1239
|
+
const s = this[__private__dont__use].malloc(t);
|
|
1240
|
+
if (!s)
|
|
1251
1241
|
throw new Error("Could not allocate memory for the request body.");
|
|
1252
|
-
return this[__private__dont__use].stringToUTF8(
|
|
1242
|
+
return typeof e == "string" ? this[__private__dont__use].stringToUTF8(
|
|
1253
1243
|
e,
|
|
1254
|
-
|
|
1244
|
+
s,
|
|
1255
1245
|
t + 1
|
|
1256
|
-
), this[__private__dont__use].ccall(
|
|
1246
|
+
) : this[__private__dont__use].HEAPU8.set(e, s), this[__private__dont__use].ccall(
|
|
1257
1247
|
"wasm_set_request_body",
|
|
1258
1248
|
null,
|
|
1259
1249
|
[NUMBER],
|
|
1260
|
-
[
|
|
1250
|
+
[s]
|
|
1261
1251
|
), this[__private__dont__use].ccall(
|
|
1262
1252
|
"wasm_set_content_length",
|
|
1263
1253
|
null,
|
|
1264
1254
|
[NUMBER],
|
|
1265
|
-
[
|
|
1266
|
-
),
|
|
1267
|
-
},
|
|
1255
|
+
[r]
|
|
1256
|
+
), s;
|
|
1257
|
+
}, j = new WeakSet(), oe = function(e) {
|
|
1268
1258
|
this[__private__dont__use].ccall(
|
|
1269
1259
|
"wasm_set_path_translated",
|
|
1270
1260
|
null,
|
|
1271
1261
|
[STRING],
|
|
1272
1262
|
[e]
|
|
1273
1263
|
);
|
|
1274
|
-
},
|
|
1275
|
-
for (const e in
|
|
1264
|
+
}, z = new WeakSet(), ae = function() {
|
|
1265
|
+
for (const e in o(this, P))
|
|
1276
1266
|
this[__private__dont__use].ccall(
|
|
1277
1267
|
"wasm_add_SERVER_entry",
|
|
1278
1268
|
null,
|
|
1279
1269
|
[STRING, STRING],
|
|
1280
|
-
[e,
|
|
1270
|
+
[e, o(this, P)[e]]
|
|
1281
1271
|
);
|
|
1282
|
-
},
|
|
1283
|
-
const { key: t, name: r, type: s, data: i } = e, n = `/tmp/${Math.random().toFixed(20)}`;
|
|
1284
|
-
this.writeFile(n, i);
|
|
1285
|
-
const o = 0;
|
|
1286
|
-
this[__private__dont__use].ccall(
|
|
1287
|
-
"wasm_add_uploaded_file",
|
|
1288
|
-
null,
|
|
1289
|
-
[STRING, STRING, STRING, STRING, NUMBER, NUMBER],
|
|
1290
|
-
[t, r, s, n, o, i.byteLength]
|
|
1291
|
-
);
|
|
1292
|
-
}, V = new WeakSet(), de = function(e) {
|
|
1272
|
+
}, G = new WeakSet(), le = function(e) {
|
|
1293
1273
|
this[__private__dont__use].ccall(
|
|
1294
1274
|
"wasm_set_php_code",
|
|
1295
1275
|
null,
|
|
1296
1276
|
[STRING],
|
|
1297
1277
|
[e]
|
|
1298
1278
|
);
|
|
1299
|
-
},
|
|
1300
|
-
var
|
|
1279
|
+
}, J = new WeakSet(), ce = async function() {
|
|
1280
|
+
var n;
|
|
1301
1281
|
let e, t;
|
|
1302
1282
|
try {
|
|
1303
|
-
e = await new Promise((
|
|
1304
|
-
var
|
|
1305
|
-
t = (
|
|
1283
|
+
e = await new Promise((i, a) => {
|
|
1284
|
+
var d;
|
|
1285
|
+
t = (p) => {
|
|
1306
1286
|
const u = new Error("Rethrown");
|
|
1307
|
-
u.cause =
|
|
1308
|
-
}, (
|
|
1287
|
+
u.cause = p.error, u.betterMessage = p.message, a(u);
|
|
1288
|
+
}, (d = o(this, E)) == null || d.addEventListener(
|
|
1309
1289
|
"error",
|
|
1310
1290
|
t
|
|
1311
1291
|
);
|
|
@@ -1316,22 +1296,22 @@ T = new WeakMap(), H = new WeakMap(), A = new WeakMap(), w = new WeakMap(), P =
|
|
|
1316
1296
|
[],
|
|
1317
1297
|
{ async: !0 }
|
|
1318
1298
|
);
|
|
1319
|
-
return c instanceof Promise ? c.then(
|
|
1299
|
+
return c instanceof Promise ? c.then(i, a) : i(c);
|
|
1320
1300
|
});
|
|
1321
|
-
} catch (
|
|
1322
|
-
for (const
|
|
1323
|
-
typeof this[
|
|
1301
|
+
} catch (i) {
|
|
1302
|
+
for (const p in this)
|
|
1303
|
+
typeof this[p] == "function" && (this[p] = () => {
|
|
1324
1304
|
throw new Error(
|
|
1325
1305
|
"PHP runtime has crashed – see the earlier error for details."
|
|
1326
1306
|
);
|
|
1327
1307
|
});
|
|
1328
1308
|
this.functionsMaybeMissingFromAsyncify = getFunctionsMaybeMissingFromAsyncify();
|
|
1329
|
-
const
|
|
1330
|
-
throw
|
|
1309
|
+
const a = i, c = "betterMessage" in a ? a.betterMessage : a.message, d = new Error(c);
|
|
1310
|
+
throw d.cause = a, d;
|
|
1331
1311
|
} finally {
|
|
1332
|
-
(
|
|
1312
|
+
(n = o(this, E)) == null || n.removeEventListener("error", t), h(this, P, {});
|
|
1333
1313
|
}
|
|
1334
|
-
const { headers: r, httpStatusCode: s } =
|
|
1314
|
+
const { headers: r, httpStatusCode: s } = f(this, U, ee).call(this);
|
|
1335
1315
|
return new PHPResponse(
|
|
1336
1316
|
s,
|
|
1337
1317
|
r,
|
|
@@ -1395,15 +1375,15 @@ function recreateMemFS(e, t, r) {
|
|
|
1395
1375
|
return;
|
|
1396
1376
|
}
|
|
1397
1377
|
e.mkdirTree(r);
|
|
1398
|
-
const
|
|
1399
|
-
for (const
|
|
1400
|
-
recreateMemFS(e, t, joinPaths(r,
|
|
1378
|
+
const n = t.readdir(r).filter((i) => i !== "." && i !== "..");
|
|
1379
|
+
for (const i of n)
|
|
1380
|
+
recreateMemFS(e, t, joinPaths(r, i));
|
|
1401
1381
|
}
|
|
1402
1382
|
function journalFSEvents(e, t, r = () => {
|
|
1403
1383
|
}) {
|
|
1404
1384
|
function s() {
|
|
1405
1385
|
t = normalizePath(t);
|
|
1406
|
-
const
|
|
1386
|
+
const i = e[__private__dont__use].FS, a = createFSHooks(i, (u) => {
|
|
1407
1387
|
if (u.path.startsWith(t))
|
|
1408
1388
|
r(u);
|
|
1409
1389
|
else if (u.operation === "RENAME" && u.toPath.startsWith(t))
|
|
@@ -1414,29 +1394,29 @@ function journalFSEvents(e, t, r = () => {
|
|
|
1414
1394
|
))
|
|
1415
1395
|
r(_);
|
|
1416
1396
|
}), c = {};
|
|
1417
|
-
for (const [u] of Object.entries(
|
|
1418
|
-
c[u] =
|
|
1419
|
-
function
|
|
1420
|
-
for (const [u, _] of Object.entries(
|
|
1421
|
-
|
|
1422
|
-
return _(...
|
|
1397
|
+
for (const [u] of Object.entries(a))
|
|
1398
|
+
c[u] = i[u];
|
|
1399
|
+
function d() {
|
|
1400
|
+
for (const [u, _] of Object.entries(a))
|
|
1401
|
+
i[u] = function(...V) {
|
|
1402
|
+
return _(...V), c[u].apply(this, V);
|
|
1423
1403
|
};
|
|
1424
1404
|
}
|
|
1425
|
-
function
|
|
1405
|
+
function p() {
|
|
1426
1406
|
for (const [u, _] of Object.entries(c))
|
|
1427
1407
|
e[__private__dont__use].FS[u] = _;
|
|
1428
1408
|
}
|
|
1429
1409
|
e[__private__dont__use].journal = {
|
|
1430
|
-
bind:
|
|
1431
|
-
unbind:
|
|
1432
|
-
},
|
|
1410
|
+
bind: d,
|
|
1411
|
+
unbind: p
|
|
1412
|
+
}, d();
|
|
1433
1413
|
}
|
|
1434
1414
|
e.addEventListener("runtime.initialized", s), e[__private__dont__use] && s();
|
|
1435
|
-
function
|
|
1415
|
+
function n() {
|
|
1436
1416
|
e[__private__dont__use].journal.unbind(), delete e[__private__dont__use].journal;
|
|
1437
1417
|
}
|
|
1438
|
-
return e.addEventListener("runtime.beforedestroy",
|
|
1439
|
-
return e.removeEventListener("runtime.initialized", s), e.removeEventListener("runtime.beforedestroy",
|
|
1418
|
+
return e.addEventListener("runtime.beforedestroy", n), function() {
|
|
1419
|
+
return e.removeEventListener("runtime.initialized", s), e.removeEventListener("runtime.beforedestroy", n), e[__private__dont__use].journal.unbind();
|
|
1440
1420
|
};
|
|
1441
1421
|
}
|
|
1442
1422
|
const createFSHooks = (e, t = () => {
|
|
@@ -1488,16 +1468,16 @@ const createFSHooks = (e, t = () => {
|
|
|
1488
1468
|
},
|
|
1489
1469
|
rename(r, s) {
|
|
1490
1470
|
try {
|
|
1491
|
-
const
|
|
1471
|
+
const n = e.lookupPath(r, {
|
|
1492
1472
|
follow: !0
|
|
1493
|
-
}),
|
|
1473
|
+
}), i = e.lookupPath(s, {
|
|
1494
1474
|
parent: !0
|
|
1495
1475
|
}).path;
|
|
1496
1476
|
t({
|
|
1497
1477
|
operation: "RENAME",
|
|
1498
|
-
nodeType: e.isDir(
|
|
1499
|
-
path:
|
|
1500
|
-
toPath: joinPaths(
|
|
1478
|
+
nodeType: e.isDir(n.node.mode) ? "directory" : "file",
|
|
1479
|
+
path: n.path,
|
|
1480
|
+
toPath: joinPaths(i, basename(s))
|
|
1501
1481
|
});
|
|
1502
1482
|
} catch {
|
|
1503
1483
|
}
|
|
@@ -1543,52 +1523,52 @@ function normalizeFilesystemOperations(e) {
|
|
|
1543
1523
|
const t = {};
|
|
1544
1524
|
for (let r = e.length - 1; r >= 0; r--) {
|
|
1545
1525
|
for (let s = r - 1; s >= 0; s--) {
|
|
1546
|
-
const
|
|
1547
|
-
if (
|
|
1526
|
+
const n = checkRelationship(e[r], e[s]);
|
|
1527
|
+
if (n === "none")
|
|
1548
1528
|
continue;
|
|
1549
|
-
const
|
|
1550
|
-
if (
|
|
1529
|
+
const i = e[r], a = e[s];
|
|
1530
|
+
if (i.operation === "RENAME" && a.operation === "RENAME") {
|
|
1551
1531
|
console.warn(
|
|
1552
1532
|
"[FS Journal] Normalizing a double rename is not yet supported:",
|
|
1553
1533
|
{
|
|
1554
|
-
current:
|
|
1555
|
-
last:
|
|
1534
|
+
current: i,
|
|
1535
|
+
last: a
|
|
1556
1536
|
}
|
|
1557
1537
|
);
|
|
1558
1538
|
continue;
|
|
1559
1539
|
}
|
|
1560
|
-
(
|
|
1540
|
+
(a.operation === "CREATE" || a.operation === "WRITE") && (i.operation === "RENAME" ? n === "same_node" ? (t[s] = [], t[r] = [
|
|
1561
1541
|
{
|
|
1562
|
-
...
|
|
1563
|
-
path:
|
|
1542
|
+
...a,
|
|
1543
|
+
path: i.toPath
|
|
1564
1544
|
},
|
|
1565
1545
|
...t[r] || []
|
|
1566
|
-
]) :
|
|
1546
|
+
]) : n === "descendant" && (t[s] = [], t[r] = [
|
|
1567
1547
|
{
|
|
1568
|
-
...
|
|
1548
|
+
...a,
|
|
1569
1549
|
path: joinPaths(
|
|
1570
|
-
|
|
1571
|
-
|
|
1550
|
+
i.toPath,
|
|
1551
|
+
a.path.substring(i.path.length)
|
|
1572
1552
|
)
|
|
1573
1553
|
},
|
|
1574
1554
|
...t[r] || []
|
|
1575
|
-
]) :
|
|
1555
|
+
]) : i.operation === "WRITE" && n === "same_node" ? t[s] = [] : i.operation === "DELETE" && n === "same_node" && (t[s] = [], t[r] = []));
|
|
1576
1556
|
}
|
|
1577
1557
|
if (Object.entries(t).length > 0) {
|
|
1578
|
-
const s = e.flatMap((
|
|
1558
|
+
const s = e.flatMap((n, i) => i in t ? t[i] : [n]);
|
|
1579
1559
|
return normalizeFilesystemOperations(s);
|
|
1580
1560
|
}
|
|
1581
1561
|
}
|
|
1582
1562
|
return e;
|
|
1583
1563
|
}
|
|
1584
1564
|
function checkRelationship(e, t) {
|
|
1585
|
-
const r = e.path, s = e.operation !== "WRITE" && e.nodeType === "directory",
|
|
1586
|
-
return
|
|
1565
|
+
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;
|
|
1566
|
+
return i === r ? "same_node" : n && r.startsWith(i + "/") ? "ancestor" : s && i.startsWith(r + "/") ? "descendant" : "none";
|
|
1587
1567
|
}
|
|
1588
1568
|
async function hydrateUpdateFileOps(e, t) {
|
|
1589
1569
|
const s = t.filter(
|
|
1590
|
-
(
|
|
1591
|
-
).map((
|
|
1570
|
+
(n) => n.operation === "WRITE"
|
|
1571
|
+
).map((n) => hydrateOp(e, n));
|
|
1592
1572
|
return await Promise.all(s), t;
|
|
1593
1573
|
}
|
|
1594
1574
|
const hydrateLock = new Semaphore({ concurrency: 15 });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@php-wasm/fs-journal",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.3",
|
|
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": "
|
|
39
|
+
"gitHead": "0a8916ec08aa5f02de5fea308b287171e7948e4b",
|
|
40
40
|
"engines": {
|
|
41
41
|
"node": ">=18.18.2",
|
|
42
42
|
"npm": ">=8.11.0"
|