@php-wasm/universal 2.0.22 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -2,7 +2,7 @@ var W = (t) => {
2
2
  throw TypeError(t);
3
3
  };
4
4
  var O = (t, e, r) => e.has(t) || W("Cannot " + r);
5
- var u = (t, e, r) => (O(t, e, "read from private field"), r ? r.call(t) : e.get(t)), _ = (t, e, r) => e.has(t) ? W("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(t) : e.set(t, r), w = (t, e, r, s) => (O(t, e, "write to private field"), s ? s.call(t, r) : e.set(t, r), r), m = (t, e, r) => (O(t, e, "access private method"), r);
5
+ var u = (t, e, r) => (O(t, e, "read from private field"), r ? r.call(t) : e.get(t)), y = (t, e, r) => e.has(t) ? W("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(t) : e.set(t, r), w = (t, e, r, s) => (O(t, e, "write to private field"), s ? s.call(t, r) : e.set(t, r), r), m = (t, e, r) => (O(t, e, "access private method"), r);
6
6
  import "@php-wasm/node-polyfills";
7
7
  import { logger } from "@php-wasm/logger";
8
8
  import { dirname, joinPaths, Semaphore, createSpawnHandler, normalizePath, AcquireTimeoutError } from "@php-wasm/util";
@@ -907,7 +907,7 @@ class PHPExecutionFailureError extends Error {
907
907
  }
908
908
  }
909
909
  const PHP_INI_PATH = "/internal/shared/php.ini", AUTO_PREPEND_SCRIPT = "/internal/shared/auto_prepend_file.php", OPCACHE_FILE_FOLDER = "/internal/shared/opcache";
910
- var k, H, b, E, T, C, y, h, B, z, $, V, G, J, Y, K, L, X, U, j;
910
+ var k, H, b, E, T, C, _, h, B, z, $, V, G, J, Y, K, L, X, U, j;
911
911
  class PHP {
912
912
  /**
913
913
  * Initializes a PHP runtime.
@@ -917,14 +917,14 @@ class PHP {
917
917
  * @param requestHandlerOptions - Optional. Options for the PHPRequestHandler. If undefined, no request handler will be initialized.
918
918
  */
919
919
  constructor(t) {
920
- _(this, h);
921
- _(this, k);
922
- _(this, H, !1);
923
- _(this, b, null);
924
- _(this, E, /* @__PURE__ */ new Map());
925
- _(this, T, []);
926
- _(this, C, {});
927
- _(this, y, {
920
+ y(this, h);
921
+ y(this, k);
922
+ y(this, H, !1);
923
+ y(this, b, null);
924
+ y(this, E, /* @__PURE__ */ new Map());
925
+ y(this, T, []);
926
+ y(this, C, {});
927
+ y(this, _, {
928
928
  enabled: !1,
929
929
  recreateRuntime: () => 0,
930
930
  needsRotating: !1,
@@ -932,7 +932,7 @@ class PHP {
932
932
  requestsMade: 0
933
933
  });
934
934
  this.semaphore = new Semaphore({ concurrency: 1 }), t !== void 0 && this.initializeRuntime(t), this.addEventListener("request.error", (e) => {
935
- e.source === "php-wasm" && (u(this, y).needsRotating = !0);
935
+ e.source === "php-wasm" && (u(this, _).needsRotating = !0);
936
936
  });
937
937
  }
938
938
  /**
@@ -1564,8 +1564,8 @@ class PHP {
1564
1564
  * or an internal crash.
1565
1565
  */
1566
1566
  enableRuntimeRotation(t) {
1567
- w(this, y, {
1568
- ...u(this, y),
1567
+ w(this, _, {
1568
+ ...u(this, _),
1569
1569
  enabled: !0,
1570
1570
  recreateRuntime: t.recreateRuntime,
1571
1571
  maxRequests: t.maxRequests ?? 400,
@@ -1573,36 +1573,34 @@ class PHP {
1573
1573
  });
1574
1574
  }
1575
1575
  async rotateRuntime() {
1576
- if (!u(this, y).enabled)
1576
+ if (!u(this, _).enabled)
1577
1577
  throw new Error(
1578
1578
  "Runtime rotation is not enabled. Call enableRuntimeRotation() first."
1579
1579
  );
1580
1580
  await this.hotSwapPHPRuntime(
1581
- await u(this, y).recreateRuntime(),
1582
- u(this, y).cwd
1583
- ), u(this, y).requestsMade = 0, u(this, y).needsRotating = !1;
1581
+ await u(this, _).recreateRuntime()
1582
+ ), u(this, _).requestsMade = 0, u(this, _).needsRotating = !1;
1584
1583
  }
1585
1584
  /**
1586
1585
  * Hot-swaps the PHP runtime for a new one without
1587
1586
  * interrupting the operations of this PHP instance.
1588
1587
  *
1589
1588
  * @param runtime
1590
- * @param cwd. Internal, the VFS path to recreate in the new runtime.
1591
- * This arg is temporary and will be removed once BasePHP
1592
- * is fully decoupled from the request handler and
1593
- * accepts a constructor-level cwd argument.
1594
- */
1595
- async hotSwapPHPRuntime(t, e) {
1596
- const r = this[__private__dont__use].FS, s = this[__private__dont__use].spawnProcess, n = [];
1597
- for (const [i, o] of Object.entries(u(this, C)))
1598
- n.push({ mountHandler: o.mountHandler, vfsPath: i }), await o.unmount();
1589
+ */
1590
+ async hotSwapPHPRuntime(t) {
1591
+ const e = this[__private__dont__use].FS, r = this.listFiles("/").map((o) => `/${o}`), s = this[__private__dont__use].spawnProcess, n = [];
1592
+ for (const [o, a] of Object.entries(u(this, C)))
1593
+ n.push({ mountHandler: a.mountHandler, vfsPath: o }), await a.unmount();
1599
1594
  try {
1600
1595
  this.exit();
1601
1596
  } catch {
1602
1597
  }
1603
- this.initializeRuntime(t), s && (this[__private__dont__use].spawnProcess = s), u(this, k) && this.setSapiName(u(this, k)), copyFS(r, this[__private__dont__use].FS, "/internal"), e && copyFS(r, this[__private__dont__use].FS, e);
1604
- for (const { mountHandler: i, vfsPath: o } of n)
1605
- this.mkdir(o), await this.mount(o, i);
1598
+ this.initializeRuntime(t), s && (this[__private__dont__use].spawnProcess = s), u(this, k) && this.setSapiName(u(this, k));
1599
+ const i = this[__private__dont__use].FS;
1600
+ for (const o of r)
1601
+ o && o !== "/request" && copyMEMFSNodes(e, i, o);
1602
+ for (const { mountHandler: o, vfsPath: a } of n)
1603
+ this.mkdir(a), await this.mount(a, o);
1606
1604
  }
1607
1605
  /**
1608
1606
  * Mounts a filesystem to a given path in the PHP filesystem.
@@ -1640,7 +1638,7 @@ class PHP {
1640
1638
  * @returns The exit code of the CLI session.
1641
1639
  */
1642
1640
  async cli(t, e = {}) {
1643
- u(this, H) && (u(this, y).needsRotating = !0);
1641
+ u(this, H) && (u(this, _).needsRotating = !0);
1644
1642
  const r = await this.semaphore.acquire();
1645
1643
  return await m(this, h, j).call(this, () => {
1646
1644
  const s = e.env || {};
@@ -1658,7 +1656,7 @@ class PHP {
1658
1656
  async: !0
1659
1657
  });
1660
1658
  }).then((s) => (s.exitCode.finally(r), s)).finally(() => {
1661
- u(this, y).needsRotating = !0;
1659
+ u(this, _).needsRotating = !0;
1662
1660
  });
1663
1661
  }
1664
1662
  setSkipShebang(t) {
@@ -1683,7 +1681,7 @@ class PHP {
1683
1681
  this.exit(0);
1684
1682
  }
1685
1683
  }
1686
- k = new WeakMap(), H = new WeakMap(), b = new WeakMap(), E = new WeakMap(), T = new WeakMap(), C = new WeakMap(), y = new WeakMap(), h = new WeakSet(), /**
1684
+ k = new WeakMap(), H = new WeakMap(), b = new WeakMap(), E = new WeakMap(), T = new WeakMap(), C = new WeakMap(), _ = new WeakMap(), h = new WeakSet(), /**
1687
1685
  * Prepares the $_SERVER entries for the PHP runtime.
1688
1686
  *
1689
1687
  * @param defaults Default entries to include in $_SERVER.
@@ -1806,7 +1804,7 @@ B = function(t, e, r) {
1806
1804
  [t, e]
1807
1805
  );
1808
1806
  }, j = async function(t) {
1809
- u(this, y).enabled && u(this, y).needsRotating && await this.rotateRuntime(), ++u(this, y).requestsMade, u(this, y).requestsMade >= u(this, y).maxRequests && (u(this, y).needsRotating = !0);
1807
+ u(this, _).enabled && u(this, _).needsRotating && await this.rotateRuntime(), ++u(this, _).requestsMade, u(this, _).requestsMade >= u(this, _).maxRequests && (u(this, _).needsRotating = !0);
1810
1808
  const e = this[__private__dont__use], r = await createInvertedReadableStream();
1811
1809
  e.onHeaders = (d) => {
1812
1810
  a || s || r.controller.enqueue(d.slice());
@@ -1887,15 +1885,10 @@ function normalizeHeaders(t) {
1887
1885
  e[r.toLowerCase()] = t[r];
1888
1886
  return e;
1889
1887
  }
1890
- function copyFS(t, e, r) {
1891
- let s;
1892
- try {
1893
- s = t.lookupPath(r);
1894
- } catch {
1895
- return;
1896
- }
1897
- if (!("contents" in s.node))
1888
+ function copyMEMFSNodes(t, e, r) {
1889
+ if (getNodeType(t, r) !== "memfs" || !["memfs", "missing"].includes(getNodeType(e, r)))
1898
1890
  return;
1891
+ const s = t.lookupPath(r);
1899
1892
  if (!t.isDir(s.node.mode)) {
1900
1893
  e.writeFile(r, t.readFile(r));
1901
1894
  return;
@@ -1903,7 +1896,7 @@ function copyFS(t, e, r) {
1903
1896
  e.mkdirTree(r);
1904
1897
  const n = t.readdir(r).filter((i) => i !== "." && i !== "..");
1905
1898
  for (const i of n)
1906
- copyFS(t, e, joinPaths(r, i));
1899
+ copyMEMFSNodes(t, e, joinPaths(r, i));
1907
1900
  }
1908
1901
  async function createInvertedReadableStream(t = {}) {
1909
1902
  let e;
@@ -1923,6 +1916,18 @@ async function createInvertedReadableStream(t = {}) {
1923
1916
  controller: n
1924
1917
  };
1925
1918
  }
1919
+ const getNodeType = (t, e) => {
1920
+ try {
1921
+ return "contents" in t.lookupPath(e, { follow: !0 }).node ? "memfs" : (
1922
+ /**
1923
+ * Could be NODEFS, PROXYFS, etc.
1924
+ */
1925
+ "not-memfs"
1926
+ );
1927
+ } catch {
1928
+ return "missing";
1929
+ }
1930
+ };
1926
1931
  async function getPhpIniEntries(t, e) {
1927
1932
  const r = parse(await t.readFileAsText(PHP_INI_PATH));
1928
1933
  if (e === void 0)
@@ -2328,7 +2333,7 @@ const _default = "application/octet-stream", asx = "video/x-ms-asf", atom = "app
2328
2333
  xspf,
2329
2334
  zip
2330
2335
  };
2331
- var x, I, N, F, M, P, A, v, S, Q, Z, ee;
2336
+ var x, M, N, F, I, P, A, v, S, Q, Z, ee;
2332
2337
  class PHPRequestHandler {
2333
2338
  /**
2334
2339
  * The request handler needs to decide whether to serve a static asset or
@@ -2342,15 +2347,15 @@ class PHPRequestHandler {
2342
2347
  * @param config - Request Handler configuration.
2343
2348
  */
2344
2349
  constructor(e) {
2345
- _(this, S);
2346
- _(this, x);
2347
- _(this, I);
2348
- _(this, N);
2349
- _(this, F);
2350
- _(this, M);
2351
- _(this, P);
2352
- _(this, A);
2353
- _(this, v);
2350
+ y(this, S);
2351
+ y(this, x);
2352
+ y(this, M);
2353
+ y(this, N);
2354
+ y(this, F);
2355
+ y(this, I);
2356
+ y(this, P);
2357
+ y(this, A);
2358
+ y(this, v);
2354
2359
  const {
2355
2360
  documentRoot: r = "/www/",
2356
2361
  absoluteUrl: s = typeof location == "object" ? location.href : DEFAULT_BASE_URL,
@@ -2368,14 +2373,14 @@ class PHPRequestHandler {
2368
2373
  maxPhpInstances: e.maxPhpInstances
2369
2374
  }), w(this, v, e.cookieStore === void 0 ? new HttpCookieStore() : e.cookieStore), w(this, x, r);
2370
2375
  const o = new URL(s);
2371
- w(this, N, o.hostname), w(this, F, o.port ? Number(o.port) : o.protocol === "https:" ? 443 : 80), w(this, I, (o.protocol || "").replace(":", ""));
2376
+ w(this, N, o.hostname), w(this, F, o.port ? Number(o.port) : o.protocol === "https:" ? 443 : 80), w(this, M, (o.protocol || "").replace(":", ""));
2372
2377
  const a = u(this, F) !== 443 && u(this, F) !== 80;
2373
- w(this, M, [
2378
+ w(this, I, [
2374
2379
  u(this, N),
2375
2380
  a ? `:${u(this, F)}` : ""
2376
2381
  ].join("")), w(this, P, o.pathname.replace(/\/+$/, "")), w(this, A, [
2377
- `${u(this, I)}://`,
2378
- u(this, M),
2382
+ `${u(this, M)}://`,
2383
+ u(this, I),
2379
2384
  u(this, P)
2380
2385
  ].join("")), this.rewriteRules = n, this.getFileNotFoundAction = i;
2381
2386
  }
@@ -2533,7 +2538,7 @@ class PHPRequestHandler {
2533
2538
  await this.processManager[Symbol.asyncDispose]();
2534
2539
  }
2535
2540
  }
2536
- x = new WeakMap(), I = new WeakMap(), N = new WeakMap(), F = new WeakMap(), M = new WeakMap(), P = new WeakMap(), A = new WeakMap(), v = new WeakMap(), S = new WeakSet(), /**
2541
+ x = new WeakMap(), M = new WeakMap(), N = new WeakMap(), F = new WeakMap(), I = new WeakMap(), P = new WeakMap(), A = new WeakMap(), v = new WeakMap(), S = new WeakSet(), /**
2537
2542
  * Serves a static file from the PHP filesystem.
2538
2543
  *
2539
2544
  * @param fsPath - Absolute path of the static file to serve.
@@ -2571,7 +2576,7 @@ Q = function(e, r) {
2571
2576
  }, ee = async function(e, r, s) {
2572
2577
  let n = "GET";
2573
2578
  const i = {
2574
- host: u(this, M),
2579
+ host: u(this, I),
2575
2580
  ...normalizeHeaders(r.headers || {})
2576
2581
  };
2577
2582
  u(this, v) && (i.cookie = u(this, v).getCookieRequestHeader());
@@ -2587,7 +2592,7 @@ Q = function(e, r) {
2587
2592
  toRelativeUrl(new URL(r.url)),
2588
2593
  u(this, P)
2589
2594
  ),
2590
- protocol: u(this, I),
2595
+ protocol: u(this, M),
2591
2596
  method: r.method || n,
2592
2597
  $_SERVER: {
2593
2598
  REMOTE_ADDR: "127.0.0.1",
@@ -2651,6 +2656,11 @@ function proxyFileSystem(t, e, r) {
2651
2656
  n
2652
2657
  );
2653
2658
  }
2659
+ function isPathToSharedFS(t, e) {
2660
+ var i;
2661
+ const r = Object.getOwnPropertySymbols(t)[0], n = t[r].FS.lookupPath(e, { noent_okay: !0 });
2662
+ return ((i = n == null ? void 0 : n.node) == null ? void 0 : i.isSharedFS) ?? !1;
2663
+ }
2654
2664
  function sandboxedSpawnHandlerFactory(t) {
2655
2665
  return createSpawnHandler(async function(e, r, s) {
2656
2666
  r.notifySpawn(), e[0] === "exec" && e.shift(), (e[0].endsWith(".php") || e[0].endsWith(".phar")) && e.unshift("php");
@@ -3425,6 +3435,7 @@ export {
3425
3435
  getLoadedRuntime,
3426
3436
  getPhpIniEntries,
3427
3437
  isExitCode,
3438
+ isPathToSharedFS,
3428
3439
  iteratePhpFiles as iterateFiles,
3429
3440
  loadPHPRuntime,
3430
3441
  prettyPrintFullStackTrace,