@faapi/faapi 3.2.0 → 3.3.0
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/dist/cli/index.js +657 -413
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +63 -6
- package/dist/index.js +549 -303
- package/dist/index.js.map +1 -1
- package/dist/testing.js +473 -239
- package/dist/testing.js.map +1 -1
- package/package.json +3 -3
package/dist/cli/index.js
CHANGED
|
@@ -476,9 +476,9 @@ var init_constants = __esm({
|
|
|
476
476
|
});
|
|
477
477
|
|
|
478
478
|
// src/utils/normalizePath.ts
|
|
479
|
-
function normalizePath(
|
|
480
|
-
if (!
|
|
481
|
-
let result =
|
|
479
|
+
function normalizePath(path24) {
|
|
480
|
+
if (!path24) return "";
|
|
481
|
+
let result = path24.replace(/\\/g, "/");
|
|
482
482
|
result = result.replace(/\/+/g, "/");
|
|
483
483
|
result = result.replace(/\/+$/, "");
|
|
484
484
|
if (result && !result.startsWith("/")) {
|
|
@@ -964,35 +964,143 @@ var init_extractToolMetadata = __esm({
|
|
|
964
964
|
|
|
965
965
|
// src/ast/createProgram.ts
|
|
966
966
|
import ts3 from "typescript";
|
|
967
|
+
import fs7 from "fs";
|
|
968
|
+
import path7 from "path";
|
|
967
969
|
function invalidateProgramCache() {
|
|
968
970
|
programCache.clear();
|
|
971
|
+
tsConfigCache.clear();
|
|
972
|
+
}
|
|
973
|
+
function findTsConfig(filePath) {
|
|
974
|
+
let dir = path7.dirname(filePath);
|
|
975
|
+
const root = path7.parse(dir).root;
|
|
976
|
+
while (true) {
|
|
977
|
+
const candidate = path7.join(dir, "tsconfig.json");
|
|
978
|
+
if (fs7.existsSync(candidate)) {
|
|
979
|
+
return candidate;
|
|
980
|
+
}
|
|
981
|
+
if (dir === root) return null;
|
|
982
|
+
const parent = path7.dirname(dir);
|
|
983
|
+
if (parent === dir) return null;
|
|
984
|
+
dir = parent;
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
function parseTsConfig(tsconfigPath) {
|
|
988
|
+
const cached = tsConfigCache.get(tsconfigPath);
|
|
989
|
+
if (cached) return cached;
|
|
990
|
+
const result = { fileNames: [] };
|
|
991
|
+
try {
|
|
992
|
+
const configFile = ts3.readConfigFile(tsconfigPath, (p) => fs7.readFileSync(p, "utf-8"));
|
|
993
|
+
if (configFile.error) {
|
|
994
|
+
tsConfigCache.set(tsconfigPath, result);
|
|
995
|
+
return result;
|
|
996
|
+
}
|
|
997
|
+
const config = configFile.config ?? {};
|
|
998
|
+
const basePath = path7.dirname(tsconfigPath);
|
|
999
|
+
const parsed = ts3.parseJsonConfigFileContent(
|
|
1000
|
+
config,
|
|
1001
|
+
ts3.sys,
|
|
1002
|
+
basePath,
|
|
1003
|
+
/* existingOptions */
|
|
1004
|
+
void 0,
|
|
1005
|
+
tsconfigPath
|
|
1006
|
+
);
|
|
1007
|
+
result.fileNames = parsed.fileNames;
|
|
1008
|
+
if (parsed.options.module !== void 0) {
|
|
1009
|
+
result.module = parsed.options.module;
|
|
1010
|
+
}
|
|
1011
|
+
if (parsed.options.moduleResolution !== void 0) {
|
|
1012
|
+
result.moduleResolution = parsed.options.moduleResolution;
|
|
1013
|
+
}
|
|
1014
|
+
} catch {
|
|
1015
|
+
}
|
|
1016
|
+
tsConfigCache.set(tsconfigPath, result);
|
|
1017
|
+
return result;
|
|
969
1018
|
}
|
|
970
1019
|
function createProgram(filePath) {
|
|
971
1020
|
const cached = programCache.get(filePath);
|
|
972
1021
|
if (cached) {
|
|
973
1022
|
return cached;
|
|
974
1023
|
}
|
|
975
|
-
const program =
|
|
1024
|
+
const program = buildProgram([filePath], findTsConfig(filePath));
|
|
1025
|
+
programCache.set(filePath, program);
|
|
1026
|
+
return program;
|
|
1027
|
+
}
|
|
1028
|
+
function createPrograms(filePaths) {
|
|
1029
|
+
const unique = [...new Set(filePaths)];
|
|
1030
|
+
const result = /* @__PURE__ */ new Map();
|
|
1031
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1032
|
+
const noTsconfigFiles = [];
|
|
1033
|
+
for (const filePath of unique) {
|
|
1034
|
+
const tsconfigPath = findTsConfig(filePath);
|
|
1035
|
+
if (!tsconfigPath) {
|
|
1036
|
+
noTsconfigFiles.push(filePath);
|
|
1037
|
+
continue;
|
|
1038
|
+
}
|
|
1039
|
+
const group = groups.get(tsconfigPath);
|
|
1040
|
+
if (group) {
|
|
1041
|
+
group.files.push(filePath);
|
|
1042
|
+
} else {
|
|
1043
|
+
groups.set(tsconfigPath, { tsconfigPath, files: [filePath] });
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
for (const { tsconfigPath, files } of groups.values()) {
|
|
1047
|
+
const cacheKey = `shared::${tsconfigPath}::${[...files].sort().join("|")}`;
|
|
1048
|
+
let program = programCache.get(cacheKey);
|
|
1049
|
+
if (!program) {
|
|
1050
|
+
program = buildProgram(files, tsconfigPath);
|
|
1051
|
+
programCache.set(cacheKey, program);
|
|
1052
|
+
}
|
|
1053
|
+
for (const filePath of files) {
|
|
1054
|
+
result.set(filePath, program);
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
for (const filePath of noTsconfigFiles) {
|
|
1058
|
+
result.set(filePath, createProgram(filePath));
|
|
1059
|
+
}
|
|
1060
|
+
return result;
|
|
1061
|
+
}
|
|
1062
|
+
function buildProgram(entryFiles, tsconfigPath) {
|
|
1063
|
+
const options = {
|
|
976
1064
|
strict: true,
|
|
977
1065
|
target: ts3.ScriptTarget.ES2022,
|
|
978
1066
|
module: ts3.ModuleKind.NodeNext,
|
|
979
1067
|
moduleResolution: ts3.ModuleResolutionKind.NodeNext,
|
|
980
1068
|
skipLibCheck: true,
|
|
981
1069
|
noEmit: true
|
|
982
|
-
}
|
|
983
|
-
|
|
984
|
-
|
|
1070
|
+
};
|
|
1071
|
+
const rootNames = [...entryFiles];
|
|
1072
|
+
if (tsconfigPath) {
|
|
1073
|
+
const tsOptions = parseTsConfig(tsconfigPath);
|
|
1074
|
+
if (tsOptions.module !== void 0) {
|
|
1075
|
+
options.module = tsOptions.module;
|
|
1076
|
+
}
|
|
1077
|
+
if (tsOptions.moduleResolution !== void 0) {
|
|
1078
|
+
options.moduleResolution = tsOptions.moduleResolution;
|
|
1079
|
+
}
|
|
1080
|
+
if (tsOptions.fileNames.length > 0) {
|
|
1081
|
+
for (const fileName of tsOptions.fileNames) {
|
|
1082
|
+
if (!rootNames.includes(fileName)) {
|
|
1083
|
+
rootNames.push(fileName);
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
return ts3.createProgram(rootNames, options);
|
|
985
1089
|
}
|
|
986
|
-
var programCache;
|
|
1090
|
+
var programCache, tsConfigCache;
|
|
987
1091
|
var init_createProgram = __esm({
|
|
988
1092
|
"src/ast/createProgram.ts"() {
|
|
989
1093
|
"use strict";
|
|
990
1094
|
programCache = /* @__PURE__ */ new Map();
|
|
1095
|
+
tsConfigCache = /* @__PURE__ */ new Map();
|
|
991
1096
|
}
|
|
992
1097
|
});
|
|
993
1098
|
|
|
994
1099
|
// src/ast/resolveTypeNode.ts
|
|
995
1100
|
import ts4 from "typescript";
|
|
1101
|
+
function setProgramContext(program) {
|
|
1102
|
+
currentProgram = program;
|
|
1103
|
+
}
|
|
996
1104
|
function resolveTypeNode(typeNode, checker, visited = /* @__PURE__ */ new Set()) {
|
|
997
1105
|
const kind = typeNode.kind;
|
|
998
1106
|
switch (kind) {
|
|
@@ -1305,11 +1413,69 @@ function resolveTypeReference(typeNode, checker, visited = /* @__PURE__ */ new S
|
|
|
1305
1413
|
if (ts4.isEnumDeclaration(declaration)) {
|
|
1306
1414
|
return resolveEnumDeclaration(declaration);
|
|
1307
1415
|
}
|
|
1416
|
+
if (ts4.isImportSpecifier(declaration) || ts4.isImportClause(declaration)) {
|
|
1417
|
+
const resolved = resolveImportAlias(typeNode, symbol, checker, visited);
|
|
1418
|
+
if (resolved) return resolved;
|
|
1419
|
+
}
|
|
1308
1420
|
}
|
|
1309
1421
|
}
|
|
1310
1422
|
}
|
|
1311
1423
|
throw new SchemaExtractionError(typeNode.getText(), `\u65E0\u6CD5\u89E3\u6790\u7684\u5F15\u7528\u7C7B\u578B "${typeName}"`);
|
|
1312
1424
|
}
|
|
1425
|
+
function resolveImportAlias(typeNode, symbol, checker, visited) {
|
|
1426
|
+
const typeName = typeNode.typeName.getText();
|
|
1427
|
+
try {
|
|
1428
|
+
const aliased = checker.getAliasedSymbol(symbol);
|
|
1429
|
+
if (aliased && aliased.declarations && aliased.declarations.length > 0) {
|
|
1430
|
+
const decl = aliased.declarations[0];
|
|
1431
|
+
if (ts4.isInterfaceDeclaration(decl)) {
|
|
1432
|
+
return resolveInterfaceDeclaration(decl, checker, visited);
|
|
1433
|
+
}
|
|
1434
|
+
if (ts4.isTypeAliasDeclaration(decl)) {
|
|
1435
|
+
return resolveTypeNode(decl.type, checker, visited);
|
|
1436
|
+
}
|
|
1437
|
+
if (ts4.isEnumDeclaration(decl)) {
|
|
1438
|
+
return resolveEnumDeclaration(decl);
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
} catch {
|
|
1442
|
+
}
|
|
1443
|
+
const program = currentProgram;
|
|
1444
|
+
if (!program) return null;
|
|
1445
|
+
const allSFs = program.getSourceFiles();
|
|
1446
|
+
for (const sourceFile of allSFs) {
|
|
1447
|
+
if (sourceFile.fileName.includes("/node_modules/") || sourceFile.fileName.includes("typescript/lib/")) {
|
|
1448
|
+
continue;
|
|
1449
|
+
}
|
|
1450
|
+
const found = findTopLevelDecl(sourceFile, typeName);
|
|
1451
|
+
if (found) {
|
|
1452
|
+
if (found.kind === "interface") {
|
|
1453
|
+
return resolveInterfaceDeclaration(found.node, checker, visited);
|
|
1454
|
+
}
|
|
1455
|
+
if (found.kind === "typeAlias") {
|
|
1456
|
+
return resolveTypeNode(found.node.type, checker, visited);
|
|
1457
|
+
}
|
|
1458
|
+
if (found.kind === "enum") {
|
|
1459
|
+
return resolveEnumDeclaration(found.node);
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
return null;
|
|
1464
|
+
}
|
|
1465
|
+
function findTopLevelDecl(sourceFile, typeName) {
|
|
1466
|
+
let found = null;
|
|
1467
|
+
ts4.forEachChild(sourceFile, (node) => {
|
|
1468
|
+
if (found) return;
|
|
1469
|
+
if (ts4.isInterfaceDeclaration(node) && node.name.text === typeName) {
|
|
1470
|
+
found = { kind: "interface", node };
|
|
1471
|
+
} else if (ts4.isTypeAliasDeclaration(node) && node.name.text === typeName) {
|
|
1472
|
+
found = { kind: "typeAlias", node };
|
|
1473
|
+
} else if (ts4.isEnumDeclaration(node) && node.name.text === typeName) {
|
|
1474
|
+
found = { kind: "enum", node };
|
|
1475
|
+
}
|
|
1476
|
+
});
|
|
1477
|
+
return found;
|
|
1478
|
+
}
|
|
1313
1479
|
function resolveEnumDeclaration(node) {
|
|
1314
1480
|
const members = [];
|
|
1315
1481
|
let nextNumericValue = 0;
|
|
@@ -1488,10 +1654,11 @@ function validateConstraints(constraints, type, fieldName) {
|
|
|
1488
1654
|
}
|
|
1489
1655
|
}
|
|
1490
1656
|
}
|
|
1491
|
-
var SchemaExtractionError, NUMBER_CONSTRAINT_KINDS, LENGTH_CONSTRAINT_KINDS, STRING_FORMAT_CONSTRAINT_KINDS;
|
|
1657
|
+
var currentProgram, SchemaExtractionError, NUMBER_CONSTRAINT_KINDS, LENGTH_CONSTRAINT_KINDS, STRING_FORMAT_CONSTRAINT_KINDS;
|
|
1492
1658
|
var init_resolveTypeNode = __esm({
|
|
1493
1659
|
"src/ast/resolveTypeNode.ts"() {
|
|
1494
1660
|
"use strict";
|
|
1661
|
+
currentProgram = null;
|
|
1495
1662
|
SchemaExtractionError = class extends Error {
|
|
1496
1663
|
constructor(typeText, reason, options) {
|
|
1497
1664
|
super(`\u65E0\u6CD5\u89E3\u6790\u7C7B\u578B "${typeText}": ${reason}`, options);
|
|
@@ -1531,80 +1698,90 @@ function extractTypeInfo(program, filePath, typeName) {
|
|
|
1531
1698
|
const sourceFile = program.getSourceFile(filePath);
|
|
1532
1699
|
if (!sourceFile) return null;
|
|
1533
1700
|
const checker = program.getTypeChecker();
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1701
|
+
setProgramContext(program);
|
|
1702
|
+
try {
|
|
1703
|
+
let result = null;
|
|
1704
|
+
ts5.forEachChild(sourceFile, (node) => {
|
|
1705
|
+
if (result) return;
|
|
1706
|
+
if (ts5.isInterfaceDeclaration(node) && node.name.text === typeName) {
|
|
1707
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1708
|
+
visited.add(typeName);
|
|
1709
|
+
const runtimeType = withFileContext(
|
|
1710
|
+
filePath,
|
|
1711
|
+
typeName,
|
|
1712
|
+
() => resolveInterfaceDeclaration(node, checker, visited)
|
|
1713
|
+
);
|
|
1714
|
+
result = {
|
|
1715
|
+
name: typeName,
|
|
1716
|
+
properties: runtimeType.kind === "object" ? runtimeType.properties : [],
|
|
1717
|
+
runtimeType
|
|
1718
|
+
};
|
|
1719
|
+
return;
|
|
1720
|
+
}
|
|
1721
|
+
if (ts5.isTypeAliasDeclaration(node) && node.name.text === typeName) {
|
|
1722
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1723
|
+
visited.add(typeName);
|
|
1724
|
+
const runtimeType = withFileContext(
|
|
1725
|
+
filePath,
|
|
1726
|
+
typeName,
|
|
1727
|
+
() => resolveTypeNode(node.type, checker, visited)
|
|
1728
|
+
);
|
|
1729
|
+
result = {
|
|
1730
|
+
name: typeName,
|
|
1731
|
+
properties: runtimeType.kind === "object" ? runtimeType.properties : [],
|
|
1732
|
+
runtimeType
|
|
1733
|
+
};
|
|
1734
|
+
return;
|
|
1735
|
+
}
|
|
1736
|
+
});
|
|
1737
|
+
return result;
|
|
1738
|
+
} finally {
|
|
1739
|
+
setProgramContext(null);
|
|
1740
|
+
}
|
|
1569
1741
|
}
|
|
1570
1742
|
function extractAllTypes(program, filePath) {
|
|
1571
1743
|
const sourceFile = program.getSourceFile(filePath);
|
|
1572
1744
|
if (!sourceFile) return /* @__PURE__ */ new Map();
|
|
1573
1745
|
const checker = program.getTypeChecker();
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1746
|
+
setProgramContext(program);
|
|
1747
|
+
try {
|
|
1748
|
+
const result = /* @__PURE__ */ new Map();
|
|
1749
|
+
ts5.forEachChild(sourceFile, (node) => {
|
|
1750
|
+
if (ts5.isInterfaceDeclaration(node)) {
|
|
1751
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1752
|
+
visited.add(node.name.text);
|
|
1753
|
+
const runtimeType = withFileContext(
|
|
1754
|
+
filePath,
|
|
1755
|
+
node.name.text,
|
|
1756
|
+
() => resolveInterfaceDeclaration(node, checker, visited)
|
|
1757
|
+
);
|
|
1758
|
+
result.set(node.name.text, {
|
|
1759
|
+
name: node.name.text,
|
|
1760
|
+
properties: runtimeType.kind === "object" ? runtimeType.properties : [],
|
|
1761
|
+
runtimeType
|
|
1762
|
+
});
|
|
1763
|
+
return;
|
|
1764
|
+
}
|
|
1765
|
+
if (ts5.isTypeAliasDeclaration(node)) {
|
|
1766
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1767
|
+
visited.add(node.name.text);
|
|
1768
|
+
const runtimeType = withFileContext(
|
|
1769
|
+
filePath,
|
|
1770
|
+
node.name.text,
|
|
1771
|
+
() => resolveTypeNode(node.type, checker, visited)
|
|
1772
|
+
);
|
|
1773
|
+
result.set(node.name.text, {
|
|
1774
|
+
name: node.name.text,
|
|
1775
|
+
properties: runtimeType.kind === "object" ? runtimeType.properties : [],
|
|
1776
|
+
runtimeType
|
|
1777
|
+
});
|
|
1778
|
+
return;
|
|
1779
|
+
}
|
|
1780
|
+
});
|
|
1781
|
+
return result;
|
|
1782
|
+
} finally {
|
|
1783
|
+
setProgramContext(null);
|
|
1784
|
+
}
|
|
1608
1785
|
}
|
|
1609
1786
|
function withFileContext(filePath, typeName, fn) {
|
|
1610
1787
|
try {
|
|
@@ -2110,11 +2287,11 @@ var init_analyzeInjection = __esm({
|
|
|
2110
2287
|
});
|
|
2111
2288
|
|
|
2112
2289
|
// src/cli/collectRouteSchemaSources.ts
|
|
2113
|
-
import
|
|
2290
|
+
import path8 from "path";
|
|
2114
2291
|
function collectRouteSchemaSources(routes, rootDir) {
|
|
2115
2292
|
const methodsByFile = /* @__PURE__ */ new Map();
|
|
2116
2293
|
for (const route of routes) {
|
|
2117
|
-
const filePath = rootDir ?
|
|
2294
|
+
const filePath = rootDir ? path8.resolve(rootDir, route.filePath) : route.filePath;
|
|
2118
2295
|
let entry = methodsByFile.get(filePath);
|
|
2119
2296
|
if (!entry) {
|
|
2120
2297
|
entry = { urlPath: route.urlPath, methods: /* @__PURE__ */ new Set() };
|
|
@@ -2122,12 +2299,11 @@ function collectRouteSchemaSources(routes, rootDir) {
|
|
|
2122
2299
|
}
|
|
2123
2300
|
entry.methods.add(route.method);
|
|
2124
2301
|
}
|
|
2125
|
-
const programByFile =
|
|
2302
|
+
const programByFile = createPrograms([...methodsByFile.keys()]);
|
|
2126
2303
|
const allTypesByFile = /* @__PURE__ */ new Map();
|
|
2127
2304
|
const mergedAllTypes = /* @__PURE__ */ new Map();
|
|
2128
2305
|
for (const filePath of methodsByFile.keys()) {
|
|
2129
|
-
const program =
|
|
2130
|
-
programByFile.set(filePath, program);
|
|
2306
|
+
const program = programByFile.get(filePath);
|
|
2131
2307
|
const allTypes = extractAllTypes(program, filePath);
|
|
2132
2308
|
allTypesByFile.set(filePath, allTypes);
|
|
2133
2309
|
for (const [name, info] of allTypes) {
|
|
@@ -2177,8 +2353,8 @@ __export(generateSchemaFiles_exports, {
|
|
|
2177
2353
|
getRuntimeSchemaPath: () => getRuntimeSchemaPath,
|
|
2178
2354
|
getSchemaOutputPath: () => getSchemaOutputPath
|
|
2179
2355
|
});
|
|
2180
|
-
import
|
|
2181
|
-
import
|
|
2356
|
+
import path9 from "path";
|
|
2357
|
+
import fs8 from "fs/promises";
|
|
2182
2358
|
function getSchemaOutputPath(sourceFile, dist, rootDir) {
|
|
2183
2359
|
let rel = sourceFile.replace(/\\/g, "/");
|
|
2184
2360
|
if (rel.startsWith("src/")) {
|
|
@@ -2186,7 +2362,7 @@ function getSchemaOutputPath(sourceFile, dist, rootDir) {
|
|
|
2186
2362
|
}
|
|
2187
2363
|
const idx = rel.lastIndexOf("/");
|
|
2188
2364
|
const relDir = idx >= 0 ? rel.slice(0, idx) : "";
|
|
2189
|
-
return
|
|
2365
|
+
return path9.resolve(rootDir, dist, relDir, "zod.js");
|
|
2190
2366
|
}
|
|
2191
2367
|
function getRuntimeSchemaPath(filePath, dist, rootDir) {
|
|
2192
2368
|
let rel = filePath.replace(/\\/g, "/");
|
|
@@ -2197,7 +2373,7 @@ function getRuntimeSchemaPath(filePath, dist, rootDir) {
|
|
|
2197
2373
|
}
|
|
2198
2374
|
const idx = rel.lastIndexOf("/");
|
|
2199
2375
|
const relDir = idx >= 0 ? rel.slice(0, idx) : "";
|
|
2200
|
-
return
|
|
2376
|
+
return path9.resolve(rootDir, dist, relDir, "zod.js");
|
|
2201
2377
|
}
|
|
2202
2378
|
function getHelpersImportPath(relDir) {
|
|
2203
2379
|
if (!relDir) return `./${HELPERS_FILENAME}`;
|
|
@@ -2247,7 +2423,7 @@ async function generateSchemaFiles(routes, rootDir, dist) {
|
|
|
2247
2423
|
}
|
|
2248
2424
|
const fileEntries = [];
|
|
2249
2425
|
for (const [filePath, fileSources] of sourcesByFile) {
|
|
2250
|
-
const relFile =
|
|
2426
|
+
const relFile = path9.relative(rootDir, filePath).replace(/\\/g, "/");
|
|
2251
2427
|
const outputPath = getSchemaOutputPath(relFile, dist, rootDir);
|
|
2252
2428
|
const allTypes = allTypesByFile.get(filePath) ?? /* @__PURE__ */ new Map();
|
|
2253
2429
|
let relForDir = relFile;
|
|
@@ -2262,7 +2438,7 @@ async function generateSchemaFiles(routes, rootDir, dist) {
|
|
|
2262
2438
|
}
|
|
2263
2439
|
const allSourceCode = fileEntries.map((e) => e.source).join("\n");
|
|
2264
2440
|
if (usesCoerceHelpers(allSourceCode)) {
|
|
2265
|
-
const helpersPath =
|
|
2441
|
+
const helpersPath = path9.resolve(rootDir, dist, HELPERS_FILENAME);
|
|
2266
2442
|
await writeSchemaFile(helpersPath, generateHelpersFileSource());
|
|
2267
2443
|
}
|
|
2268
2444
|
await Promise.all(
|
|
@@ -2270,8 +2446,8 @@ async function generateSchemaFiles(routes, rootDir, dist) {
|
|
|
2270
2446
|
);
|
|
2271
2447
|
}
|
|
2272
2448
|
async function writeSchemaFile(outputPath, source) {
|
|
2273
|
-
await
|
|
2274
|
-
await
|
|
2449
|
+
await fs8.mkdir(path9.dirname(outputPath), { recursive: true });
|
|
2450
|
+
await fs8.writeFile(outputPath, source, "utf-8");
|
|
2275
2451
|
}
|
|
2276
2452
|
var init_generateSchemaFiles = __esm({
|
|
2277
2453
|
"src/cli/generateSchemaFiles.ts"() {
|
|
@@ -2282,8 +2458,8 @@ var init_generateSchemaFiles = __esm({
|
|
|
2282
2458
|
});
|
|
2283
2459
|
|
|
2284
2460
|
// src/cli/generateToolArtifacts.ts
|
|
2285
|
-
import
|
|
2286
|
-
import
|
|
2461
|
+
import path10 from "path";
|
|
2462
|
+
import fs9 from "fs/promises";
|
|
2287
2463
|
import { existsSync } from "fs";
|
|
2288
2464
|
function getToolSchemaOutputPath(sourceFile, dist, rootDir) {
|
|
2289
2465
|
let rel = sourceFile.replace(/\\/g, "/");
|
|
@@ -2292,7 +2468,7 @@ function getToolSchemaOutputPath(sourceFile, dist, rootDir) {
|
|
|
2292
2468
|
}
|
|
2293
2469
|
const idx = rel.lastIndexOf("/");
|
|
2294
2470
|
const relDir = idx >= 0 ? rel.slice(0, idx) : "";
|
|
2295
|
-
return
|
|
2471
|
+
return path10.resolve(rootDir, dist, relDir, "zod.js");
|
|
2296
2472
|
}
|
|
2297
2473
|
function toProdFilePath3(filePath, dist) {
|
|
2298
2474
|
let rel = filePath.replace(/\\/g, "/");
|
|
@@ -2312,12 +2488,12 @@ function serializeTools(tools, dist = "dist") {
|
|
|
2312
2488
|
}));
|
|
2313
2489
|
}
|
|
2314
2490
|
async function writeToolsModule(manifest, outputPath) {
|
|
2315
|
-
const dir =
|
|
2316
|
-
await
|
|
2491
|
+
const dir = path10.dirname(outputPath);
|
|
2492
|
+
await fs9.mkdir(dir, { recursive: true });
|
|
2317
2493
|
const content = `// \u81EA\u52A8\u751F\u6210,\u8BF7\u52FF\u624B\u52A8\u7F16\u8F91(faapi build/dev \u4EA7\u7269)
|
|
2318
2494
|
export const tools = ${JSON.stringify(manifest, null, 2)};
|
|
2319
2495
|
`;
|
|
2320
|
-
await
|
|
2496
|
+
await fs9.writeFile(outputPath, content, "utf-8");
|
|
2321
2497
|
}
|
|
2322
2498
|
function hydrateTools(manifest) {
|
|
2323
2499
|
return manifest.map((t) => ({
|
|
@@ -2332,7 +2508,7 @@ function collectToolSchemaSources(tools, rootDir) {
|
|
|
2332
2508
|
const toolsByFile = /* @__PURE__ */ new Map();
|
|
2333
2509
|
for (const tool of tools) {
|
|
2334
2510
|
if (!tool.inputTypeName) continue;
|
|
2335
|
-
const absPath =
|
|
2511
|
+
const absPath = path10.resolve(rootDir, tool.filePath);
|
|
2336
2512
|
let list = toolsByFile.get(absPath);
|
|
2337
2513
|
if (!list) {
|
|
2338
2514
|
list = [];
|
|
@@ -2340,15 +2516,16 @@ function collectToolSchemaSources(tools, rootDir) {
|
|
|
2340
2516
|
}
|
|
2341
2517
|
list.push(tool);
|
|
2342
2518
|
}
|
|
2519
|
+
const programByFile = createPrograms([...toolsByFile.keys()]);
|
|
2343
2520
|
const allTypesByFile = /* @__PURE__ */ new Map();
|
|
2344
2521
|
for (const filePath of toolsByFile.keys()) {
|
|
2345
|
-
const program =
|
|
2522
|
+
const program = programByFile.get(filePath);
|
|
2346
2523
|
const allTypes = extractAllTypes(program, filePath);
|
|
2347
2524
|
allTypesByFile.set(filePath, allTypes);
|
|
2348
2525
|
}
|
|
2349
2526
|
const sources = [];
|
|
2350
2527
|
for (const [filePath, fileTools] of toolsByFile) {
|
|
2351
|
-
const program =
|
|
2528
|
+
const program = programByFile.get(filePath);
|
|
2352
2529
|
for (const tool of fileTools) {
|
|
2353
2530
|
const inputTypeName = tool.inputTypeName;
|
|
2354
2531
|
const typeInfo = extractTypeInfo(program, filePath, inputTypeName);
|
|
@@ -2394,16 +2571,17 @@ function generateToolSchemaFileSource(sources, allTypes, helpersImportPath) {
|
|
|
2394
2571
|
}
|
|
2395
2572
|
async function maybeGenerateHelpers(allSourceCode, distDir) {
|
|
2396
2573
|
if (!usesCoerceHelpers(allSourceCode)) return;
|
|
2397
|
-
const helpersPath =
|
|
2574
|
+
const helpersPath = path10.resolve(distDir, HELPERS_FILENAME);
|
|
2398
2575
|
if (existsSync(helpersPath)) return;
|
|
2399
|
-
await
|
|
2400
|
-
await
|
|
2576
|
+
await fs9.mkdir(path10.dirname(helpersPath), { recursive: true });
|
|
2577
|
+
await fs9.writeFile(helpersPath, generateHelpersFileSource(), "utf-8");
|
|
2401
2578
|
}
|
|
2402
2579
|
async function generateToolArtifacts(tools, rootDir, dist, options) {
|
|
2403
2580
|
const metadata = [];
|
|
2581
|
+
const programByFile = createPrograms(tools.map((m) => path10.resolve(rootDir, m.filePath)));
|
|
2404
2582
|
for (const manifest of tools) {
|
|
2405
|
-
const absPath =
|
|
2406
|
-
const program =
|
|
2583
|
+
const absPath = path10.resolve(rootDir, manifest.filePath);
|
|
2584
|
+
const program = programByFile.get(absPath);
|
|
2407
2585
|
const result = extractToolMetadata(program, absPath, manifest.functionName, {
|
|
2408
2586
|
name: manifest.name,
|
|
2409
2587
|
filePath: manifest.filePath
|
|
@@ -2413,7 +2591,7 @@ async function generateToolArtifacts(tools, rootDir, dist, options) {
|
|
|
2413
2591
|
}
|
|
2414
2592
|
}
|
|
2415
2593
|
const serialized = serializeTools(metadata, dist);
|
|
2416
|
-
const toolsPath =
|
|
2594
|
+
const toolsPath = path10.resolve(rootDir, dist, TOOLS_FILE);
|
|
2417
2595
|
await writeToolsModule(serialized, toolsPath);
|
|
2418
2596
|
if (options?.skipSchema) {
|
|
2419
2597
|
return metadata;
|
|
@@ -2436,7 +2614,7 @@ async function generateToolArtifacts(tools, rootDir, dist, options) {
|
|
|
2436
2614
|
}
|
|
2437
2615
|
const fileEntries = [];
|
|
2438
2616
|
for (const [filePath, fileSources] of sourcesByFile) {
|
|
2439
|
-
const relFile =
|
|
2617
|
+
const relFile = path10.relative(rootDir, filePath).replace(/\\/g, "/");
|
|
2440
2618
|
const outputPath = getToolSchemaOutputPath(relFile, dist, rootDir);
|
|
2441
2619
|
const allTypes = allTypesByFile.get(filePath) ?? /* @__PURE__ */ new Map();
|
|
2442
2620
|
let relForDir = relFile;
|
|
@@ -2450,7 +2628,7 @@ async function generateToolArtifacts(tools, rootDir, dist, options) {
|
|
|
2450
2628
|
fileEntries.push({ outputPath, source });
|
|
2451
2629
|
}
|
|
2452
2630
|
const allSourceCode = fileEntries.map((e) => e.source).join("\n");
|
|
2453
|
-
const distDir =
|
|
2631
|
+
const distDir = path10.resolve(rootDir, dist);
|
|
2454
2632
|
await maybeGenerateHelpers(allSourceCode, distDir);
|
|
2455
2633
|
await Promise.all(
|
|
2456
2634
|
fileEntries.map(({ outputPath, source }) => writeToolSchemaFile(outputPath, source))
|
|
@@ -2458,8 +2636,8 @@ async function generateToolArtifacts(tools, rootDir, dist, options) {
|
|
|
2458
2636
|
return metadata;
|
|
2459
2637
|
}
|
|
2460
2638
|
async function writeToolSchemaFile(outputPath, source) {
|
|
2461
|
-
await
|
|
2462
|
-
await
|
|
2639
|
+
await fs9.mkdir(path10.dirname(outputPath), { recursive: true });
|
|
2640
|
+
await fs9.writeFile(outputPath, source, "utf-8");
|
|
2463
2641
|
}
|
|
2464
2642
|
var TOOLS_FILE;
|
|
2465
2643
|
var init_generateToolArtifacts = __esm({
|
|
@@ -2476,8 +2654,8 @@ var init_generateToolArtifacts = __esm({
|
|
|
2476
2654
|
|
|
2477
2655
|
// src/agents/scanAgents.ts
|
|
2478
2656
|
import fg3 from "fast-glob";
|
|
2479
|
-
import
|
|
2480
|
-
import
|
|
2657
|
+
import path11 from "path";
|
|
2658
|
+
import fs10 from "fs";
|
|
2481
2659
|
function extractAgentNameFromPath(filePath) {
|
|
2482
2660
|
const normalized = filePath.replace(/\\/g, "/");
|
|
2483
2661
|
const match = normalized.match(/(?:^|\/)agents\/([^/]+)\/handler\.ts$/);
|
|
@@ -2507,8 +2685,8 @@ async function scanAgents(rootDir, patterns) {
|
|
|
2507
2685
|
if (fileName !== "handler.ts" && fileName !== "handler.js") {
|
|
2508
2686
|
continue;
|
|
2509
2687
|
}
|
|
2510
|
-
const absPath =
|
|
2511
|
-
const source = await
|
|
2688
|
+
const absPath = path11.resolve(rootDir, normalizedFile);
|
|
2689
|
+
const source = await fs10.promises.readFile(absPath, "utf8").catch(() => "");
|
|
2512
2690
|
const { hasRun } = detectAgentExports(source);
|
|
2513
2691
|
const name = extractAgentNameFromPath(normalizedFile);
|
|
2514
2692
|
const prevFile = seen.get(name);
|
|
@@ -2728,8 +2906,8 @@ var init_extractAgentMetadata = __esm({
|
|
|
2728
2906
|
});
|
|
2729
2907
|
|
|
2730
2908
|
// src/cli/generateAgentArtifacts.ts
|
|
2731
|
-
import
|
|
2732
|
-
import
|
|
2909
|
+
import path12 from "path";
|
|
2910
|
+
import fs11 from "fs/promises";
|
|
2733
2911
|
function toProdFilePath4(filePath, dist) {
|
|
2734
2912
|
let rel = filePath.replace(/\\/g, "/");
|
|
2735
2913
|
if (rel.startsWith("src/")) {
|
|
@@ -2752,12 +2930,12 @@ function serializeAgents(agents, dist = "dist") {
|
|
|
2752
2930
|
}));
|
|
2753
2931
|
}
|
|
2754
2932
|
async function writeAgentsModule(manifest, outputPath) {
|
|
2755
|
-
const dir =
|
|
2756
|
-
await
|
|
2933
|
+
const dir = path12.dirname(outputPath);
|
|
2934
|
+
await fs11.mkdir(dir, { recursive: true });
|
|
2757
2935
|
const content = `// \u81EA\u52A8\u751F\u6210,\u8BF7\u52FF\u624B\u52A8\u7F16\u8F91(faapi build/dev \u4EA7\u7269)
|
|
2758
2936
|
export const agents = ${JSON.stringify(manifest, null, 2)};
|
|
2759
2937
|
`;
|
|
2760
|
-
await
|
|
2938
|
+
await fs11.writeFile(outputPath, content, "utf-8");
|
|
2761
2939
|
}
|
|
2762
2940
|
function hydrateAgents(manifest) {
|
|
2763
2941
|
return manifest.map((a) => ({
|
|
@@ -2774,9 +2952,10 @@ function hydrateAgents(manifest) {
|
|
|
2774
2952
|
}
|
|
2775
2953
|
async function generateAgentArtifacts(agents, rootDir, dist) {
|
|
2776
2954
|
const metadata = [];
|
|
2955
|
+
const programByFile = createPrograms(agents.map((m) => path12.resolve(rootDir, m.filePath)));
|
|
2777
2956
|
for (const manifest of agents) {
|
|
2778
|
-
const absPath =
|
|
2779
|
-
const program =
|
|
2957
|
+
const absPath = path12.resolve(rootDir, manifest.filePath);
|
|
2958
|
+
const program = programByFile.get(absPath);
|
|
2780
2959
|
const result = extractAgentMetadata(program, absPath, {
|
|
2781
2960
|
name: manifest.name,
|
|
2782
2961
|
filePath: manifest.filePath,
|
|
@@ -2787,7 +2966,7 @@ async function generateAgentArtifacts(agents, rootDir, dist) {
|
|
|
2787
2966
|
}
|
|
2788
2967
|
}
|
|
2789
2968
|
const serialized = serializeAgents(metadata, dist);
|
|
2790
|
-
const agentsPath =
|
|
2969
|
+
const agentsPath = path12.resolve(rootDir, dist, AGENTS_FILE);
|
|
2791
2970
|
await writeAgentsModule(serialized, agentsPath);
|
|
2792
2971
|
return metadata;
|
|
2793
2972
|
}
|
|
@@ -2802,15 +2981,15 @@ var init_generateAgentArtifacts = __esm({
|
|
|
2802
2981
|
});
|
|
2803
2982
|
|
|
2804
2983
|
// src/config/loadConfig.ts
|
|
2805
|
-
import
|
|
2806
|
-
import
|
|
2984
|
+
import path13 from "path";
|
|
2985
|
+
import fs12 from "fs";
|
|
2807
2986
|
async function loadConfig(rootDir, dist) {
|
|
2808
|
-
const configProductPath =
|
|
2809
|
-
if (
|
|
2987
|
+
const configProductPath = path13.resolve(rootDir, dist, CONFIG_PRODUCT_FILE);
|
|
2988
|
+
if (fs12.existsSync(configProductPath)) {
|
|
2810
2989
|
const module = await importWithCacheBust(configProductPath);
|
|
2811
2990
|
return module.default ?? {};
|
|
2812
2991
|
}
|
|
2813
|
-
const hasSourceConfig =
|
|
2992
|
+
const hasSourceConfig = fs12.existsSync(path13.join(rootDir, "faapi.config.ts")) || fs12.existsSync(path13.join(rootDir, "faapi.config.js"));
|
|
2814
2993
|
if (hasSourceConfig) {
|
|
2815
2994
|
throw new Error(
|
|
2816
2995
|
`[faapi] ${dist}/${CONFIG_PRODUCT_FILE} \u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u6267\u884C \`faapi build\`\uFF08\u6216 \`faapi dev\`\uFF09\u751F\u6210\u4EA7\u7269\u3002`
|
|
@@ -2828,8 +3007,8 @@ var init_loadConfig = __esm({
|
|
|
2828
3007
|
});
|
|
2829
3008
|
|
|
2830
3009
|
// src/cli/loadEnv.ts
|
|
2831
|
-
import
|
|
2832
|
-
import
|
|
3010
|
+
import fs13 from "fs";
|
|
3011
|
+
import path14 from "path";
|
|
2833
3012
|
function resolveEnv() {
|
|
2834
3013
|
return process.env.NODE_ENV || "development";
|
|
2835
3014
|
}
|
|
@@ -2895,9 +3074,9 @@ function loadEnv(rootDir) {
|
|
|
2895
3074
|
const files = getEnvFiles(env);
|
|
2896
3075
|
const merged = {};
|
|
2897
3076
|
for (const file of files) {
|
|
2898
|
-
const filePath =
|
|
2899
|
-
if (!
|
|
2900
|
-
const content =
|
|
3077
|
+
const filePath = path14.join(rootDir, file);
|
|
3078
|
+
if (!fs13.existsSync(filePath)) continue;
|
|
3079
|
+
const content = fs13.readFileSync(filePath, "utf-8");
|
|
2901
3080
|
const parsed = parseEnvFile(content, merged);
|
|
2902
3081
|
Object.assign(merged, parsed);
|
|
2903
3082
|
}
|
|
@@ -3003,7 +3182,7 @@ var init_esm = __esm({
|
|
|
3003
3182
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
3004
3183
|
const statMethod = opts.lstat ? lstat : stat;
|
|
3005
3184
|
if (wantBigintFsStats) {
|
|
3006
|
-
this._stat = (
|
|
3185
|
+
this._stat = (path24) => statMethod(path24, { bigint: true });
|
|
3007
3186
|
} else {
|
|
3008
3187
|
this._stat = statMethod;
|
|
3009
3188
|
}
|
|
@@ -3028,8 +3207,8 @@ var init_esm = __esm({
|
|
|
3028
3207
|
const par = this.parent;
|
|
3029
3208
|
const fil = par && par.files;
|
|
3030
3209
|
if (fil && fil.length > 0) {
|
|
3031
|
-
const { path:
|
|
3032
|
-
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent,
|
|
3210
|
+
const { path: path24, depth } = par;
|
|
3211
|
+
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path24));
|
|
3033
3212
|
const awaited = await Promise.all(slice);
|
|
3034
3213
|
for (const entry of awaited) {
|
|
3035
3214
|
if (!entry)
|
|
@@ -3069,20 +3248,20 @@ var init_esm = __esm({
|
|
|
3069
3248
|
this.reading = false;
|
|
3070
3249
|
}
|
|
3071
3250
|
}
|
|
3072
|
-
async _exploreDir(
|
|
3251
|
+
async _exploreDir(path24, depth) {
|
|
3073
3252
|
let files;
|
|
3074
3253
|
try {
|
|
3075
|
-
files = await readdir(
|
|
3254
|
+
files = await readdir(path24, this._rdOptions);
|
|
3076
3255
|
} catch (error) {
|
|
3077
3256
|
this._onError(error);
|
|
3078
3257
|
}
|
|
3079
|
-
return { files, depth, path:
|
|
3258
|
+
return { files, depth, path: path24 };
|
|
3080
3259
|
}
|
|
3081
|
-
async _formatEntry(dirent,
|
|
3260
|
+
async _formatEntry(dirent, path24) {
|
|
3082
3261
|
let entry;
|
|
3083
3262
|
const basename3 = this._isDirent ? dirent.name : dirent;
|
|
3084
3263
|
try {
|
|
3085
|
-
const fullPath = presolve(pjoin(
|
|
3264
|
+
const fullPath = presolve(pjoin(path24, basename3));
|
|
3086
3265
|
entry = { path: prelative(this._root, fullPath), fullPath, basename: basename3 };
|
|
3087
3266
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
3088
3267
|
} catch (err) {
|
|
@@ -3143,16 +3322,16 @@ import { watchFile, unwatchFile, watch as fs_watch } from "fs";
|
|
|
3143
3322
|
import { open, stat as stat2, lstat as lstat2, realpath as fsrealpath } from "fs/promises";
|
|
3144
3323
|
import * as sysPath from "path";
|
|
3145
3324
|
import { type as osType } from "os";
|
|
3146
|
-
function createFsWatchInstance(
|
|
3325
|
+
function createFsWatchInstance(path24, options, listener, errHandler, emitRaw) {
|
|
3147
3326
|
const handleEvent = (rawEvent, evPath) => {
|
|
3148
|
-
listener(
|
|
3149
|
-
emitRaw(rawEvent, evPath, { watchedPath:
|
|
3150
|
-
if (evPath &&
|
|
3151
|
-
fsWatchBroadcast(sysPath.resolve(
|
|
3327
|
+
listener(path24);
|
|
3328
|
+
emitRaw(rawEvent, evPath, { watchedPath: path24 });
|
|
3329
|
+
if (evPath && path24 !== evPath) {
|
|
3330
|
+
fsWatchBroadcast(sysPath.resolve(path24, evPath), KEY_LISTENERS, sysPath.join(path24, evPath));
|
|
3152
3331
|
}
|
|
3153
3332
|
};
|
|
3154
3333
|
try {
|
|
3155
|
-
return fs_watch(
|
|
3334
|
+
return fs_watch(path24, {
|
|
3156
3335
|
persistent: options.persistent
|
|
3157
3336
|
}, handleEvent);
|
|
3158
3337
|
} catch (error) {
|
|
@@ -3497,12 +3676,12 @@ var init_handler = __esm({
|
|
|
3497
3676
|
listener(val1, val2, val3);
|
|
3498
3677
|
});
|
|
3499
3678
|
};
|
|
3500
|
-
setFsWatchListener = (
|
|
3679
|
+
setFsWatchListener = (path24, fullPath, options, handlers) => {
|
|
3501
3680
|
const { listener, errHandler, rawEmitter } = handlers;
|
|
3502
3681
|
let cont = FsWatchInstances.get(fullPath);
|
|
3503
3682
|
let watcher;
|
|
3504
3683
|
if (!options.persistent) {
|
|
3505
|
-
watcher = createFsWatchInstance(
|
|
3684
|
+
watcher = createFsWatchInstance(path24, options, listener, errHandler, rawEmitter);
|
|
3506
3685
|
if (!watcher)
|
|
3507
3686
|
return;
|
|
3508
3687
|
return watcher.close.bind(watcher);
|
|
@@ -3513,7 +3692,7 @@ var init_handler = __esm({
|
|
|
3513
3692
|
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
3514
3693
|
} else {
|
|
3515
3694
|
watcher = createFsWatchInstance(
|
|
3516
|
-
|
|
3695
|
+
path24,
|
|
3517
3696
|
options,
|
|
3518
3697
|
fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
|
|
3519
3698
|
errHandler,
|
|
@@ -3528,7 +3707,7 @@ var init_handler = __esm({
|
|
|
3528
3707
|
cont.watcherUnusable = true;
|
|
3529
3708
|
if (isWindows && error.code === "EPERM") {
|
|
3530
3709
|
try {
|
|
3531
|
-
const fd = await open(
|
|
3710
|
+
const fd = await open(path24, "r");
|
|
3532
3711
|
await fd.close();
|
|
3533
3712
|
broadcastErr(error);
|
|
3534
3713
|
} catch (err) {
|
|
@@ -3559,7 +3738,7 @@ var init_handler = __esm({
|
|
|
3559
3738
|
};
|
|
3560
3739
|
};
|
|
3561
3740
|
FsWatchFileInstances = /* @__PURE__ */ new Map();
|
|
3562
|
-
setFsWatchFileListener = (
|
|
3741
|
+
setFsWatchFileListener = (path24, fullPath, options, handlers) => {
|
|
3563
3742
|
const { listener, rawEmitter } = handlers;
|
|
3564
3743
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
3565
3744
|
const copts = cont && cont.options;
|
|
@@ -3581,7 +3760,7 @@ var init_handler = __esm({
|
|
|
3581
3760
|
});
|
|
3582
3761
|
const currmtime = curr.mtimeMs;
|
|
3583
3762
|
if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
|
|
3584
|
-
foreach(cont.listeners, (listener2) => listener2(
|
|
3763
|
+
foreach(cont.listeners, (listener2) => listener2(path24, curr));
|
|
3585
3764
|
}
|
|
3586
3765
|
})
|
|
3587
3766
|
};
|
|
@@ -3609,13 +3788,13 @@ var init_handler = __esm({
|
|
|
3609
3788
|
* @param listener on fs change
|
|
3610
3789
|
* @returns closer for the watcher instance
|
|
3611
3790
|
*/
|
|
3612
|
-
_watchWithNodeFs(
|
|
3791
|
+
_watchWithNodeFs(path24, listener) {
|
|
3613
3792
|
const opts = this.fsw.options;
|
|
3614
|
-
const directory = sysPath.dirname(
|
|
3615
|
-
const basename3 = sysPath.basename(
|
|
3793
|
+
const directory = sysPath.dirname(path24);
|
|
3794
|
+
const basename3 = sysPath.basename(path24);
|
|
3616
3795
|
const parent = this.fsw._getWatchedDir(directory);
|
|
3617
3796
|
parent.add(basename3);
|
|
3618
|
-
const absolutePath = sysPath.resolve(
|
|
3797
|
+
const absolutePath = sysPath.resolve(path24);
|
|
3619
3798
|
const options = {
|
|
3620
3799
|
persistent: opts.persistent
|
|
3621
3800
|
};
|
|
@@ -3625,12 +3804,12 @@ var init_handler = __esm({
|
|
|
3625
3804
|
if (opts.usePolling) {
|
|
3626
3805
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
3627
3806
|
options.interval = enableBin && isBinaryPath(basename3) ? opts.binaryInterval : opts.interval;
|
|
3628
|
-
closer = setFsWatchFileListener(
|
|
3807
|
+
closer = setFsWatchFileListener(path24, absolutePath, options, {
|
|
3629
3808
|
listener,
|
|
3630
3809
|
rawEmitter: this.fsw._emitRaw
|
|
3631
3810
|
});
|
|
3632
3811
|
} else {
|
|
3633
|
-
closer = setFsWatchListener(
|
|
3812
|
+
closer = setFsWatchListener(path24, absolutePath, options, {
|
|
3634
3813
|
listener,
|
|
3635
3814
|
errHandler: this._boundHandleError,
|
|
3636
3815
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -3652,7 +3831,7 @@ var init_handler = __esm({
|
|
|
3652
3831
|
let prevStats = stats;
|
|
3653
3832
|
if (parent.has(basename3))
|
|
3654
3833
|
return;
|
|
3655
|
-
const listener = async (
|
|
3834
|
+
const listener = async (path24, newStats) => {
|
|
3656
3835
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
3657
3836
|
return;
|
|
3658
3837
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
@@ -3666,11 +3845,11 @@ var init_handler = __esm({
|
|
|
3666
3845
|
this.fsw._emit(EV.CHANGE, file, newStats2);
|
|
3667
3846
|
}
|
|
3668
3847
|
if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
|
|
3669
|
-
this.fsw._closeFile(
|
|
3848
|
+
this.fsw._closeFile(path24);
|
|
3670
3849
|
prevStats = newStats2;
|
|
3671
3850
|
const closer2 = this._watchWithNodeFs(file, listener);
|
|
3672
3851
|
if (closer2)
|
|
3673
|
-
this.fsw._addPathCloser(
|
|
3852
|
+
this.fsw._addPathCloser(path24, closer2);
|
|
3674
3853
|
} else {
|
|
3675
3854
|
prevStats = newStats2;
|
|
3676
3855
|
}
|
|
@@ -3702,7 +3881,7 @@ var init_handler = __esm({
|
|
|
3702
3881
|
* @param item basename of this item
|
|
3703
3882
|
* @returns true if no more processing is needed for this entry.
|
|
3704
3883
|
*/
|
|
3705
|
-
async _handleSymlink(entry, directory,
|
|
3884
|
+
async _handleSymlink(entry, directory, path24, item) {
|
|
3706
3885
|
if (this.fsw.closed) {
|
|
3707
3886
|
return;
|
|
3708
3887
|
}
|
|
@@ -3712,7 +3891,7 @@ var init_handler = __esm({
|
|
|
3712
3891
|
this.fsw._incrReadyCount();
|
|
3713
3892
|
let linkPath;
|
|
3714
3893
|
try {
|
|
3715
|
-
linkPath = await fsrealpath(
|
|
3894
|
+
linkPath = await fsrealpath(path24);
|
|
3716
3895
|
} catch (e) {
|
|
3717
3896
|
this.fsw._emitReady();
|
|
3718
3897
|
return true;
|
|
@@ -3722,12 +3901,12 @@ var init_handler = __esm({
|
|
|
3722
3901
|
if (dir.has(item)) {
|
|
3723
3902
|
if (this.fsw._symlinkPaths.get(full) !== linkPath) {
|
|
3724
3903
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
3725
|
-
this.fsw._emit(EV.CHANGE,
|
|
3904
|
+
this.fsw._emit(EV.CHANGE, path24, entry.stats);
|
|
3726
3905
|
}
|
|
3727
3906
|
} else {
|
|
3728
3907
|
dir.add(item);
|
|
3729
3908
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
3730
|
-
this.fsw._emit(EV.ADD,
|
|
3909
|
+
this.fsw._emit(EV.ADD, path24, entry.stats);
|
|
3731
3910
|
}
|
|
3732
3911
|
this.fsw._emitReady();
|
|
3733
3912
|
return true;
|
|
@@ -3756,9 +3935,9 @@ var init_handler = __esm({
|
|
|
3756
3935
|
return;
|
|
3757
3936
|
}
|
|
3758
3937
|
const item = entry.path;
|
|
3759
|
-
let
|
|
3938
|
+
let path24 = sysPath.join(directory, item);
|
|
3760
3939
|
current.add(item);
|
|
3761
|
-
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory,
|
|
3940
|
+
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path24, item)) {
|
|
3762
3941
|
return;
|
|
3763
3942
|
}
|
|
3764
3943
|
if (this.fsw.closed) {
|
|
@@ -3767,8 +3946,8 @@ var init_handler = __esm({
|
|
|
3767
3946
|
}
|
|
3768
3947
|
if (item === target || !target && !previous.has(item)) {
|
|
3769
3948
|
this.fsw._incrReadyCount();
|
|
3770
|
-
|
|
3771
|
-
this._addToNodeFs(
|
|
3949
|
+
path24 = sysPath.join(dir, sysPath.relative(dir, path24));
|
|
3950
|
+
this._addToNodeFs(path24, initialAdd, wh, depth + 1);
|
|
3772
3951
|
}
|
|
3773
3952
|
}).on(EV.ERROR, this._boundHandleError);
|
|
3774
3953
|
return new Promise((resolve3, reject) => {
|
|
@@ -3837,13 +4016,13 @@ var init_handler = __esm({
|
|
|
3837
4016
|
* @param depth Child path actually targeted for watch
|
|
3838
4017
|
* @param target Child path actually targeted for watch
|
|
3839
4018
|
*/
|
|
3840
|
-
async _addToNodeFs(
|
|
4019
|
+
async _addToNodeFs(path24, initialAdd, priorWh, depth, target) {
|
|
3841
4020
|
const ready = this.fsw._emitReady;
|
|
3842
|
-
if (this.fsw._isIgnored(
|
|
4021
|
+
if (this.fsw._isIgnored(path24) || this.fsw.closed) {
|
|
3843
4022
|
ready();
|
|
3844
4023
|
return false;
|
|
3845
4024
|
}
|
|
3846
|
-
const wh = this.fsw._getWatchHelpers(
|
|
4025
|
+
const wh = this.fsw._getWatchHelpers(path24);
|
|
3847
4026
|
if (priorWh) {
|
|
3848
4027
|
wh.filterPath = (entry) => priorWh.filterPath(entry);
|
|
3849
4028
|
wh.filterDir = (entry) => priorWh.filterDir(entry);
|
|
@@ -3859,8 +4038,8 @@ var init_handler = __esm({
|
|
|
3859
4038
|
const follow = this.fsw.options.followSymlinks;
|
|
3860
4039
|
let closer;
|
|
3861
4040
|
if (stats.isDirectory()) {
|
|
3862
|
-
const absPath = sysPath.resolve(
|
|
3863
|
-
const targetPath = follow ? await fsrealpath(
|
|
4041
|
+
const absPath = sysPath.resolve(path24);
|
|
4042
|
+
const targetPath = follow ? await fsrealpath(path24) : path24;
|
|
3864
4043
|
if (this.fsw.closed)
|
|
3865
4044
|
return;
|
|
3866
4045
|
closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
|
|
@@ -3870,29 +4049,29 @@ var init_handler = __esm({
|
|
|
3870
4049
|
this.fsw._symlinkPaths.set(absPath, targetPath);
|
|
3871
4050
|
}
|
|
3872
4051
|
} else if (stats.isSymbolicLink()) {
|
|
3873
|
-
const targetPath = follow ? await fsrealpath(
|
|
4052
|
+
const targetPath = follow ? await fsrealpath(path24) : path24;
|
|
3874
4053
|
if (this.fsw.closed)
|
|
3875
4054
|
return;
|
|
3876
4055
|
const parent = sysPath.dirname(wh.watchPath);
|
|
3877
4056
|
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
3878
4057
|
this.fsw._emit(EV.ADD, wh.watchPath, stats);
|
|
3879
|
-
closer = await this._handleDir(parent, stats, initialAdd, depth,
|
|
4058
|
+
closer = await this._handleDir(parent, stats, initialAdd, depth, path24, wh, targetPath);
|
|
3880
4059
|
if (this.fsw.closed)
|
|
3881
4060
|
return;
|
|
3882
4061
|
if (targetPath !== void 0) {
|
|
3883
|
-
this.fsw._symlinkPaths.set(sysPath.resolve(
|
|
4062
|
+
this.fsw._symlinkPaths.set(sysPath.resolve(path24), targetPath);
|
|
3884
4063
|
}
|
|
3885
4064
|
} else {
|
|
3886
4065
|
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
3887
4066
|
}
|
|
3888
4067
|
ready();
|
|
3889
4068
|
if (closer)
|
|
3890
|
-
this.fsw._addPathCloser(
|
|
4069
|
+
this.fsw._addPathCloser(path24, closer);
|
|
3891
4070
|
return false;
|
|
3892
4071
|
} catch (error) {
|
|
3893
4072
|
if (this.fsw._handleError(error)) {
|
|
3894
4073
|
ready();
|
|
3895
|
-
return
|
|
4074
|
+
return path24;
|
|
3896
4075
|
}
|
|
3897
4076
|
}
|
|
3898
4077
|
}
|
|
@@ -3931,26 +4110,26 @@ function createPattern(matcher) {
|
|
|
3931
4110
|
}
|
|
3932
4111
|
return () => false;
|
|
3933
4112
|
}
|
|
3934
|
-
function normalizePath2(
|
|
3935
|
-
if (typeof
|
|
4113
|
+
function normalizePath2(path24) {
|
|
4114
|
+
if (typeof path24 !== "string")
|
|
3936
4115
|
throw new Error("string expected");
|
|
3937
|
-
|
|
3938
|
-
|
|
4116
|
+
path24 = sysPath2.normalize(path24);
|
|
4117
|
+
path24 = path24.replace(/\\/g, "/");
|
|
3939
4118
|
let prepend = false;
|
|
3940
|
-
if (
|
|
4119
|
+
if (path24.startsWith("//"))
|
|
3941
4120
|
prepend = true;
|
|
3942
4121
|
const DOUBLE_SLASH_RE2 = /\/\//;
|
|
3943
|
-
while (
|
|
3944
|
-
|
|
4122
|
+
while (path24.match(DOUBLE_SLASH_RE2))
|
|
4123
|
+
path24 = path24.replace(DOUBLE_SLASH_RE2, "/");
|
|
3945
4124
|
if (prepend)
|
|
3946
|
-
|
|
3947
|
-
return
|
|
4125
|
+
path24 = "/" + path24;
|
|
4126
|
+
return path24;
|
|
3948
4127
|
}
|
|
3949
4128
|
function matchPatterns(patterns, testString, stats) {
|
|
3950
|
-
const
|
|
4129
|
+
const path24 = normalizePath2(testString);
|
|
3951
4130
|
for (let index = 0; index < patterns.length; index++) {
|
|
3952
4131
|
const pattern = patterns[index];
|
|
3953
|
-
if (pattern(
|
|
4132
|
+
if (pattern(path24, stats)) {
|
|
3954
4133
|
return true;
|
|
3955
4134
|
}
|
|
3956
4135
|
}
|
|
@@ -4011,19 +4190,19 @@ var init_esm2 = __esm({
|
|
|
4011
4190
|
}
|
|
4012
4191
|
return str;
|
|
4013
4192
|
};
|
|
4014
|
-
normalizePathToUnix = (
|
|
4015
|
-
normalizeIgnored = (cwd = "") => (
|
|
4016
|
-
if (typeof
|
|
4017
|
-
return normalizePathToUnix(sysPath2.isAbsolute(
|
|
4193
|
+
normalizePathToUnix = (path24) => toUnix(sysPath2.normalize(toUnix(path24)));
|
|
4194
|
+
normalizeIgnored = (cwd = "") => (path24) => {
|
|
4195
|
+
if (typeof path24 === "string") {
|
|
4196
|
+
return normalizePathToUnix(sysPath2.isAbsolute(path24) ? path24 : sysPath2.join(cwd, path24));
|
|
4018
4197
|
} else {
|
|
4019
|
-
return
|
|
4198
|
+
return path24;
|
|
4020
4199
|
}
|
|
4021
4200
|
};
|
|
4022
|
-
getAbsolutePath = (
|
|
4023
|
-
if (sysPath2.isAbsolute(
|
|
4024
|
-
return
|
|
4201
|
+
getAbsolutePath = (path24, cwd) => {
|
|
4202
|
+
if (sysPath2.isAbsolute(path24)) {
|
|
4203
|
+
return path24;
|
|
4025
4204
|
}
|
|
4026
|
-
return sysPath2.join(cwd,
|
|
4205
|
+
return sysPath2.join(cwd, path24);
|
|
4027
4206
|
};
|
|
4028
4207
|
EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
|
|
4029
4208
|
DirEntry = class {
|
|
@@ -4078,10 +4257,10 @@ var init_esm2 = __esm({
|
|
|
4078
4257
|
STAT_METHOD_F = "stat";
|
|
4079
4258
|
STAT_METHOD_L = "lstat";
|
|
4080
4259
|
WatchHelper = class {
|
|
4081
|
-
constructor(
|
|
4260
|
+
constructor(path24, follow, fsw) {
|
|
4082
4261
|
this.fsw = fsw;
|
|
4083
|
-
const watchPath =
|
|
4084
|
-
this.path =
|
|
4262
|
+
const watchPath = path24;
|
|
4263
|
+
this.path = path24 = path24.replace(REPLACER_RE, "");
|
|
4085
4264
|
this.watchPath = watchPath;
|
|
4086
4265
|
this.fullWatchPath = sysPath2.resolve(watchPath);
|
|
4087
4266
|
this.dirParts = [];
|
|
@@ -4203,20 +4382,20 @@ var init_esm2 = __esm({
|
|
|
4203
4382
|
this._closePromise = void 0;
|
|
4204
4383
|
let paths = unifyPaths(paths_);
|
|
4205
4384
|
if (cwd) {
|
|
4206
|
-
paths = paths.map((
|
|
4207
|
-
const absPath = getAbsolutePath(
|
|
4385
|
+
paths = paths.map((path24) => {
|
|
4386
|
+
const absPath = getAbsolutePath(path24, cwd);
|
|
4208
4387
|
return absPath;
|
|
4209
4388
|
});
|
|
4210
4389
|
}
|
|
4211
|
-
paths.forEach((
|
|
4212
|
-
this._removeIgnoredPath(
|
|
4390
|
+
paths.forEach((path24) => {
|
|
4391
|
+
this._removeIgnoredPath(path24);
|
|
4213
4392
|
});
|
|
4214
4393
|
this._userIgnored = void 0;
|
|
4215
4394
|
if (!this._readyCount)
|
|
4216
4395
|
this._readyCount = 0;
|
|
4217
4396
|
this._readyCount += paths.length;
|
|
4218
|
-
Promise.all(paths.map(async (
|
|
4219
|
-
const res = await this._nodeFsHandler._addToNodeFs(
|
|
4397
|
+
Promise.all(paths.map(async (path24) => {
|
|
4398
|
+
const res = await this._nodeFsHandler._addToNodeFs(path24, !_internal, void 0, 0, _origAdd);
|
|
4220
4399
|
if (res)
|
|
4221
4400
|
this._emitReady();
|
|
4222
4401
|
return res;
|
|
@@ -4238,17 +4417,17 @@ var init_esm2 = __esm({
|
|
|
4238
4417
|
return this;
|
|
4239
4418
|
const paths = unifyPaths(paths_);
|
|
4240
4419
|
const { cwd } = this.options;
|
|
4241
|
-
paths.forEach((
|
|
4242
|
-
if (!sysPath2.isAbsolute(
|
|
4420
|
+
paths.forEach((path24) => {
|
|
4421
|
+
if (!sysPath2.isAbsolute(path24) && !this._closers.has(path24)) {
|
|
4243
4422
|
if (cwd)
|
|
4244
|
-
|
|
4245
|
-
|
|
4423
|
+
path24 = sysPath2.join(cwd, path24);
|
|
4424
|
+
path24 = sysPath2.resolve(path24);
|
|
4246
4425
|
}
|
|
4247
|
-
this._closePath(
|
|
4248
|
-
this._addIgnoredPath(
|
|
4249
|
-
if (this._watched.has(
|
|
4426
|
+
this._closePath(path24);
|
|
4427
|
+
this._addIgnoredPath(path24);
|
|
4428
|
+
if (this._watched.has(path24)) {
|
|
4250
4429
|
this._addIgnoredPath({
|
|
4251
|
-
path:
|
|
4430
|
+
path: path24,
|
|
4252
4431
|
recursive: true
|
|
4253
4432
|
});
|
|
4254
4433
|
}
|
|
@@ -4312,38 +4491,38 @@ var init_esm2 = __esm({
|
|
|
4312
4491
|
* @param stats arguments to be passed with event
|
|
4313
4492
|
* @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
|
|
4314
4493
|
*/
|
|
4315
|
-
async _emit(event,
|
|
4494
|
+
async _emit(event, path24, stats) {
|
|
4316
4495
|
if (this.closed)
|
|
4317
4496
|
return;
|
|
4318
4497
|
const opts = this.options;
|
|
4319
4498
|
if (isWindows)
|
|
4320
|
-
|
|
4499
|
+
path24 = sysPath2.normalize(path24);
|
|
4321
4500
|
if (opts.cwd)
|
|
4322
|
-
|
|
4323
|
-
const args = [
|
|
4501
|
+
path24 = sysPath2.relative(opts.cwd, path24);
|
|
4502
|
+
const args = [path24];
|
|
4324
4503
|
if (stats != null)
|
|
4325
4504
|
args.push(stats);
|
|
4326
4505
|
const awf = opts.awaitWriteFinish;
|
|
4327
4506
|
let pw;
|
|
4328
|
-
if (awf && (pw = this._pendingWrites.get(
|
|
4507
|
+
if (awf && (pw = this._pendingWrites.get(path24))) {
|
|
4329
4508
|
pw.lastChange = /* @__PURE__ */ new Date();
|
|
4330
4509
|
return this;
|
|
4331
4510
|
}
|
|
4332
4511
|
if (opts.atomic) {
|
|
4333
4512
|
if (event === EVENTS.UNLINK) {
|
|
4334
|
-
this._pendingUnlinks.set(
|
|
4513
|
+
this._pendingUnlinks.set(path24, [event, ...args]);
|
|
4335
4514
|
setTimeout(() => {
|
|
4336
|
-
this._pendingUnlinks.forEach((entry,
|
|
4515
|
+
this._pendingUnlinks.forEach((entry, path25) => {
|
|
4337
4516
|
this.emit(...entry);
|
|
4338
4517
|
this.emit(EVENTS.ALL, ...entry);
|
|
4339
|
-
this._pendingUnlinks.delete(
|
|
4518
|
+
this._pendingUnlinks.delete(path25);
|
|
4340
4519
|
});
|
|
4341
4520
|
}, typeof opts.atomic === "number" ? opts.atomic : 100);
|
|
4342
4521
|
return this;
|
|
4343
4522
|
}
|
|
4344
|
-
if (event === EVENTS.ADD && this._pendingUnlinks.has(
|
|
4523
|
+
if (event === EVENTS.ADD && this._pendingUnlinks.has(path24)) {
|
|
4345
4524
|
event = EVENTS.CHANGE;
|
|
4346
|
-
this._pendingUnlinks.delete(
|
|
4525
|
+
this._pendingUnlinks.delete(path24);
|
|
4347
4526
|
}
|
|
4348
4527
|
}
|
|
4349
4528
|
if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
|
|
@@ -4361,16 +4540,16 @@ var init_esm2 = __esm({
|
|
|
4361
4540
|
this.emitWithAll(event, args);
|
|
4362
4541
|
}
|
|
4363
4542
|
};
|
|
4364
|
-
this._awaitWriteFinish(
|
|
4543
|
+
this._awaitWriteFinish(path24, awf.stabilityThreshold, event, awfEmit);
|
|
4365
4544
|
return this;
|
|
4366
4545
|
}
|
|
4367
4546
|
if (event === EVENTS.CHANGE) {
|
|
4368
|
-
const isThrottled = !this._throttle(EVENTS.CHANGE,
|
|
4547
|
+
const isThrottled = !this._throttle(EVENTS.CHANGE, path24, 50);
|
|
4369
4548
|
if (isThrottled)
|
|
4370
4549
|
return this;
|
|
4371
4550
|
}
|
|
4372
4551
|
if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
|
|
4373
|
-
const fullPath = opts.cwd ? sysPath2.join(opts.cwd,
|
|
4552
|
+
const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path24) : path24;
|
|
4374
4553
|
let stats2;
|
|
4375
4554
|
try {
|
|
4376
4555
|
stats2 = await stat3(fullPath);
|
|
@@ -4401,23 +4580,23 @@ var init_esm2 = __esm({
|
|
|
4401
4580
|
* @param timeout duration of time to suppress duplicate actions
|
|
4402
4581
|
* @returns tracking object or false if action should be suppressed
|
|
4403
4582
|
*/
|
|
4404
|
-
_throttle(actionType,
|
|
4583
|
+
_throttle(actionType, path24, timeout) {
|
|
4405
4584
|
if (!this._throttled.has(actionType)) {
|
|
4406
4585
|
this._throttled.set(actionType, /* @__PURE__ */ new Map());
|
|
4407
4586
|
}
|
|
4408
4587
|
const action = this._throttled.get(actionType);
|
|
4409
4588
|
if (!action)
|
|
4410
4589
|
throw new Error("invalid throttle");
|
|
4411
|
-
const actionPath = action.get(
|
|
4590
|
+
const actionPath = action.get(path24);
|
|
4412
4591
|
if (actionPath) {
|
|
4413
4592
|
actionPath.count++;
|
|
4414
4593
|
return false;
|
|
4415
4594
|
}
|
|
4416
4595
|
let timeoutObject;
|
|
4417
4596
|
const clear = () => {
|
|
4418
|
-
const item = action.get(
|
|
4597
|
+
const item = action.get(path24);
|
|
4419
4598
|
const count = item ? item.count : 0;
|
|
4420
|
-
action.delete(
|
|
4599
|
+
action.delete(path24);
|
|
4421
4600
|
clearTimeout(timeoutObject);
|
|
4422
4601
|
if (item)
|
|
4423
4602
|
clearTimeout(item.timeoutObject);
|
|
@@ -4425,7 +4604,7 @@ var init_esm2 = __esm({
|
|
|
4425
4604
|
};
|
|
4426
4605
|
timeoutObject = setTimeout(clear, timeout);
|
|
4427
4606
|
const thr = { timeoutObject, clear, count: 0 };
|
|
4428
|
-
action.set(
|
|
4607
|
+
action.set(path24, thr);
|
|
4429
4608
|
return thr;
|
|
4430
4609
|
}
|
|
4431
4610
|
_incrReadyCount() {
|
|
@@ -4439,44 +4618,44 @@ var init_esm2 = __esm({
|
|
|
4439
4618
|
* @param event
|
|
4440
4619
|
* @param awfEmit Callback to be called when ready for event to be emitted.
|
|
4441
4620
|
*/
|
|
4442
|
-
_awaitWriteFinish(
|
|
4621
|
+
_awaitWriteFinish(path24, threshold, event, awfEmit) {
|
|
4443
4622
|
const awf = this.options.awaitWriteFinish;
|
|
4444
4623
|
if (typeof awf !== "object")
|
|
4445
4624
|
return;
|
|
4446
4625
|
const pollInterval = awf.pollInterval;
|
|
4447
4626
|
let timeoutHandler;
|
|
4448
|
-
let fullPath =
|
|
4449
|
-
if (this.options.cwd && !sysPath2.isAbsolute(
|
|
4450
|
-
fullPath = sysPath2.join(this.options.cwd,
|
|
4627
|
+
let fullPath = path24;
|
|
4628
|
+
if (this.options.cwd && !sysPath2.isAbsolute(path24)) {
|
|
4629
|
+
fullPath = sysPath2.join(this.options.cwd, path24);
|
|
4451
4630
|
}
|
|
4452
4631
|
const now = /* @__PURE__ */ new Date();
|
|
4453
4632
|
const writes = this._pendingWrites;
|
|
4454
4633
|
function awaitWriteFinishFn(prevStat) {
|
|
4455
4634
|
statcb(fullPath, (err, curStat) => {
|
|
4456
|
-
if (err || !writes.has(
|
|
4635
|
+
if (err || !writes.has(path24)) {
|
|
4457
4636
|
if (err && err.code !== "ENOENT")
|
|
4458
4637
|
awfEmit(err);
|
|
4459
4638
|
return;
|
|
4460
4639
|
}
|
|
4461
4640
|
const now2 = Number(/* @__PURE__ */ new Date());
|
|
4462
4641
|
if (prevStat && curStat.size !== prevStat.size) {
|
|
4463
|
-
writes.get(
|
|
4642
|
+
writes.get(path24).lastChange = now2;
|
|
4464
4643
|
}
|
|
4465
|
-
const pw = writes.get(
|
|
4644
|
+
const pw = writes.get(path24);
|
|
4466
4645
|
const df = now2 - pw.lastChange;
|
|
4467
4646
|
if (df >= threshold) {
|
|
4468
|
-
writes.delete(
|
|
4647
|
+
writes.delete(path24);
|
|
4469
4648
|
awfEmit(void 0, curStat);
|
|
4470
4649
|
} else {
|
|
4471
4650
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
4472
4651
|
}
|
|
4473
4652
|
});
|
|
4474
4653
|
}
|
|
4475
|
-
if (!writes.has(
|
|
4476
|
-
writes.set(
|
|
4654
|
+
if (!writes.has(path24)) {
|
|
4655
|
+
writes.set(path24, {
|
|
4477
4656
|
lastChange: now,
|
|
4478
4657
|
cancelWait: () => {
|
|
4479
|
-
writes.delete(
|
|
4658
|
+
writes.delete(path24);
|
|
4480
4659
|
clearTimeout(timeoutHandler);
|
|
4481
4660
|
return event;
|
|
4482
4661
|
}
|
|
@@ -4487,8 +4666,8 @@ var init_esm2 = __esm({
|
|
|
4487
4666
|
/**
|
|
4488
4667
|
* Determines whether user has asked to ignore this path.
|
|
4489
4668
|
*/
|
|
4490
|
-
_isIgnored(
|
|
4491
|
-
if (this.options.atomic && DOT_RE.test(
|
|
4669
|
+
_isIgnored(path24, stats) {
|
|
4670
|
+
if (this.options.atomic && DOT_RE.test(path24))
|
|
4492
4671
|
return true;
|
|
4493
4672
|
if (!this._userIgnored) {
|
|
4494
4673
|
const { cwd } = this.options;
|
|
@@ -4498,17 +4677,17 @@ var init_esm2 = __esm({
|
|
|
4498
4677
|
const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
|
|
4499
4678
|
this._userIgnored = anymatch(list, void 0);
|
|
4500
4679
|
}
|
|
4501
|
-
return this._userIgnored(
|
|
4680
|
+
return this._userIgnored(path24, stats);
|
|
4502
4681
|
}
|
|
4503
|
-
_isntIgnored(
|
|
4504
|
-
return !this._isIgnored(
|
|
4682
|
+
_isntIgnored(path24, stat4) {
|
|
4683
|
+
return !this._isIgnored(path24, stat4);
|
|
4505
4684
|
}
|
|
4506
4685
|
/**
|
|
4507
4686
|
* Provides a set of common helpers and properties relating to symlink handling.
|
|
4508
4687
|
* @param path file or directory pattern being watched
|
|
4509
4688
|
*/
|
|
4510
|
-
_getWatchHelpers(
|
|
4511
|
-
return new WatchHelper(
|
|
4689
|
+
_getWatchHelpers(path24) {
|
|
4690
|
+
return new WatchHelper(path24, this.options.followSymlinks, this);
|
|
4512
4691
|
}
|
|
4513
4692
|
// Directory helpers
|
|
4514
4693
|
// -----------------
|
|
@@ -4540,63 +4719,63 @@ var init_esm2 = __esm({
|
|
|
4540
4719
|
* @param item base path of item/directory
|
|
4541
4720
|
*/
|
|
4542
4721
|
_remove(directory, item, isDirectory) {
|
|
4543
|
-
const
|
|
4544
|
-
const fullPath = sysPath2.resolve(
|
|
4545
|
-
isDirectory = isDirectory != null ? isDirectory : this._watched.has(
|
|
4546
|
-
if (!this._throttle("remove",
|
|
4722
|
+
const path24 = sysPath2.join(directory, item);
|
|
4723
|
+
const fullPath = sysPath2.resolve(path24);
|
|
4724
|
+
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path24) || this._watched.has(fullPath);
|
|
4725
|
+
if (!this._throttle("remove", path24, 100))
|
|
4547
4726
|
return;
|
|
4548
4727
|
if (!isDirectory && this._watched.size === 1) {
|
|
4549
4728
|
this.add(directory, item, true);
|
|
4550
4729
|
}
|
|
4551
|
-
const wp = this._getWatchedDir(
|
|
4730
|
+
const wp = this._getWatchedDir(path24);
|
|
4552
4731
|
const nestedDirectoryChildren = wp.getChildren();
|
|
4553
|
-
nestedDirectoryChildren.forEach((nested) => this._remove(
|
|
4732
|
+
nestedDirectoryChildren.forEach((nested) => this._remove(path24, nested));
|
|
4554
4733
|
const parent = this._getWatchedDir(directory);
|
|
4555
4734
|
const wasTracked = parent.has(item);
|
|
4556
4735
|
parent.remove(item);
|
|
4557
4736
|
if (this._symlinkPaths.has(fullPath)) {
|
|
4558
4737
|
this._symlinkPaths.delete(fullPath);
|
|
4559
4738
|
}
|
|
4560
|
-
let relPath =
|
|
4739
|
+
let relPath = path24;
|
|
4561
4740
|
if (this.options.cwd)
|
|
4562
|
-
relPath = sysPath2.relative(this.options.cwd,
|
|
4741
|
+
relPath = sysPath2.relative(this.options.cwd, path24);
|
|
4563
4742
|
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
4564
4743
|
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
4565
4744
|
if (event === EVENTS.ADD)
|
|
4566
4745
|
return;
|
|
4567
4746
|
}
|
|
4568
|
-
this._watched.delete(
|
|
4747
|
+
this._watched.delete(path24);
|
|
4569
4748
|
this._watched.delete(fullPath);
|
|
4570
4749
|
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
4571
|
-
if (wasTracked && !this._isIgnored(
|
|
4572
|
-
this._emit(eventName,
|
|
4573
|
-
this._closePath(
|
|
4750
|
+
if (wasTracked && !this._isIgnored(path24))
|
|
4751
|
+
this._emit(eventName, path24);
|
|
4752
|
+
this._closePath(path24);
|
|
4574
4753
|
}
|
|
4575
4754
|
/**
|
|
4576
4755
|
* Closes all watchers for a path
|
|
4577
4756
|
*/
|
|
4578
|
-
_closePath(
|
|
4579
|
-
this._closeFile(
|
|
4580
|
-
const dir = sysPath2.dirname(
|
|
4581
|
-
this._getWatchedDir(dir).remove(sysPath2.basename(
|
|
4757
|
+
_closePath(path24) {
|
|
4758
|
+
this._closeFile(path24);
|
|
4759
|
+
const dir = sysPath2.dirname(path24);
|
|
4760
|
+
this._getWatchedDir(dir).remove(sysPath2.basename(path24));
|
|
4582
4761
|
}
|
|
4583
4762
|
/**
|
|
4584
4763
|
* Closes only file-specific watchers
|
|
4585
4764
|
*/
|
|
4586
|
-
_closeFile(
|
|
4587
|
-
const closers = this._closers.get(
|
|
4765
|
+
_closeFile(path24) {
|
|
4766
|
+
const closers = this._closers.get(path24);
|
|
4588
4767
|
if (!closers)
|
|
4589
4768
|
return;
|
|
4590
4769
|
closers.forEach((closer) => closer());
|
|
4591
|
-
this._closers.delete(
|
|
4770
|
+
this._closers.delete(path24);
|
|
4592
4771
|
}
|
|
4593
|
-
_addPathCloser(
|
|
4772
|
+
_addPathCloser(path24, closer) {
|
|
4594
4773
|
if (!closer)
|
|
4595
4774
|
return;
|
|
4596
|
-
let list = this._closers.get(
|
|
4775
|
+
let list = this._closers.get(path24);
|
|
4597
4776
|
if (!list) {
|
|
4598
4777
|
list = [];
|
|
4599
|
-
this._closers.set(
|
|
4778
|
+
this._closers.set(path24, list);
|
|
4600
4779
|
}
|
|
4601
4780
|
list.push(closer);
|
|
4602
4781
|
}
|
|
@@ -4623,8 +4802,8 @@ var init_esm2 = __esm({
|
|
|
4623
4802
|
});
|
|
4624
4803
|
|
|
4625
4804
|
// src/cli/compileDevRoutes.ts
|
|
4626
|
-
import
|
|
4627
|
-
import
|
|
4805
|
+
import path15 from "path";
|
|
4806
|
+
import fs14 from "fs";
|
|
4628
4807
|
import fg4 from "fast-glob";
|
|
4629
4808
|
async function compileDevRoutes(options) {
|
|
4630
4809
|
const { rootDir, dist, files, logLevel = "silent" } = options;
|
|
@@ -4637,11 +4816,11 @@ async function compileDevRoutes(options) {
|
|
|
4637
4816
|
if (entryPoints.length === 0) {
|
|
4638
4817
|
return { compiledFiles: [] };
|
|
4639
4818
|
}
|
|
4640
|
-
const absDist =
|
|
4641
|
-
await
|
|
4819
|
+
const absDist = path15.resolve(rootDir, dist);
|
|
4820
|
+
await fs14.promises.mkdir(absDist, { recursive: true });
|
|
4642
4821
|
const plugins = buildAliasPlugins(rootDir);
|
|
4643
4822
|
const esbuild = await import("esbuild");
|
|
4644
|
-
const outbase =
|
|
4823
|
+
const outbase = path15.resolve(rootDir, APP_DIR2);
|
|
4645
4824
|
const result = await esbuild.build({
|
|
4646
4825
|
entryPoints,
|
|
4647
4826
|
outdir: absDist,
|
|
@@ -4658,10 +4837,10 @@ async function compileDevRoutes(options) {
|
|
|
4658
4837
|
if (result.outputFiles) {
|
|
4659
4838
|
await Promise.all(
|
|
4660
4839
|
result.outputFiles.map(async (file) => {
|
|
4661
|
-
await
|
|
4840
|
+
await fs14.promises.mkdir(path15.dirname(file.path), { recursive: true });
|
|
4662
4841
|
const tmp = `${file.path}.tmp-${process.pid}-${Math.random().toString(36).slice(2)}`;
|
|
4663
|
-
await
|
|
4664
|
-
await
|
|
4842
|
+
await fs14.promises.writeFile(tmp, file.contents);
|
|
4843
|
+
await fs14.promises.rename(tmp, file.path);
|
|
4665
4844
|
})
|
|
4666
4845
|
);
|
|
4667
4846
|
}
|
|
@@ -4677,7 +4856,7 @@ var init_compileDevRoutes = __esm({
|
|
|
4677
4856
|
});
|
|
4678
4857
|
|
|
4679
4858
|
// src/cli/watcher.ts
|
|
4680
|
-
import
|
|
4859
|
+
import path16 from "path";
|
|
4681
4860
|
function startWatcher(options) {
|
|
4682
4861
|
const { rootDir, app, devDist } = options;
|
|
4683
4862
|
let rebuildTimer = null;
|
|
@@ -4727,11 +4906,11 @@ function startWatcher(options) {
|
|
|
4727
4906
|
}
|
|
4728
4907
|
});
|
|
4729
4908
|
watcher.on("add", (file) => {
|
|
4730
|
-
pendingFiles.add(
|
|
4909
|
+
pendingFiles.add(path16.resolve(rootDir, file));
|
|
4731
4910
|
scheduleRebuild();
|
|
4732
4911
|
});
|
|
4733
4912
|
watcher.on("change", (file) => {
|
|
4734
|
-
pendingFiles.add(
|
|
4913
|
+
pendingFiles.add(path16.resolve(rootDir, file));
|
|
4735
4914
|
scheduleRebuild();
|
|
4736
4915
|
});
|
|
4737
4916
|
watcher.on("unlink", () => {
|
|
@@ -4788,42 +4967,91 @@ var init_detectRouteConflicts = __esm({
|
|
|
4788
4967
|
});
|
|
4789
4968
|
|
|
4790
4969
|
// src/router/matchRoute.ts
|
|
4791
|
-
function
|
|
4970
|
+
function getHttpIndex(routes) {
|
|
4971
|
+
let index = httpIndexCache.get(routes);
|
|
4972
|
+
if (index) return index;
|
|
4973
|
+
index = { static: /* @__PURE__ */ new Map(), methodsByStaticPath: /* @__PURE__ */ new Map(), dynamics: [] };
|
|
4792
4974
|
for (const route of routes) {
|
|
4793
|
-
if (route.
|
|
4794
|
-
|
|
4795
|
-
}
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4975
|
+
if (route.isDynamic) {
|
|
4976
|
+
index.dynamics.push(route);
|
|
4977
|
+
} else {
|
|
4978
|
+
index.static.set(`${route.method}|${route.urlPath}`, route);
|
|
4979
|
+
let methods = index.methodsByStaticPath.get(route.urlPath);
|
|
4980
|
+
if (!methods) {
|
|
4981
|
+
methods = /* @__PURE__ */ new Set();
|
|
4982
|
+
index.methodsByStaticPath.set(route.urlPath, methods);
|
|
4799
4983
|
}
|
|
4984
|
+
methods.add(route.method);
|
|
4985
|
+
}
|
|
4986
|
+
}
|
|
4987
|
+
httpIndexCache.set(routes, index);
|
|
4988
|
+
return index;
|
|
4989
|
+
}
|
|
4990
|
+
function getWsIndex(routes) {
|
|
4991
|
+
let index = wsIndexCache.get(routes);
|
|
4992
|
+
if (index) return index;
|
|
4993
|
+
index = { static: /* @__PURE__ */ new Map(), dynamics: [] };
|
|
4994
|
+
for (const route of routes) {
|
|
4995
|
+
if (route.isDynamic) {
|
|
4996
|
+
index.dynamics.push(route);
|
|
4997
|
+
} else {
|
|
4998
|
+
index.static.set(route.urlPath, route);
|
|
4999
|
+
}
|
|
5000
|
+
}
|
|
5001
|
+
wsIndexCache.set(routes, index);
|
|
5002
|
+
return index;
|
|
5003
|
+
}
|
|
5004
|
+
function matchRoute(routes, method, path24) {
|
|
5005
|
+
const index = getHttpIndex(routes);
|
|
5006
|
+
const staticHit = index.static.get(`${method}|${path24}`);
|
|
5007
|
+
if (staticHit) {
|
|
5008
|
+
return { route: staticHit, params: {} };
|
|
5009
|
+
}
|
|
5010
|
+
for (const route of index.dynamics) {
|
|
5011
|
+
if (route.method !== method) {
|
|
4800
5012
|
continue;
|
|
4801
5013
|
}
|
|
4802
|
-
const params = matchDynamicPath(route.urlPath,
|
|
5014
|
+
const params = matchDynamicPath(route.urlPath, path24, route.paramNames, route.isCatchAll);
|
|
4803
5015
|
if (params !== null) {
|
|
4804
5016
|
return { route, params };
|
|
4805
5017
|
}
|
|
4806
5018
|
}
|
|
4807
5019
|
return null;
|
|
4808
5020
|
}
|
|
4809
|
-
function matchWsRoute(wsRoutes,
|
|
4810
|
-
|
|
4811
|
-
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
const params = matchDynamicPath(route.urlPath, path23, route.paramNames, route.isCatchAll);
|
|
5021
|
+
function matchWsRoute(wsRoutes, path24) {
|
|
5022
|
+
const index = getWsIndex(wsRoutes);
|
|
5023
|
+
const staticHit = index.static.get(path24);
|
|
5024
|
+
if (staticHit) {
|
|
5025
|
+
return { route: staticHit, params: {} };
|
|
5026
|
+
}
|
|
5027
|
+
for (const route of index.dynamics) {
|
|
5028
|
+
const params = matchDynamicPath(route.urlPath, path24, route.paramNames, route.isCatchAll);
|
|
4818
5029
|
if (params !== null) {
|
|
4819
5030
|
return { route, params };
|
|
4820
5031
|
}
|
|
4821
5032
|
}
|
|
4822
5033
|
return null;
|
|
4823
5034
|
}
|
|
4824
|
-
function
|
|
5035
|
+
function findAllowedMethods(routes, path24) {
|
|
5036
|
+
const index = getHttpIndex(routes);
|
|
5037
|
+
const methods = /* @__PURE__ */ new Set();
|
|
5038
|
+
const staticMethods = index.methodsByStaticPath.get(path24);
|
|
5039
|
+
if (staticMethods) {
|
|
5040
|
+
for (const method of staticMethods) {
|
|
5041
|
+
methods.add(method);
|
|
5042
|
+
}
|
|
5043
|
+
}
|
|
5044
|
+
for (const route of index.dynamics) {
|
|
5045
|
+
const params = matchDynamicPath(route.urlPath, path24, route.paramNames, route.isCatchAll);
|
|
5046
|
+
if (params !== null) {
|
|
5047
|
+
methods.add(route.method);
|
|
5048
|
+
}
|
|
5049
|
+
}
|
|
5050
|
+
return Array.from(methods);
|
|
5051
|
+
}
|
|
5052
|
+
function matchDynamicPath(pattern, path24, paramNames, isCatchAll) {
|
|
4825
5053
|
const patternSegments = pattern.split("/").filter(Boolean);
|
|
4826
|
-
const pathSegments =
|
|
5054
|
+
const pathSegments = path24.split("/").filter(Boolean);
|
|
4827
5055
|
if (isCatchAll) {
|
|
4828
5056
|
const nonCatchAllCount = patternSegments.length - 1;
|
|
4829
5057
|
if (pathSegments.length <= nonCatchAllCount) {
|
|
@@ -4867,9 +5095,12 @@ function matchDynamicPath(pattern, path23, paramNames, isCatchAll) {
|
|
|
4867
5095
|
}
|
|
4868
5096
|
return params;
|
|
4869
5097
|
}
|
|
5098
|
+
var httpIndexCache, wsIndexCache;
|
|
4870
5099
|
var init_matchRoute = __esm({
|
|
4871
5100
|
"src/router/matchRoute.ts"() {
|
|
4872
5101
|
"use strict";
|
|
5102
|
+
httpIndexCache = /* @__PURE__ */ new WeakMap();
|
|
5103
|
+
wsIndexCache = /* @__PURE__ */ new WeakMap();
|
|
4873
5104
|
}
|
|
4874
5105
|
});
|
|
4875
5106
|
|
|
@@ -4908,12 +5139,12 @@ var init_validateRouteModule = __esm({
|
|
|
4908
5139
|
});
|
|
4909
5140
|
|
|
4910
5141
|
// src/cli/compileOnDemand.ts
|
|
4911
|
-
import
|
|
4912
|
-
import
|
|
5142
|
+
import path17 from "path";
|
|
5143
|
+
import fs15 from "fs";
|
|
4913
5144
|
function isProductFresh(sourceAbsPath, productAbsPath) {
|
|
4914
5145
|
try {
|
|
4915
|
-
const srcStat =
|
|
4916
|
-
const prodStat =
|
|
5146
|
+
const srcStat = fs15.statSync(sourceAbsPath);
|
|
5147
|
+
const prodStat = fs15.statSync(productAbsPath);
|
|
4917
5148
|
return prodStat.mtimeMs >= srcStat.mtimeMs;
|
|
4918
5149
|
} catch {
|
|
4919
5150
|
return false;
|
|
@@ -4932,6 +5163,7 @@ function createDevOnDemandState() {
|
|
|
4932
5163
|
function clearCompiledFiles() {
|
|
4933
5164
|
state.compiledFiles.clear();
|
|
4934
5165
|
state.inFlightCompilations.clear();
|
|
5166
|
+
sourcePathCache.clear();
|
|
4935
5167
|
}
|
|
4936
5168
|
async function ensureCompiled(sourceAbsPath, rootDir, dist) {
|
|
4937
5169
|
const inFlight = state.inFlightCompilations.get(sourceAbsPath);
|
|
@@ -4943,7 +5175,7 @@ async function ensureCompiled(sourceAbsPath, rootDir, dist) {
|
|
|
4943
5175
|
if (state.compiledFiles.has(sourceAbsPath)) {
|
|
4944
5176
|
return false;
|
|
4945
5177
|
}
|
|
4946
|
-
if (!
|
|
5178
|
+
if (!fs15.existsSync(sourceAbsPath)) {
|
|
4947
5179
|
return false;
|
|
4948
5180
|
}
|
|
4949
5181
|
const productPath = prodSourcePathToProductPath(sourceAbsPath, rootDir, dist);
|
|
@@ -4969,11 +5201,11 @@ async function ensureCompiled(sourceAbsPath, rootDir, dist) {
|
|
|
4969
5201
|
}
|
|
4970
5202
|
}
|
|
4971
5203
|
function prodSourcePathToProductPath(sourceAbsPath, rootDir, dist) {
|
|
4972
|
-
const rel =
|
|
5204
|
+
const rel = path17.relative(rootDir, sourceAbsPath).replace(/\\/g, "/");
|
|
4973
5205
|
if (!rel.startsWith("src/")) return null;
|
|
4974
5206
|
const relWithoutSrc = rel.slice(4);
|
|
4975
5207
|
const jsRel = relWithoutSrc.replace(/\.ts$/, ".js");
|
|
4976
|
-
return
|
|
5208
|
+
return path17.resolve(rootDir, dist, jsRel);
|
|
4977
5209
|
}
|
|
4978
5210
|
function clearGeneratedSchemas() {
|
|
4979
5211
|
state.generatedSchemas.clear();
|
|
@@ -4989,9 +5221,9 @@ async function ensureSchemaGenerated(schemaPath, routeFilePath, routes, rootDir,
|
|
|
4989
5221
|
if (state.generatedSchemas.has(schemaPath)) {
|
|
4990
5222
|
return false;
|
|
4991
5223
|
}
|
|
4992
|
-
const prodAbsPath =
|
|
5224
|
+
const prodAbsPath = path17.resolve(rootDir, routeFilePath);
|
|
4993
5225
|
const sourceAbsPath = prodPathToSourcePath(prodAbsPath, rootDir, dist);
|
|
4994
|
-
if (!
|
|
5226
|
+
if (!fs15.existsSync(sourceAbsPath)) {
|
|
4995
5227
|
return false;
|
|
4996
5228
|
}
|
|
4997
5229
|
if (isProductFresh(sourceAbsPath, schemaPath)) {
|
|
@@ -5002,7 +5234,7 @@ async function ensureSchemaGenerated(schemaPath, routeFilePath, routes, rootDir,
|
|
|
5002
5234
|
if (fileRoutes.length === 0) {
|
|
5003
5235
|
return false;
|
|
5004
5236
|
}
|
|
5005
|
-
const sourceRelPath =
|
|
5237
|
+
const sourceRelPath = path17.relative(rootDir, sourceAbsPath).replace(/\\/g, "/");
|
|
5006
5238
|
const sourceRoutes = fileRoutes.map((r) => ({ ...r, filePath: sourceRelPath }));
|
|
5007
5239
|
const generatePromise = (async () => {
|
|
5008
5240
|
await generateSchemaFiles(sourceRoutes, rootDir, dist);
|
|
@@ -5023,22 +5255,30 @@ async function deleteSchemaFiles(routes, rootDir, dist) {
|
|
|
5023
5255
|
if (deleted.has(schemaPath)) continue;
|
|
5024
5256
|
deleted.add(schemaPath);
|
|
5025
5257
|
try {
|
|
5026
|
-
await
|
|
5258
|
+
await fs15.promises.unlink(schemaPath);
|
|
5027
5259
|
} catch {
|
|
5028
5260
|
}
|
|
5029
5261
|
}
|
|
5030
5262
|
}
|
|
5031
5263
|
function prodPathToSourcePath(prodAbsPath, rootDir, dist) {
|
|
5032
|
-
const
|
|
5264
|
+
const cached = sourcePathCache.get(prodAbsPath);
|
|
5265
|
+
if (cached) return cached;
|
|
5266
|
+
const rel = path17.relative(rootDir, prodAbsPath).replace(/\\/g, "/");
|
|
5033
5267
|
let relWithoutDist = rel;
|
|
5034
5268
|
if (relWithoutDist.startsWith(`${dist}/`)) {
|
|
5035
5269
|
relWithoutDist = relWithoutDist.slice(dist.length + 1);
|
|
5036
5270
|
}
|
|
5037
5271
|
const srcRel = `src/${relWithoutDist}`;
|
|
5038
5272
|
const tsRel = srcRel.replace(/\.js$/, ".ts");
|
|
5039
|
-
const tsAbs =
|
|
5040
|
-
|
|
5041
|
-
|
|
5273
|
+
const tsAbs = path17.resolve(rootDir, tsRel);
|
|
5274
|
+
let result;
|
|
5275
|
+
if (fs15.existsSync(tsAbs)) {
|
|
5276
|
+
result = tsAbs;
|
|
5277
|
+
} else {
|
|
5278
|
+
result = path17.resolve(rootDir, srcRel);
|
|
5279
|
+
}
|
|
5280
|
+
sourcePathCache.set(prodAbsPath, result);
|
|
5281
|
+
return result;
|
|
5042
5282
|
}
|
|
5043
5283
|
function setDevOnDemandEnabled(enabled) {
|
|
5044
5284
|
state.enabled = enabled;
|
|
@@ -5052,7 +5292,7 @@ function setDevDist(dist) {
|
|
|
5052
5292
|
function getDevDist() {
|
|
5053
5293
|
return state.distDir;
|
|
5054
5294
|
}
|
|
5055
|
-
var state;
|
|
5295
|
+
var state, sourcePathCache;
|
|
5056
5296
|
var init_compileOnDemand = __esm({
|
|
5057
5297
|
"src/cli/compileOnDemand.ts"() {
|
|
5058
5298
|
"use strict";
|
|
@@ -5060,17 +5300,17 @@ var init_compileOnDemand = __esm({
|
|
|
5060
5300
|
init_generateSchemaFiles();
|
|
5061
5301
|
init_generateSchemaFiles();
|
|
5062
5302
|
state = createDevOnDemandState();
|
|
5303
|
+
sourcePathCache = /* @__PURE__ */ new Map();
|
|
5063
5304
|
}
|
|
5064
5305
|
});
|
|
5065
5306
|
|
|
5066
5307
|
// src/loader/loadRouteModule.ts
|
|
5067
|
-
import fs15 from "fs";
|
|
5068
5308
|
async function loadRouteModule(filePath, method, rootDir) {
|
|
5069
5309
|
if (isDevOnDemandEnabled() && rootDir) {
|
|
5070
5310
|
const dist = getDevDist();
|
|
5071
5311
|
if (dist) {
|
|
5072
5312
|
const sourcePath = prodPathToSourcePath(filePath, rootDir, dist);
|
|
5073
|
-
if (sourcePath
|
|
5313
|
+
if (sourcePath) {
|
|
5074
5314
|
try {
|
|
5075
5315
|
await ensureCompiled(sourcePath, rootDir, dist);
|
|
5076
5316
|
} catch (compileErr) {
|
|
@@ -5250,14 +5490,14 @@ var init_httpErrors = __esm({
|
|
|
5250
5490
|
issues;
|
|
5251
5491
|
};
|
|
5252
5492
|
RouteNotFoundError = class extends FaapiError {
|
|
5253
|
-
constructor(
|
|
5254
|
-
super("ROUTE_NOT_FOUND", `Route not found: ${
|
|
5493
|
+
constructor(path24) {
|
|
5494
|
+
super("ROUTE_NOT_FOUND", `Route not found: ${path24}`, 404);
|
|
5255
5495
|
this.name = "RouteNotFoundError";
|
|
5256
5496
|
}
|
|
5257
5497
|
};
|
|
5258
5498
|
MethodNotAllowedError = class extends FaapiError {
|
|
5259
|
-
constructor(method,
|
|
5260
|
-
super("METHOD_NOT_ALLOWED", `Method ${method} not allowed for ${
|
|
5499
|
+
constructor(method, path24, allowedMethods) {
|
|
5500
|
+
super("METHOD_NOT_ALLOWED", `Method ${method} not allowed for ${path24}`, 405);
|
|
5261
5501
|
this.allowedMethods = allowedMethods;
|
|
5262
5502
|
this.name = "MethodNotAllowedError";
|
|
5263
5503
|
}
|
|
@@ -5396,7 +5636,9 @@ function formatSetCookie(name, value, options) {
|
|
|
5396
5636
|
return cookie;
|
|
5397
5637
|
}
|
|
5398
5638
|
function createContext(request, params, config = {}, ip = "") {
|
|
5399
|
-
|
|
5639
|
+
return createContextFromUrl(request, new URL(request.url), params, config, ip);
|
|
5640
|
+
}
|
|
5641
|
+
function createContextFromUrl(request, url, params, config = {}, ip = "") {
|
|
5400
5642
|
const meta = { headers: {}, setCookies: [] };
|
|
5401
5643
|
const parsedCookies = parseCookies(request.headers.get("cookie") ?? "");
|
|
5402
5644
|
const cookiesObj = {};
|
|
@@ -5572,7 +5814,7 @@ var init_parseMultipart = __esm({
|
|
|
5572
5814
|
});
|
|
5573
5815
|
|
|
5574
5816
|
// src/runtime/resolveInput.ts
|
|
5575
|
-
async function
|
|
5817
|
+
async function resolveInputFromUrl(method, request, url) {
|
|
5576
5818
|
const inputType = getInputTypeForMethod(method);
|
|
5577
5819
|
if (inputType === "body") {
|
|
5578
5820
|
const contentType = request.headers.get("content-type") ?? "";
|
|
@@ -5607,7 +5849,6 @@ async function resolveInput(method, request) {
|
|
|
5607
5849
|
}
|
|
5608
5850
|
return result.data;
|
|
5609
5851
|
}
|
|
5610
|
-
const url = new URL(request.url);
|
|
5611
5852
|
return queryToObject(url.searchParams);
|
|
5612
5853
|
}
|
|
5613
5854
|
var init_resolveInput = __esm({
|
|
@@ -6031,9 +6272,9 @@ async function validateInput(schemaPath, method, inputType, input) {
|
|
|
6031
6272
|
function mapZodIssues(error) {
|
|
6032
6273
|
return error.issues.map((issue) => {
|
|
6033
6274
|
const code = mapZodCode(issue.code, issue.message);
|
|
6034
|
-
const
|
|
6275
|
+
const path24 = issue.path.map(String).join(".") || "";
|
|
6035
6276
|
return {
|
|
6036
|
-
path:
|
|
6277
|
+
path: path24,
|
|
6037
6278
|
code,
|
|
6038
6279
|
expected: issue.expected ?? mapExpectedFromMessage(issue.message),
|
|
6039
6280
|
received: issue.received ?? mapReceivedFromMessage(issue.message),
|
|
@@ -6086,11 +6327,13 @@ var init_validateInput = __esm({
|
|
|
6086
6327
|
});
|
|
6087
6328
|
|
|
6088
6329
|
// src/utils/getClientIp.ts
|
|
6089
|
-
function getClientIp(req) {
|
|
6090
|
-
|
|
6091
|
-
|
|
6092
|
-
|
|
6093
|
-
|
|
6330
|
+
function getClientIp(req, trustedProxy = false) {
|
|
6331
|
+
if (trustedProxy) {
|
|
6332
|
+
const xff = req.headers["x-forwarded-for"];
|
|
6333
|
+
if (typeof xff === "string" && xff.length > 0) {
|
|
6334
|
+
const first = xff.split(",")[0]?.trim();
|
|
6335
|
+
if (first) return first;
|
|
6336
|
+
}
|
|
6094
6337
|
}
|
|
6095
6338
|
const remote = req.socket?.remoteAddress;
|
|
6096
6339
|
if (remote) {
|
|
@@ -6349,7 +6592,7 @@ var init_wsHandler = __esm({
|
|
|
6349
6592
|
// src/server/handleWsUpgrade.ts
|
|
6350
6593
|
import fs16 from "fs";
|
|
6351
6594
|
import { WebSocketServer, WebSocket } from "ws";
|
|
6352
|
-
import
|
|
6595
|
+
import path18 from "path";
|
|
6353
6596
|
function getPathname(req) {
|
|
6354
6597
|
const url = req.url ?? "/";
|
|
6355
6598
|
const idx = url.indexOf("?");
|
|
@@ -6418,7 +6661,7 @@ async function sendResponseToSocket(socket, response) {
|
|
|
6418
6661
|
socket.destroy();
|
|
6419
6662
|
}
|
|
6420
6663
|
function attachWebSocket(options) {
|
|
6421
|
-
const { server, routesRef, rootDir, config, globalMiddlewares } = options;
|
|
6664
|
+
const { server, routesRef, rootDir, config, globalMiddlewares, trustedProxy = false } = options;
|
|
6422
6665
|
const wss = new WebSocketServer({ noServer: true });
|
|
6423
6666
|
server.on("upgrade", async (req, socket, head) => {
|
|
6424
6667
|
const currentWsRoutes = routesRef.wsCurrent;
|
|
@@ -6434,13 +6677,13 @@ function attachWebSocket(options) {
|
|
|
6434
6677
|
const host = req.headers.host ?? "localhost";
|
|
6435
6678
|
const url = `http://${host}${req.url ?? "/"}`;
|
|
6436
6679
|
const request = new Request(url, { method: "GET", headers });
|
|
6437
|
-
const ctx = createContext(request, params, config, getClientIp(req));
|
|
6680
|
+
const ctx = createContext(request, params, config, getClientIp(req, trustedProxy));
|
|
6438
6681
|
const meta = ctx.meta;
|
|
6439
6682
|
let upgraded = false;
|
|
6440
6683
|
const finalHandler = async () => {
|
|
6441
6684
|
let handlers;
|
|
6442
6685
|
try {
|
|
6443
|
-
const absoluteFilePath =
|
|
6686
|
+
const absoluteFilePath = path18.resolve(rootDir, route.filePath);
|
|
6444
6687
|
handlers = await loadWsHandler(absoluteFilePath, ctx, rootDir);
|
|
6445
6688
|
} catch (err) {
|
|
6446
6689
|
const reason = err instanceof Error ? err.message : String(err);
|
|
@@ -6514,7 +6757,7 @@ import {
|
|
|
6514
6757
|
import { createSecureServer as createHttp2SecureServer } from "http2";
|
|
6515
6758
|
import { readFileSync } from "fs";
|
|
6516
6759
|
import { Readable as Readable3 } from "stream";
|
|
6517
|
-
import
|
|
6760
|
+
import path19 from "path";
|
|
6518
6761
|
function toWebRequest(req, bodyLimit = DEFAULT_BODY_LIMIT) {
|
|
6519
6762
|
const forwardedProto = req.headers["x-forwarded-proto"];
|
|
6520
6763
|
const protocol = Array.isArray(forwardedProto) ? forwardedProto[0]?.split(",")[0]?.trim() ?? "http" : forwardedProto?.split(",")[0]?.trim() ?? "http";
|
|
@@ -6523,16 +6766,26 @@ function toWebRequest(req, bodyLimit = DEFAULT_BODY_LIMIT) {
|
|
|
6523
6766
|
const headers = nodeHttpToWebHeaders(req);
|
|
6524
6767
|
const method = req.method ?? "GET";
|
|
6525
6768
|
if (method === "GET" || method === "HEAD") {
|
|
6526
|
-
return new Request(url.toString(), { method, headers });
|
|
6769
|
+
return { request: new Request(url.toString(), { method, headers }), url };
|
|
6770
|
+
}
|
|
6771
|
+
const contentLength = req.headers["content-length"];
|
|
6772
|
+
if (contentLength !== void 0) {
|
|
6773
|
+
const declared = Number(Array.isArray(contentLength) ? contentLength[0] : contentLength);
|
|
6774
|
+
if (Number.isFinite(declared) && declared > bodyLimit) {
|
|
6775
|
+
throw new PayloadTooLargeError(bodyLimit);
|
|
6776
|
+
}
|
|
6527
6777
|
}
|
|
6528
6778
|
const stream = Readable3.toWeb(req);
|
|
6529
6779
|
const limitedStream = limitStreamSize(stream, bodyLimit);
|
|
6530
|
-
return
|
|
6531
|
-
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
6780
|
+
return {
|
|
6781
|
+
request: new Request(url.toString(), {
|
|
6782
|
+
method,
|
|
6783
|
+
headers,
|
|
6784
|
+
body: limitedStream,
|
|
6785
|
+
duplex: "half"
|
|
6786
|
+
}),
|
|
6787
|
+
url
|
|
6788
|
+
};
|
|
6536
6789
|
}
|
|
6537
6790
|
function limitStreamSize(stream, maxSize) {
|
|
6538
6791
|
let totalSize = 0;
|
|
@@ -6584,22 +6837,6 @@ function limitStreamSize(stream, maxSize) {
|
|
|
6584
6837
|
}
|
|
6585
6838
|
});
|
|
6586
6839
|
}
|
|
6587
|
-
function findAllowedMethods(routes, path23) {
|
|
6588
|
-
const methods = /* @__PURE__ */ new Set();
|
|
6589
|
-
for (const route of routes) {
|
|
6590
|
-
if (route.urlPath === path23) {
|
|
6591
|
-
methods.add(route.method);
|
|
6592
|
-
continue;
|
|
6593
|
-
}
|
|
6594
|
-
if (route.isDynamic) {
|
|
6595
|
-
const params = matchDynamicPath(route.urlPath, path23, route.paramNames, route.isCatchAll);
|
|
6596
|
-
if (params !== null) {
|
|
6597
|
-
methods.add(route.method);
|
|
6598
|
-
}
|
|
6599
|
-
}
|
|
6600
|
-
}
|
|
6601
|
-
return Array.from(methods);
|
|
6602
|
-
}
|
|
6603
6840
|
function createServer(options) {
|
|
6604
6841
|
const {
|
|
6605
6842
|
routes,
|
|
@@ -6614,7 +6851,8 @@ function createServer(options) {
|
|
|
6614
6851
|
helmet: helmetOption,
|
|
6615
6852
|
logger: loggerOption,
|
|
6616
6853
|
bodyLimit = DEFAULT_BODY_LIMIT,
|
|
6617
|
-
http2: http2Option
|
|
6854
|
+
http2: http2Option,
|
|
6855
|
+
trustedProxy = false
|
|
6618
6856
|
} = options;
|
|
6619
6857
|
const routesRef = { current: routes, wsCurrent: wsRoutes ?? [] };
|
|
6620
6858
|
const configMiddlewares = [];
|
|
@@ -6626,6 +6864,10 @@ function createServer(options) {
|
|
|
6626
6864
|
}
|
|
6627
6865
|
const loggerMiddlewareInst = loggerOption === false ? null : loggerOption === true || loggerOption === void 0 ? logger() : logger(loggerOption);
|
|
6628
6866
|
if (loggerMiddlewareInst) configMiddlewares.push(loggerMiddlewareInst);
|
|
6867
|
+
const outerMiddlewares = [...configMiddlewares];
|
|
6868
|
+
if (globalMiddlewares && globalMiddlewares.length > 0) {
|
|
6869
|
+
outerMiddlewares.push(...globalMiddlewares);
|
|
6870
|
+
}
|
|
6629
6871
|
const server = (() => {
|
|
6630
6872
|
if (http2Option) {
|
|
6631
6873
|
const h2Opts = typeof http2Option === "object" ? http2Option : {};
|
|
@@ -6645,29 +6887,29 @@ function createServer(options) {
|
|
|
6645
6887
|
dist,
|
|
6646
6888
|
req,
|
|
6647
6889
|
res,
|
|
6648
|
-
|
|
6890
|
+
outerMiddlewares,
|
|
6649
6891
|
onError,
|
|
6650
6892
|
config,
|
|
6651
|
-
globalMiddlewares,
|
|
6652
6893
|
globalInjectors,
|
|
6653
|
-
bodyLimit
|
|
6894
|
+
bodyLimit,
|
|
6895
|
+
trustedProxy
|
|
6654
6896
|
).catch(() => {
|
|
6655
6897
|
res.statusCode = 500;
|
|
6656
6898
|
res.end();
|
|
6657
6899
|
});
|
|
6658
6900
|
});
|
|
6659
6901
|
if (routesRef.wsCurrent.length > 0) {
|
|
6660
|
-
attachWebSocket({ server, routesRef, rootDir, config, globalMiddlewares });
|
|
6902
|
+
attachWebSocket({ server, routesRef, rootDir, config, globalMiddlewares, trustedProxy });
|
|
6661
6903
|
}
|
|
6662
6904
|
return { server, routesRef };
|
|
6663
6905
|
}
|
|
6664
|
-
function prepareRequest(req, config, bodyLimit) {
|
|
6665
|
-
const request = toWebRequest(req, bodyLimit);
|
|
6906
|
+
function prepareRequest(req, config, bodyLimit, trustedProxy) {
|
|
6907
|
+
const { request, url } = toWebRequest(req, bodyLimit);
|
|
6666
6908
|
const method = request.method.toUpperCase();
|
|
6667
|
-
const urlPath =
|
|
6668
|
-
const ctx =
|
|
6909
|
+
const urlPath = url.pathname;
|
|
6910
|
+
const ctx = createContextFromUrl(request, url, {}, config, getClientIp(req, trustedProxy));
|
|
6669
6911
|
const meta = ctx.meta;
|
|
6670
|
-
return { request, ctx, meta, method, urlPath };
|
|
6912
|
+
return { request, url, ctx, meta, method, urlPath };
|
|
6671
6913
|
}
|
|
6672
6914
|
function resolveRouteOrThrow(routes, method, urlPath) {
|
|
6673
6915
|
const match = matchRoute(routes, method, urlPath);
|
|
@@ -6679,14 +6921,14 @@ function resolveRouteOrThrow(routes, method, urlPath) {
|
|
|
6679
6921
|
throw new RouteNotFoundError(urlPath);
|
|
6680
6922
|
}
|
|
6681
6923
|
function createRoutePipeline(opts) {
|
|
6682
|
-
const { routes, method, urlPath, ctx, request, rootDir, dist, globalInjectors } = opts;
|
|
6924
|
+
const { routes, method, urlPath, url, ctx, request, rootDir, dist, globalInjectors } = opts;
|
|
6683
6925
|
return async () => {
|
|
6684
6926
|
const match = resolveRouteOrThrow(routes, method, urlPath);
|
|
6685
6927
|
ctx.params = match.params;
|
|
6686
6928
|
const { route } = match;
|
|
6687
|
-
const absoluteFilePath =
|
|
6929
|
+
const absoluteFilePath = path19.resolve(rootDir, route.filePath);
|
|
6688
6930
|
const routeModule = await loadRouteModule(absoluteFilePath, route.method, rootDir);
|
|
6689
|
-
const input = await
|
|
6931
|
+
const input = await resolveInputFromUrl(route.method, request, url);
|
|
6690
6932
|
const inputType = getInputTypeForMethod(route.method);
|
|
6691
6933
|
const schemaPath = getRuntimeSchemaPath(route.filePath, dist, rootDir);
|
|
6692
6934
|
if (isDevOnDemandEnabled()) {
|
|
@@ -6718,33 +6960,33 @@ async function sendSuccessResponse(response, res) {
|
|
|
6718
6960
|
await sendNodeResponse(response, res);
|
|
6719
6961
|
}
|
|
6720
6962
|
async function sendErrorResponse(err, meta, res, onError, ctx) {
|
|
6721
|
-
await sendNodeResponse(mergeMeta(buildErrorResponse(err, ctx
|
|
6722
|
-
if (onError) {
|
|
6963
|
+
await sendNodeResponse(mergeMeta(buildErrorResponse(err, ctx?.config), meta), res);
|
|
6964
|
+
if (onError && ctx) {
|
|
6723
6965
|
try {
|
|
6724
6966
|
await onError(err, ctx);
|
|
6725
6967
|
} catch {
|
|
6726
6968
|
}
|
|
6727
6969
|
}
|
|
6728
6970
|
}
|
|
6729
|
-
async function handleRequest(routes, rootDir, dist, req, res,
|
|
6730
|
-
|
|
6731
|
-
|
|
6732
|
-
routes,
|
|
6733
|
-
method,
|
|
6734
|
-
urlPath,
|
|
6735
|
-
ctx,
|
|
6736
|
-
request,
|
|
6737
|
-
rootDir,
|
|
6738
|
-
dist,
|
|
6739
|
-
globalMiddlewares,
|
|
6740
|
-
globalInjectors
|
|
6741
|
-
});
|
|
6742
|
-
const outerMiddlewares = [];
|
|
6743
|
-
if (configMiddlewares.length > 0) outerMiddlewares.push(...configMiddlewares);
|
|
6744
|
-
if (globalMiddlewares && globalMiddlewares.length > 0) {
|
|
6745
|
-
outerMiddlewares.push(...globalMiddlewares);
|
|
6746
|
-
}
|
|
6971
|
+
async function handleRequest(routes, rootDir, dist, req, res, outerMiddlewares, onError, config, globalInjectors, bodyLimit, trustedProxy) {
|
|
6972
|
+
let meta = { headers: {}, setCookies: [] };
|
|
6973
|
+
let ctx;
|
|
6747
6974
|
try {
|
|
6975
|
+
const prepared = prepareRequest(req, config, bodyLimit, trustedProxy);
|
|
6976
|
+
ctx = prepared.ctx;
|
|
6977
|
+
meta = prepared.meta;
|
|
6978
|
+
const { request, url, method, urlPath } = prepared;
|
|
6979
|
+
const routePipeline = createRoutePipeline({
|
|
6980
|
+
routes,
|
|
6981
|
+
method,
|
|
6982
|
+
urlPath,
|
|
6983
|
+
url,
|
|
6984
|
+
ctx,
|
|
6985
|
+
request,
|
|
6986
|
+
rootDir,
|
|
6987
|
+
dist,
|
|
6988
|
+
globalInjectors
|
|
6989
|
+
});
|
|
6748
6990
|
const response = outerMiddlewares.length > 0 ? await compose(outerMiddlewares, ctx, routePipeline) : await routePipeline();
|
|
6749
6991
|
await sendSuccessResponse(response, res);
|
|
6750
6992
|
} catch (err) {
|
|
@@ -6888,10 +7130,10 @@ var init_skillRegistry = __esm({
|
|
|
6888
7130
|
|
|
6889
7131
|
// src/cli/createAppCore.ts
|
|
6890
7132
|
import fs17 from "fs";
|
|
6891
|
-
import
|
|
7133
|
+
import path20 from "path";
|
|
6892
7134
|
import { PassThrough, Readable as Readable4 } from "stream";
|
|
6893
7135
|
async function loadAndHydrateTools(rootDir, dist) {
|
|
6894
|
-
const toolsPath =
|
|
7136
|
+
const toolsPath = path20.resolve(rootDir, dist, TOOLS_FILE2);
|
|
6895
7137
|
if (!fs17.existsSync(toolsPath)) {
|
|
6896
7138
|
return [];
|
|
6897
7139
|
}
|
|
@@ -6901,7 +7143,7 @@ async function loadAndHydrateTools(rootDir, dist) {
|
|
|
6901
7143
|
return hydrated;
|
|
6902
7144
|
}
|
|
6903
7145
|
async function loadAndHydrateAgents(rootDir, dist) {
|
|
6904
|
-
const agentsPath =
|
|
7146
|
+
const agentsPath = path20.resolve(rootDir, dist, AGENTS_FILE2);
|
|
6905
7147
|
if (!fs17.existsSync(agentsPath)) {
|
|
6906
7148
|
return [];
|
|
6907
7149
|
}
|
|
@@ -6926,7 +7168,7 @@ function isFaapiConfigKey(key) {
|
|
|
6926
7168
|
async function createAppBase(options) {
|
|
6927
7169
|
const rootDir = options?.rootDir ?? process.cwd();
|
|
6928
7170
|
const dist = options?.dist ?? process.env.FAAPI_DIST ?? DEFAULT_DIST;
|
|
6929
|
-
const routesPath =
|
|
7171
|
+
const routesPath = path20.resolve(rootDir, dist, ROUTES_FILE);
|
|
6930
7172
|
if (!fs17.existsSync(routesPath)) {
|
|
6931
7173
|
throw new Error(
|
|
6932
7174
|
`[faapi] ${dist}/${ROUTES_FILE} \u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u6267\u884C \`faapi build\`\uFF08\u6216 \`faapi dev\`\uFF09\u751F\u6210\u4EA7\u7269\u3002`
|
|
@@ -6962,7 +7204,8 @@ async function createAppBase(options) {
|
|
|
6962
7204
|
helmet: config?.helmet,
|
|
6963
7205
|
logger: config?.logger,
|
|
6964
7206
|
bodyLimit: config?.bodyLimit,
|
|
6965
|
-
http2: config?.http2
|
|
7207
|
+
http2: config?.http2,
|
|
7208
|
+
trustedProxy: config?.trustedProxy
|
|
6966
7209
|
});
|
|
6967
7210
|
const { handlerWrappers, upgradeWrappers } = await loadPlugins(config?.plugins, {
|
|
6968
7211
|
rootDir,
|
|
@@ -7181,6 +7424,7 @@ var init_createAppCore = __esm({
|
|
|
7181
7424
|
"bodyLimit",
|
|
7182
7425
|
"logger",
|
|
7183
7426
|
"http2",
|
|
7427
|
+
"trustedProxy",
|
|
7184
7428
|
"response"
|
|
7185
7429
|
]);
|
|
7186
7430
|
}
|
|
@@ -7253,7 +7497,7 @@ __export(devCommand_exports, {
|
|
|
7253
7497
|
generateRouteArtifacts: () => generateRouteArtifacts,
|
|
7254
7498
|
generateToolArtifactsForDev: () => generateToolArtifactsForDev
|
|
7255
7499
|
});
|
|
7256
|
-
import
|
|
7500
|
+
import path21 from "path";
|
|
7257
7501
|
async function devCommand(options) {
|
|
7258
7502
|
const rootDir = process.cwd();
|
|
7259
7503
|
if (!process.env.NODE_ENV) process.env.NODE_ENV = "development";
|
|
@@ -7280,7 +7524,7 @@ async function devCommand(options) {
|
|
|
7280
7524
|
async function generateRouteArtifacts(rootDir, patterns, dist) {
|
|
7281
7525
|
const { routes, wsRoutes } = await scanRoutes(rootDir, patterns, dist);
|
|
7282
7526
|
const sorted = sortRoutes(routes);
|
|
7283
|
-
const routesPath =
|
|
7527
|
+
const routesPath = path21.resolve(rootDir, dist, ROUTES_FILE2);
|
|
7284
7528
|
const serialized = serializeRoutes(sorted, wsRoutes, rootDir, dist);
|
|
7285
7529
|
await writeRoutesModule(serialized, routesPath);
|
|
7286
7530
|
}
|
|
@@ -7318,7 +7562,7 @@ var init_devCommand = __esm({
|
|
|
7318
7562
|
});
|
|
7319
7563
|
|
|
7320
7564
|
// src/cli/compileBuildRoutes.ts
|
|
7321
|
-
import
|
|
7565
|
+
import path22 from "path";
|
|
7322
7566
|
import fs18 from "fs";
|
|
7323
7567
|
import fg5 from "fast-glob";
|
|
7324
7568
|
async function compileBuildRoutes(options) {
|
|
@@ -7332,11 +7576,11 @@ async function compileBuildRoutes(options) {
|
|
|
7332
7576
|
if (entryPoints.length === 0) {
|
|
7333
7577
|
return { compiledFiles: [] };
|
|
7334
7578
|
}
|
|
7335
|
-
const absDist =
|
|
7579
|
+
const absDist = path22.resolve(rootDir, dist);
|
|
7336
7580
|
await fs18.promises.mkdir(absDist, { recursive: true });
|
|
7337
7581
|
const plugins = buildAliasPlugins(rootDir);
|
|
7338
7582
|
const esbuild = await import("esbuild");
|
|
7339
|
-
const outbase =
|
|
7583
|
+
const outbase = path22.resolve(rootDir, APP_DIR3);
|
|
7340
7584
|
await esbuild.build({
|
|
7341
7585
|
entryPoints,
|
|
7342
7586
|
outdir: absDist,
|
|
@@ -7367,7 +7611,7 @@ var buildCommand_exports = {};
|
|
|
7367
7611
|
__export(buildCommand_exports, {
|
|
7368
7612
|
buildCommand: () => buildCommand
|
|
7369
7613
|
});
|
|
7370
|
-
import
|
|
7614
|
+
import path23 from "path";
|
|
7371
7615
|
import fs19 from "fs";
|
|
7372
7616
|
async function buildCommand(options) {
|
|
7373
7617
|
const rootDir = options?.rootDir ?? process.cwd();
|
|
@@ -7412,9 +7656,9 @@ async function buildCommand(options) {
|
|
|
7412
7656
|
}
|
|
7413
7657
|
console.log("\n[4/8] Generating schema...");
|
|
7414
7658
|
await generateSchemaFiles(sorted, rootDir, outdir);
|
|
7415
|
-
console.log(` Schema: zod.js files under ${
|
|
7659
|
+
console.log(` Schema: zod.js files under ${path23.resolve(rootDir, outdir)}`);
|
|
7416
7660
|
console.log("\n[5/8] Generating routes manifest...");
|
|
7417
|
-
const routesPath =
|
|
7661
|
+
const routesPath = path23.resolve(rootDir, outdir, "faapi-routes.js");
|
|
7418
7662
|
const serialized = serializeRoutes(sorted, wsRoutes, rootDir, outdir);
|
|
7419
7663
|
await writeRoutesModule(serialized, routesPath);
|
|
7420
7664
|
console.log(` Written to ${routesPath}`);
|
|
@@ -7422,14 +7666,14 @@ async function buildCommand(options) {
|
|
|
7422
7666
|
const tools = await scanTools(rootDir, TOOL_PATTERNS);
|
|
7423
7667
|
const toolMeta = await generateToolArtifacts(tools, rootDir, outdir);
|
|
7424
7668
|
console.log(` Found ${toolMeta.length} tool(s)`);
|
|
7425
|
-
console.log(` Tool manifest: ${
|
|
7669
|
+
console.log(` Tool manifest: ${path23.resolve(rootDir, outdir, "faapi-tools.js")}`);
|
|
7426
7670
|
console.log("\n[7/8] Generating agent manifest...");
|
|
7427
7671
|
const agents = await scanAgents(rootDir, DEFAULT_AGENT_PATTERNS);
|
|
7428
7672
|
const agentMeta = await generateAgentArtifacts(agents, rootDir, outdir);
|
|
7429
7673
|
console.log(` Found ${agentMeta.length} agent(s)`);
|
|
7430
|
-
console.log(` Agent manifest: ${
|
|
7674
|
+
console.log(` Agent manifest: ${path23.resolve(rootDir, outdir, "faapi-agents.js")}`);
|
|
7431
7675
|
console.log("\n[8/8] Generating entry file...");
|
|
7432
|
-
const mainPath =
|
|
7676
|
+
const mainPath = path23.resolve(rootDir, outdir, "main.js");
|
|
7433
7677
|
const createProdAppArgs = options?.dist && options.dist !== DEFAULT_DIST2 ? `{ dist: '${outdir}' }` : "";
|
|
7434
7678
|
const mainContent = `// \u7531 faapi build \u81EA\u52A8\u751F\u6210\uFF0C\u8BF7\u52FF\u624B\u52A8\u7F16\u8F91
|
|
7435
7679
|
import { createProdApp, loadEnv } from '@faapi/faapi';
|