@php-wasm/node 3.1.21 → 3.1.25
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/README.md +49 -6
- package/index.cjs +322 -348
- package/index.js +313 -343
- package/lib/extensions/load-extensions.d.ts +61 -0
- package/lib/extensions/node-extension-resources.d.ts +20 -0
- package/lib/index.d.ts +1 -1
- package/lib/load-runtime.d.ts +21 -1
- package/package.json +19 -19
- package/lib/extensions/intl/with-intl.d.ts +0 -2
- package/lib/extensions/memcached/with-memcached.d.ts +0 -2
- package/lib/extensions/redis/with-redis.d.ts +0 -2
- package/lib/extensions/xdebug/with-xdebug.d.ts +0 -11
package/index.cjs
CHANGED
|
@@ -37,8 +37,7 @@ __export(src_exports, {
|
|
|
37
37
|
getPHPLoaderModule: () => getPHPLoaderModule,
|
|
38
38
|
loadNodeRuntime: () => loadNodeRuntime,
|
|
39
39
|
useHostFilesystem: () => useHostFilesystem,
|
|
40
|
-
withNetworking: () => withNetworking
|
|
41
|
-
withXdebug: () => withXdebug
|
|
40
|
+
withNetworking: () => withNetworking
|
|
42
41
|
});
|
|
43
42
|
module.exports = __toCommonJS(src_exports);
|
|
44
43
|
|
|
@@ -425,7 +424,7 @@ async function withNetworking(phpModuleArgs = {}) {
|
|
|
425
424
|
}
|
|
426
425
|
|
|
427
426
|
// packages/php-wasm/node/src/lib/load-runtime.ts
|
|
428
|
-
var
|
|
427
|
+
var import_universal9 = require("@php-wasm/universal");
|
|
429
428
|
|
|
430
429
|
// packages/php-wasm/node/src/lib/wasm-user-space.ts
|
|
431
430
|
var import_promises = require("dns/promises");
|
|
@@ -495,8 +494,8 @@ function bindUserSpace({ fileLockManager }, {
|
|
|
495
494
|
[F_WRLCK]: "exclusive",
|
|
496
495
|
[F_UNLCK]: "unlocked"
|
|
497
496
|
},
|
|
498
|
-
is_path_to_shared_fs(
|
|
499
|
-
const { node } = FS.lookupPath(
|
|
497
|
+
is_path_to_shared_fs(path3) {
|
|
498
|
+
const { node } = FS.lookupPath(path3, { noent_okay: true });
|
|
500
499
|
if (!node) {
|
|
501
500
|
return false;
|
|
502
501
|
}
|
|
@@ -1127,7 +1126,7 @@ function bindUserSpace({ fileLockManager }, {
|
|
|
1127
1126
|
}
|
|
1128
1127
|
|
|
1129
1128
|
// packages/php-wasm/node/src/lib/load-runtime.ts
|
|
1130
|
-
var
|
|
1129
|
+
var import_fs2 = __toESM(require("fs"), 1);
|
|
1131
1130
|
|
|
1132
1131
|
// packages/php-wasm/node/src/lib/file-lock-manager-for-posix.ts
|
|
1133
1132
|
var import_universal2 = require("@php-wasm/universal");
|
|
@@ -1145,7 +1144,7 @@ var FileLockManagerForPosix = class {
|
|
|
1145
1144
|
this.wholeFileLockMap = /* @__PURE__ */ new Map();
|
|
1146
1145
|
this.rangeLockedFds = /* @__PURE__ */ new Map();
|
|
1147
1146
|
}
|
|
1148
|
-
lockWholeFile(
|
|
1147
|
+
lockWholeFile(path3, op) {
|
|
1149
1148
|
const opType = op.type === "unlock" ? "un" : op.waitForLock ? op.type === "exclusive" ? "ex" : "sh" : op.type === "exclusive" ? "exnb" : "shnb";
|
|
1150
1149
|
try {
|
|
1151
1150
|
(0, import_fs_ext_extra_prebuilt.flockSync)(op.fd, opType);
|
|
@@ -1157,7 +1156,7 @@ var FileLockManagerForPosix = class {
|
|
|
1157
1156
|
}
|
|
1158
1157
|
this.wholeFileLockMap.get(op.pid).set(op.fd, {
|
|
1159
1158
|
...op,
|
|
1160
|
-
path:
|
|
1159
|
+
path: path3
|
|
1161
1160
|
});
|
|
1162
1161
|
}
|
|
1163
1162
|
return true;
|
|
@@ -1168,7 +1167,7 @@ var FileLockManagerForPosix = class {
|
|
|
1168
1167
|
return false;
|
|
1169
1168
|
}
|
|
1170
1169
|
}
|
|
1171
|
-
lockFileByteRange(
|
|
1170
|
+
lockFileByteRange(path3, op, waitForLock) {
|
|
1172
1171
|
if (op.start === op.end) {
|
|
1173
1172
|
op = {
|
|
1174
1173
|
...op,
|
|
@@ -1189,10 +1188,10 @@ var FileLockManagerForPosix = class {
|
|
|
1189
1188
|
this.rangeLockedFds.set(op.pid, /* @__PURE__ */ new Map());
|
|
1190
1189
|
}
|
|
1191
1190
|
const pidMap = this.rangeLockedFds.get(op.pid);
|
|
1192
|
-
if (!pidMap.has(
|
|
1193
|
-
pidMap.set(
|
|
1191
|
+
if (!pidMap.has(path3)) {
|
|
1192
|
+
pidMap.set(path3, /* @__PURE__ */ new Set());
|
|
1194
1193
|
}
|
|
1195
|
-
pidMap.get(
|
|
1194
|
+
pidMap.get(path3).add(op.fd);
|
|
1196
1195
|
return true;
|
|
1197
1196
|
} catch (e) {
|
|
1198
1197
|
if (!isLockDenialError(e)) {
|
|
@@ -1201,13 +1200,13 @@ var FileLockManagerForPosix = class {
|
|
|
1201
1200
|
return false;
|
|
1202
1201
|
}
|
|
1203
1202
|
}
|
|
1204
|
-
findFirstConflictingByteRangeLock(
|
|
1203
|
+
findFirstConflictingByteRangeLock(path3, op) {
|
|
1205
1204
|
if (op.type === "unlocked") {
|
|
1206
1205
|
return void 0;
|
|
1207
1206
|
}
|
|
1208
|
-
const obtainedLock = this.lockFileByteRange(
|
|
1207
|
+
const obtainedLock = this.lockFileByteRange(path3, op, false);
|
|
1209
1208
|
if (obtainedLock) {
|
|
1210
|
-
this.lockFileByteRange(
|
|
1209
|
+
this.lockFileByteRange(path3, { ...op, type: "unlocked" }, true);
|
|
1211
1210
|
return void 0;
|
|
1212
1211
|
}
|
|
1213
1212
|
return {
|
|
@@ -1235,11 +1234,11 @@ var FileLockManagerForPosix = class {
|
|
|
1235
1234
|
}
|
|
1236
1235
|
this.wholeFileLockMap.delete(targetPid);
|
|
1237
1236
|
}
|
|
1238
|
-
for (const [
|
|
1237
|
+
for (const [path3, fdSet] of this.rangeLockedFds.get(targetPid) ?? []) {
|
|
1239
1238
|
for (const fd of fdSet) {
|
|
1240
1239
|
try {
|
|
1241
1240
|
this.lockFileByteRange(
|
|
1242
|
-
|
|
1241
|
+
path3,
|
|
1243
1242
|
{
|
|
1244
1243
|
pid: targetPid,
|
|
1245
1244
|
fd,
|
|
@@ -1251,7 +1250,7 @@ var FileLockManagerForPosix = class {
|
|
|
1251
1250
|
);
|
|
1252
1251
|
} catch (e) {
|
|
1253
1252
|
import_logger2.logger.error(
|
|
1254
|
-
`releaseLocksForProcess: failed to unlock byte range for pid=${targetPid} fd=${fd} path=${
|
|
1253
|
+
`releaseLocksForProcess: failed to unlock byte range for pid=${targetPid} fd=${fd} path=${path3}`,
|
|
1255
1254
|
e
|
|
1256
1255
|
);
|
|
1257
1256
|
}
|
|
@@ -1308,7 +1307,7 @@ var FileLockManagerForWindows = class {
|
|
|
1308
1307
|
this.wholeFileLockMap = /* @__PURE__ */ new Map();
|
|
1309
1308
|
this.rangeLockedFds = /* @__PURE__ */ new Map();
|
|
1310
1309
|
}
|
|
1311
|
-
lockWholeFile(
|
|
1310
|
+
lockWholeFile(path3, op) {
|
|
1312
1311
|
const start = 0n;
|
|
1313
1312
|
const end = 2n ** 64n - 1n;
|
|
1314
1313
|
if (op.type === "unlock") {
|
|
@@ -1320,7 +1319,7 @@ var FileLockManagerForWindows = class {
|
|
|
1320
1319
|
}
|
|
1321
1320
|
} else {
|
|
1322
1321
|
import_logger3.logger.warn(
|
|
1323
|
-
`lockWholeFile: unlock failed for pid=${op.pid} fd=${op.fd} path=${
|
|
1322
|
+
`lockWholeFile: unlock failed for pid=${op.pid} fd=${op.fd} path=${path3}`
|
|
1324
1323
|
);
|
|
1325
1324
|
}
|
|
1326
1325
|
return success2;
|
|
@@ -1388,22 +1387,22 @@ var FileLockManagerForWindows = class {
|
|
|
1388
1387
|
}
|
|
1389
1388
|
this.wholeFileLockMap.get(op.pid).set(op.fd, {
|
|
1390
1389
|
...op,
|
|
1391
|
-
path:
|
|
1390
|
+
path: path3
|
|
1392
1391
|
});
|
|
1393
1392
|
}
|
|
1394
1393
|
return success;
|
|
1395
1394
|
}
|
|
1396
|
-
lockFileByteRange(
|
|
1395
|
+
lockFileByteRange(path3, op, waitForLock) {
|
|
1397
1396
|
if (op.start === op.end) {
|
|
1398
1397
|
op = {
|
|
1399
1398
|
...op,
|
|
1400
1399
|
end: import_universal3.MAX_ADDRESSABLE_FILE_OFFSET
|
|
1401
1400
|
};
|
|
1402
1401
|
}
|
|
1403
|
-
if (!this.rangeLockedFds.has(
|
|
1404
|
-
this.rangeLockedFds.set(
|
|
1402
|
+
if (!this.rangeLockedFds.has(path3)) {
|
|
1403
|
+
this.rangeLockedFds.set(path3, new import_universal3.FileLockIntervalTree());
|
|
1405
1404
|
}
|
|
1406
|
-
const lockedRangeTree = this.rangeLockedFds.get(
|
|
1405
|
+
const lockedRangeTree = this.rangeLockedFds.get(path3);
|
|
1407
1406
|
const overlappingLocks = lockedRangeTree.findOverlapping(op);
|
|
1408
1407
|
let preexistingLock;
|
|
1409
1408
|
if (overlappingLocks.length === 1 && overlappingLocks[0].pid === op.pid && // NOTE: FD shouldn't matter for fcntl() F_SETLK because it is a process-level lock,
|
|
@@ -1488,12 +1487,12 @@ var FileLockManagerForWindows = class {
|
|
|
1488
1487
|
return true;
|
|
1489
1488
|
}
|
|
1490
1489
|
}
|
|
1491
|
-
findFirstConflictingByteRangeLock(
|
|
1490
|
+
findFirstConflictingByteRangeLock(path3, op) {
|
|
1492
1491
|
if (op.type === "unlocked") {
|
|
1493
1492
|
return void 0;
|
|
1494
1493
|
}
|
|
1495
|
-
const obtainedLock = !!this.lockFileByteRange(
|
|
1496
|
-
this.lockFileByteRange(
|
|
1494
|
+
const obtainedLock = !!this.lockFileByteRange(path3, op, false);
|
|
1495
|
+
this.lockFileByteRange(path3, { ...op, type: "unlocked" }, false);
|
|
1497
1496
|
if (obtainedLock) {
|
|
1498
1497
|
return void 0;
|
|
1499
1498
|
}
|
|
@@ -1522,18 +1521,18 @@ var FileLockManagerForWindows = class {
|
|
|
1522
1521
|
}
|
|
1523
1522
|
this.wholeFileLockMap.delete(targetPid);
|
|
1524
1523
|
}
|
|
1525
|
-
for (const [
|
|
1524
|
+
for (const [path3, lockedRangeTree] of this.rangeLockedFds.entries()) {
|
|
1526
1525
|
const rangesLockedByTargetPid = lockedRangeTree.findLocksForProcess(targetPid);
|
|
1527
1526
|
for (const op of rangesLockedByTargetPid) {
|
|
1528
1527
|
try {
|
|
1529
1528
|
this.lockFileByteRange(
|
|
1530
|
-
|
|
1529
|
+
path3,
|
|
1531
1530
|
{ ...op, type: "unlocked" },
|
|
1532
1531
|
false
|
|
1533
1532
|
);
|
|
1534
1533
|
} catch (e) {
|
|
1535
1534
|
import_logger3.logger.error(
|
|
1536
|
-
`releaseLocksForProcess: failed to unlock byte range for pid=${targetPid} fd=${op.fd} path=${
|
|
1535
|
+
`releaseLocksForProcess: failed to unlock byte range for pid=${targetPid} fd=${op.fd} path=${path3}`,
|
|
1537
1536
|
e
|
|
1538
1537
|
);
|
|
1539
1538
|
}
|
|
@@ -1569,200 +1568,59 @@ var FileLockManagerForWindows = class {
|
|
|
1569
1568
|
}
|
|
1570
1569
|
};
|
|
1571
1570
|
|
|
1572
|
-
// packages/php-wasm/node/src/lib/extensions/
|
|
1571
|
+
// packages/php-wasm/node/src/lib/extensions/load-extensions.ts
|
|
1573
1572
|
var import_cli_util = require("@php-wasm/cli-util");
|
|
1574
|
-
var
|
|
1573
|
+
var import_universal8 = require("@php-wasm/universal");
|
|
1575
1574
|
var import_fs = __toESM(require("fs"), 1);
|
|
1575
|
+
var import_path2 = __toESM(require("path"), 1);
|
|
1576
1576
|
|
|
1577
|
-
// packages/php-wasm/node/src/lib/extensions/
|
|
1577
|
+
// packages/php-wasm/node/src/lib/extensions/intl/get-intl-extension-module.ts
|
|
1578
1578
|
var import_universal4 = require("@php-wasm/universal");
|
|
1579
|
-
async function
|
|
1579
|
+
async function getIntlExtensionModule(version = import_universal4.LatestSupportedPHPVersion) {
|
|
1580
1580
|
switch (version) {
|
|
1581
1581
|
case "8.5":
|
|
1582
|
-
return (await import("@php-wasm/node-8-5")).
|
|
1582
|
+
return (await import("@php-wasm/node-8-5")).getIntlExtensionPath();
|
|
1583
1583
|
case "8.4":
|
|
1584
|
-
return (await import("@php-wasm/node-8-4")).
|
|
1584
|
+
return (await import("@php-wasm/node-8-4")).getIntlExtensionPath();
|
|
1585
1585
|
case "8.3":
|
|
1586
|
-
return (await import("@php-wasm/node-8-3")).
|
|
1586
|
+
return (await import("@php-wasm/node-8-3")).getIntlExtensionPath();
|
|
1587
1587
|
case "8.2":
|
|
1588
|
-
return (await import("@php-wasm/node-8-2")).
|
|
1588
|
+
return (await import("@php-wasm/node-8-2")).getIntlExtensionPath();
|
|
1589
1589
|
case "8.1":
|
|
1590
|
-
return (await import("@php-wasm/node-8-1")).
|
|
1590
|
+
return (await import("@php-wasm/node-8-1")).getIntlExtensionPath();
|
|
1591
1591
|
case "8.0":
|
|
1592
|
-
return (await import("@php-wasm/node-8-0")).
|
|
1592
|
+
return (await import("@php-wasm/node-8-0")).getIntlExtensionPath();
|
|
1593
1593
|
case "7.4":
|
|
1594
|
-
return (await import("@php-wasm/node-7-4")).
|
|
1594
|
+
return (await import("@php-wasm/node-7-4")).getIntlExtensionPath();
|
|
1595
1595
|
}
|
|
1596
1596
|
throw new Error(`Unsupported PHP version ${version}`);
|
|
1597
1597
|
}
|
|
1598
1598
|
|
|
1599
|
-
// packages/php-wasm/node/src/lib/extensions/
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
const filePath = await getXdebugExtensionModule(version);
|
|
1603
|
-
const extension = import_fs.default.readFileSync(filePath);
|
|
1604
|
-
return {
|
|
1605
|
-
...options,
|
|
1606
|
-
ENV: {
|
|
1607
|
-
...options.ENV,
|
|
1608
|
-
PHP_INI_SCAN_DIR: "/internal/shared/extensions"
|
|
1609
|
-
},
|
|
1610
|
-
onRuntimeInitialized: (phpRuntime) => {
|
|
1611
|
-
if (options.onRuntimeInitialized) {
|
|
1612
|
-
options.onRuntimeInitialized(phpRuntime);
|
|
1613
|
-
}
|
|
1614
|
-
if (!import_universal5.FSHelpers.fileExists(
|
|
1615
|
-
phpRuntime.FS,
|
|
1616
|
-
"/internal/shared/extensions"
|
|
1617
|
-
)) {
|
|
1618
|
-
phpRuntime.FS.mkdirTree("/internal/shared/extensions");
|
|
1619
|
-
}
|
|
1620
|
-
if (!import_universal5.FSHelpers.fileExists(
|
|
1621
|
-
phpRuntime.FS,
|
|
1622
|
-
`/internal/shared/extensions/${fileName}`
|
|
1623
|
-
)) {
|
|
1624
|
-
phpRuntime.FS.writeFile(
|
|
1625
|
-
`/internal/shared/extensions/${fileName}`,
|
|
1626
|
-
new Uint8Array(extension)
|
|
1627
|
-
);
|
|
1628
|
-
}
|
|
1629
|
-
if (!import_universal5.FSHelpers.fileExists(
|
|
1630
|
-
phpRuntime.FS,
|
|
1631
|
-
"/internal/shared/extensions/xdebug.ini"
|
|
1632
|
-
)) {
|
|
1633
|
-
const ideKey = xdebugOptions.ideKey || import_cli_util.DEFAULT_IDE_KEY;
|
|
1634
|
-
phpRuntime.FS.writeFile(
|
|
1635
|
-
"/internal/shared/extensions/xdebug.ini",
|
|
1636
|
-
[
|
|
1637
|
-
"zend_extension=/internal/shared/extensions/xdebug.so",
|
|
1638
|
-
"xdebug.mode=debug,develop",
|
|
1639
|
-
"xdebug.start_with_request=yes",
|
|
1640
|
-
`xdebug.idekey="${ideKey}"`,
|
|
1641
|
-
// Path mapping is only available starting
|
|
1642
|
-
// from Xdebug 3.5, which is used by PHP 8.5+
|
|
1643
|
-
// Previous versions will ignore this entry.
|
|
1644
|
-
"xdebug.path_mapping=yes"
|
|
1645
|
-
].join("\n")
|
|
1646
|
-
);
|
|
1647
|
-
}
|
|
1648
|
-
const isPHP85orHigher = import_universal5.SupportedPHPVersionsList.indexOf(version) <= import_universal5.SupportedPHPVersions.indexOf("8.5");
|
|
1649
|
-
if (isPHP85orHigher) {
|
|
1650
|
-
const { pathMappings, pathSkippings } = xdebugOptions;
|
|
1651
|
-
if (!pathMappings && !pathSkippings)
|
|
1652
|
-
return;
|
|
1653
|
-
phpRuntime.FS.mkdir("/.xdebug");
|
|
1654
|
-
if (pathMappings) {
|
|
1655
|
-
phpRuntime.FS.writeFile(
|
|
1656
|
-
"/.xdebug/path.map",
|
|
1657
|
-
pathMappings.map((map) => `${map.vfsPath} = ${map.hostPath}`).join("\n")
|
|
1658
|
-
);
|
|
1659
|
-
}
|
|
1660
|
-
if (pathSkippings) {
|
|
1661
|
-
phpRuntime.FS.writeFile(
|
|
1662
|
-
"/.xdebug/skip.map",
|
|
1663
|
-
pathSkippings.map((path2) => `${path2} = SKIP`).join("\n")
|
|
1664
|
-
);
|
|
1665
|
-
}
|
|
1666
|
-
}
|
|
1667
|
-
}
|
|
1668
|
-
};
|
|
1669
|
-
}
|
|
1670
|
-
|
|
1671
|
-
// packages/php-wasm/node/src/lib/extensions/intl/with-intl.ts
|
|
1672
|
-
var import_universal7 = require("@php-wasm/universal");
|
|
1673
|
-
var import_fs2 = __toESM(require("fs"), 1);
|
|
1674
|
-
var import_path = __toESM(require("path"), 1);
|
|
1675
|
-
|
|
1676
|
-
// packages/php-wasm/node/src/lib/extensions/intl/get-intl-extension-module.ts
|
|
1677
|
-
var import_universal6 = require("@php-wasm/universal");
|
|
1678
|
-
async function getIntlExtensionModule(version = import_universal6.LatestSupportedPHPVersion) {
|
|
1599
|
+
// packages/php-wasm/node/src/lib/extensions/memcached/get-memcached-extension-module.ts
|
|
1600
|
+
var import_universal5 = require("@php-wasm/universal");
|
|
1601
|
+
async function getMemcachedExtensionModule(version = import_universal5.LatestSupportedPHPVersion) {
|
|
1679
1602
|
switch (version) {
|
|
1680
1603
|
case "8.5":
|
|
1681
|
-
return (await import("@php-wasm/node-8-5")).
|
|
1604
|
+
return (await import("@php-wasm/node-8-5")).getMemcachedExtensionPath();
|
|
1682
1605
|
case "8.4":
|
|
1683
|
-
return (await import("@php-wasm/node-8-4")).
|
|
1606
|
+
return (await import("@php-wasm/node-8-4")).getMemcachedExtensionPath();
|
|
1684
1607
|
case "8.3":
|
|
1685
|
-
return (await import("@php-wasm/node-8-3")).
|
|
1608
|
+
return (await import("@php-wasm/node-8-3")).getMemcachedExtensionPath();
|
|
1686
1609
|
case "8.2":
|
|
1687
|
-
return (await import("@php-wasm/node-8-2")).
|
|
1610
|
+
return (await import("@php-wasm/node-8-2")).getMemcachedExtensionPath();
|
|
1688
1611
|
case "8.1":
|
|
1689
|
-
return (await import("@php-wasm/node-8-1")).
|
|
1612
|
+
return (await import("@php-wasm/node-8-1")).getMemcachedExtensionPath();
|
|
1690
1613
|
case "8.0":
|
|
1691
|
-
return (await import("@php-wasm/node-8-0")).
|
|
1614
|
+
return (await import("@php-wasm/node-8-0")).getMemcachedExtensionPath();
|
|
1692
1615
|
case "7.4":
|
|
1693
|
-
return (await import("@php-wasm/node-7-4")).
|
|
1616
|
+
return (await import("@php-wasm/node-7-4")).getMemcachedExtensionPath();
|
|
1694
1617
|
}
|
|
1695
1618
|
throw new Error(`Unsupported PHP version ${version}`);
|
|
1696
1619
|
}
|
|
1697
1620
|
|
|
1698
|
-
// packages/php-wasm/node/src/lib/extensions/intl/with-intl.ts
|
|
1699
|
-
var import_meta = {};
|
|
1700
|
-
async function withIntl(version = import_universal7.LatestSupportedPHPVersion, options) {
|
|
1701
|
-
const extensionName = "intl.so";
|
|
1702
|
-
const extensionPath = await getIntlExtensionModule(version);
|
|
1703
|
-
const extension = import_fs2.default.readFileSync(extensionPath);
|
|
1704
|
-
const dataName = "icu.dat";
|
|
1705
|
-
const moduleDir = typeof __dirname !== "undefined" ? __dirname : import_meta.dirname;
|
|
1706
|
-
const dataPath = import_path.default.join(moduleDir, "shared", dataName);
|
|
1707
|
-
const ICUData = import_fs2.default.readFileSync(dataPath);
|
|
1708
|
-
return {
|
|
1709
|
-
...options,
|
|
1710
|
-
ENV: {
|
|
1711
|
-
...options.ENV,
|
|
1712
|
-
PHP_INI_SCAN_DIR: "/internal/shared/extensions",
|
|
1713
|
-
ICU_DATA: "/internal/shared"
|
|
1714
|
-
},
|
|
1715
|
-
onRuntimeInitialized: (phpRuntime) => {
|
|
1716
|
-
if (options.onRuntimeInitialized) {
|
|
1717
|
-
options.onRuntimeInitialized(phpRuntime);
|
|
1718
|
-
}
|
|
1719
|
-
if (!import_universal7.FSHelpers.fileExists(
|
|
1720
|
-
phpRuntime.FS,
|
|
1721
|
-
"/internal/shared/extensions"
|
|
1722
|
-
)) {
|
|
1723
|
-
phpRuntime.FS.mkdirTree("/internal/shared/extensions");
|
|
1724
|
-
}
|
|
1725
|
-
if (!import_universal7.FSHelpers.fileExists(
|
|
1726
|
-
phpRuntime.FS,
|
|
1727
|
-
`/internal/shared/extensions/${extensionName}`
|
|
1728
|
-
)) {
|
|
1729
|
-
phpRuntime.FS.writeFile(
|
|
1730
|
-
`/internal/shared/extensions/${extensionName}`,
|
|
1731
|
-
new Uint8Array(extension)
|
|
1732
|
-
);
|
|
1733
|
-
}
|
|
1734
|
-
if (!import_universal7.FSHelpers.fileExists(
|
|
1735
|
-
phpRuntime.FS,
|
|
1736
|
-
"/internal/shared/extensions/intl.ini"
|
|
1737
|
-
)) {
|
|
1738
|
-
phpRuntime.FS.writeFile(
|
|
1739
|
-
"/internal/shared/extensions/intl.ini",
|
|
1740
|
-
[
|
|
1741
|
-
`extension=/internal/shared/extensions/${extensionName}`
|
|
1742
|
-
].join("\n")
|
|
1743
|
-
);
|
|
1744
|
-
}
|
|
1745
|
-
if (!import_universal7.FSHelpers.fileExists(
|
|
1746
|
-
phpRuntime.FS,
|
|
1747
|
-
`${phpRuntime.ENV.ICU_DATA}/${dataName}`
|
|
1748
|
-
)) {
|
|
1749
|
-
phpRuntime.FS.mkdirTree(phpRuntime.ENV.ICU_DATA);
|
|
1750
|
-
phpRuntime.FS.writeFile(
|
|
1751
|
-
`${phpRuntime.ENV.ICU_DATA}/icudt74l.dat`,
|
|
1752
|
-
new Uint8Array(ICUData)
|
|
1753
|
-
);
|
|
1754
|
-
}
|
|
1755
|
-
}
|
|
1756
|
-
};
|
|
1757
|
-
}
|
|
1758
|
-
|
|
1759
|
-
// packages/php-wasm/node/src/lib/extensions/redis/with-redis.ts
|
|
1760
|
-
var import_universal9 = require("@php-wasm/universal");
|
|
1761
|
-
var import_fs3 = __toESM(require("fs"), 1);
|
|
1762
|
-
|
|
1763
1621
|
// packages/php-wasm/node/src/lib/extensions/redis/get-redis-extension-module.ts
|
|
1764
|
-
var
|
|
1765
|
-
async function getRedisExtensionModule(version =
|
|
1622
|
+
var import_universal6 = require("@php-wasm/universal");
|
|
1623
|
+
async function getRedisExtensionModule(version = import_universal6.LatestSupportedPHPVersion) {
|
|
1766
1624
|
switch (version) {
|
|
1767
1625
|
case "8.5":
|
|
1768
1626
|
return (await import("@php-wasm/node-8-5")).getRedisExtensionPath();
|
|
@@ -1782,132 +1640,258 @@ async function getRedisExtensionModule(version = import_universal8.LatestSupport
|
|
|
1782
1640
|
throw new Error(`Unsupported PHP version ${version}`);
|
|
1783
1641
|
}
|
|
1784
1642
|
|
|
1785
|
-
// packages/php-wasm/node/src/lib/extensions/
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
const extensionPath = await getRedisExtensionModule(version);
|
|
1789
|
-
const extension = import_fs3.default.readFileSync(extensionPath);
|
|
1790
|
-
return {
|
|
1791
|
-
...options,
|
|
1792
|
-
ENV: {
|
|
1793
|
-
...options.ENV,
|
|
1794
|
-
PHP_INI_SCAN_DIR: "/internal/shared/extensions"
|
|
1795
|
-
},
|
|
1796
|
-
onRuntimeInitialized: (phpRuntime) => {
|
|
1797
|
-
if (options.onRuntimeInitialized) {
|
|
1798
|
-
options.onRuntimeInitialized(phpRuntime);
|
|
1799
|
-
}
|
|
1800
|
-
if (!import_universal9.FSHelpers.fileExists(
|
|
1801
|
-
phpRuntime.FS,
|
|
1802
|
-
"/internal/shared/extensions"
|
|
1803
|
-
)) {
|
|
1804
|
-
phpRuntime.FS.mkdirTree("/internal/shared/extensions");
|
|
1805
|
-
}
|
|
1806
|
-
if (!import_universal9.FSHelpers.fileExists(
|
|
1807
|
-
phpRuntime.FS,
|
|
1808
|
-
`/internal/shared/extensions/${extensionName}`
|
|
1809
|
-
)) {
|
|
1810
|
-
phpRuntime.FS.writeFile(
|
|
1811
|
-
`/internal/shared/extensions/${extensionName}`,
|
|
1812
|
-
new Uint8Array(extension)
|
|
1813
|
-
);
|
|
1814
|
-
}
|
|
1815
|
-
if (!import_universal9.FSHelpers.fileExists(
|
|
1816
|
-
phpRuntime.FS,
|
|
1817
|
-
"/internal/shared/extensions/redis.ini"
|
|
1818
|
-
)) {
|
|
1819
|
-
phpRuntime.FS.writeFile(
|
|
1820
|
-
"/internal/shared/extensions/redis.ini",
|
|
1821
|
-
[
|
|
1822
|
-
`extension=/internal/shared/extensions/${extensionName}`
|
|
1823
|
-
].join("\n")
|
|
1824
|
-
);
|
|
1825
|
-
}
|
|
1826
|
-
}
|
|
1827
|
-
};
|
|
1828
|
-
}
|
|
1829
|
-
|
|
1830
|
-
// packages/php-wasm/node/src/lib/extensions/memcached/with-memcached.ts
|
|
1831
|
-
var import_universal11 = require("@php-wasm/universal");
|
|
1832
|
-
var import_fs4 = __toESM(require("fs"), 1);
|
|
1833
|
-
|
|
1834
|
-
// packages/php-wasm/node/src/lib/extensions/memcached/get-memcached-extension-module.ts
|
|
1835
|
-
var import_universal10 = require("@php-wasm/universal");
|
|
1836
|
-
async function getMemcachedExtensionModule(version = import_universal10.LatestSupportedPHPVersion) {
|
|
1643
|
+
// packages/php-wasm/node/src/lib/extensions/xdebug/get-xdebug-extension-module.ts
|
|
1644
|
+
var import_universal7 = require("@php-wasm/universal");
|
|
1645
|
+
async function getXdebugExtensionModule(version = import_universal7.LatestSupportedPHPVersion) {
|
|
1837
1646
|
switch (version) {
|
|
1838
1647
|
case "8.5":
|
|
1839
|
-
return (await import("@php-wasm/node-8-5")).
|
|
1648
|
+
return (await import("@php-wasm/node-8-5")).getXdebugExtensionPath();
|
|
1840
1649
|
case "8.4":
|
|
1841
|
-
return (await import("@php-wasm/node-8-4")).
|
|
1650
|
+
return (await import("@php-wasm/node-8-4")).getXdebugExtensionPath();
|
|
1842
1651
|
case "8.3":
|
|
1843
|
-
return (await import("@php-wasm/node-8-3")).
|
|
1652
|
+
return (await import("@php-wasm/node-8-3")).getXdebugExtensionPath();
|
|
1844
1653
|
case "8.2":
|
|
1845
|
-
return (await import("@php-wasm/node-8-2")).
|
|
1654
|
+
return (await import("@php-wasm/node-8-2")).getXdebugExtensionPath();
|
|
1846
1655
|
case "8.1":
|
|
1847
|
-
return (await import("@php-wasm/node-8-1")).
|
|
1656
|
+
return (await import("@php-wasm/node-8-1")).getXdebugExtensionPath();
|
|
1848
1657
|
case "8.0":
|
|
1849
|
-
return (await import("@php-wasm/node-8-0")).
|
|
1658
|
+
return (await import("@php-wasm/node-8-0")).getXdebugExtensionPath();
|
|
1850
1659
|
case "7.4":
|
|
1851
|
-
return (await import("@php-wasm/node-7-4")).
|
|
1660
|
+
return (await import("@php-wasm/node-7-4")).getXdebugExtensionPath();
|
|
1852
1661
|
}
|
|
1853
1662
|
throw new Error(`Unsupported PHP version ${version}`);
|
|
1854
1663
|
}
|
|
1855
1664
|
|
|
1856
|
-
// packages/php-wasm/node/src/lib/extensions/
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1665
|
+
// packages/php-wasm/node/src/lib/extensions/node-extension-resources.ts
|
|
1666
|
+
var import_promises2 = require("fs/promises");
|
|
1667
|
+
var import_path = __toESM(require("path"), 1);
|
|
1668
|
+
var import_url = require("url");
|
|
1669
|
+
function normalizeNodeExtensionSource(source) {
|
|
1670
|
+
if (source.format === "url") {
|
|
1671
|
+
return {
|
|
1672
|
+
...source,
|
|
1673
|
+
url: toNodeResourceUrl(source.url)
|
|
1674
|
+
};
|
|
1675
|
+
}
|
|
1676
|
+
if (source.format !== "manifest") {
|
|
1677
|
+
return source;
|
|
1678
|
+
}
|
|
1679
|
+
if ("manifest" in source) {
|
|
1680
|
+
return source.baseUrl ? {
|
|
1681
|
+
...source,
|
|
1682
|
+
baseUrl: toNodeResourceUrl(source.baseUrl)
|
|
1683
|
+
} : source;
|
|
1684
|
+
}
|
|
1861
1685
|
return {
|
|
1862
|
-
...
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
}
|
|
1877
|
-
if (!import_universal11.FSHelpers.fileExists(
|
|
1878
|
-
phpRuntime.FS,
|
|
1879
|
-
`/internal/shared/extensions/${extensionName}`
|
|
1880
|
-
)) {
|
|
1881
|
-
phpRuntime.FS.writeFile(
|
|
1882
|
-
`/internal/shared/extensions/${extensionName}`,
|
|
1883
|
-
new Uint8Array(extension)
|
|
1884
|
-
);
|
|
1885
|
-
}
|
|
1886
|
-
if (!import_universal11.FSHelpers.fileExists(
|
|
1887
|
-
phpRuntime.FS,
|
|
1888
|
-
"/internal/shared/extensions/memcached.ini"
|
|
1889
|
-
)) {
|
|
1890
|
-
phpRuntime.FS.writeFile(
|
|
1891
|
-
"/internal/shared/extensions/memcached.ini",
|
|
1892
|
-
[
|
|
1893
|
-
`extension=/internal/shared/extensions/${extensionName}`
|
|
1894
|
-
].join("\n")
|
|
1895
|
-
);
|
|
1896
|
-
}
|
|
1686
|
+
...source,
|
|
1687
|
+
manifestUrl: toNodeResourceUrl(source.manifestUrl)
|
|
1688
|
+
};
|
|
1689
|
+
}
|
|
1690
|
+
async function fetchNodeExtensionResource(input) {
|
|
1691
|
+
const url = input instanceof Request ? new URL(input.url) : input instanceof URL ? input : toNodeResourceUrl(String(input));
|
|
1692
|
+
if (url.protocol === "file:") {
|
|
1693
|
+
try {
|
|
1694
|
+
return new Response(await (0, import_promises2.readFile)((0, import_url.fileURLToPath)(url)));
|
|
1695
|
+
} catch (error) {
|
|
1696
|
+
return new Response(String(error), {
|
|
1697
|
+
status: 404,
|
|
1698
|
+
statusText: "Not Found"
|
|
1699
|
+
});
|
|
1897
1700
|
}
|
|
1701
|
+
}
|
|
1702
|
+
return fetch(input);
|
|
1703
|
+
}
|
|
1704
|
+
function toNodeResourceUrl(urlOrPath) {
|
|
1705
|
+
if (urlOrPath instanceof URL) {
|
|
1706
|
+
return urlOrPath;
|
|
1707
|
+
}
|
|
1708
|
+
try {
|
|
1709
|
+
const url = new URL(urlOrPath);
|
|
1710
|
+
if (url.protocol === "http:" || url.protocol === "https:" || url.protocol === "file:") {
|
|
1711
|
+
return url;
|
|
1712
|
+
}
|
|
1713
|
+
} catch {
|
|
1714
|
+
}
|
|
1715
|
+
return (0, import_url.pathToFileURL)(import_path.default.resolve(urlOrPath));
|
|
1716
|
+
}
|
|
1717
|
+
|
|
1718
|
+
// packages/php-wasm/node/src/lib/extensions/load-extensions.ts
|
|
1719
|
+
var import_meta = {};
|
|
1720
|
+
async function withPHPExtensions(version, asyncMode, options, extensions = []) {
|
|
1721
|
+
if (!extensions.length) {
|
|
1722
|
+
return options;
|
|
1723
|
+
}
|
|
1724
|
+
const resolvedExtensions = await Promise.all(
|
|
1725
|
+
extensions.map(
|
|
1726
|
+
(extension) => resolveRuntimePHPExtension(version, asyncMode, extension)
|
|
1727
|
+
)
|
|
1728
|
+
);
|
|
1729
|
+
return (0, import_universal8.withResolvedPHPExtensions)(options, resolvedExtensions);
|
|
1730
|
+
}
|
|
1731
|
+
async function resolveRuntimePHPExtension(version, asyncMode, extension) {
|
|
1732
|
+
if (typeof extension === "object" && "source" in extension) {
|
|
1733
|
+
if (asyncMode === "asyncify") {
|
|
1734
|
+
throw new Error(
|
|
1735
|
+
"External PHP extensions require JSPI. Asyncify is only supported for PHP.wasm bundled extensions."
|
|
1736
|
+
);
|
|
1737
|
+
}
|
|
1738
|
+
return await (0, import_universal8.resolvePHPExtension)({
|
|
1739
|
+
...extension,
|
|
1740
|
+
source: normalizeNodeExtensionSource(extension.source),
|
|
1741
|
+
phpVersion: version,
|
|
1742
|
+
fetch: extension.fetch ?? fetchNodeExtensionResource
|
|
1743
|
+
});
|
|
1744
|
+
}
|
|
1745
|
+
const builtIn = typeof extension === "string" ? { name: extension } : extension;
|
|
1746
|
+
switch (builtIn.name) {
|
|
1747
|
+
case "intl": {
|
|
1748
|
+
const extensionPath = await getIntlExtensionModule(version);
|
|
1749
|
+
const soBytes = new Uint8Array(import_fs.default.readFileSync(extensionPath));
|
|
1750
|
+
const dataName = "icu.dat";
|
|
1751
|
+
const moduleDir = typeof __dirname !== "undefined" ? __dirname : import_meta.dirname;
|
|
1752
|
+
const ICUData = import_fs.default.readFileSync(
|
|
1753
|
+
resolveIntlDataPath(moduleDir, dataName)
|
|
1754
|
+
);
|
|
1755
|
+
return await (0, import_universal8.resolvePHPExtension)({
|
|
1756
|
+
source: {
|
|
1757
|
+
format: "so",
|
|
1758
|
+
name: "intl",
|
|
1759
|
+
bytes: soBytes
|
|
1760
|
+
},
|
|
1761
|
+
phpVersion: version,
|
|
1762
|
+
env: {
|
|
1763
|
+
ICU_DATA: "/internal/shared"
|
|
1764
|
+
},
|
|
1765
|
+
extraFiles: {
|
|
1766
|
+
targetPath: "/internal/shared",
|
|
1767
|
+
files: {
|
|
1768
|
+
// The Intl extension looks for the hard-coded ICU data name.
|
|
1769
|
+
"icudt74l.dat": new Uint8Array(ICUData)
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
});
|
|
1773
|
+
}
|
|
1774
|
+
case "redis": {
|
|
1775
|
+
const extensionPath = await getRedisExtensionModule(version);
|
|
1776
|
+
return await (0, import_universal8.resolvePHPExtension)({
|
|
1777
|
+
source: {
|
|
1778
|
+
format: "so",
|
|
1779
|
+
name: "redis",
|
|
1780
|
+
bytes: new Uint8Array(import_fs.default.readFileSync(extensionPath))
|
|
1781
|
+
},
|
|
1782
|
+
phpVersion: version
|
|
1783
|
+
});
|
|
1784
|
+
}
|
|
1785
|
+
case "memcached": {
|
|
1786
|
+
const extensionPath = await getMemcachedExtensionModule(version);
|
|
1787
|
+
return await (0, import_universal8.resolvePHPExtension)({
|
|
1788
|
+
source: {
|
|
1789
|
+
format: "so",
|
|
1790
|
+
name: "memcached",
|
|
1791
|
+
bytes: new Uint8Array(import_fs.default.readFileSync(extensionPath))
|
|
1792
|
+
},
|
|
1793
|
+
phpVersion: version
|
|
1794
|
+
});
|
|
1795
|
+
}
|
|
1796
|
+
case "xdebug": {
|
|
1797
|
+
const xdebugOptions = builtIn.options ?? {};
|
|
1798
|
+
const filePath = await getXdebugExtensionModule(version);
|
|
1799
|
+
const ideKey = xdebugOptions.ideKey || import_cli_util.DEFAULT_IDE_KEY;
|
|
1800
|
+
return await (0, import_universal8.resolvePHPExtension)({
|
|
1801
|
+
source: {
|
|
1802
|
+
format: "so",
|
|
1803
|
+
name: "xdebug",
|
|
1804
|
+
bytes: new Uint8Array(import_fs.default.readFileSync(filePath))
|
|
1805
|
+
},
|
|
1806
|
+
phpVersion: version,
|
|
1807
|
+
loadWithIniDirective: "zend_extension",
|
|
1808
|
+
iniEntries: {
|
|
1809
|
+
"xdebug.mode": "debug,develop",
|
|
1810
|
+
"xdebug.start_with_request": "yes",
|
|
1811
|
+
"xdebug.idekey": `"${ideKey}"`,
|
|
1812
|
+
// Path mapping is only available starting from Xdebug 3.5,
|
|
1813
|
+
// which is used by PHP 8.5+. Previous versions ignore it.
|
|
1814
|
+
"xdebug.path_mapping": "yes"
|
|
1815
|
+
},
|
|
1816
|
+
extraFiles: resolveXdebugExtraFiles(version, xdebugOptions)
|
|
1817
|
+
});
|
|
1818
|
+
}
|
|
1819
|
+
default:
|
|
1820
|
+
throw new Error(
|
|
1821
|
+
`Unknown bundled PHP extension: ${String(builtIn.name)}.`
|
|
1822
|
+
);
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1825
|
+
function resolveIntlDataPath(moduleDir, dataName) {
|
|
1826
|
+
const candidatePaths = [
|
|
1827
|
+
// Built package layout: dist/packages/php-wasm/node/shared/icu.dat.
|
|
1828
|
+
import_path2.default.join(moduleDir, "shared", dataName),
|
|
1829
|
+
// Source/test layout: src/lib/extensions/intl/shared/icu.dat.
|
|
1830
|
+
import_path2.default.join(moduleDir, "intl", "shared", dataName)
|
|
1831
|
+
];
|
|
1832
|
+
const dataPath = candidatePaths.find(
|
|
1833
|
+
(candidate) => import_fs.default.existsSync(candidate)
|
|
1834
|
+
);
|
|
1835
|
+
if (!dataPath) {
|
|
1836
|
+
throw new Error(
|
|
1837
|
+
`Could not find ${dataName}. Checked: ${candidatePaths.join(", ")}`
|
|
1838
|
+
);
|
|
1839
|
+
}
|
|
1840
|
+
return dataPath;
|
|
1841
|
+
}
|
|
1842
|
+
function resolveXdebugExtraFiles(version, xdebugOptions) {
|
|
1843
|
+
const isPHP85orHigher = import_universal8.SupportedPHPVersions.indexOf(version) <= import_universal8.SupportedPHPVersions.indexOf("8.5");
|
|
1844
|
+
if (!isPHP85orHigher) {
|
|
1845
|
+
return void 0;
|
|
1846
|
+
}
|
|
1847
|
+
const { pathMappings, pathSkippings } = xdebugOptions;
|
|
1848
|
+
if (!pathMappings && !pathSkippings) {
|
|
1849
|
+
return void 0;
|
|
1850
|
+
}
|
|
1851
|
+
const files = {};
|
|
1852
|
+
if (pathMappings) {
|
|
1853
|
+
files["path.map"] = pathMappings.map((map) => `${map.vfsPath} = ${map.hostPath}`).join("\n");
|
|
1854
|
+
}
|
|
1855
|
+
if (pathSkippings) {
|
|
1856
|
+
files["skip.map"] = pathSkippings.map((path3) => `${path3} = SKIP`).join("\n");
|
|
1857
|
+
}
|
|
1858
|
+
return {
|
|
1859
|
+
targetPath: "/.xdebug",
|
|
1860
|
+
files
|
|
1898
1861
|
};
|
|
1899
1862
|
}
|
|
1900
1863
|
|
|
1901
1864
|
// packages/php-wasm/node/src/lib/load-runtime.ts
|
|
1902
1865
|
var import_util = require("@php-wasm/util");
|
|
1903
1866
|
var import_os = require("os");
|
|
1904
|
-
|
|
1867
|
+
|
|
1868
|
+
// node_modules/wasm-feature-detect/dist/esm/index.js
|
|
1869
|
+
var jspi = () => (async () => "Suspending" in WebAssembly)();
|
|
1870
|
+
|
|
1871
|
+
// packages/php-wasm/node/src/lib/load-runtime.ts
|
|
1872
|
+
var dangerousDefaultProcessIdAllocator = process.env.VITEST ? new import_universal9.ProcessIdAllocator() : void 0;
|
|
1905
1873
|
async function loadNodeRuntime(phpVersion, options = {}) {
|
|
1906
1874
|
const processId = options.emscriptenOptions?.processId ?? // !! Only assign a default process ID during test.
|
|
1907
1875
|
// Otherwise, multiple workers with duplicate process IDs
|
|
1908
1876
|
// could break file locking and lead to database corruption.
|
|
1909
1877
|
(process.env.VITEST ? dangerousDefaultProcessIdAllocator.claim() : void 0);
|
|
1910
|
-
const isLegacy = (0,
|
|
1878
|
+
const isLegacy = (0, import_universal9.isLegacyPHPVersion)(phpVersion);
|
|
1879
|
+
const phpWasmAsyncMode = await jspi() ? "jspi" : "asyncify";
|
|
1880
|
+
const requestedExtensions = [...options.extensions ?? []];
|
|
1881
|
+
if (options.withIntl && !hasBuiltInExtension(requestedExtensions, "intl")) {
|
|
1882
|
+
requestedExtensions.push("intl");
|
|
1883
|
+
}
|
|
1884
|
+
if (options.withRedis && !hasBuiltInExtension(requestedExtensions, "redis")) {
|
|
1885
|
+
requestedExtensions.push("redis");
|
|
1886
|
+
}
|
|
1887
|
+
if (options.withMemcached && !hasBuiltInExtension(requestedExtensions, "memcached")) {
|
|
1888
|
+
requestedExtensions.push("memcached");
|
|
1889
|
+
}
|
|
1890
|
+
if (options.withXdebug && !hasBuiltInExtension(requestedExtensions, "xdebug")) {
|
|
1891
|
+
requestedExtensions.push(
|
|
1892
|
+
typeof options.withXdebug === "object" ? { name: "xdebug", options: options.withXdebug } : "xdebug"
|
|
1893
|
+
);
|
|
1894
|
+
}
|
|
1911
1895
|
let emscriptenOptions = {
|
|
1912
1896
|
/**
|
|
1913
1897
|
* Emscripten default behavior is to kill the process when
|
|
@@ -1919,13 +1903,14 @@ async function loadNodeRuntime(phpVersion, options = {}) {
|
|
|
1919
1903
|
},
|
|
1920
1904
|
bindUserSpace: (userSpaceContext) => {
|
|
1921
1905
|
const nativeFileLockManager = (0, import_os.platform)() === "win32" ? new FileLockManagerForWindows() : new FileLockManagerForPosix();
|
|
1922
|
-
const fileLockManager = options.fileLockManager ? new
|
|
1906
|
+
const fileLockManager = options.fileLockManager ? new import_universal9.FileLockManagerComposite({
|
|
1923
1907
|
nativeLockManager: nativeFileLockManager,
|
|
1924
1908
|
wasmLockManager: options.fileLockManager
|
|
1925
1909
|
}) : nativeFileLockManager;
|
|
1926
1910
|
return bindUserSpace({ fileLockManager }, userSpaceContext);
|
|
1927
1911
|
},
|
|
1928
1912
|
...options.emscriptenOptions || {},
|
|
1913
|
+
phpWasmAsyncMode,
|
|
1929
1914
|
processId,
|
|
1930
1915
|
// For legacy PHP: pre-create php.ini via a preRun step. See
|
|
1931
1916
|
// createLegacyPhpIniPreRunStep for why this must run before
|
|
@@ -1933,7 +1918,7 @@ async function loadNodeRuntime(phpVersion, options = {}) {
|
|
|
1933
1918
|
// hooks (the spread above may have set them).
|
|
1934
1919
|
...isLegacy ? {
|
|
1935
1920
|
preRun: [
|
|
1936
|
-
(0,
|
|
1921
|
+
(0, import_universal9.createLegacyPhpIniPreRunStep)(),
|
|
1937
1922
|
...options.emscriptenOptions?.preRun ?? []
|
|
1938
1923
|
]
|
|
1939
1924
|
} : {},
|
|
@@ -1941,7 +1926,7 @@ async function loadNodeRuntime(phpVersion, options = {}) {
|
|
|
1941
1926
|
if (options?.followSymlinks === true) {
|
|
1942
1927
|
phpRuntime.FS.filesystems.NODEFS.node_ops.readlink = (node) => {
|
|
1943
1928
|
const absoluteSourcePath = phpRuntime.FS.filesystems.NODEFS.tryFSOperation(
|
|
1944
|
-
() =>
|
|
1929
|
+
() => import_fs2.default.realpathSync(
|
|
1945
1930
|
phpRuntime.FS.filesystems.NODEFS.realPath(node)
|
|
1946
1931
|
)
|
|
1947
1932
|
);
|
|
@@ -1950,9 +1935,9 @@ async function loadNodeRuntime(phpVersion, options = {}) {
|
|
|
1950
1935
|
`/internal/symlinks`,
|
|
1951
1936
|
normalizedPath
|
|
1952
1937
|
);
|
|
1953
|
-
if (
|
|
1954
|
-
const sourceStat =
|
|
1955
|
-
if (!
|
|
1938
|
+
if (import_fs2.default.existsSync(absoluteSourcePath)) {
|
|
1939
|
+
const sourceStat = import_fs2.default.statSync(absoluteSourcePath);
|
|
1940
|
+
if (!import_universal9.FSHelpers.fileExists(
|
|
1956
1941
|
phpRuntime.FS,
|
|
1957
1942
|
symlinkMountPath
|
|
1958
1943
|
)) {
|
|
@@ -1991,66 +1976,56 @@ async function loadNodeRuntime(phpVersion, options = {}) {
|
|
|
1991
1976
|
phpRuntime.FS.root.mount.opts.root = ".";
|
|
1992
1977
|
}
|
|
1993
1978
|
};
|
|
1994
|
-
if (isLegacy &&
|
|
1979
|
+
if (isLegacy && requestedExtensions.length) {
|
|
1995
1980
|
throw new Error(
|
|
1996
1981
|
`Extensions (xdebug, intl, redis, memcached) are not available for legacy PHP ${phpVersion}.`
|
|
1997
1982
|
);
|
|
1998
1983
|
}
|
|
1999
1984
|
if (!isLegacy) {
|
|
2000
1985
|
const modernVersion = phpVersion;
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
}
|
|
2008
|
-
if (options?.withIntl === true) {
|
|
2009
|
-
emscriptenOptions = await withIntl(
|
|
2010
|
-
modernVersion,
|
|
2011
|
-
emscriptenOptions
|
|
2012
|
-
);
|
|
2013
|
-
}
|
|
2014
|
-
if (options?.withRedis === true) {
|
|
2015
|
-
emscriptenOptions = await withRedis(
|
|
2016
|
-
modernVersion,
|
|
2017
|
-
emscriptenOptions
|
|
2018
|
-
);
|
|
2019
|
-
}
|
|
2020
|
-
if (options?.withMemcached === true) {
|
|
2021
|
-
emscriptenOptions = await withMemcached(
|
|
2022
|
-
modernVersion,
|
|
2023
|
-
emscriptenOptions
|
|
2024
|
-
);
|
|
2025
|
-
}
|
|
1986
|
+
emscriptenOptions = await withPHPExtensions(
|
|
1987
|
+
modernVersion,
|
|
1988
|
+
phpWasmAsyncMode,
|
|
1989
|
+
emscriptenOptions,
|
|
1990
|
+
requestedExtensions
|
|
1991
|
+
);
|
|
2026
1992
|
}
|
|
2027
1993
|
emscriptenOptions = await withNetworking(emscriptenOptions);
|
|
2028
1994
|
const phpLoaderModule = await getPHPLoaderModule(phpVersion);
|
|
2029
|
-
const runtimeId = await (0,
|
|
1995
|
+
const runtimeId = await (0, import_universal9.loadPHPRuntime)(phpLoaderModule, emscriptenOptions);
|
|
2030
1996
|
return runtimeId;
|
|
2031
1997
|
}
|
|
1998
|
+
function hasBuiltInExtension(extensions, name) {
|
|
1999
|
+
return extensions.some((extension) => {
|
|
2000
|
+
if (typeof extension === "string") {
|
|
2001
|
+
return extension === name;
|
|
2002
|
+
}
|
|
2003
|
+
return !("source" in extension) && extension.name === name;
|
|
2004
|
+
});
|
|
2005
|
+
}
|
|
2032
2006
|
|
|
2033
2007
|
// packages/php-wasm/node/src/lib/use-host-filesystem.ts
|
|
2034
2008
|
var import_node_fs = require("node:fs");
|
|
2035
2009
|
|
|
2036
2010
|
// packages/php-wasm/node/src/lib/node-fs-mount.ts
|
|
2037
|
-
var
|
|
2011
|
+
var import_universal10 = require("@php-wasm/universal");
|
|
2038
2012
|
var import_util2 = require("@php-wasm/util");
|
|
2039
|
-
var
|
|
2040
|
-
var
|
|
2013
|
+
var import_fs3 = require("fs");
|
|
2014
|
+
var import_path3 = require("path");
|
|
2041
2015
|
function createNodeFsMountHandler(localPath) {
|
|
2042
2016
|
return function(php, FS, vfsMountPoint) {
|
|
2043
2017
|
let removeVfsNode = false;
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2018
|
+
const mountRoot = (0, import_fs3.realpathSync)(localPath);
|
|
2019
|
+
if (!import_universal10.FSHelpers.fileExists(FS, vfsMountPoint)) {
|
|
2020
|
+
const stat = (0, import_fs3.statSync)(mountRoot);
|
|
2021
|
+
if (stat.isFile()) {
|
|
2022
|
+
FS.mkdirTree((0, import_path3.dirname)(vfsMountPoint));
|
|
2048
2023
|
FS.writeFile(vfsMountPoint, "");
|
|
2049
|
-
} else if (
|
|
2024
|
+
} else if (stat.isDirectory()) {
|
|
2050
2025
|
FS.mkdirTree(vfsMountPoint);
|
|
2051
2026
|
} else {
|
|
2052
2027
|
throw new Error(
|
|
2053
|
-
"Unsupported file type. PHP-wasm supports only symlinks that
|
|
2028
|
+
"Unsupported file type. PHP-wasm supports mounting only files and directories, including symlinks that resolve to files or directories."
|
|
2054
2029
|
);
|
|
2055
2030
|
}
|
|
2056
2031
|
removeVfsNode = true;
|
|
@@ -2067,7 +2042,7 @@ function createNodeFsMountHandler(localPath) {
|
|
|
2067
2042
|
}
|
|
2068
2043
|
throw e;
|
|
2069
2044
|
}
|
|
2070
|
-
FS.mount(FS.filesystems["NODEFS"], { root:
|
|
2045
|
+
FS.mount(FS.filesystems["NODEFS"], { root: mountRoot }, vfsMountPoint);
|
|
2071
2046
|
return () => {
|
|
2072
2047
|
FS.unmount(vfsMountPoint);
|
|
2073
2048
|
if (removeVfsNode) {
|
|
@@ -2103,20 +2078,20 @@ function useHostFilesystem(php) {
|
|
|
2103
2078
|
}
|
|
2104
2079
|
php.chdir(process.cwd());
|
|
2105
2080
|
}
|
|
2106
|
-
function statPathFollowSymlinks(
|
|
2107
|
-
let stat = (0, import_node_fs.lstatSync)(
|
|
2081
|
+
function statPathFollowSymlinks(path3) {
|
|
2082
|
+
let stat = (0, import_node_fs.lstatSync)(path3);
|
|
2108
2083
|
if (stat.isSymbolicLink()) {
|
|
2109
|
-
const
|
|
2110
|
-
let target =
|
|
2084
|
+
const fs3 = require("fs");
|
|
2085
|
+
let target = path3;
|
|
2111
2086
|
const seen = /* @__PURE__ */ new Set();
|
|
2112
2087
|
while (true) {
|
|
2113
2088
|
if (seen.has(target)) {
|
|
2114
|
-
throw new Error(`Symlink loop detected: ${
|
|
2089
|
+
throw new Error(`Symlink loop detected: ${path3}`);
|
|
2115
2090
|
}
|
|
2116
2091
|
seen.add(target);
|
|
2117
2092
|
const linkStat = (0, import_node_fs.lstatSync)(target);
|
|
2118
2093
|
if (linkStat.isSymbolicLink()) {
|
|
2119
|
-
target =
|
|
2094
|
+
target = fs3.realpathSync(target);
|
|
2120
2095
|
continue;
|
|
2121
2096
|
}
|
|
2122
2097
|
stat = linkStat;
|
|
@@ -2134,6 +2109,5 @@ function statPathFollowSymlinks(path2) {
|
|
|
2134
2109
|
getPHPLoaderModule,
|
|
2135
2110
|
loadNodeRuntime,
|
|
2136
2111
|
useHostFilesystem,
|
|
2137
|
-
withNetworking
|
|
2138
|
-
withXdebug
|
|
2112
|
+
withNetworking
|
|
2139
2113
|
});
|