@php-wasm/fs-journal
Advanced tools
Comparing version 0.6.16 to 0.7.0
598
index.js
@@ -5,3 +5,3 @@ var Y = (e, t, r) => { | ||
}; | ||
var l = (e, t, r) => (Y(e, t, "read from private field"), r ? r.call(e) : t.get(e)), u = (e, t, r) => { | ||
var l = (e, t, r) => (Y(e, t, "read from private field"), r ? r.call(e) : t.get(e)), d = (e, t, r) => { | ||
if (t.has(e)) | ||
@@ -65,4 +65,4 @@ throw TypeError("Cannot add the same private member more than once"); | ||
new Uint8Array(i.buffer).set(c); | ||
const d = c.byteLength; | ||
n.byobRequest.respond(d), r += d, r >= s.size && n.close(); | ||
const u = c.byteLength; | ||
n.byobRequest.respond(u), r += u, r >= s.size && n.close(); | ||
} | ||
@@ -231,6 +231,20 @@ }); | ||
} | ||
const SleepFinished = Symbol("SleepFinished"); | ||
function sleep(e) { | ||
return new Promise((t) => { | ||
setTimeout(() => t(SleepFinished), e); | ||
}); | ||
} | ||
class AcquireTimeoutError extends Error { | ||
constructor() { | ||
super("Acquiring lock timed out"); | ||
} | ||
} | ||
class Semaphore { | ||
constructor({ concurrency: t }) { | ||
this._running = 0, this.concurrency = t, this.queue = []; | ||
constructor({ concurrency: t, timeout: r }) { | ||
this._running = 0, this.concurrency = t, this.timeout = r, this.queue = []; | ||
} | ||
get remaining() { | ||
return this.concurrency - this.running; | ||
} | ||
get running() { | ||
@@ -241,5 +255,13 @@ return this._running; | ||
for (; ; ) | ||
if (this._running >= this.concurrency) | ||
await new Promise((t) => this.queue.push(t)); | ||
else { | ||
if (this._running >= this.concurrency) { | ||
const t = new Promise((r) => { | ||
this.queue.push(r); | ||
}); | ||
this.timeout !== void 0 ? await Promise.race([t, sleep(this.timeout)]).then( | ||
(r) => { | ||
if (r === SleepFinished) | ||
throw new AcquireTimeoutError(); | ||
} | ||
) : await t; | ||
} else { | ||
this._running++; | ||
@@ -420,90 +442,2 @@ let t = !1; | ||
} | ||
var v, T; | ||
class PHPBrowser { | ||
/** | ||
* @param server - The PHP server to browse. | ||
* @param config - The browser configuration. | ||
*/ | ||
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 | ||
}); | ||
} | ||
/** | ||
* Sends the request to the server. | ||
* | ||
* When cookies are present in the response, this method stores | ||
* them and sends them with any subsequent requests. | ||
* | ||
* When a redirection is present in the response, this method | ||
* follows it by discarding a response and sending a subsequent | ||
* request. | ||
* | ||
* @param request - The request. | ||
* @param redirects - Internal. The number of redirects handled so far. | ||
* @returns PHPRequestHandler response. | ||
*/ | ||
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; | ||
} | ||
/** @inheritDoc */ | ||
pathToInternalUrl(t) { | ||
return this.requestHandler.pathToInternalUrl(t); | ||
} | ||
/** @inheritDoc */ | ||
internalUrlToPath(t) { | ||
return this.requestHandler.internalUrlToPath(t); | ||
} | ||
/** @inheritDoc */ | ||
get absoluteUrl() { | ||
return this.requestHandler.absoluteUrl; | ||
} | ||
/** @inheritDoc */ | ||
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"; | ||
@@ -521,12 +455,12 @@ function toRelativeUrl(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)) | ||
for (const [c, u] of Object.entries(e)) | ||
n.push(`--${t}\r | ||
`), n.push(`Content-Disposition: form-data; name="${c}"`), d instanceof File && n.push(`; filename="${d.name}"`), n.push(`\r | ||
`), d instanceof File && (n.push("Content-Type: application/octet-stream"), n.push(`\r | ||
`), n.push(`Content-Disposition: form-data; name="${c}"`), u instanceof File && n.push(`; filename="${u.name}"`), n.push(`\r | ||
`), u instanceof File && (n.push("Content-Type: application/octet-stream"), n.push(`\r | ||
`)), n.push(`\r | ||
`), d instanceof File ? n.push(await fileToUint8Array(d)) : n.push(d), n.push(`\r | ||
`), u instanceof File ? n.push(await fileToUint8Array(u)) : n.push(u), n.push(`\r | ||
`); | ||
n.push(`--${t}--\r | ||
`); | ||
const i = n.reduce((c, d) => c + d.length, 0), o = new Uint8Array(i); | ||
const i = n.reduce((c, u) => c + u.length, 0), o = new Uint8Array(i); | ||
let a = 0; | ||
@@ -548,3 +482,26 @@ for (const c of n) | ||
} | ||
var m, F, N, R, x, _, C, b, I, K, O, Z, U, X; | ||
class HttpCookieStore { | ||
constructor() { | ||
this.cookies = {}; | ||
} | ||
rememberCookiesFromResponseHeaders(t) { | ||
if (t != null && t["set-cookie"]) | ||
for (const r of t["set-cookie"]) | ||
try { | ||
if (!r.includes("=")) | ||
continue; | ||
const s = r.indexOf("="), n = r.substring(0, s), i = r.substring(s + 1).split(";")[0]; | ||
this.cookies[n] = i; | ||
} catch (s) { | ||
console.error(s); | ||
} | ||
} | ||
getCookieRequestHeader() { | ||
const t = []; | ||
for (const r in this.cookies) | ||
t.push(`${r}=${this.cookies[r]}`); | ||
return t.join("; "); | ||
} | ||
} | ||
var m, b, A, P, S, _, T, v, F, H, Z, N, X, O, ee; | ||
class PHPRequestHandler { | ||
@@ -562,3 +519,3 @@ /** | ||
*/ | ||
u(this, I); | ||
d(this, H); | ||
/** | ||
@@ -571,3 +528,3 @@ * Runs the requested PHP file with all the request and $_SERVER | ||
*/ | ||
u(this, O); | ||
d(this, N); | ||
/** | ||
@@ -582,12 +539,13 @@ * Resolve the requested path to the filesystem path of the requested PHP file. | ||
*/ | ||
u(this, U); | ||
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); | ||
p(this, b, new Semaphore({ concurrency: 1 })); | ||
d(this, O); | ||
d(this, m, void 0); | ||
d(this, b, void 0); | ||
d(this, A, void 0); | ||
d(this, P, void 0); | ||
d(this, S, void 0); | ||
d(this, _, void 0); | ||
d(this, T, void 0); | ||
d(this, v, void 0); | ||
d(this, F, void 0); | ||
p(this, v, new Semaphore({ concurrency: 1 })); | ||
const { | ||
@@ -598,20 +556,32 @@ documentRoot: s = "/www/", | ||
} = r; | ||
this.php = t, p(this, m, s); | ||
this.php = t, p(this, F, new HttpCookieStore()), p(this, m, s); | ||
const o = new URL(n); | ||
p(this, N, o.hostname), p(this, R, o.port ? Number(o.port) : o.protocol === "https:" ? 443 : 80), p(this, F, (o.protocol || "").replace(":", "")); | ||
const a = l(this, R) !== 443 && l(this, R) !== 80; | ||
p(this, x, [ | ||
l(this, N), | ||
a ? `:${l(this, R)}` : "" | ||
].join("")), p(this, _, o.pathname.replace(/\/+$/, "")), p(this, C, [ | ||
`${l(this, F)}://`, | ||
l(this, x), | ||
p(this, A, o.hostname), p(this, P, o.port ? Number(o.port) : o.protocol === "https:" ? 443 : 80), p(this, b, (o.protocol || "").replace(":", "")); | ||
const a = l(this, P) !== 443 && l(this, P) !== 80; | ||
p(this, S, [ | ||
l(this, A), | ||
a ? `:${l(this, P)}` : "" | ||
].join("")), p(this, _, o.pathname.replace(/\/+$/, "")), p(this, T, [ | ||
`${l(this, b)}://`, | ||
l(this, S), | ||
l(this, _) | ||
].join("")), this.rewriteRules = i; | ||
} | ||
/** @inheritDoc */ | ||
/** | ||
* Converts a path to an absolute URL based at the PHPRequestHandler | ||
* root. | ||
* | ||
* @param path The server path to convert to an absolute URL. | ||
* @returns The absolute URL. | ||
*/ | ||
pathToInternalUrl(t) { | ||
return `${this.absoluteUrl}${t}`; | ||
} | ||
/** @inheritDoc */ | ||
/** | ||
* Converts an absolute URL based at the PHPRequestHandler to a relative path | ||
* without the server pathname and scope. | ||
* | ||
* @param internalUrl An absolute URL based at the PHPRequestHandler root. | ||
* @returns The relative path. | ||
*/ | ||
internalUrlToPath(t) { | ||
@@ -622,13 +592,65 @@ const r = new URL(t); | ||
get isRequestRunning() { | ||
return l(this, b).running > 0; | ||
return l(this, v).running > 0; | ||
} | ||
/** @inheritDoc */ | ||
/** | ||
* The absolute URL of this PHPRequestHandler instance. | ||
*/ | ||
get absoluteUrl() { | ||
return l(this, C); | ||
return l(this, T); | ||
} | ||
/** @inheritDoc */ | ||
/** | ||
* The directory in the PHP filesystem where the server will look | ||
* for the files to serve. Default: `/var/www`. | ||
*/ | ||
get documentRoot() { | ||
return l(this, m); | ||
} | ||
/** @inheritDoc */ | ||
/** | ||
* Serves the request – either by serving a static file, or by | ||
* dispatching it to the PHP runtime. | ||
* | ||
* The request() method mode behaves like a web server and only works if | ||
* the PHP was initialized with a `requestHandler` option (which the online version | ||
* of WordPress Playground does by default). | ||
* | ||
* In the request mode, you pass an object containing the request information | ||
* (method, headers, body, etc.) and the path to the PHP file to run: | ||
* | ||
* ```ts | ||
* const php = PHP.load('7.4', { | ||
* requestHandler: { | ||
* documentRoot: "/www" | ||
* } | ||
* }) | ||
* php.writeFile("/www/index.php", `<?php echo file_get_contents("php://input");`); | ||
* const result = await php.request({ | ||
* method: "GET", | ||
* headers: { | ||
* "Content-Type": "text/plain" | ||
* }, | ||
* body: "Hello world!", | ||
* path: "/www/index.php" | ||
* }); | ||
* // result.text === "Hello world!" | ||
* ``` | ||
* | ||
* The `request()` method cannot be used in conjunction with `cli()`. | ||
* | ||
* @example | ||
* ```js | ||
* const output = await php.request({ | ||
* method: 'GET', | ||
* url: '/index.php', | ||
* headers: { | ||
* 'X-foo': 'bar', | ||
* }, | ||
* body: { | ||
* foo: 'bar', | ||
* }, | ||
* }); | ||
* console.log(output.stdout); // "Hello world!" | ||
* ``` | ||
* | ||
* @param request - PHP Request data. | ||
*/ | ||
async request(t) { | ||
@@ -646,6 +668,6 @@ const r = t.url.startsWith("http://") || t.url.startsWith("https://"), s = new URL( | ||
), i = joinPaths(l(this, m), n); | ||
return seemsLikeAPHPRequestHandlerPath(i) ? await f(this, O, Z).call(this, t, s) : f(this, I, K).call(this, i); | ||
return seemsLikeAPHPRequestHandlerPath(i) ? await f(this, N, X).call(this, t, s) : f(this, H, Z).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(), I = new WeakSet(), K = function(t) { | ||
m = new WeakMap(), b = new WeakMap(), A = new WeakMap(), P = new WeakMap(), S = new WeakMap(), _ = new WeakMap(), T = new WeakMap(), v = new WeakMap(), F = new WeakMap(), H = new WeakSet(), Z = function(t) { | ||
if (!this.php.fileExists(t)) | ||
@@ -675,5 +697,5 @@ return new PHPResponse( | ||
); | ||
}, O = new WeakSet(), Z = async function(t, r) { | ||
}, N = new WeakSet(), X = async function(t, r) { | ||
var n; | ||
if (l(this, b).running > 0 && ((n = t.headers) == null ? void 0 : n["x-request-issuer"]) === "php") | ||
if (l(this, v).running > 0 && ((n = t.headers) == null ? void 0 : n["x-request-issuer"]) === "php") | ||
return console.warn( | ||
@@ -686,12 +708,9 @@ "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." | ||
); | ||
const s = await l(this, b).acquire(); | ||
const s = await l(this, v).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 || {}) | ||
host: l(this, S), | ||
...normalizeHeaders(t.headers || {}), | ||
cookie: l(this, F).getCookieRequestHeader() | ||
}; | ||
@@ -701,8 +720,8 @@ let a = t.body; | ||
i = "POST"; | ||
const { bytes: d, contentType: h } = await encodeAsMultipart(a); | ||
a = d, o["content-type"] = h; | ||
const { bytes: u, contentType: h } = await encodeAsMultipart(a); | ||
a = u, o["content-type"] = h; | ||
} | ||
let c; | ||
try { | ||
c = f(this, U, X).call(this, decodeURIComponent(r.pathname)); | ||
c = f(this, O, ee).call(this, decodeURIComponent(r.pathname)); | ||
} catch { | ||
@@ -716,3 +735,3 @@ return new PHPResponse( | ||
try { | ||
return await this.php.run({ | ||
const u = await this.php.run({ | ||
relativeUri: ensurePathPrefix( | ||
@@ -722,4 +741,9 @@ toRelativeUrl(r), | ||
), | ||
protocol: l(this, F), | ||
protocol: l(this, b), | ||
method: t.method || i, | ||
$_SERVER: { | ||
REMOTE_ADDR: "127.0.0.1", | ||
DOCUMENT_ROOT: l(this, m), | ||
HTTPS: l(this, T).startsWith("https://") ? "on" : "" | ||
}, | ||
body: a, | ||
@@ -729,7 +753,10 @@ scriptPath: c, | ||
}); | ||
} catch (d) { | ||
const h = d; | ||
return l(this, F).rememberCookiesFromResponseHeaders( | ||
u.headers | ||
), u; | ||
} catch (u) { | ||
const h = u; | ||
if (h != null && h.response) | ||
return h.response; | ||
throw d; | ||
throw u; | ||
} | ||
@@ -739,3 +766,3 @@ } finally { | ||
} | ||
}, U = new WeakSet(), X = function(t) { | ||
}, O = new WeakSet(), ee = function(t) { | ||
let r = removePathPrefix(t, l(this, _)); | ||
@@ -784,2 +811,34 @@ 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"; | ||
return "text/plain"; | ||
case "pdf": | ||
return "application/pdf"; | ||
case "webp": | ||
return "image/webp"; | ||
case "mp3": | ||
return "audio/mpeg"; | ||
case "mp4": | ||
return "video/mp4"; | ||
case "csv": | ||
return "text/csv"; | ||
case "xls": | ||
return "application/vnd.ms-excel"; | ||
case "xlsx": | ||
return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; | ||
case "doc": | ||
return "application/msword"; | ||
case "docx": | ||
return "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; | ||
case "ppt": | ||
return "application/vnd.ms-powerpoint"; | ||
case "pptx": | ||
return "application/vnd.openxmlformats-officedocument.presentationml.presentation"; | ||
case "zip": | ||
return "application/zip"; | ||
case "rar": | ||
return "application/x-rar-compressed"; | ||
case "tar": | ||
return "application/x-tar"; | ||
case "gz": | ||
return "application/gzip"; | ||
case "7z": | ||
return "application/x-7z-compressed"; | ||
default: | ||
@@ -897,4 +956,4 @@ return "application-octet-stream"; | ||
if (c in FileErrorCodes) { | ||
const d = FileErrorCodes[c], h = typeof o[0] == "string" ? o[0] : null, P = h !== null ? e.replaceAll("{path}", h) : e; | ||
throw new Error(`${P}: ${d}`, { | ||
const u = FileErrorCodes[c], h = typeof o[0] == "string" ? o[0] : null, g = h !== null ? e.replaceAll("{path}", h) : e; | ||
throw new Error(`${g}: ${u}`, { | ||
cause: a | ||
@@ -927,3 +986,3 @@ }); | ||
} | ||
var S, k, A, y, w, g, E, H, M, ee, B, te, L, re, D, se, q, ne, $, ie, W, oe, j, ae, z, le, G, ce, J, ue, Q, de; | ||
var R, x, k, y, w, E, C, I, te, M, re, U, se, B, ne, L, ie, D, oe, $, ae, q, le, W, ce, j, ue, z, de, G, he, J, pe, V, fe, Q, _e; | ||
class BasePHP { | ||
@@ -938,25 +997,34 @@ /** | ||
constructor(e, t) { | ||
u(this, M); | ||
u(this, B); | ||
u(this, L); | ||
u(this, D); | ||
u(this, q); | ||
u(this, $); | ||
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); | ||
p(this, S, []), p(this, y, !1), p(this, w, null), p(this, g, {}), p(this, E, /* @__PURE__ */ 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) | ||
)); | ||
/** | ||
* Prepares the $_SERVER entries for the PHP runtime. | ||
* | ||
* @param defaults Default entries to include in $_SERVER. | ||
* @param headers HTTP headers to include in $_SERVER (as HTTP_ prefixed entries). | ||
* @param port HTTP port, used to determine infer $_SERVER['HTTPS'] value if none | ||
* was provided. | ||
* @returns Computed $_SERVER entries. | ||
*/ | ||
d(this, I); | ||
d(this, M); | ||
d(this, U); | ||
d(this, B); | ||
d(this, L); | ||
d(this, D); | ||
d(this, $); | ||
d(this, q); | ||
d(this, W); | ||
d(this, j); | ||
d(this, z); | ||
d(this, G); | ||
d(this, J); | ||
d(this, V); | ||
d(this, Q); | ||
d(this, R, void 0); | ||
d(this, x, void 0); | ||
d(this, k, void 0); | ||
d(this, y, void 0); | ||
d(this, w, void 0); | ||
d(this, E, void 0); | ||
d(this, C, void 0); | ||
p(this, R, []), p(this, y, !1), p(this, w, null), p(this, E, /* @__PURE__ */ new Map()), p(this, C, []), this.semaphore = new Semaphore({ concurrency: 1 }), e !== void 0 && this.initializeRuntime(e), t && (this.requestHandler = new PHPRequestHandler(this, t)); | ||
} | ||
@@ -978,3 +1046,3 @@ addEventListener(e, t) { | ||
async onMessage(e) { | ||
l(this, H).push(e); | ||
l(this, C).push(e); | ||
} | ||
@@ -987,17 +1055,15 @@ /** @inheritDoc */ | ||
get absoluteUrl() { | ||
return this.requestHandler.requestHandler.absoluteUrl; | ||
return this.requestHandler.absoluteUrl; | ||
} | ||
/** @inheritDoc */ | ||
get documentRoot() { | ||
return this.requestHandler.requestHandler.documentRoot; | ||
return this.requestHandler.documentRoot; | ||
} | ||
/** @inheritDoc */ | ||
pathToInternalUrl(e) { | ||
return this.requestHandler.requestHandler.pathToInternalUrl(e); | ||
return this.requestHandler.pathToInternalUrl(e); | ||
} | ||
/** @inheritDoc */ | ||
internalUrlToPath(e) { | ||
return this.requestHandler.requestHandler.internalUrlToPath( | ||
e | ||
); | ||
return this.requestHandler.internalUrlToPath(e); | ||
} | ||
@@ -1011,3 +1077,3 @@ initializeRuntime(e) { | ||
this[__private__dont__use] = t, t.onMessage = async (r) => { | ||
for (const s of l(this, H)) { | ||
for (const s of l(this, C)) { | ||
const n = await s(r); | ||
@@ -1033,3 +1099,3 @@ if (n) | ||
); | ||
p(this, A, e); | ||
p(this, k, e); | ||
} | ||
@@ -1040,3 +1106,3 @@ /** @inheritDoc */ | ||
throw new Error("Cannot set PHP ini path after calling run()."); | ||
p(this, k, e), this[__private__dont__use].ccall( | ||
p(this, x, e), this[__private__dont__use].ccall( | ||
"wasm_set_phpini_path", | ||
@@ -1052,3 +1118,3 @@ null, | ||
throw new Error("Cannot set PHP ini entries after calling run()."); | ||
l(this, S).push([e, t]); | ||
l(this, R).push([e, t]); | ||
} | ||
@@ -1060,6 +1126,6 @@ /** @inheritDoc */ | ||
/** @inheritDoc */ | ||
async request(e, t) { | ||
async request(e) { | ||
if (!this.requestHandler) | ||
throw new Error("No request handler available."); | ||
return this.requestHandler.request(e, t); | ||
return this.requestHandler.request(e); | ||
} | ||
@@ -1071,23 +1137,26 @@ /** @inheritDoc */ | ||
try { | ||
if (l(this, y) || (f(this, M, ee).call(this), p(this, y, !0)), e.scriptPath && !this.fileExists(e.scriptPath)) | ||
if (l(this, y) || (f(this, M, re).call(this), p(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, q, 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, $, 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) { | ||
console.warn("PHP.run() output was:", o.text); | ||
const a = new PHPExecutionFailureError( | ||
`PHP.run() failed with exit code ${o.exitCode} and the following output: ` + o.errors, | ||
o, | ||
f(this, z, de).call(this, e.scriptPath || ""), f(this, B, ne).call(this, e.relativeUri || ""), f(this, q, le).call(this, e.method || "GET"); | ||
const s = normalizeHeaders(e.headers || {}), n = s.host || "example.com:443", i = f(this, $, ae).call(this, n, e.protocol || "http"); | ||
f(this, L, ie).call(this, n), f(this, D, oe).call(this, i), f(this, W, ce).call(this, s), e.body && (r = f(this, j, ue).call(this, e.body)), typeof e.code == "string" && f(this, V, fe).call(this, " ?>" + e.code); | ||
const o = f(this, I, te).call(this, e.$_SERVER, s, i); | ||
for (const u in o) | ||
f(this, G, he).call(this, u, o[u]); | ||
const a = e.env || {}; | ||
for (const u in a) | ||
f(this, J, pe).call(this, u, a[u]); | ||
const c = await f(this, Q, _e).call(this); | ||
if (c.exitCode !== 0) { | ||
console.warn("PHP.run() output was:", c.text); | ||
const u = new PHPExecutionFailureError( | ||
`PHP.run() failed with exit code ${c.exitCode} and the following output: ` + c.errors, | ||
c, | ||
"request" | ||
); | ||
throw console.error(a), a; | ||
throw console.error(u), u; | ||
} | ||
return o; | ||
return c; | ||
} catch (s) { | ||
@@ -1110,5 +1179,2 @@ throw this.dispatchEvent({ | ||
} | ||
addServerGlobalEntry(e, t) { | ||
l(this, g)[e] = t; | ||
} | ||
defineConstant(e, t) { | ||
@@ -1201,5 +1267,9 @@ let r = {}; | ||
* @param runtime | ||
* @param cwd. Internal, the VFS path to recreate in the new runtime. | ||
* This arg is temporary and will be removed once BasePHP | ||
* is fully decoupled from the request handler and | ||
* accepts a constructor-level cwd argument. | ||
*/ | ||
hotSwapPHPRuntime(e) { | ||
const t = this[__private__dont__use].FS; | ||
hotSwapPHPRuntime(e, t) { | ||
const r = this[__private__dont__use].FS; | ||
try { | ||
@@ -1209,6 +1279,3 @@ this.exit(); | ||
} | ||
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); | ||
} | ||
this.initializeRuntime(e), l(this, x) && this.setPhpIniPath(l(this, x)), l(this, k) && this.setSapiName(l(this, k)), t && copyFS(r, this[__private__dont__use].FS, t); | ||
} | ||
@@ -1226,3 +1293,13 @@ exit(e = 0) { | ||
} | ||
S = new WeakMap(), k = new WeakMap(), A = new WeakMap(), y = new WeakMap(), w = new WeakMap(), g = new WeakMap(), E = new WeakMap(), H = new WeakMap(), M = new WeakSet(), ee = function() { | ||
R = new WeakMap(), x = new WeakMap(), k = new WeakMap(), y = new WeakMap(), w = new WeakMap(), E = new WeakMap(), C = new WeakMap(), I = new WeakSet(), te = function(e, t, r) { | ||
const s = { | ||
...e || {} | ||
}; | ||
s.HTTPS = s.HTTPS || r === 443 ? "on" : "off"; | ||
for (const n in t) { | ||
let i = "HTTP_"; | ||
["content-type", "content-length"].includes(n.toLowerCase()) && (i = ""), s[`${i}${n.toUpperCase().replace(/-/g, "_")}`] = t[n]; | ||
} | ||
return s; | ||
}, M = new WeakSet(), re = function() { | ||
if (this.setPhpIniEntry("auto_prepend_file", "/internal/consts.php"), this.fileExists("/internal/consts.php") || this.writeFile( | ||
@@ -1239,4 +1316,4 @@ "/internal/consts.php", | ||
}` | ||
), l(this, S).length > 0) { | ||
const e = l(this, S).map(([t, r]) => `${t}=${r}`).join(` | ||
), l(this, R).length > 0) { | ||
const e = l(this, R).map(([t, r]) => `${t}=${r}`).join(` | ||
`) + ` | ||
@@ -1253,3 +1330,3 @@ | ||
this[__private__dont__use].ccall("php_wasm_init", null, [], []); | ||
}, B = new WeakSet(), te = function() { | ||
}, U = new WeakSet(), se = function() { | ||
const e = "/internal/headers.json"; | ||
@@ -1271,3 +1348,3 @@ if (!this.fileExists(e)) | ||
}; | ||
}, L = new WeakSet(), re = function(e) { | ||
}, B = new WeakSet(), ne = function(e) { | ||
if (this[__private__dont__use].ccall( | ||
@@ -1287,3 +1364,3 @@ "wasm_set_request_uri", | ||
} | ||
}, D = new WeakSet(), se = function(e, t) { | ||
}, L = new WeakSet(), ie = function(e) { | ||
this[__private__dont__use].ccall( | ||
@@ -1295,2 +1372,10 @@ "wasm_set_request_host", | ||
); | ||
}, D = new WeakSet(), oe = function(e) { | ||
this[__private__dont__use].ccall( | ||
"wasm_set_request_port", | ||
null, | ||
[NUMBER], | ||
[e] | ||
); | ||
}, $ = new WeakSet(), ae = function(e, t) { | ||
let r; | ||
@@ -1301,9 +1386,4 @@ try { | ||
} | ||
(!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"); | ||
}, q = new WeakSet(), ne = function(e) { | ||
return (!r || isNaN(r) || r === 80) && (r = t === "https" ? 443 : 80), r; | ||
}, q = new WeakSet(), le = function(e) { | ||
this[__private__dont__use].ccall( | ||
@@ -1315,3 +1395,3 @@ "wasm_set_request_method", | ||
); | ||
}, $ = new WeakSet(), ie = function(e) { | ||
}, W = new WeakSet(), ce = function(e) { | ||
e.cookie && this[__private__dont__use].ccall( | ||
@@ -1333,10 +1413,3 @@ "wasm_set_cookies", | ||
); | ||
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) { | ||
}, j = new WeakSet(), ue = function(e) { | ||
let t, r; | ||
@@ -1364,3 +1437,3 @@ typeof e == "string" ? (console.warn( | ||
), s; | ||
}, j = new WeakSet(), ae = function(e) { | ||
}, z = new WeakSet(), de = function(e) { | ||
this[__private__dont__use].ccall( | ||
@@ -1372,12 +1445,11 @@ "wasm_set_path_translated", | ||
); | ||
}, 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) { | ||
}, G = new WeakSet(), he = function(e, t) { | ||
this[__private__dont__use].ccall( | ||
"wasm_add_SERVER_entry", | ||
null, | ||
[STRING, STRING], | ||
[e, t] | ||
); | ||
}, J = new WeakSet(), pe = function(e, t) { | ||
this[__private__dont__use].ccall( | ||
"wasm_add_ENV_entry", | ||
@@ -1388,3 +1460,3 @@ null, | ||
); | ||
}, J = new WeakSet(), ue = function(e) { | ||
}, V = new WeakSet(), fe = function(e) { | ||
this[__private__dont__use].ccall( | ||
@@ -1396,3 +1468,3 @@ "wasm_set_php_code", | ||
); | ||
}, Q = new WeakSet(), de = async function() { | ||
}, Q = new WeakSet(), _e = async function() { | ||
var n; | ||
@@ -1403,6 +1475,6 @@ let e, t; | ||
var c; | ||
t = (d) => { | ||
console.error(d), console.error(d.error); | ||
t = (u) => { | ||
console.error(u), console.error(u.error); | ||
const h = new Error("Rethrown"); | ||
h.cause = d.error, h.betterMessage = d.message, o(h); | ||
h.cause = u.error, h.betterMessage = u.message, o(h); | ||
}, (c = l(this, w)) == null || c.addEventListener( | ||
@@ -1422,4 +1494,4 @@ "error", | ||
} catch (i) { | ||
for (const d in this) | ||
typeof this[d] == "function" && (this[d] = () => { | ||
for (const u in this) | ||
typeof this[u] == "function" && (this[u] = () => { | ||
throw new Error( | ||
@@ -1433,5 +1505,5 @@ "PHP runtime has crashed – see the earlier error for details." | ||
} finally { | ||
(n = l(this, w)) == null || n.removeEventListener("error", t), p(this, g, {}); | ||
(n = l(this, w)) == null || n.removeEventListener("error", t); | ||
} | ||
const { headers: r, httpStatusCode: s } = f(this, B, te).call(this); | ||
const { headers: r, httpStatusCode: s } = f(this, U, se).call(this); | ||
return new PHPResponse( | ||
@@ -1507,3 +1579,3 @@ e === 0 ? s : 500, | ||
else if (h.operation === "RENAME" && h.toPath.startsWith(t)) | ||
for (const P of recordExistingPath( | ||
for (const g of recordExistingPath( | ||
e, | ||
@@ -1513,3 +1585,3 @@ h.path, | ||
)) | ||
r(P); | ||
r(g); | ||
}), a = {}; | ||
@@ -1519,14 +1591,14 @@ for (const [h] of Object.entries(o)) | ||
function c() { | ||
for (const [h, P] of Object.entries(o)) | ||
i[h] = function(...V) { | ||
return P(...V), a[h].apply(this, V); | ||
for (const [h, g] of Object.entries(o)) | ||
i[h] = function(...K) { | ||
return g(...K), a[h].apply(this, K); | ||
}; | ||
} | ||
function d() { | ||
for (const [h, P] of Object.entries(a)) | ||
e[__private__dont__use].FS[h] = P; | ||
function u() { | ||
for (const [h, g] of Object.entries(a)) | ||
e[__private__dont__use].FS[h] = g; | ||
} | ||
e[__private__dont__use].journal = { | ||
bind: c, | ||
unbind: d | ||
unbind: u | ||
}, c(); | ||
@@ -1533,0 +1605,0 @@ } |
{ | ||
"name": "@php-wasm/fs-journal", | ||
"version": "0.6.16", | ||
"version": "0.7.0", | ||
"description": "Bindings to journal the PHP filesystem", | ||
@@ -39,3 +39,3 @@ "repository": { | ||
"license": "GPL-2.0-or-later", | ||
"gitHead": "1981567e7eacecbc4a18c870267c20bf489afd8f", | ||
"gitHead": "c5eba3d709f2821c4303521e8c81b962e3bcca23", | ||
"engines": { | ||
@@ -42,0 +42,0 @@ "node": ">=18.18.0", |
Sorry, the diff of this file is not supported yet
93628
2018