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