New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@php-wasm/universal

Package Overview
Dependencies
Maintainers
3
Versions
125
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@php-wasm/universal - npm Package Compare versions

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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc