@php-wasm/universal
Advanced tools
Comparing version 0.3.1 to 0.4.0
1169
index.js
@@ -1,3 +0,13 @@ | ||
const v = Symbol("error"), E = Symbol("message"); | ||
class b extends Event { | ||
var se = (s, e, t) => { | ||
if (!e.has(s)) | ||
throw TypeError("Cannot " + t); | ||
}; | ||
var i = (s, e, t) => (se(s, e, "read from private field"), t ? t.call(s) : e.get(s)), l = (s, e, t) => { | ||
if (e.has(s)) | ||
throw TypeError("Cannot add the same private member more than once"); | ||
e instanceof WeakSet ? e.add(s) : e.set(s, t); | ||
}, p = (s, e, t, r) => (se(s, e, "write to private field"), r ? r.call(s, t) : e.set(s, t), t); | ||
var m = (s, e, t) => (se(s, e, "access private method"), t); | ||
const ie = Symbol("error"), oe = Symbol("message"); | ||
class ne extends Event { | ||
/** | ||
@@ -11,18 +21,18 @@ * Create a new `ErrorEvent`. | ||
constructor(e, t = {}) { | ||
super(e), this[v] = t.error === void 0 ? null : t.error, this[E] = t.message === void 0 ? "" : t.message; | ||
super(e), this[ie] = t.error === void 0 ? null : t.error, this[oe] = t.message === void 0 ? "" : t.message; | ||
} | ||
get error() { | ||
return this[v]; | ||
return this[ie]; | ||
} | ||
get message() { | ||
return this[E]; | ||
return this[oe]; | ||
} | ||
} | ||
Object.defineProperty(b.prototype, "error", { enumerable: !0 }); | ||
Object.defineProperty(b.prototype, "message", { enumerable: !0 }); | ||
const U = typeof globalThis.ErrorEvent == "function" ? globalThis.ErrorEvent : b; | ||
function I(s) { | ||
return s instanceof Error ? "exitCode" in s && s?.exitCode === 0 || s?.name === "ExitStatus" && "status" in s && s.status === 0 : !1; | ||
Object.defineProperty(ne.prototype, "error", { enumerable: !0 }); | ||
Object.defineProperty(ne.prototype, "message", { enumerable: !0 }); | ||
const Ae = typeof globalThis.ErrorEvent == "function" ? globalThis.ErrorEvent : ne; | ||
function Oe(s) { | ||
return s instanceof Error ? "exitCode" in s && (s == null ? void 0 : s.exitCode) === 0 || (s == null ? void 0 : s.name) === "ExitStatus" && "status" in s && s.status === 0 : !1; | ||
} | ||
class L extends EventTarget { | ||
class Ie extends EventTarget { | ||
constructor() { | ||
@@ -41,7 +51,7 @@ super(...arguments), this.listenersCount = 0; | ||
} | ||
function N(s) { | ||
function Le(s) { | ||
s.asm = { | ||
...s.asm | ||
}; | ||
const e = new L(); | ||
const e = new Ie(); | ||
for (const t in s.asm) | ||
@@ -51,16 +61,17 @@ if (typeof s.asm[t] == "function") { | ||
s.asm[t] = function(...n) { | ||
var o; | ||
try { | ||
return r(...n); | ||
} catch (o) { | ||
if (!(o instanceof Error)) | ||
throw o; | ||
const i = M( | ||
o, | ||
s.lastAsyncifyStackSource?.stack | ||
} catch (a) { | ||
if (!(a instanceof Error)) | ||
throw a; | ||
const h = Ne( | ||
a, | ||
(o = s.lastAsyncifyStackSource) == null ? void 0 : o.stack | ||
); | ||
if (s.lastAsyncifyStackSource && (o.cause = s.lastAsyncifyStackSource), e.hasListeners()) { | ||
if (s.lastAsyncifyStackSource && (a.cause = s.lastAsyncifyStackSource), e.hasListeners()) { | ||
e.dispatchEvent( | ||
new U("error", { | ||
error: o, | ||
message: i | ||
new Ae("error", { | ||
error: a, | ||
message: h | ||
}) | ||
@@ -70,3 +81,3 @@ ); | ||
} | ||
throw I(o) || D(i), o; | ||
throw Oe(a) || De(h), a; | ||
} | ||
@@ -77,9 +88,9 @@ }; | ||
} | ||
let w = []; | ||
function $() { | ||
return w; | ||
let re = []; | ||
function Ue() { | ||
return re; | ||
} | ||
function M(s, e) { | ||
function Ne(s, e) { | ||
if (s.message === "unreachable") { | ||
let t = q; | ||
let t = Me; | ||
e || (t += ` | ||
@@ -90,6 +101,6 @@ | ||
`), w = W( | ||
`), re = je( | ||
e || s.stack || "" | ||
); | ||
for (const r of w) | ||
for (const r of re) | ||
t += ` * ${r} | ||
@@ -101,3 +112,3 @@ `; | ||
} | ||
const q = ` | ||
const Me = ` | ||
"unreachable" WASM instruction executed. | ||
@@ -126,16 +137,16 @@ | ||
`, _ = "\x1B[41m", B = "\x1B[1m", R = "\x1B[0m", x = "\x1B[K"; | ||
let S = !1; | ||
function D(s) { | ||
if (!S) { | ||
S = !0, console.log(`${_} | ||
${x} | ||
${B} WASM ERROR${R}${_}`); | ||
`, ae = "\x1B[41m", qe = "\x1B[1m", le = "\x1B[0m", ce = "\x1B[K"; | ||
let he = !1; | ||
function De(s) { | ||
if (!he) { | ||
he = !0, console.log(`${ae} | ||
${ce} | ||
${qe} WASM ERROR${le}${ae}`); | ||
for (const e of s.split(` | ||
`)) | ||
console.log(`${x} ${e} `); | ||
console.log(`${R}`); | ||
console.log(`${ce} ${e} `); | ||
console.log(`${le}`); | ||
} | ||
} | ||
function W(s) { | ||
function je(s) { | ||
try { | ||
@@ -157,3 +168,3 @@ const e = s.split(` | ||
} | ||
class g { | ||
class F { | ||
constructor(e, t, r, n = "", o = 0) { | ||
@@ -163,3 +174,3 @@ this.httpStatusCode = e, this.headers = t, this.bytes = r, this.exitCode = o, this.errors = n; | ||
static fromRawData(e) { | ||
return new g( | ||
return new F( | ||
e.httpStatusCode, | ||
@@ -194,3 +205,4 @@ e.headers, | ||
} | ||
const F = [ | ||
const me = [ | ||
"8.3", | ||
"8.2", | ||
@@ -203,5 +215,4 @@ "8.1", | ||
"7.1", | ||
"7.0", | ||
"5.6" | ||
], ie = F[0], ae = F, j = [ | ||
"7.0" | ||
], ot = me[0], at = me, Be = [ | ||
"iconv", | ||
@@ -211,8 +222,7 @@ "mbstring", | ||
"gd" | ||
], le = { | ||
"kitchen-sink": j | ||
], lt = { | ||
"kitchen-sink": Be | ||
}; | ||
class z { | ||
#e; | ||
#t; | ||
var S, $; | ||
class We { | ||
/** | ||
@@ -223,7 +233,9 @@ * @param server - The PHP server to browse. | ||
constructor(e, t = {}) { | ||
this.requestHandler = e, this.#e = {}, this.#t = { | ||
l(this, S, void 0); | ||
l(this, $, void 0); | ||
this.requestHandler = e, p(this, S, {}), p(this, $, { | ||
handleRedirects: !1, | ||
maxRedirects: 4, | ||
...t | ||
}; | ||
}); | ||
} | ||
@@ -249,6 +261,6 @@ /** | ||
...e.headers, | ||
cookie: this.#r() | ||
cookie: this.serializeCookies() | ||
} | ||
}); | ||
if (r.headers["set-cookie"] && this.#s(r.headers["set-cookie"]), this.#t.handleRedirects && r.headers.location && t < this.#t.maxRedirects) { | ||
if (r.headers["set-cookie"] && this.setCookies(r.headers["set-cookie"]), i(this, $).handleRedirects && r.headers.location && t < i(this, $).maxRedirects) { | ||
const n = new URL( | ||
@@ -285,3 +297,3 @@ r.headers.location[0], | ||
} | ||
#s(e) { | ||
setCookies(e) { | ||
for (const t of e) | ||
@@ -292,3 +304,3 @@ try { | ||
const r = t.indexOf("="), n = t.substring(0, r), o = t.substring(r + 1).split(";")[0]; | ||
this.#e[n] = o; | ||
i(this, S)[n] = o; | ||
} catch (r) { | ||
@@ -298,10 +310,11 @@ console.error(r); | ||
} | ||
#r() { | ||
serializeCookies() { | ||
const e = []; | ||
for (const t in this.#e) | ||
e.push(`${t}=${this.#e[t]}`); | ||
for (const t in i(this, S)) | ||
e.push(`${t}=${i(this, S)[t]}`); | ||
return e.join("; "); | ||
} | ||
} | ||
class G { | ||
S = new WeakMap(), $ = new WeakMap(); | ||
class ye { | ||
constructor({ concurrency: e }) { | ||
@@ -334,21 +347,14 @@ this._running = 0, this.concurrency = e, this.queue = []; | ||
} | ||
const V = "http://example.com"; | ||
function k(s) { | ||
const ze = "http://example.com"; | ||
function ue(s) { | ||
return s.toString().substring(s.origin.length); | ||
} | ||
function H(s, e) { | ||
function de(s, e) { | ||
return !e || !s.startsWith(e) ? s : s.substring(e.length); | ||
} | ||
function Y(s, e) { | ||
function Ge(s, e) { | ||
return !e || s.startsWith(e) ? s : e + s; | ||
} | ||
class J { | ||
#e; | ||
#t; | ||
#s; | ||
#r; | ||
#o; | ||
#n; | ||
#i; | ||
#a; | ||
var b, A, N, k, O, _, I, L, D, ge, j, we, B, Pe; | ||
class Ve { | ||
/** | ||
@@ -359,19 +365,52 @@ * @param php - The PHP instance. | ||
constructor(e, t = {}) { | ||
this.#a = new G({ concurrency: 1 }); | ||
/** | ||
* Serves a static file from the PHP filesystem. | ||
* | ||
* @param fsPath - Absolute path of the static file to serve. | ||
* @returns The response. | ||
*/ | ||
l(this, D); | ||
/** | ||
* Runs the requested PHP file with all the request and $_SERVER | ||
* superglobals populated. | ||
* | ||
* @param request - The request. | ||
* @returns The response. | ||
*/ | ||
l(this, j); | ||
/** | ||
* Resolve the requested path to the filesystem path of the requested PHP file. | ||
* | ||
* Fall back to index.php as if there was a url rewriting rule in place. | ||
* | ||
* @param requestedPath - The requested pathname. | ||
* @throws {Error} If the requested path doesn't exist. | ||
* @returns The resolved filesystem path. | ||
*/ | ||
l(this, B); | ||
l(this, b, void 0); | ||
l(this, A, void 0); | ||
l(this, N, void 0); | ||
l(this, k, void 0); | ||
l(this, O, void 0); | ||
l(this, _, void 0); | ||
l(this, I, void 0); | ||
l(this, L, void 0); | ||
p(this, L, new ye({ concurrency: 1 })); | ||
const { | ||
documentRoot: r = "/www/", | ||
absoluteUrl: n = typeof location == "object" ? location?.href : "" | ||
absoluteUrl: n = typeof location == "object" ? location == null ? void 0 : location.href : "" | ||
} = t; | ||
this.php = e, this.#e = r; | ||
this.php = e, p(this, b, r); | ||
const o = new URL(n); | ||
this.#s = o.hostname, this.#r = o.port ? Number(o.port) : o.protocol === "https:" ? 443 : 80, this.#t = (o.protocol || "").replace(":", ""); | ||
const i = this.#r !== 443 && this.#r !== 80; | ||
this.#o = [ | ||
this.#s, | ||
i ? `:${this.#r}` : "" | ||
].join(""), this.#n = o.pathname.replace(/\/+$/, ""), this.#i = [ | ||
`${this.#t}://`, | ||
this.#o, | ||
this.#n | ||
].join(""); | ||
p(this, N, o.hostname), p(this, k, o.port ? Number(o.port) : o.protocol === "https:" ? 443 : 80), p(this, A, (o.protocol || "").replace(":", "")); | ||
const a = i(this, k) !== 443 && i(this, k) !== 80; | ||
p(this, O, [ | ||
i(this, N), | ||
a ? `:${i(this, k)}` : "" | ||
].join("")), p(this, _, o.pathname.replace(/\/+$/, "")), p(this, I, [ | ||
`${i(this, A)}://`, | ||
i(this, O), | ||
i(this, _) | ||
].join("")); | ||
} | ||
@@ -385,14 +424,14 @@ /** @inheritDoc */ | ||
const t = new URL(e); | ||
return t.pathname.startsWith(this.#n) && (t.pathname = t.pathname.slice(this.#n.length)), k(t); | ||
return t.pathname.startsWith(i(this, _)) && (t.pathname = t.pathname.slice(i(this, _).length)), ue(t); | ||
} | ||
get isRequestRunning() { | ||
return this.#a.running > 0; | ||
return i(this, L).running > 0; | ||
} | ||
/** @inheritDoc */ | ||
get absoluteUrl() { | ||
return this.#i; | ||
return i(this, I); | ||
} | ||
/** @inheritDoc */ | ||
get documentRoot() { | ||
return this.#e; | ||
return i(this, b); | ||
} | ||
@@ -403,126 +442,103 @@ /** @inheritDoc */ | ||
e.url, | ||
t ? void 0 : V | ||
), n = H( | ||
t ? void 0 : ze | ||
), n = de( | ||
r.pathname, | ||
this.#n | ||
), o = `${this.#e}${n}`; | ||
return Q(o) ? await this.#c(e, r) : this.#l(o); | ||
i(this, _) | ||
), o = `${i(this, b)}${n}`; | ||
return Ke(o) ? await m(this, j, we).call(this, e, r) : m(this, D, ge).call(this, o); | ||
} | ||
/** | ||
* Serves a static file from the PHP filesystem. | ||
* | ||
* @param fsPath - Absolute path of the static file to serve. | ||
* @returns The response. | ||
*/ | ||
#l(e) { | ||
if (!this.php.fileExists(e)) | ||
return new g( | ||
404, | ||
// Let the service worker know that no static file was found | ||
// and that it's okay to issue a real fetch() to the server. | ||
{ | ||
"x-file-type": ["static"] | ||
}, | ||
new TextEncoder().encode("404 File not found") | ||
); | ||
const t = this.php.readFileAsBuffer(e); | ||
return new g( | ||
200, | ||
} | ||
b = new WeakMap(), A = new WeakMap(), N = new WeakMap(), k = new WeakMap(), O = new WeakMap(), _ = new WeakMap(), I = new WeakMap(), L = new WeakMap(), D = new WeakSet(), ge = function(e) { | ||
if (!this.php.fileExists(e)) | ||
return new F( | ||
404, | ||
// Let the service worker know that no static file was found | ||
// and that it's okay to issue a real fetch() to the server. | ||
{ | ||
"content-length": [`${t.byteLength}`], | ||
// @TODO: Infer the content-type from the arrayBuffer instead of the file path. | ||
// The code below won't return the correct mime-type if the extension | ||
// was tampered with. | ||
"content-type": [Z(e)], | ||
"accept-ranges": ["bytes"], | ||
"cache-control": ["public, max-age=0"] | ||
"x-file-type": ["static"] | ||
}, | ||
t | ||
new TextEncoder().encode("404 File not found") | ||
); | ||
} | ||
/** | ||
* Runs the requested PHP file with all the request and $_SERVER | ||
* superglobals populated. | ||
* | ||
* @param request - The request. | ||
* @returns The response. | ||
*/ | ||
async #c(e, t) { | ||
const r = await this.#a.acquire(); | ||
const t = this.php.readFileAsBuffer(e); | ||
return new F( | ||
200, | ||
{ | ||
"content-length": [`${t.byteLength}`], | ||
// @TODO: Infer the content-type from the arrayBuffer instead of the file path. | ||
// The code below won't return the correct mime-type if the extension | ||
// was tampered with. | ||
"content-type": [Ye(e)], | ||
"accept-ranges": ["bytes"], | ||
"cache-control": ["public, max-age=0"] | ||
}, | ||
t | ||
); | ||
}, j = new WeakSet(), we = async function(e, t) { | ||
var n; | ||
const r = await i(this, L).acquire(); | ||
try { | ||
this.php.addServerGlobalEntry("DOCUMENT_ROOT", i(this, b)), this.php.addServerGlobalEntry( | ||
"HTTPS", | ||
i(this, I).startsWith("https://") ? "on" : "" | ||
); | ||
let o = "GET"; | ||
const a = { | ||
host: i(this, O), | ||
...$e(e.headers || {}) | ||
}, h = []; | ||
if (e.files && Object.keys(e.files).length) { | ||
o = "POST"; | ||
for (const u in e.files) { | ||
const E = e.files[u]; | ||
h.push({ | ||
key: u, | ||
name: E.name, | ||
type: E.type, | ||
data: new Uint8Array(await E.arrayBuffer()) | ||
}); | ||
} | ||
(n = a["content-type"]) != null && n.startsWith("multipart/form-data") && (e.formData = Je( | ||
e.body || "" | ||
), a["content-type"] = "application/x-www-form-urlencoded", delete e.body); | ||
} | ||
let d; | ||
e.formData !== void 0 ? (o = "POST", a["content-type"] = a["content-type"] || "application/x-www-form-urlencoded", d = new URLSearchParams( | ||
e.formData | ||
).toString()) : d = e.body; | ||
let f; | ||
try { | ||
this.php.addServerGlobalEntry("DOCUMENT_ROOT", this.#e), this.php.addServerGlobalEntry( | ||
"HTTPS", | ||
this.#i.startsWith("https://") ? "on" : "" | ||
f = m(this, B, Pe).call(this, t.pathname); | ||
} catch { | ||
return new F( | ||
404, | ||
{}, | ||
new TextEncoder().encode("404 File not found") | ||
); | ||
let n = "GET"; | ||
const o = { | ||
host: this.#o, | ||
...A(e.headers || {}) | ||
}, i = []; | ||
if (e.files && Object.keys(e.files).length) { | ||
n = "POST"; | ||
for (const c in e.files) { | ||
const m = e.files[c]; | ||
i.push({ | ||
key: c, | ||
name: m.name, | ||
type: m.type, | ||
data: new Uint8Array(await m.arrayBuffer()) | ||
}); | ||
} | ||
o["content-type"]?.startsWith("multipart/form-data") && (e.formData = K( | ||
e.body || "" | ||
), o["content-type"] = "application/x-www-form-urlencoded", delete e.body); | ||
} | ||
let l; | ||
e.formData !== void 0 ? (n = "POST", o["content-type"] = o["content-type"] || "application/x-www-form-urlencoded", l = new URLSearchParams( | ||
e.formData | ||
).toString()) : l = e.body; | ||
let h; | ||
try { | ||
h = this.#h(t.pathname); | ||
} catch { | ||
return new g( | ||
404, | ||
{}, | ||
new TextEncoder().encode("404 File not found") | ||
); | ||
} | ||
return await this.php.run({ | ||
relativeUri: Y( | ||
k(t), | ||
this.#n | ||
), | ||
protocol: this.#t, | ||
method: e.method || n, | ||
body: l, | ||
fileInfos: i, | ||
scriptPath: h, | ||
headers: o | ||
}); | ||
} finally { | ||
r(); | ||
} | ||
return await this.php.run({ | ||
relativeUri: Ge( | ||
ue(t), | ||
i(this, _) | ||
), | ||
protocol: i(this, A), | ||
method: e.method || o, | ||
body: d, | ||
fileInfos: h, | ||
scriptPath: f, | ||
headers: a | ||
}); | ||
} finally { | ||
r(); | ||
} | ||
/** | ||
* Resolve the requested path to the filesystem path of the requested PHP file. | ||
* | ||
* Fall back to index.php as if there was a url rewriting rule in place. | ||
* | ||
* @param requestedPath - The requested pathname. | ||
* @throws {Error} If the requested path doesn't exist. | ||
* @returns The resolved filesystem path. | ||
*/ | ||
#h(e) { | ||
let t = H(e, this.#n); | ||
t.includes(".php") ? t = t.split(".php")[0] + ".php" : (t.endsWith("/") || (t += "/"), t.endsWith("index.php") || (t += "index.php")); | ||
const r = `${this.#e}${t}`; | ||
if (this.php.fileExists(r)) | ||
return r; | ||
if (!this.php.fileExists(`${this.#e}/index.php`)) | ||
throw new Error(`File not found: ${r}`); | ||
return `${this.#e}/index.php`; | ||
} | ||
} | ||
function K(s) { | ||
}, B = new WeakSet(), Pe = function(e) { | ||
let t = de(e, i(this, _)); | ||
t.includes(".php") ? t = t.split(".php")[0] + ".php" : (t.endsWith("/") || (t += "/"), t.endsWith("index.php") || (t += "index.php")); | ||
const r = `${i(this, b)}${t}`; | ||
if (this.php.fileExists(r)) | ||
return r; | ||
if (!this.php.fileExists(`${i(this, b)}/index.php`)) | ||
throw new Error(`File not found: ${r}`); | ||
return `${i(this, b)}/index.php`; | ||
}; | ||
function Je(s) { | ||
const e = {}, t = s.match(/--(.*)\r\n/); | ||
@@ -533,12 +549,12 @@ if (!t) | ||
return n.shift(), n.pop(), n.forEach((o) => { | ||
const i = o.indexOf(`\r | ||
const a = o.indexOf(`\r | ||
\r | ||
`), l = o.substring(0, i).trim(), h = o.substring(i + 4).trim(), c = l.match(/name="([^"]+)"/); | ||
if (c) { | ||
const m = c[1]; | ||
e[m] = h; | ||
`), h = o.substring(0, a).trim(), d = o.substring(a + 4).trim(), f = h.match(/name="([^"]+)"/); | ||
if (f) { | ||
const u = f[1]; | ||
e[u] = d; | ||
} | ||
}), e; | ||
} | ||
function Z(s) { | ||
function Ye(s) { | ||
switch (s.split(".").pop()) { | ||
@@ -583,12 +599,12 @@ case "css": | ||
} | ||
function Q(s) { | ||
return X(s) || ee(s); | ||
function Ke(s) { | ||
return Ze(s) || Qe(s); | ||
} | ||
function X(s) { | ||
function Ze(s) { | ||
return s.endsWith(".php") || s.includes(".php/"); | ||
} | ||
function ee(s) { | ||
function Qe(s) { | ||
return !s.split("/").pop().includes("."); | ||
} | ||
const T = { | ||
const pe = { | ||
0: "No error occurred. System call completed successfully.", | ||
@@ -672,17 +688,17 @@ 1: "Argument list too long.", | ||
}; | ||
function p(s = "") { | ||
function w(s = "") { | ||
return function(t, r, n) { | ||
const o = n.value; | ||
n.value = function(...i) { | ||
n.value = function(...a) { | ||
try { | ||
return o.apply(this, i); | ||
} catch (l) { | ||
const h = typeof l == "object" ? l?.errno : null; | ||
if (h in T) { | ||
const c = T[h], m = typeof i[0] == "string" ? i[0] : null, O = m !== null ? s.replaceAll("{path}", m) : s; | ||
throw new Error(`${O}: ${c}`, { | ||
cause: l | ||
return o.apply(this, a); | ||
} catch (h) { | ||
const d = typeof h == "object" ? h == null ? void 0 : h.errno : null; | ||
if (d in pe) { | ||
const f = pe[d], u = typeof a[0] == "string" ? a[0] : null, E = u !== null ? s.replaceAll("{path}", u) : s; | ||
throw new Error(`${E}: ${f}`, { | ||
cause: h | ||
}); | ||
} | ||
throw l; | ||
throw h; | ||
} | ||
@@ -692,6 +708,7 @@ }; | ||
} | ||
async function ce(s, e = {}, t = []) { | ||
const [r, n, o] = C(), [i, l] = C(), h = s.init(re, { | ||
onAbort(c) { | ||
o(c), l(), console.error(c); | ||
const Xe = Symbol("RuntimeId"), q = /* @__PURE__ */ new Map(); | ||
async function ct(s, e = {}, t = []) { | ||
const [r, n, o] = fe(), [a, h] = fe(), d = s.init(tt, { | ||
onAbort(u) { | ||
o(u), h(), console.error(u); | ||
}, | ||
@@ -702,3 +719,3 @@ ENV: {}, | ||
// fixes it. | ||
locateFile: (c) => c, | ||
locateFile: (u) => u, | ||
...e, | ||
@@ -709,19 +726,23 @@ noInitialRun: !0, | ||
}, | ||
monitorRunDependencies(c) { | ||
c === 0 && (delete h.monitorRunDependencies, l()); | ||
monitorRunDependencies(u) { | ||
u === 0 && (delete d.monitorRunDependencies, h()); | ||
} | ||
}); | ||
return await Promise.all( | ||
await Promise.all( | ||
t.map( | ||
({ default: c }) => c(h) | ||
({ default: u }) => u(d) | ||
) | ||
), t.length || l(), await i, await r, P.push(h), P.length - 1; | ||
), t.length || h(), await a, await r; | ||
const f = q.size; | ||
return d.originalExit = d._exit, d._exit = function(u) { | ||
return q.delete(f), d.originalExit(u); | ||
}, d[Xe] = f, q.set(f, d), f; | ||
} | ||
const P = []; | ||
function te(s) { | ||
return P[s]; | ||
function et(s) { | ||
return q.get(s); | ||
} | ||
const re = function() { | ||
return typeof process < "u" && process.release?.name === "node" ? "NODE" : typeof window < "u" ? "WEB" : typeof WorkerGlobalScope < "u" && self instanceof WorkerGlobalScope ? "WORKER" : "NODE"; | ||
}(), C = () => { | ||
const tt = function() { | ||
var s; | ||
return typeof process < "u" && ((s = process.release) == null ? void 0 : s.name) === "node" ? "NODE" : typeof window < "u" ? "WEB" : typeof WorkerGlobalScope < "u" && self instanceof WorkerGlobalScope ? "WORKER" : "NODE"; | ||
}(), fe = () => { | ||
const s = [], e = new Promise((t, r) => { | ||
@@ -732,9 +753,10 @@ s.push(t, r); | ||
}; | ||
var se = Object.defineProperty, ne = Object.getOwnPropertyDescriptor, f = (s, e, t, r) => { | ||
for (var n = r > 1 ? void 0 : r ? ne(e, t) : e, o = s.length - 1, i; o >= 0; o--) | ||
(i = s[o]) && (n = (r ? i(e, t, n) : i(n)) || n); | ||
return r && n && se(e, t, n), n; | ||
var st = Object.defineProperty, rt = Object.getOwnPropertyDescriptor, P = (s, e, t, r) => { | ||
for (var n = r > 1 ? void 0 : r ? rt(e, t) : e, o = s.length - 1, a; o >= 0; o--) | ||
(a = s[o]) && (n = (r ? a(e, t, n) : a(n)) || n); | ||
return r && n && st(e, t, n), n; | ||
}; | ||
const u = "string", y = "number", a = Symbol("__private__dont__use"); | ||
class d { | ||
const y = "string", T = "number", c = Symbol("__private__dont__use"); | ||
var H, x, C, R, v, U, M, W, be, z, _e, G, Ee, V, ve, J, xe, Y, Re, K, Se, Z, ke, Q, He, X, Ce, ee, Te, te, Fe; | ||
class g { | ||
/** | ||
@@ -748,16 +770,56 @@ * Initializes a PHP runtime. | ||
constructor(e, t) { | ||
this.#e = [], this.#t = !1, this.#s = null, this.#r = {}, this.#o = [], e !== void 0 && this.initializeRuntime(e), t && (this.requestHandler = new z( | ||
new J(this, t) | ||
l(this, W); | ||
l(this, z); | ||
l(this, G); | ||
l(this, V); | ||
l(this, J); | ||
l(this, Y); | ||
l(this, K); | ||
l(this, Z); | ||
l(this, Q); | ||
/** | ||
* Adds file information to $_FILES superglobal in PHP. | ||
* | ||
* In particular: | ||
* * Creates the file data in the filesystem | ||
* * Registers the file details in PHP | ||
* | ||
* @param fileInfo - File details | ||
*/ | ||
l(this, X); | ||
l(this, ee); | ||
l(this, te); | ||
l(this, H, void 0); | ||
l(this, x, void 0); | ||
l(this, C, void 0); | ||
l(this, R, void 0); | ||
l(this, v, void 0); | ||
l(this, U, void 0); | ||
l(this, M, void 0); | ||
p(this, H, []), p(this, x, !1), p(this, C, null), p(this, R, {}), p(this, v, /* @__PURE__ */ new Map()), p(this, U, []), p(this, M, new ye({ concurrency: 1 })), e !== void 0 && this.initializeRuntime(e), t && (this.requestHandler = new We( | ||
new Ve(this, t) | ||
)); | ||
} | ||
#e; | ||
#t; | ||
#s; | ||
#r; | ||
#o; | ||
addEventListener(e, t) { | ||
i(this, v).has(e) || i(this, v).set(e, /* @__PURE__ */ new Set()), i(this, v).get(e).add(t); | ||
} | ||
removeEventListener(e, t) { | ||
var r; | ||
(r = i(this, v).get(e)) == null || r.delete(t); | ||
} | ||
dispatchEvent(e) { | ||
const t = i(this, v).get(e.type); | ||
if (t) | ||
for (const r of t) | ||
r(e); | ||
} | ||
/** @inheritDoc */ | ||
async onMessage(e) { | ||
this.#o.push(e); | ||
i(this, U).push(e); | ||
} | ||
/** @inheritDoc */ | ||
async setSpawnHandler(e) { | ||
this[c].spawnProcess = e; | ||
} | ||
/** @inheritDoc */ | ||
get absoluteUrl() { | ||
@@ -781,17 +843,21 @@ return this.requestHandler.requestHandler.absoluteUrl; | ||
initializeRuntime(e) { | ||
if (this[a]) | ||
if (this[c]) | ||
throw new Error("PHP runtime already initialized."); | ||
const t = te(e); | ||
const t = et(e); | ||
if (!t) | ||
throw new Error("Invalid PHP runtime id."); | ||
this[a] = t, t.onMessage = (r) => { | ||
for (const n of this.#o) | ||
n(r); | ||
}, this.#s = N(t); | ||
this[c] = t, t.onMessage = async (r) => { | ||
for (const n of i(this, U)) { | ||
const o = await n(r); | ||
if (o) | ||
return o; | ||
} | ||
return ""; | ||
}, p(this, C, Le(t)); | ||
} | ||
/** @inheritDoc */ | ||
setPhpIniPath(e) { | ||
if (this.#t) | ||
if (i(this, x)) | ||
throw new Error("Cannot set PHP ini path after calling run()."); | ||
this[a].ccall( | ||
this[c].ccall( | ||
"wasm_set_phpini_path", | ||
@@ -805,9 +871,9 @@ null, | ||
setPhpIniEntry(e, t) { | ||
if (this.#t) | ||
if (i(this, x)) | ||
throw new Error("Cannot set PHP ini entries after calling run()."); | ||
this.#e.push([e, t]); | ||
i(this, H).push([e, t]); | ||
} | ||
/** @inheritDoc */ | ||
chdir(e) { | ||
this[a].FS.chdir(e); | ||
this[c].FS.chdir(e); | ||
} | ||
@@ -822,217 +888,37 @@ /** @inheritDoc */ | ||
async run(e) { | ||
this.#t || (this.#n(), this.#t = !0), this.#d(e.scriptPath || ""), this.#a(e.relativeUri || ""), this.#c(e.method || "GET"); | ||
const { host: t, ...r } = { | ||
host: "example.com:443", | ||
...A(e.headers || {}) | ||
}; | ||
if (this.#l(t, e.protocol || "http"), this.#h(r), e.body && this.#u(e.body), e.fileInfos) | ||
for (const n of e.fileInfos) | ||
this.#f(n); | ||
return e.code && this.#m(" ?>" + e.code), this.#p(), await this.#y(); | ||
} | ||
#n() { | ||
if (this.#e.length > 0) { | ||
const e = this.#e.map(([t, r]) => `${t}=${r}`).join(` | ||
`) + ` | ||
`; | ||
this[a].ccall( | ||
"wasm_set_phpini_entries", | ||
null, | ||
[u], | ||
[e] | ||
); | ||
} | ||
this[a].ccall("php_wasm_init", null, [], []); | ||
} | ||
#i() { | ||
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 n of t.headers) { | ||
if (!n.includes(": ")) | ||
continue; | ||
const o = n.indexOf(": "), i = n.substring(0, o).toLowerCase(), l = n.substring(o + 2); | ||
i in r || (r[i] = []), r[i].push(l); | ||
} | ||
return { | ||
headers: r, | ||
httpStatusCode: t.status | ||
}; | ||
} | ||
#a(e) { | ||
if (this[a].ccall( | ||
"wasm_set_request_uri", | ||
null, | ||
[u], | ||
[e] | ||
), e.includes("?")) { | ||
const t = e.substring(e.indexOf("?") + 1); | ||
this[a].ccall( | ||
"wasm_set_query_string", | ||
null, | ||
[u], | ||
[t] | ||
); | ||
} | ||
} | ||
#l(e, t) { | ||
this[a].ccall( | ||
"wasm_set_request_host", | ||
null, | ||
[u], | ||
[e] | ||
); | ||
let r; | ||
const t = await i(this, M).acquire(); | ||
try { | ||
r = parseInt(new URL(e).port, 10); | ||
} catch { | ||
i(this, x) || (m(this, W, be).call(this), p(this, x, !0)), m(this, Z, ke).call(this, e.scriptPath || ""), m(this, G, Ee).call(this, e.relativeUri || ""), m(this, J, xe).call(this, e.method || "GET"); | ||
const r = $e(e.headers || {}), n = r.host || "example.com:443"; | ||
if (m(this, V, ve).call(this, n, e.protocol || "http"), m(this, Y, Re).call(this, r), e.body && m(this, K, Se).call(this, e.body), e.fileInfos) | ||
for (const o of e.fileInfos) | ||
m(this, X, Ce).call(this, o); | ||
return e.code && m(this, ee, Te).call(this, " ?>" + e.code), m(this, Q, He).call(this), await m(this, te, Fe).call(this); | ||
} finally { | ||
t(), this.dispatchEvent({ | ||
type: "request.end" | ||
}); | ||
} | ||
(!r || isNaN(r) || r === 80) && (r = t === "https" ? 443 : 80), this[a].ccall( | ||
"wasm_set_request_port", | ||
null, | ||
[y], | ||
[r] | ||
), (t === "https" || !t && r === 443) && this.addServerGlobalEntry("HTTPS", "on"); | ||
} | ||
#c(e) { | ||
this[a].ccall( | ||
"wasm_set_request_method", | ||
null, | ||
[u], | ||
[e] | ||
); | ||
} | ||
#h(e) { | ||
e.cookie && this[a].ccall( | ||
"wasm_set_cookies", | ||
null, | ||
[u], | ||
[e.cookie] | ||
), e["content-type"] && this[a].ccall( | ||
"wasm_set_content_type", | ||
null, | ||
[u], | ||
[e["content-type"]] | ||
), e["content-length"] && this[a].ccall( | ||
"wasm_set_content_length", | ||
null, | ||
[y], | ||
[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] | ||
); | ||
} | ||
} | ||
#u(e) { | ||
this[a].ccall( | ||
"wasm_set_request_body", | ||
null, | ||
[u], | ||
[e] | ||
), this[a].ccall( | ||
"wasm_set_content_length", | ||
null, | ||
[y], | ||
[new TextEncoder().encode(e).length] | ||
); | ||
} | ||
#d(e) { | ||
this[a].ccall( | ||
"wasm_set_path_translated", | ||
null, | ||
[u], | ||
[e] | ||
); | ||
} | ||
addServerGlobalEntry(e, t) { | ||
this.#r[e] = t; | ||
i(this, R)[e] = t; | ||
} | ||
#p() { | ||
for (const e in this.#r) | ||
this[a].ccall( | ||
"wasm_add_SERVER_entry", | ||
null, | ||
[u, u], | ||
[e, this.#r[e]] | ||
defineConstant(e, t) { | ||
let r = {}; | ||
try { | ||
r = JSON.parse( | ||
this.fileExists("/tmp/consts.json") && this.readFileAsText("/tmp/consts.json") || "{}" | ||
); | ||
} | ||
/** | ||
* Adds file information to $_FILES superglobal in PHP. | ||
* | ||
* In particular: | ||
* * Creates the file data in the filesystem | ||
* * Registers the file details in PHP | ||
* | ||
* @param fileInfo - File details | ||
*/ | ||
#f(e) { | ||
const { key: t, name: r, type: n, data: o } = e, i = `/tmp/${Math.random().toFixed(20)}`; | ||
this.writeFile(i, o); | ||
const l = 0; | ||
this[a].ccall( | ||
"wasm_add_uploaded_file", | ||
null, | ||
[u, u, u, u, y, y], | ||
[t, r, n, i, l, o.byteLength] | ||
); | ||
} | ||
#m(e) { | ||
this[a].ccall( | ||
"wasm_set_php_code", | ||
null, | ||
[u], | ||
[e] | ||
); | ||
} | ||
async #y() { | ||
let e, t; | ||
try { | ||
e = await new Promise((o, i) => { | ||
t = (h) => { | ||
const c = new Error("Rethrown"); | ||
c.cause = h.error, c.betterMessage = h.message, i(c); | ||
}, this.#s?.addEventListener( | ||
"error", | ||
t | ||
); | ||
const l = this[a].ccall( | ||
"wasm_sapi_handle_request", | ||
y, | ||
[], | ||
[] | ||
); | ||
return l instanceof Promise ? l.then(o, i) : o(l); | ||
}); | ||
} catch (o) { | ||
for (const c in this) | ||
typeof this[c] == "function" && (this[c] = () => { | ||
throw new Error( | ||
"PHP runtime has crashed – see the earlier error for details." | ||
); | ||
}); | ||
this.functionsMaybeMissingFromAsyncify = $(); | ||
const i = o, l = "betterMessage" in i ? i.betterMessage : i.message, h = new Error(l); | ||
throw h.cause = i, h; | ||
} finally { | ||
this.#s?.removeEventListener("error", t), this.#r = {}; | ||
} catch { | ||
} | ||
const { headers: r, httpStatusCode: n } = this.#i(); | ||
return new g( | ||
n, | ||
r, | ||
this.readFileAsBuffer("/tmp/stdout"), | ||
this.readFileAsText("/tmp/stderr"), | ||
e | ||
this.writeFile( | ||
"/tmp/consts.json", | ||
JSON.stringify({ | ||
...r, | ||
[e]: t | ||
}) | ||
); | ||
} | ||
mkdir(e) { | ||
this[a].FS.mkdirTree(e); | ||
this[c].FS.mkdirTree(e); | ||
} | ||
@@ -1046,18 +932,18 @@ mkdirTree(e) { | ||
readFileAsBuffer(e) { | ||
return this[a].FS.readFile(e); | ||
return this[c].FS.readFile(e); | ||
} | ||
writeFile(e, t) { | ||
this[a].FS.writeFile(e, t); | ||
this[c].FS.writeFile(e, t); | ||
} | ||
unlink(e) { | ||
this[a].FS.unlink(e); | ||
this[c].FS.unlink(e); | ||
} | ||
mv(e, t) { | ||
this[a].FS.rename(e, t); | ||
this[c].FS.rename(e, t); | ||
} | ||
rmdir(e, t = { recursive: !0 }) { | ||
t?.recursive && this.listFiles(e).forEach((r) => { | ||
t != null && t.recursive && this.listFiles(e).forEach((r) => { | ||
const n = `${e}/${r}`; | ||
this.isDir(n) ? this.rmdir(n, t) : this.unlink(n); | ||
}), this[a].FS.rmdir(e); | ||
}), this[c].FS.rmdir(e); | ||
} | ||
@@ -1068,3 +954,3 @@ listFiles(e, t = { prependPath: !1 }) { | ||
try { | ||
const r = this[a].FS.readdir(e).filter( | ||
const r = this[c].FS.readdir(e).filter( | ||
(n) => n !== "." && n !== ".." | ||
@@ -1082,4 +968,4 @@ ); | ||
isDir(e) { | ||
return this.fileExists(e) ? this[a].FS.isDir( | ||
this[a].FS.lookupPath(e).node.mode | ||
return this.fileExists(e) ? this[c].FS.isDir( | ||
this[c].FS.lookupPath(e).node.mode | ||
) : !1; | ||
@@ -1089,3 +975,3 @@ } | ||
try { | ||
return this[a].FS.lookupPath(e), !0; | ||
return this[c].FS.lookupPath(e), !0; | ||
} catch { | ||
@@ -1095,37 +981,234 @@ return !1; | ||
} | ||
exit(e = 0) { | ||
return this[c]._exit(e); | ||
} | ||
} | ||
f([ | ||
p('Could not create directory "{path}"') | ||
], d.prototype, "mkdir", 1); | ||
f([ | ||
p('Could not create directory "{path}"') | ||
], d.prototype, "mkdirTree", 1); | ||
f([ | ||
p('Could not read "{path}"') | ||
], d.prototype, "readFileAsText", 1); | ||
f([ | ||
p('Could not read "{path}"') | ||
], d.prototype, "readFileAsBuffer", 1); | ||
f([ | ||
p('Could not write to "{path}"') | ||
], d.prototype, "writeFile", 1); | ||
f([ | ||
p('Could not unlink "{path}"') | ||
], d.prototype, "unlink", 1); | ||
f([ | ||
p('Could not move "{path}"') | ||
], d.prototype, "mv", 1); | ||
f([ | ||
p('Could not remove directory "{path}"') | ||
], d.prototype, "rmdir", 1); | ||
f([ | ||
p('Could not list files in "{path}"') | ||
], d.prototype, "listFiles", 1); | ||
f([ | ||
p('Could not stat "{path}"') | ||
], d.prototype, "isDir", 1); | ||
f([ | ||
p('Could not stat "{path}"') | ||
], d.prototype, "fileExists", 1); | ||
function A(s) { | ||
H = new WeakMap(), x = new WeakMap(), C = new WeakMap(), R = new WeakMap(), v = new WeakMap(), U = new WeakMap(), M = new WeakMap(), W = new WeakSet(), be = function() { | ||
if (this.setPhpIniEntry("auto_prepend_file", "/tmp/consts.php"), this.fileExists("/tmp/consts.php") || this.writeFile( | ||
"/tmp/consts.php", | ||
`<?php | ||
if(file_exists('/tmp/consts.json')) { | ||
$consts = json_decode(file_get_contents('/tmp/consts.json'), true); | ||
foreach ($consts as $const => $value) { | ||
if (!defined($const) && is_scalar($value)) { | ||
define($const, $value); | ||
} | ||
} | ||
}` | ||
), i(this, H).length > 0) { | ||
const e = i(this, H).map(([t, r]) => `${t}=${r}`).join(` | ||
`) + ` | ||
`; | ||
this[c].ccall( | ||
"wasm_set_phpini_entries", | ||
null, | ||
[y], | ||
[e] | ||
); | ||
} | ||
this[c].ccall("php_wasm_init", null, [], []); | ||
}, z = new WeakSet(), _e = 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 n of t.headers) { | ||
if (!n.includes(": ")) | ||
continue; | ||
const o = n.indexOf(": "), a = n.substring(0, o).toLowerCase(), h = n.substring(o + 2); | ||
a in r || (r[a] = []), r[a].push(h); | ||
} | ||
return { | ||
headers: r, | ||
httpStatusCode: t.status | ||
}; | ||
}, G = new WeakSet(), Ee = function(e) { | ||
if (this[c].ccall( | ||
"wasm_set_request_uri", | ||
null, | ||
[y], | ||
[e] | ||
), e.includes("?")) { | ||
const t = e.substring(e.indexOf("?") + 1); | ||
this[c].ccall( | ||
"wasm_set_query_string", | ||
null, | ||
[y], | ||
[t] | ||
); | ||
} | ||
}, V = new WeakSet(), ve = function(e, t) { | ||
this[c].ccall( | ||
"wasm_set_request_host", | ||
null, | ||
[y], | ||
[e] | ||
); | ||
let r; | ||
try { | ||
r = parseInt(new URL(e).port, 10); | ||
} catch { | ||
} | ||
(!r || isNaN(r) || r === 80) && (r = t === "https" ? 443 : 80), this[c].ccall( | ||
"wasm_set_request_port", | ||
null, | ||
[T], | ||
[r] | ||
), (t === "https" || !t && r === 443) && this.addServerGlobalEntry("HTTPS", "on"); | ||
}, J = new WeakSet(), xe = function(e) { | ||
this[c].ccall( | ||
"wasm_set_request_method", | ||
null, | ||
[y], | ||
[e] | ||
); | ||
}, Y = new WeakSet(), Re = function(e) { | ||
e.cookie && this[c].ccall( | ||
"wasm_set_cookies", | ||
null, | ||
[y], | ||
[e.cookie] | ||
), e["content-type"] && this[c].ccall( | ||
"wasm_set_content_type", | ||
null, | ||
[y], | ||
[e["content-type"]] | ||
), e["content-length"] && this[c].ccall( | ||
"wasm_set_content_length", | ||
null, | ||
[T], | ||
[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] | ||
); | ||
} | ||
}, K = new WeakSet(), Se = function(e) { | ||
this[c].ccall( | ||
"wasm_set_request_body", | ||
null, | ||
[y], | ||
[e] | ||
), this[c].ccall( | ||
"wasm_set_content_length", | ||
null, | ||
[T], | ||
[new TextEncoder().encode(e).length] | ||
); | ||
}, Z = new WeakSet(), ke = function(e) { | ||
this[c].ccall( | ||
"wasm_set_path_translated", | ||
null, | ||
[y], | ||
[e] | ||
); | ||
}, Q = new WeakSet(), He = function() { | ||
for (const e in i(this, R)) | ||
this[c].ccall( | ||
"wasm_add_SERVER_entry", | ||
null, | ||
[y, y], | ||
[e, i(this, R)[e]] | ||
); | ||
}, X = new WeakSet(), Ce = function(e) { | ||
const { key: t, name: r, type: n, data: o } = e, a = `/tmp/${Math.random().toFixed(20)}`; | ||
this.writeFile(a, o); | ||
const h = 0; | ||
this[c].ccall( | ||
"wasm_add_uploaded_file", | ||
null, | ||
[y, y, y, y, T, T], | ||
[t, r, n, a, h, o.byteLength] | ||
); | ||
}, ee = new WeakSet(), Te = function(e) { | ||
this[c].ccall( | ||
"wasm_set_php_code", | ||
null, | ||
[y], | ||
[e] | ||
); | ||
}, te = new WeakSet(), Fe = async function() { | ||
var o; | ||
let e, t; | ||
try { | ||
e = await new Promise((a, h) => { | ||
var f; | ||
t = (u) => { | ||
const E = new Error("Rethrown"); | ||
E.cause = u.error, E.betterMessage = u.message, h(E); | ||
}, (f = i(this, C)) == null || f.addEventListener( | ||
"error", | ||
t | ||
); | ||
const d = this[c].ccall( | ||
"wasm_sapi_handle_request", | ||
T, | ||
[], | ||
[], | ||
{ async: !0 } | ||
); | ||
return d instanceof Promise ? d.then(a, h) : a(d); | ||
}); | ||
} catch (a) { | ||
for (const u in this) | ||
typeof this[u] == "function" && (this[u] = () => { | ||
throw new Error( | ||
"PHP runtime has crashed – see the earlier error for details." | ||
); | ||
}); | ||
this.functionsMaybeMissingFromAsyncify = Ue(); | ||
const h = a, d = "betterMessage" in h ? h.betterMessage : h.message, f = new Error(d); | ||
throw f.cause = h, f; | ||
} finally { | ||
(o = i(this, C)) == null || o.removeEventListener("error", t), p(this, R, {}); | ||
} | ||
const { headers: r, httpStatusCode: n } = m(this, z, _e).call(this); | ||
return new F( | ||
n, | ||
r, | ||
this.readFileAsBuffer("/tmp/stdout"), | ||
this.readFileAsText("/tmp/stderr"), | ||
e | ||
); | ||
}; | ||
P([ | ||
w('Could not create directory "{path}"') | ||
], g.prototype, "mkdir", 1); | ||
P([ | ||
w('Could not create directory "{path}"') | ||
], g.prototype, "mkdirTree", 1); | ||
P([ | ||
w('Could not read "{path}"') | ||
], g.prototype, "readFileAsText", 1); | ||
P([ | ||
w('Could not read "{path}"') | ||
], g.prototype, "readFileAsBuffer", 1); | ||
P([ | ||
w('Could not write to "{path}"') | ||
], g.prototype, "writeFile", 1); | ||
P([ | ||
w('Could not unlink "{path}"') | ||
], g.prototype, "unlink", 1); | ||
P([ | ||
w('Could not move "{path}"') | ||
], g.prototype, "mv", 1); | ||
P([ | ||
w('Could not remove directory "{path}"') | ||
], g.prototype, "rmdir", 1); | ||
P([ | ||
w('Could not list files in "{path}"') | ||
], g.prototype, "listFiles", 1); | ||
P([ | ||
w('Could not stat "{path}"') | ||
], g.prototype, "isDir", 1); | ||
P([ | ||
w('Could not stat "{path}"') | ||
], g.prototype, "fileExists", 1); | ||
function $e(s) { | ||
const e = {}; | ||
@@ -1136,29 +1219,29 @@ for (const t in s) | ||
} | ||
function oe(s) { | ||
return !(s instanceof d); | ||
function nt(s) { | ||
return !(s instanceof g); | ||
} | ||
function he(s) { | ||
return !oe(s); | ||
function ht(s) { | ||
return !nt(s); | ||
} | ||
export { | ||
d as BasePHP, | ||
V as DEFAULT_BASE_URL, | ||
ie as LatestSupportedPHPVersion, | ||
z as PHPBrowser, | ||
J as PHPRequestHandler, | ||
g as PHPResponse, | ||
le as SupportedPHPExtensionBundles, | ||
j as SupportedPHPExtensionsList, | ||
F as SupportedPHPVersions, | ||
ae as SupportedPHPVersionsList, | ||
L as UnhandledRejectionsTarget, | ||
a as __private__dont__use, | ||
Y as ensurePathPrefix, | ||
I as isExitCodeZero, | ||
oe as isLocalPHP, | ||
he as isRemotePHP, | ||
ce as loadPHPRuntime, | ||
H as removePathPrefix, | ||
p as rethrowFileSystemError, | ||
k as toRelativeUrl | ||
g as BasePHP, | ||
ze as DEFAULT_BASE_URL, | ||
ot as LatestSupportedPHPVersion, | ||
We as PHPBrowser, | ||
Ve as PHPRequestHandler, | ||
F as PHPResponse, | ||
lt as SupportedPHPExtensionBundles, | ||
Be as SupportedPHPExtensionsList, | ||
me as SupportedPHPVersions, | ||
at as SupportedPHPVersionsList, | ||
Ie as UnhandledRejectionsTarget, | ||
c as __private__dont__use, | ||
Ge as ensurePathPrefix, | ||
Oe as isExitCodeZero, | ||
nt as isLocalPHP, | ||
ht as isRemotePHP, | ||
ct as loadPHPRuntime, | ||
de as removePathPrefix, | ||
w as rethrowFileSystemError, | ||
ue as toRelativeUrl | ||
}; |
@@ -5,3 +5,3 @@ import { PHPBrowser } from './php-browser'; | ||
import type { PHPRuntimeId } from './load-php-runtime'; | ||
import { IsomorphicLocalPHP, MessageListener, PHPRequest, PHPRunOptions, RmDirOptions, ListFilesOptions } from './universal-php'; | ||
import { IsomorphicLocalPHP, MessageListener, PHPRequest, PHPRequestHeaders, PHPRunOptions, RmDirOptions, ListFilesOptions, SpawnHandler, PHPEventListener, PHPEvent } from './universal-php'; | ||
export declare const __private__dont__use: unique symbol; | ||
@@ -28,5 +28,10 @@ /** | ||
constructor(PHPRuntimeId?: PHPRuntimeId, serverOptions?: PHPRequestHandlerConfiguration); | ||
addEventListener(eventType: PHPEvent['type'], listener: PHPEventListener): void; | ||
removeEventListener(eventType: PHPEvent['type'], listener: PHPEventListener): void; | ||
dispatchEvent<Event extends PHPEvent>(event: Event): void; | ||
/** @inheritDoc */ | ||
onMessage(listener: MessageListener): Promise<void>; | ||
/** @inheritDoc */ | ||
setSpawnHandler(handler: SpawnHandler): Promise<void>; | ||
/** @inheritDoc */ | ||
get absoluteUrl(): string; | ||
@@ -51,2 +56,3 @@ /** @inheritDoc */ | ||
addServerGlobalEntry(key: string, value: string): void; | ||
defineConstant(key: string, value: string | number | null): void; | ||
/** @inheritDoc */ | ||
@@ -74,3 +80,4 @@ mkdir(path: string): void; | ||
fileExists(path: string): boolean; | ||
exit(code?: number): any; | ||
} | ||
export declare function normalizeHeaders(headers: PHPRunOptions['headers']): PHPRunOptions['headers']; | ||
export declare function normalizeHeaders(headers: PHPRequestHeaders): PHPRequestHeaders; |
@@ -1,2 +0,2 @@ | ||
export type { FileInfo, IsomorphicLocalPHP, IsomorphicRemotePHP, MessageListener, PHPOutput, PHPRunOptions, UniversalPHP, ListFilesOptions, RmDirOptions, HTTPMethod, PHPRequest, PHPRequestHeaders, RequestHandler, } from './universal-php'; | ||
export type { FileInfo, IsomorphicLocalPHP, IsomorphicRemotePHP, MessageListener, PHPOutput, PHPRunOptions, UniversalPHP, ListFilesOptions, RmDirOptions, PHPEvent, PHPEventListener, HTTPMethod, PHPRequest, PHPRequestHeaders, RequestHandler, SpawnHandler, } from './universal-php'; | ||
export { UnhandledRejectionsTarget } from './wasm-error-reporting'; | ||
@@ -3,0 +3,0 @@ export { PHPResponse } from './php-response'; |
@@ -52,2 +52,4 @@ import type { PHPRequestHandler } from './php-request-handler'; | ||
get documentRoot(): string; | ||
setCookies(cookies: string[]): void; | ||
serializeCookies(): string; | ||
} |
@@ -1,4 +0,4 @@ | ||
export declare const SupportedPHPVersions: readonly ["8.2", "8.1", "8.0", "7.4", "7.3", "7.2", "7.1", "7.0", "5.6"]; | ||
export declare const LatestSupportedPHPVersion: "8.2"; | ||
export declare const SupportedPHPVersions: readonly ["8.3", "8.2", "8.1", "8.0", "7.4", "7.3", "7.2", "7.1", "7.0"]; | ||
export declare const LatestSupportedPHPVersion: "8.3"; | ||
export declare const SupportedPHPVersionsList: string[]; | ||
export type SupportedPHPVersion = (typeof SupportedPHPVersions)[number]; |
import { Remote } from 'comlink'; | ||
import { PHPResponse } from './php-response'; | ||
/** | ||
* Represents an event related to the PHP filesystem. | ||
*/ | ||
export interface PHPRequestEndEvent { | ||
type: 'request.end'; | ||
} | ||
/** | ||
* Represents an event related to the PHP instance. | ||
* This is intentionally not an extension of CustomEvent | ||
* to make it isomorphic between different JavaScript runtimes. | ||
*/ | ||
export type PHPEvent = PHPRequestEndEvent; | ||
/** | ||
* A callback function that handles PHP events. | ||
*/ | ||
export type PHPEventListener = (event: PHPEvent) => void; | ||
/** | ||
* Handles HTTP requests using PHP runtime as a backend. | ||
@@ -9,3 +25,3 @@ * | ||
* ```js | ||
* import { PHP } from '@php-wasm/web'; | ||
* import { PHP } from '../../../web/src/index.ts'; | ||
* | ||
@@ -136,2 +152,20 @@ * const php = await PHP.load( '7.4', { | ||
/** | ||
* Defines a constant in the PHP runtime. | ||
* @param key - The name of the constant. | ||
* @param value - The value of the constant. | ||
*/ | ||
defineConstant(key: string, value: string | number | null): void; | ||
/** | ||
* Adds an event listener for a PHP event. | ||
* @param eventType - The type of event to listen for. | ||
* @param listener - The listener function to be called when the event is triggered. | ||
*/ | ||
addEventListener(eventType: PHPEvent['type'], listener: PHPEventListener): void; | ||
/** | ||
* Removes an event listener for a PHP event. | ||
* @param eventType - The type of event to remove the listener from. | ||
* @param listener - The listener function to be removed. | ||
*/ | ||
removeEventListener(eventType: PHPEvent['type'], listener: PHPEventListener): void; | ||
/** | ||
* Sets the path to the php.ini file to use for the PHP instance. | ||
@@ -348,4 +382,21 @@ * | ||
onMessage(listener: MessageListener): void; | ||
/** | ||
* Registers a handler to spawns a child process when | ||
* `proc_open()`, `popen()`, `exec()`, `system()`, or `passthru()` | ||
* is called. | ||
* | ||
* @param handler Callback function to spawn a process. | ||
*/ | ||
setSpawnHandler(handler: SpawnHandler): void; | ||
} | ||
export type MessageListener = (data: string) => void; | ||
export type MessageListener = (data: string) => Promise<string | Uint8Array | void> | string | void; | ||
interface EventEmitter { | ||
on(event: string, listener: (...args: any[]) => void): this; | ||
emit(event: string, ...args: any[]): boolean; | ||
} | ||
type ChildProcess = EventEmitter & { | ||
stdout: EventEmitter; | ||
stderr: EventEmitter; | ||
}; | ||
export type SpawnHandler = (command: string) => ChildProcess; | ||
export type IsomorphicRemotePHP = Remote<IsomorphicLocalPHP>; | ||
@@ -447,1 +498,2 @@ export type UniversalPHP = IsomorphicLocalPHP | IsomorphicRemotePHP; | ||
} | ||
export {}; |
{ | ||
"name": "@php-wasm/universal", | ||
"version": "0.3.1", | ||
"version": "0.4.0", | ||
"description": "PHP.wasm – emscripten bindings for PHP", | ||
@@ -39,3 +39,3 @@ "repository": { | ||
"license": "GPL-2.0-or-later", | ||
"gitHead": "73b285f8b496c7442474fd7325b3f6b1287cbf95", | ||
"gitHead": "0851e71512709843af0539f747caded8ea904fe6", | ||
"engines": { | ||
@@ -42,0 +42,0 @@ "node": ">=16.15.1", |
Sorry, the diff of this file is not supported yet
92138
2360