@faapi/faapi 3.1.0 → 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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(path23) {
480
- if (!path23) return "";
481
- let result = path23.replace(/\\/g, "/");
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,107 @@ 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 = ts3.createProgram([filePath], {
1024
+ const options = {
976
1025
  strict: true,
977
1026
  target: ts3.ScriptTarget.ES2022,
978
1027
  module: ts3.ModuleKind.NodeNext,
979
1028
  moduleResolution: ts3.ModuleResolutionKind.NodeNext,
980
1029
  skipLibCheck: true,
981
1030
  noEmit: true
982
- });
1031
+ };
1032
+ let rootNames = [filePath];
1033
+ const tsconfigPath = findTsConfig(filePath);
1034
+ if (tsconfigPath) {
1035
+ const tsOptions = parseTsConfig(tsconfigPath);
1036
+ if (tsOptions.module !== void 0) {
1037
+ options.module = tsOptions.module;
1038
+ }
1039
+ if (tsOptions.moduleResolution !== void 0) {
1040
+ options.moduleResolution = tsOptions.moduleResolution;
1041
+ }
1042
+ if (tsOptions.fileNames.length > 0) {
1043
+ if (!tsOptions.fileNames.includes(filePath)) {
1044
+ rootNames = [filePath, ...tsOptions.fileNames];
1045
+ } else {
1046
+ rootNames = tsOptions.fileNames;
1047
+ }
1048
+ }
1049
+ }
1050
+ const program = ts3.createProgram(rootNames, options);
983
1051
  programCache.set(filePath, program);
984
1052
  return program;
985
1053
  }
986
- var programCache;
1054
+ var programCache, tsConfigCache;
987
1055
  var init_createProgram = __esm({
988
1056
  "src/ast/createProgram.ts"() {
989
1057
  "use strict";
990
1058
  programCache = /* @__PURE__ */ new Map();
1059
+ tsConfigCache = /* @__PURE__ */ new Map();
991
1060
  }
992
1061
  });
993
1062
 
994
1063
  // src/ast/resolveTypeNode.ts
995
1064
  import ts4 from "typescript";
1065
+ function setProgramContext(program) {
1066
+ currentProgram = program;
1067
+ }
996
1068
  function resolveTypeNode(typeNode, checker, visited = /* @__PURE__ */ new Set()) {
997
1069
  const kind = typeNode.kind;
998
1070
  switch (kind) {
@@ -1305,11 +1377,69 @@ function resolveTypeReference(typeNode, checker, visited = /* @__PURE__ */ new S
1305
1377
  if (ts4.isEnumDeclaration(declaration)) {
1306
1378
  return resolveEnumDeclaration(declaration);
1307
1379
  }
1380
+ if (ts4.isImportSpecifier(declaration) || ts4.isImportClause(declaration)) {
1381
+ const resolved = resolveImportAlias(typeNode, symbol, checker, visited);
1382
+ if (resolved) return resolved;
1383
+ }
1308
1384
  }
1309
1385
  }
1310
1386
  }
1311
1387
  throw new SchemaExtractionError(typeNode.getText(), `\u65E0\u6CD5\u89E3\u6790\u7684\u5F15\u7528\u7C7B\u578B "${typeName}"`);
1312
1388
  }
1389
+ function resolveImportAlias(typeNode, symbol, checker, visited) {
1390
+ const typeName = typeNode.typeName.getText();
1391
+ try {
1392
+ const aliased = checker.getAliasedSymbol(symbol);
1393
+ if (aliased && aliased.declarations && aliased.declarations.length > 0) {
1394
+ const decl = aliased.declarations[0];
1395
+ if (ts4.isInterfaceDeclaration(decl)) {
1396
+ return resolveInterfaceDeclaration(decl, checker, visited);
1397
+ }
1398
+ if (ts4.isTypeAliasDeclaration(decl)) {
1399
+ return resolveTypeNode(decl.type, checker, visited);
1400
+ }
1401
+ if (ts4.isEnumDeclaration(decl)) {
1402
+ return resolveEnumDeclaration(decl);
1403
+ }
1404
+ }
1405
+ } catch {
1406
+ }
1407
+ const program = currentProgram;
1408
+ if (!program) return null;
1409
+ const allSFs = program.getSourceFiles();
1410
+ for (const sourceFile of allSFs) {
1411
+ if (sourceFile.fileName.includes("/node_modules/") || sourceFile.fileName.includes("typescript/lib/")) {
1412
+ continue;
1413
+ }
1414
+ const found = findTopLevelDecl(sourceFile, typeName);
1415
+ if (found) {
1416
+ if (found.kind === "interface") {
1417
+ return resolveInterfaceDeclaration(found.node, checker, visited);
1418
+ }
1419
+ if (found.kind === "typeAlias") {
1420
+ return resolveTypeNode(found.node.type, checker, visited);
1421
+ }
1422
+ if (found.kind === "enum") {
1423
+ return resolveEnumDeclaration(found.node);
1424
+ }
1425
+ }
1426
+ }
1427
+ return null;
1428
+ }
1429
+ function findTopLevelDecl(sourceFile, typeName) {
1430
+ let found = null;
1431
+ ts4.forEachChild(sourceFile, (node) => {
1432
+ if (found) return;
1433
+ if (ts4.isInterfaceDeclaration(node) && node.name.text === typeName) {
1434
+ found = { kind: "interface", node };
1435
+ } else if (ts4.isTypeAliasDeclaration(node) && node.name.text === typeName) {
1436
+ found = { kind: "typeAlias", node };
1437
+ } else if (ts4.isEnumDeclaration(node) && node.name.text === typeName) {
1438
+ found = { kind: "enum", node };
1439
+ }
1440
+ });
1441
+ return found;
1442
+ }
1313
1443
  function resolveEnumDeclaration(node) {
1314
1444
  const members = [];
1315
1445
  let nextNumericValue = 0;
@@ -1488,10 +1618,11 @@ function validateConstraints(constraints, type, fieldName) {
1488
1618
  }
1489
1619
  }
1490
1620
  }
1491
- var SchemaExtractionError, NUMBER_CONSTRAINT_KINDS, LENGTH_CONSTRAINT_KINDS, STRING_FORMAT_CONSTRAINT_KINDS;
1621
+ var currentProgram, SchemaExtractionError, NUMBER_CONSTRAINT_KINDS, LENGTH_CONSTRAINT_KINDS, STRING_FORMAT_CONSTRAINT_KINDS;
1492
1622
  var init_resolveTypeNode = __esm({
1493
1623
  "src/ast/resolveTypeNode.ts"() {
1494
1624
  "use strict";
1625
+ currentProgram = null;
1495
1626
  SchemaExtractionError = class extends Error {
1496
1627
  constructor(typeText, reason, options) {
1497
1628
  super(`\u65E0\u6CD5\u89E3\u6790\u7C7B\u578B "${typeText}": ${reason}`, options);
@@ -1531,80 +1662,90 @@ function extractTypeInfo(program, filePath, typeName) {
1531
1662
  const sourceFile = program.getSourceFile(filePath);
1532
1663
  if (!sourceFile) return null;
1533
1664
  const checker = program.getTypeChecker();
1534
- let result = null;
1535
- ts5.forEachChild(sourceFile, (node) => {
1536
- if (result) return;
1537
- if (ts5.isInterfaceDeclaration(node) && node.name.text === typeName) {
1538
- const visited = /* @__PURE__ */ new Set();
1539
- visited.add(typeName);
1540
- const runtimeType = withFileContext(
1541
- filePath,
1542
- typeName,
1543
- () => resolveInterfaceDeclaration(node, checker, visited)
1544
- );
1545
- result = {
1546
- name: typeName,
1547
- properties: runtimeType.kind === "object" ? runtimeType.properties : [],
1548
- runtimeType
1549
- };
1550
- return;
1551
- }
1552
- if (ts5.isTypeAliasDeclaration(node) && node.name.text === typeName) {
1553
- const visited = /* @__PURE__ */ new Set();
1554
- visited.add(typeName);
1555
- const runtimeType = withFileContext(
1556
- filePath,
1557
- typeName,
1558
- () => resolveTypeNode(node.type, checker, visited)
1559
- );
1560
- result = {
1561
- name: typeName,
1562
- properties: runtimeType.kind === "object" ? runtimeType.properties : [],
1563
- runtimeType
1564
- };
1565
- return;
1566
- }
1567
- });
1568
- return result;
1665
+ setProgramContext(program);
1666
+ try {
1667
+ let result = null;
1668
+ ts5.forEachChild(sourceFile, (node) => {
1669
+ if (result) return;
1670
+ if (ts5.isInterfaceDeclaration(node) && node.name.text === typeName) {
1671
+ const visited = /* @__PURE__ */ new Set();
1672
+ visited.add(typeName);
1673
+ const runtimeType = withFileContext(
1674
+ filePath,
1675
+ typeName,
1676
+ () => resolveInterfaceDeclaration(node, checker, visited)
1677
+ );
1678
+ result = {
1679
+ name: typeName,
1680
+ properties: runtimeType.kind === "object" ? runtimeType.properties : [],
1681
+ runtimeType
1682
+ };
1683
+ return;
1684
+ }
1685
+ if (ts5.isTypeAliasDeclaration(node) && node.name.text === typeName) {
1686
+ const visited = /* @__PURE__ */ new Set();
1687
+ visited.add(typeName);
1688
+ const runtimeType = withFileContext(
1689
+ filePath,
1690
+ typeName,
1691
+ () => resolveTypeNode(node.type, checker, visited)
1692
+ );
1693
+ result = {
1694
+ name: typeName,
1695
+ properties: runtimeType.kind === "object" ? runtimeType.properties : [],
1696
+ runtimeType
1697
+ };
1698
+ return;
1699
+ }
1700
+ });
1701
+ return result;
1702
+ } finally {
1703
+ setProgramContext(null);
1704
+ }
1569
1705
  }
1570
1706
  function extractAllTypes(program, filePath) {
1571
1707
  const sourceFile = program.getSourceFile(filePath);
1572
1708
  if (!sourceFile) return /* @__PURE__ */ new Map();
1573
1709
  const checker = program.getTypeChecker();
1574
- const result = /* @__PURE__ */ new Map();
1575
- ts5.forEachChild(sourceFile, (node) => {
1576
- if (ts5.isInterfaceDeclaration(node)) {
1577
- const visited = /* @__PURE__ */ new Set();
1578
- visited.add(node.name.text);
1579
- const runtimeType = withFileContext(
1580
- filePath,
1581
- node.name.text,
1582
- () => resolveInterfaceDeclaration(node, checker, visited)
1583
- );
1584
- result.set(node.name.text, {
1585
- name: node.name.text,
1586
- properties: runtimeType.kind === "object" ? runtimeType.properties : [],
1587
- runtimeType
1588
- });
1589
- return;
1590
- }
1591
- if (ts5.isTypeAliasDeclaration(node)) {
1592
- const visited = /* @__PURE__ */ new Set();
1593
- visited.add(node.name.text);
1594
- const runtimeType = withFileContext(
1595
- filePath,
1596
- node.name.text,
1597
- () => resolveTypeNode(node.type, checker, visited)
1598
- );
1599
- result.set(node.name.text, {
1600
- name: node.name.text,
1601
- properties: runtimeType.kind === "object" ? runtimeType.properties : [],
1602
- runtimeType
1603
- });
1604
- return;
1605
- }
1606
- });
1607
- return result;
1710
+ setProgramContext(program);
1711
+ try {
1712
+ const result = /* @__PURE__ */ new Map();
1713
+ ts5.forEachChild(sourceFile, (node) => {
1714
+ if (ts5.isInterfaceDeclaration(node)) {
1715
+ const visited = /* @__PURE__ */ new Set();
1716
+ visited.add(node.name.text);
1717
+ const runtimeType = withFileContext(
1718
+ filePath,
1719
+ node.name.text,
1720
+ () => resolveInterfaceDeclaration(node, checker, visited)
1721
+ );
1722
+ result.set(node.name.text, {
1723
+ name: node.name.text,
1724
+ properties: runtimeType.kind === "object" ? runtimeType.properties : [],
1725
+ runtimeType
1726
+ });
1727
+ return;
1728
+ }
1729
+ if (ts5.isTypeAliasDeclaration(node)) {
1730
+ const visited = /* @__PURE__ */ new Set();
1731
+ visited.add(node.name.text);
1732
+ const runtimeType = withFileContext(
1733
+ filePath,
1734
+ node.name.text,
1735
+ () => resolveTypeNode(node.type, checker, visited)
1736
+ );
1737
+ result.set(node.name.text, {
1738
+ name: node.name.text,
1739
+ properties: runtimeType.kind === "object" ? runtimeType.properties : [],
1740
+ runtimeType
1741
+ });
1742
+ return;
1743
+ }
1744
+ });
1745
+ return result;
1746
+ } finally {
1747
+ setProgramContext(null);
1748
+ }
1608
1749
  }
1609
1750
  function withFileContext(filePath, typeName, fn) {
1610
1751
  try {
@@ -2110,11 +2251,11 @@ var init_analyzeInjection = __esm({
2110
2251
  });
2111
2252
 
2112
2253
  // src/cli/collectRouteSchemaSources.ts
2113
- import path7 from "path";
2254
+ import path8 from "path";
2114
2255
  function collectRouteSchemaSources(routes, rootDir) {
2115
2256
  const methodsByFile = /* @__PURE__ */ new Map();
2116
2257
  for (const route of routes) {
2117
- const filePath = rootDir ? path7.resolve(rootDir, route.filePath) : route.filePath;
2258
+ const filePath = rootDir ? path8.resolve(rootDir, route.filePath) : route.filePath;
2118
2259
  let entry = methodsByFile.get(filePath);
2119
2260
  if (!entry) {
2120
2261
  entry = { urlPath: route.urlPath, methods: /* @__PURE__ */ new Set() };
@@ -2177,8 +2318,8 @@ __export(generateSchemaFiles_exports, {
2177
2318
  getRuntimeSchemaPath: () => getRuntimeSchemaPath,
2178
2319
  getSchemaOutputPath: () => getSchemaOutputPath
2179
2320
  });
2180
- import path8 from "path";
2181
- import fs7 from "fs/promises";
2321
+ import path9 from "path";
2322
+ import fs8 from "fs/promises";
2182
2323
  function getSchemaOutputPath(sourceFile, dist, rootDir) {
2183
2324
  let rel = sourceFile.replace(/\\/g, "/");
2184
2325
  if (rel.startsWith("src/")) {
@@ -2186,7 +2327,7 @@ function getSchemaOutputPath(sourceFile, dist, rootDir) {
2186
2327
  }
2187
2328
  const idx = rel.lastIndexOf("/");
2188
2329
  const relDir = idx >= 0 ? rel.slice(0, idx) : "";
2189
- return path8.resolve(rootDir, dist, relDir, "zod.js");
2330
+ return path9.resolve(rootDir, dist, relDir, "zod.js");
2190
2331
  }
2191
2332
  function getRuntimeSchemaPath(filePath, dist, rootDir) {
2192
2333
  let rel = filePath.replace(/\\/g, "/");
@@ -2197,7 +2338,7 @@ function getRuntimeSchemaPath(filePath, dist, rootDir) {
2197
2338
  }
2198
2339
  const idx = rel.lastIndexOf("/");
2199
2340
  const relDir = idx >= 0 ? rel.slice(0, idx) : "";
2200
- return path8.resolve(rootDir, dist, relDir, "zod.js");
2341
+ return path9.resolve(rootDir, dist, relDir, "zod.js");
2201
2342
  }
2202
2343
  function getHelpersImportPath(relDir) {
2203
2344
  if (!relDir) return `./${HELPERS_FILENAME}`;
@@ -2247,7 +2388,7 @@ async function generateSchemaFiles(routes, rootDir, dist) {
2247
2388
  }
2248
2389
  const fileEntries = [];
2249
2390
  for (const [filePath, fileSources] of sourcesByFile) {
2250
- const relFile = path8.relative(rootDir, filePath).replace(/\\/g, "/");
2391
+ const relFile = path9.relative(rootDir, filePath).replace(/\\/g, "/");
2251
2392
  const outputPath = getSchemaOutputPath(relFile, dist, rootDir);
2252
2393
  const allTypes = allTypesByFile.get(filePath) ?? /* @__PURE__ */ new Map();
2253
2394
  let relForDir = relFile;
@@ -2262,7 +2403,7 @@ async function generateSchemaFiles(routes, rootDir, dist) {
2262
2403
  }
2263
2404
  const allSourceCode = fileEntries.map((e) => e.source).join("\n");
2264
2405
  if (usesCoerceHelpers(allSourceCode)) {
2265
- const helpersPath = path8.resolve(rootDir, dist, HELPERS_FILENAME);
2406
+ const helpersPath = path9.resolve(rootDir, dist, HELPERS_FILENAME);
2266
2407
  await writeSchemaFile(helpersPath, generateHelpersFileSource());
2267
2408
  }
2268
2409
  await Promise.all(
@@ -2270,8 +2411,8 @@ async function generateSchemaFiles(routes, rootDir, dist) {
2270
2411
  );
2271
2412
  }
2272
2413
  async function writeSchemaFile(outputPath, source) {
2273
- await fs7.mkdir(path8.dirname(outputPath), { recursive: true });
2274
- await fs7.writeFile(outputPath, source, "utf-8");
2414
+ await fs8.mkdir(path9.dirname(outputPath), { recursive: true });
2415
+ await fs8.writeFile(outputPath, source, "utf-8");
2275
2416
  }
2276
2417
  var init_generateSchemaFiles = __esm({
2277
2418
  "src/cli/generateSchemaFiles.ts"() {
@@ -2282,8 +2423,8 @@ var init_generateSchemaFiles = __esm({
2282
2423
  });
2283
2424
 
2284
2425
  // src/cli/generateToolArtifacts.ts
2285
- import path9 from "path";
2286
- import fs8 from "fs/promises";
2426
+ import path10 from "path";
2427
+ import fs9 from "fs/promises";
2287
2428
  import { existsSync } from "fs";
2288
2429
  function getToolSchemaOutputPath(sourceFile, dist, rootDir) {
2289
2430
  let rel = sourceFile.replace(/\\/g, "/");
@@ -2292,7 +2433,7 @@ function getToolSchemaOutputPath(sourceFile, dist, rootDir) {
2292
2433
  }
2293
2434
  const idx = rel.lastIndexOf("/");
2294
2435
  const relDir = idx >= 0 ? rel.slice(0, idx) : "";
2295
- return path9.resolve(rootDir, dist, relDir, "zod.js");
2436
+ return path10.resolve(rootDir, dist, relDir, "zod.js");
2296
2437
  }
2297
2438
  function toProdFilePath3(filePath, dist) {
2298
2439
  let rel = filePath.replace(/\\/g, "/");
@@ -2312,12 +2453,12 @@ function serializeTools(tools, dist = "dist") {
2312
2453
  }));
2313
2454
  }
2314
2455
  async function writeToolsModule(manifest, outputPath) {
2315
- const dir = path9.dirname(outputPath);
2316
- await fs8.mkdir(dir, { recursive: true });
2456
+ const dir = path10.dirname(outputPath);
2457
+ await fs9.mkdir(dir, { recursive: true });
2317
2458
  const content = `// \u81EA\u52A8\u751F\u6210,\u8BF7\u52FF\u624B\u52A8\u7F16\u8F91(faapi build/dev \u4EA7\u7269)
2318
2459
  export const tools = ${JSON.stringify(manifest, null, 2)};
2319
2460
  `;
2320
- await fs8.writeFile(outputPath, content, "utf-8");
2461
+ await fs9.writeFile(outputPath, content, "utf-8");
2321
2462
  }
2322
2463
  function hydrateTools(manifest) {
2323
2464
  return manifest.map((t) => ({
@@ -2332,7 +2473,7 @@ function collectToolSchemaSources(tools, rootDir) {
2332
2473
  const toolsByFile = /* @__PURE__ */ new Map();
2333
2474
  for (const tool of tools) {
2334
2475
  if (!tool.inputTypeName) continue;
2335
- const absPath = path9.resolve(rootDir, tool.filePath);
2476
+ const absPath = path10.resolve(rootDir, tool.filePath);
2336
2477
  let list = toolsByFile.get(absPath);
2337
2478
  if (!list) {
2338
2479
  list = [];
@@ -2394,15 +2535,15 @@ function generateToolSchemaFileSource(sources, allTypes, helpersImportPath) {
2394
2535
  }
2395
2536
  async function maybeGenerateHelpers(allSourceCode, distDir) {
2396
2537
  if (!usesCoerceHelpers(allSourceCode)) return;
2397
- const helpersPath = path9.resolve(distDir, HELPERS_FILENAME);
2538
+ const helpersPath = path10.resolve(distDir, HELPERS_FILENAME);
2398
2539
  if (existsSync(helpersPath)) return;
2399
- await fs8.mkdir(path9.dirname(helpersPath), { recursive: true });
2400
- await fs8.writeFile(helpersPath, generateHelpersFileSource(), "utf-8");
2540
+ await fs9.mkdir(path10.dirname(helpersPath), { recursive: true });
2541
+ await fs9.writeFile(helpersPath, generateHelpersFileSource(), "utf-8");
2401
2542
  }
2402
2543
  async function generateToolArtifacts(tools, rootDir, dist, options) {
2403
2544
  const metadata = [];
2404
2545
  for (const manifest of tools) {
2405
- const absPath = path9.resolve(rootDir, manifest.filePath);
2546
+ const absPath = path10.resolve(rootDir, manifest.filePath);
2406
2547
  const program = createProgram(absPath);
2407
2548
  const result = extractToolMetadata(program, absPath, manifest.functionName, {
2408
2549
  name: manifest.name,
@@ -2413,7 +2554,7 @@ async function generateToolArtifacts(tools, rootDir, dist, options) {
2413
2554
  }
2414
2555
  }
2415
2556
  const serialized = serializeTools(metadata, dist);
2416
- const toolsPath = path9.resolve(rootDir, dist, TOOLS_FILE);
2557
+ const toolsPath = path10.resolve(rootDir, dist, TOOLS_FILE);
2417
2558
  await writeToolsModule(serialized, toolsPath);
2418
2559
  if (options?.skipSchema) {
2419
2560
  return metadata;
@@ -2436,7 +2577,7 @@ async function generateToolArtifacts(tools, rootDir, dist, options) {
2436
2577
  }
2437
2578
  const fileEntries = [];
2438
2579
  for (const [filePath, fileSources] of sourcesByFile) {
2439
- const relFile = path9.relative(rootDir, filePath).replace(/\\/g, "/");
2580
+ const relFile = path10.relative(rootDir, filePath).replace(/\\/g, "/");
2440
2581
  const outputPath = getToolSchemaOutputPath(relFile, dist, rootDir);
2441
2582
  const allTypes = allTypesByFile.get(filePath) ?? /* @__PURE__ */ new Map();
2442
2583
  let relForDir = relFile;
@@ -2450,7 +2591,7 @@ async function generateToolArtifacts(tools, rootDir, dist, options) {
2450
2591
  fileEntries.push({ outputPath, source });
2451
2592
  }
2452
2593
  const allSourceCode = fileEntries.map((e) => e.source).join("\n");
2453
- const distDir = path9.resolve(rootDir, dist);
2594
+ const distDir = path10.resolve(rootDir, dist);
2454
2595
  await maybeGenerateHelpers(allSourceCode, distDir);
2455
2596
  await Promise.all(
2456
2597
  fileEntries.map(({ outputPath, source }) => writeToolSchemaFile(outputPath, source))
@@ -2458,8 +2599,8 @@ async function generateToolArtifacts(tools, rootDir, dist, options) {
2458
2599
  return metadata;
2459
2600
  }
2460
2601
  async function writeToolSchemaFile(outputPath, source) {
2461
- await fs8.mkdir(path9.dirname(outputPath), { recursive: true });
2462
- await fs8.writeFile(outputPath, source, "utf-8");
2602
+ await fs9.mkdir(path10.dirname(outputPath), { recursive: true });
2603
+ await fs9.writeFile(outputPath, source, "utf-8");
2463
2604
  }
2464
2605
  var TOOLS_FILE;
2465
2606
  var init_generateToolArtifacts = __esm({
@@ -2476,8 +2617,8 @@ var init_generateToolArtifacts = __esm({
2476
2617
 
2477
2618
  // src/agents/scanAgents.ts
2478
2619
  import fg3 from "fast-glob";
2479
- import path10 from "path";
2480
- import fs9 from "fs";
2620
+ import path11 from "path";
2621
+ import fs10 from "fs";
2481
2622
  function extractAgentNameFromPath(filePath) {
2482
2623
  const normalized = filePath.replace(/\\/g, "/");
2483
2624
  const match = normalized.match(/(?:^|\/)agents\/([^/]+)\/handler\.ts$/);
@@ -2507,8 +2648,8 @@ async function scanAgents(rootDir, patterns) {
2507
2648
  if (fileName !== "handler.ts" && fileName !== "handler.js") {
2508
2649
  continue;
2509
2650
  }
2510
- const absPath = path10.resolve(rootDir, normalizedFile);
2511
- const source = await fs9.promises.readFile(absPath, "utf8").catch(() => "");
2651
+ const absPath = path11.resolve(rootDir, normalizedFile);
2652
+ const source = await fs10.promises.readFile(absPath, "utf8").catch(() => "");
2512
2653
  const { hasRun } = detectAgentExports(source);
2513
2654
  const name = extractAgentNameFromPath(normalizedFile);
2514
2655
  const prevFile = seen.get(name);
@@ -2728,8 +2869,8 @@ var init_extractAgentMetadata = __esm({
2728
2869
  });
2729
2870
 
2730
2871
  // src/cli/generateAgentArtifacts.ts
2731
- import path11 from "path";
2732
- import fs10 from "fs/promises";
2872
+ import path12 from "path";
2873
+ import fs11 from "fs/promises";
2733
2874
  function toProdFilePath4(filePath, dist) {
2734
2875
  let rel = filePath.replace(/\\/g, "/");
2735
2876
  if (rel.startsWith("src/")) {
@@ -2752,12 +2893,12 @@ function serializeAgents(agents, dist = "dist") {
2752
2893
  }));
2753
2894
  }
2754
2895
  async function writeAgentsModule(manifest, outputPath) {
2755
- const dir = path11.dirname(outputPath);
2756
- await fs10.mkdir(dir, { recursive: true });
2896
+ const dir = path12.dirname(outputPath);
2897
+ await fs11.mkdir(dir, { recursive: true });
2757
2898
  const content = `// \u81EA\u52A8\u751F\u6210,\u8BF7\u52FF\u624B\u52A8\u7F16\u8F91(faapi build/dev \u4EA7\u7269)
2758
2899
  export const agents = ${JSON.stringify(manifest, null, 2)};
2759
2900
  `;
2760
- await fs10.writeFile(outputPath, content, "utf-8");
2901
+ await fs11.writeFile(outputPath, content, "utf-8");
2761
2902
  }
2762
2903
  function hydrateAgents(manifest) {
2763
2904
  return manifest.map((a) => ({
@@ -2775,7 +2916,7 @@ function hydrateAgents(manifest) {
2775
2916
  async function generateAgentArtifacts(agents, rootDir, dist) {
2776
2917
  const metadata = [];
2777
2918
  for (const manifest of agents) {
2778
- const absPath = path11.resolve(rootDir, manifest.filePath);
2919
+ const absPath = path12.resolve(rootDir, manifest.filePath);
2779
2920
  const program = createProgram(absPath);
2780
2921
  const result = extractAgentMetadata(program, absPath, {
2781
2922
  name: manifest.name,
@@ -2787,7 +2928,7 @@ async function generateAgentArtifacts(agents, rootDir, dist) {
2787
2928
  }
2788
2929
  }
2789
2930
  const serialized = serializeAgents(metadata, dist);
2790
- const agentsPath = path11.resolve(rootDir, dist, AGENTS_FILE);
2931
+ const agentsPath = path12.resolve(rootDir, dist, AGENTS_FILE);
2791
2932
  await writeAgentsModule(serialized, agentsPath);
2792
2933
  return metadata;
2793
2934
  }
@@ -2802,15 +2943,15 @@ var init_generateAgentArtifacts = __esm({
2802
2943
  });
2803
2944
 
2804
2945
  // src/config/loadConfig.ts
2805
- import path12 from "path";
2806
- import fs11 from "fs";
2946
+ import path13 from "path";
2947
+ import fs12 from "fs";
2807
2948
  async function loadConfig(rootDir, dist) {
2808
- const configProductPath = path12.resolve(rootDir, dist, CONFIG_PRODUCT_FILE);
2809
- if (fs11.existsSync(configProductPath)) {
2949
+ const configProductPath = path13.resolve(rootDir, dist, CONFIG_PRODUCT_FILE);
2950
+ if (fs12.existsSync(configProductPath)) {
2810
2951
  const module = await importWithCacheBust(configProductPath);
2811
2952
  return module.default ?? {};
2812
2953
  }
2813
- const hasSourceConfig = fs11.existsSync(path12.join(rootDir, "faapi.config.ts")) || fs11.existsSync(path12.join(rootDir, "faapi.config.js"));
2954
+ const hasSourceConfig = fs12.existsSync(path13.join(rootDir, "faapi.config.ts")) || fs12.existsSync(path13.join(rootDir, "faapi.config.js"));
2814
2955
  if (hasSourceConfig) {
2815
2956
  throw new Error(
2816
2957
  `[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 +2969,8 @@ var init_loadConfig = __esm({
2828
2969
  });
2829
2970
 
2830
2971
  // src/cli/loadEnv.ts
2831
- import fs12 from "fs";
2832
- import path13 from "path";
2972
+ import fs13 from "fs";
2973
+ import path14 from "path";
2833
2974
  function resolveEnv() {
2834
2975
  return process.env.NODE_ENV || "development";
2835
2976
  }
@@ -2895,9 +3036,9 @@ function loadEnv(rootDir) {
2895
3036
  const files = getEnvFiles(env);
2896
3037
  const merged = {};
2897
3038
  for (const file of files) {
2898
- const filePath = path13.join(rootDir, file);
2899
- if (!fs12.existsSync(filePath)) continue;
2900
- const content = fs12.readFileSync(filePath, "utf-8");
3039
+ const filePath = path14.join(rootDir, file);
3040
+ if (!fs13.existsSync(filePath)) continue;
3041
+ const content = fs13.readFileSync(filePath, "utf-8");
2901
3042
  const parsed = parseEnvFile(content, merged);
2902
3043
  Object.assign(merged, parsed);
2903
3044
  }
@@ -3003,7 +3144,7 @@ var init_esm = __esm({
3003
3144
  this._directoryFilter = normalizeFilter(opts.directoryFilter);
3004
3145
  const statMethod = opts.lstat ? lstat : stat;
3005
3146
  if (wantBigintFsStats) {
3006
- this._stat = (path23) => statMethod(path23, { bigint: true });
3147
+ this._stat = (path24) => statMethod(path24, { bigint: true });
3007
3148
  } else {
3008
3149
  this._stat = statMethod;
3009
3150
  }
@@ -3028,8 +3169,8 @@ var init_esm = __esm({
3028
3169
  const par = this.parent;
3029
3170
  const fil = par && par.files;
3030
3171
  if (fil && fil.length > 0) {
3031
- const { path: path23, depth } = par;
3032
- const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path23));
3172
+ const { path: path24, depth } = par;
3173
+ const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path24));
3033
3174
  const awaited = await Promise.all(slice);
3034
3175
  for (const entry of awaited) {
3035
3176
  if (!entry)
@@ -3069,20 +3210,20 @@ var init_esm = __esm({
3069
3210
  this.reading = false;
3070
3211
  }
3071
3212
  }
3072
- async _exploreDir(path23, depth) {
3213
+ async _exploreDir(path24, depth) {
3073
3214
  let files;
3074
3215
  try {
3075
- files = await readdir(path23, this._rdOptions);
3216
+ files = await readdir(path24, this._rdOptions);
3076
3217
  } catch (error) {
3077
3218
  this._onError(error);
3078
3219
  }
3079
- return { files, depth, path: path23 };
3220
+ return { files, depth, path: path24 };
3080
3221
  }
3081
- async _formatEntry(dirent, path23) {
3222
+ async _formatEntry(dirent, path24) {
3082
3223
  let entry;
3083
3224
  const basename3 = this._isDirent ? dirent.name : dirent;
3084
3225
  try {
3085
- const fullPath = presolve(pjoin(path23, basename3));
3226
+ const fullPath = presolve(pjoin(path24, basename3));
3086
3227
  entry = { path: prelative(this._root, fullPath), fullPath, basename: basename3 };
3087
3228
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
3088
3229
  } catch (err) {
@@ -3143,16 +3284,16 @@ import { watchFile, unwatchFile, watch as fs_watch } from "fs";
3143
3284
  import { open, stat as stat2, lstat as lstat2, realpath as fsrealpath } from "fs/promises";
3144
3285
  import * as sysPath from "path";
3145
3286
  import { type as osType } from "os";
3146
- function createFsWatchInstance(path23, options, listener, errHandler, emitRaw) {
3287
+ function createFsWatchInstance(path24, options, listener, errHandler, emitRaw) {
3147
3288
  const handleEvent = (rawEvent, evPath) => {
3148
- listener(path23);
3149
- emitRaw(rawEvent, evPath, { watchedPath: path23 });
3150
- if (evPath && path23 !== evPath) {
3151
- fsWatchBroadcast(sysPath.resolve(path23, evPath), KEY_LISTENERS, sysPath.join(path23, evPath));
3289
+ listener(path24);
3290
+ emitRaw(rawEvent, evPath, { watchedPath: path24 });
3291
+ if (evPath && path24 !== evPath) {
3292
+ fsWatchBroadcast(sysPath.resolve(path24, evPath), KEY_LISTENERS, sysPath.join(path24, evPath));
3152
3293
  }
3153
3294
  };
3154
3295
  try {
3155
- return fs_watch(path23, {
3296
+ return fs_watch(path24, {
3156
3297
  persistent: options.persistent
3157
3298
  }, handleEvent);
3158
3299
  } catch (error) {
@@ -3497,12 +3638,12 @@ var init_handler = __esm({
3497
3638
  listener(val1, val2, val3);
3498
3639
  });
3499
3640
  };
3500
- setFsWatchListener = (path23, fullPath, options, handlers) => {
3641
+ setFsWatchListener = (path24, fullPath, options, handlers) => {
3501
3642
  const { listener, errHandler, rawEmitter } = handlers;
3502
3643
  let cont = FsWatchInstances.get(fullPath);
3503
3644
  let watcher;
3504
3645
  if (!options.persistent) {
3505
- watcher = createFsWatchInstance(path23, options, listener, errHandler, rawEmitter);
3646
+ watcher = createFsWatchInstance(path24, options, listener, errHandler, rawEmitter);
3506
3647
  if (!watcher)
3507
3648
  return;
3508
3649
  return watcher.close.bind(watcher);
@@ -3513,7 +3654,7 @@ var init_handler = __esm({
3513
3654
  addAndConvert(cont, KEY_RAW, rawEmitter);
3514
3655
  } else {
3515
3656
  watcher = createFsWatchInstance(
3516
- path23,
3657
+ path24,
3517
3658
  options,
3518
3659
  fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
3519
3660
  errHandler,
@@ -3528,7 +3669,7 @@ var init_handler = __esm({
3528
3669
  cont.watcherUnusable = true;
3529
3670
  if (isWindows && error.code === "EPERM") {
3530
3671
  try {
3531
- const fd = await open(path23, "r");
3672
+ const fd = await open(path24, "r");
3532
3673
  await fd.close();
3533
3674
  broadcastErr(error);
3534
3675
  } catch (err) {
@@ -3559,7 +3700,7 @@ var init_handler = __esm({
3559
3700
  };
3560
3701
  };
3561
3702
  FsWatchFileInstances = /* @__PURE__ */ new Map();
3562
- setFsWatchFileListener = (path23, fullPath, options, handlers) => {
3703
+ setFsWatchFileListener = (path24, fullPath, options, handlers) => {
3563
3704
  const { listener, rawEmitter } = handlers;
3564
3705
  let cont = FsWatchFileInstances.get(fullPath);
3565
3706
  const copts = cont && cont.options;
@@ -3581,7 +3722,7 @@ var init_handler = __esm({
3581
3722
  });
3582
3723
  const currmtime = curr.mtimeMs;
3583
3724
  if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
3584
- foreach(cont.listeners, (listener2) => listener2(path23, curr));
3725
+ foreach(cont.listeners, (listener2) => listener2(path24, curr));
3585
3726
  }
3586
3727
  })
3587
3728
  };
@@ -3609,13 +3750,13 @@ var init_handler = __esm({
3609
3750
  * @param listener on fs change
3610
3751
  * @returns closer for the watcher instance
3611
3752
  */
3612
- _watchWithNodeFs(path23, listener) {
3753
+ _watchWithNodeFs(path24, listener) {
3613
3754
  const opts = this.fsw.options;
3614
- const directory = sysPath.dirname(path23);
3615
- const basename3 = sysPath.basename(path23);
3755
+ const directory = sysPath.dirname(path24);
3756
+ const basename3 = sysPath.basename(path24);
3616
3757
  const parent = this.fsw._getWatchedDir(directory);
3617
3758
  parent.add(basename3);
3618
- const absolutePath = sysPath.resolve(path23);
3759
+ const absolutePath = sysPath.resolve(path24);
3619
3760
  const options = {
3620
3761
  persistent: opts.persistent
3621
3762
  };
@@ -3625,12 +3766,12 @@ var init_handler = __esm({
3625
3766
  if (opts.usePolling) {
3626
3767
  const enableBin = opts.interval !== opts.binaryInterval;
3627
3768
  options.interval = enableBin && isBinaryPath(basename3) ? opts.binaryInterval : opts.interval;
3628
- closer = setFsWatchFileListener(path23, absolutePath, options, {
3769
+ closer = setFsWatchFileListener(path24, absolutePath, options, {
3629
3770
  listener,
3630
3771
  rawEmitter: this.fsw._emitRaw
3631
3772
  });
3632
3773
  } else {
3633
- closer = setFsWatchListener(path23, absolutePath, options, {
3774
+ closer = setFsWatchListener(path24, absolutePath, options, {
3634
3775
  listener,
3635
3776
  errHandler: this._boundHandleError,
3636
3777
  rawEmitter: this.fsw._emitRaw
@@ -3652,7 +3793,7 @@ var init_handler = __esm({
3652
3793
  let prevStats = stats;
3653
3794
  if (parent.has(basename3))
3654
3795
  return;
3655
- const listener = async (path23, newStats) => {
3796
+ const listener = async (path24, newStats) => {
3656
3797
  if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
3657
3798
  return;
3658
3799
  if (!newStats || newStats.mtimeMs === 0) {
@@ -3666,11 +3807,11 @@ var init_handler = __esm({
3666
3807
  this.fsw._emit(EV.CHANGE, file, newStats2);
3667
3808
  }
3668
3809
  if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
3669
- this.fsw._closeFile(path23);
3810
+ this.fsw._closeFile(path24);
3670
3811
  prevStats = newStats2;
3671
3812
  const closer2 = this._watchWithNodeFs(file, listener);
3672
3813
  if (closer2)
3673
- this.fsw._addPathCloser(path23, closer2);
3814
+ this.fsw._addPathCloser(path24, closer2);
3674
3815
  } else {
3675
3816
  prevStats = newStats2;
3676
3817
  }
@@ -3702,7 +3843,7 @@ var init_handler = __esm({
3702
3843
  * @param item basename of this item
3703
3844
  * @returns true if no more processing is needed for this entry.
3704
3845
  */
3705
- async _handleSymlink(entry, directory, path23, item) {
3846
+ async _handleSymlink(entry, directory, path24, item) {
3706
3847
  if (this.fsw.closed) {
3707
3848
  return;
3708
3849
  }
@@ -3712,7 +3853,7 @@ var init_handler = __esm({
3712
3853
  this.fsw._incrReadyCount();
3713
3854
  let linkPath;
3714
3855
  try {
3715
- linkPath = await fsrealpath(path23);
3856
+ linkPath = await fsrealpath(path24);
3716
3857
  } catch (e) {
3717
3858
  this.fsw._emitReady();
3718
3859
  return true;
@@ -3722,12 +3863,12 @@ var init_handler = __esm({
3722
3863
  if (dir.has(item)) {
3723
3864
  if (this.fsw._symlinkPaths.get(full) !== linkPath) {
3724
3865
  this.fsw._symlinkPaths.set(full, linkPath);
3725
- this.fsw._emit(EV.CHANGE, path23, entry.stats);
3866
+ this.fsw._emit(EV.CHANGE, path24, entry.stats);
3726
3867
  }
3727
3868
  } else {
3728
3869
  dir.add(item);
3729
3870
  this.fsw._symlinkPaths.set(full, linkPath);
3730
- this.fsw._emit(EV.ADD, path23, entry.stats);
3871
+ this.fsw._emit(EV.ADD, path24, entry.stats);
3731
3872
  }
3732
3873
  this.fsw._emitReady();
3733
3874
  return true;
@@ -3756,9 +3897,9 @@ var init_handler = __esm({
3756
3897
  return;
3757
3898
  }
3758
3899
  const item = entry.path;
3759
- let path23 = sysPath.join(directory, item);
3900
+ let path24 = sysPath.join(directory, item);
3760
3901
  current.add(item);
3761
- if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path23, item)) {
3902
+ if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path24, item)) {
3762
3903
  return;
3763
3904
  }
3764
3905
  if (this.fsw.closed) {
@@ -3767,8 +3908,8 @@ var init_handler = __esm({
3767
3908
  }
3768
3909
  if (item === target || !target && !previous.has(item)) {
3769
3910
  this.fsw._incrReadyCount();
3770
- path23 = sysPath.join(dir, sysPath.relative(dir, path23));
3771
- this._addToNodeFs(path23, initialAdd, wh, depth + 1);
3911
+ path24 = sysPath.join(dir, sysPath.relative(dir, path24));
3912
+ this._addToNodeFs(path24, initialAdd, wh, depth + 1);
3772
3913
  }
3773
3914
  }).on(EV.ERROR, this._boundHandleError);
3774
3915
  return new Promise((resolve3, reject) => {
@@ -3837,13 +3978,13 @@ var init_handler = __esm({
3837
3978
  * @param depth Child path actually targeted for watch
3838
3979
  * @param target Child path actually targeted for watch
3839
3980
  */
3840
- async _addToNodeFs(path23, initialAdd, priorWh, depth, target) {
3981
+ async _addToNodeFs(path24, initialAdd, priorWh, depth, target) {
3841
3982
  const ready = this.fsw._emitReady;
3842
- if (this.fsw._isIgnored(path23) || this.fsw.closed) {
3983
+ if (this.fsw._isIgnored(path24) || this.fsw.closed) {
3843
3984
  ready();
3844
3985
  return false;
3845
3986
  }
3846
- const wh = this.fsw._getWatchHelpers(path23);
3987
+ const wh = this.fsw._getWatchHelpers(path24);
3847
3988
  if (priorWh) {
3848
3989
  wh.filterPath = (entry) => priorWh.filterPath(entry);
3849
3990
  wh.filterDir = (entry) => priorWh.filterDir(entry);
@@ -3859,8 +4000,8 @@ var init_handler = __esm({
3859
4000
  const follow = this.fsw.options.followSymlinks;
3860
4001
  let closer;
3861
4002
  if (stats.isDirectory()) {
3862
- const absPath = sysPath.resolve(path23);
3863
- const targetPath = follow ? await fsrealpath(path23) : path23;
4003
+ const absPath = sysPath.resolve(path24);
4004
+ const targetPath = follow ? await fsrealpath(path24) : path24;
3864
4005
  if (this.fsw.closed)
3865
4006
  return;
3866
4007
  closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
@@ -3870,29 +4011,29 @@ var init_handler = __esm({
3870
4011
  this.fsw._symlinkPaths.set(absPath, targetPath);
3871
4012
  }
3872
4013
  } else if (stats.isSymbolicLink()) {
3873
- const targetPath = follow ? await fsrealpath(path23) : path23;
4014
+ const targetPath = follow ? await fsrealpath(path24) : path24;
3874
4015
  if (this.fsw.closed)
3875
4016
  return;
3876
4017
  const parent = sysPath.dirname(wh.watchPath);
3877
4018
  this.fsw._getWatchedDir(parent).add(wh.watchPath);
3878
4019
  this.fsw._emit(EV.ADD, wh.watchPath, stats);
3879
- closer = await this._handleDir(parent, stats, initialAdd, depth, path23, wh, targetPath);
4020
+ closer = await this._handleDir(parent, stats, initialAdd, depth, path24, wh, targetPath);
3880
4021
  if (this.fsw.closed)
3881
4022
  return;
3882
4023
  if (targetPath !== void 0) {
3883
- this.fsw._symlinkPaths.set(sysPath.resolve(path23), targetPath);
4024
+ this.fsw._symlinkPaths.set(sysPath.resolve(path24), targetPath);
3884
4025
  }
3885
4026
  } else {
3886
4027
  closer = this._handleFile(wh.watchPath, stats, initialAdd);
3887
4028
  }
3888
4029
  ready();
3889
4030
  if (closer)
3890
- this.fsw._addPathCloser(path23, closer);
4031
+ this.fsw._addPathCloser(path24, closer);
3891
4032
  return false;
3892
4033
  } catch (error) {
3893
4034
  if (this.fsw._handleError(error)) {
3894
4035
  ready();
3895
- return path23;
4036
+ return path24;
3896
4037
  }
3897
4038
  }
3898
4039
  }
@@ -3931,26 +4072,26 @@ function createPattern(matcher) {
3931
4072
  }
3932
4073
  return () => false;
3933
4074
  }
3934
- function normalizePath2(path23) {
3935
- if (typeof path23 !== "string")
4075
+ function normalizePath2(path24) {
4076
+ if (typeof path24 !== "string")
3936
4077
  throw new Error("string expected");
3937
- path23 = sysPath2.normalize(path23);
3938
- path23 = path23.replace(/\\/g, "/");
4078
+ path24 = sysPath2.normalize(path24);
4079
+ path24 = path24.replace(/\\/g, "/");
3939
4080
  let prepend = false;
3940
- if (path23.startsWith("//"))
4081
+ if (path24.startsWith("//"))
3941
4082
  prepend = true;
3942
4083
  const DOUBLE_SLASH_RE2 = /\/\//;
3943
- while (path23.match(DOUBLE_SLASH_RE2))
3944
- path23 = path23.replace(DOUBLE_SLASH_RE2, "/");
4084
+ while (path24.match(DOUBLE_SLASH_RE2))
4085
+ path24 = path24.replace(DOUBLE_SLASH_RE2, "/");
3945
4086
  if (prepend)
3946
- path23 = "/" + path23;
3947
- return path23;
4087
+ path24 = "/" + path24;
4088
+ return path24;
3948
4089
  }
3949
4090
  function matchPatterns(patterns, testString, stats) {
3950
- const path23 = normalizePath2(testString);
4091
+ const path24 = normalizePath2(testString);
3951
4092
  for (let index = 0; index < patterns.length; index++) {
3952
4093
  const pattern = patterns[index];
3953
- if (pattern(path23, stats)) {
4094
+ if (pattern(path24, stats)) {
3954
4095
  return true;
3955
4096
  }
3956
4097
  }
@@ -4011,19 +4152,19 @@ var init_esm2 = __esm({
4011
4152
  }
4012
4153
  return str;
4013
4154
  };
4014
- normalizePathToUnix = (path23) => toUnix(sysPath2.normalize(toUnix(path23)));
4015
- normalizeIgnored = (cwd = "") => (path23) => {
4016
- if (typeof path23 === "string") {
4017
- return normalizePathToUnix(sysPath2.isAbsolute(path23) ? path23 : sysPath2.join(cwd, path23));
4155
+ normalizePathToUnix = (path24) => toUnix(sysPath2.normalize(toUnix(path24)));
4156
+ normalizeIgnored = (cwd = "") => (path24) => {
4157
+ if (typeof path24 === "string") {
4158
+ return normalizePathToUnix(sysPath2.isAbsolute(path24) ? path24 : sysPath2.join(cwd, path24));
4018
4159
  } else {
4019
- return path23;
4160
+ return path24;
4020
4161
  }
4021
4162
  };
4022
- getAbsolutePath = (path23, cwd) => {
4023
- if (sysPath2.isAbsolute(path23)) {
4024
- return path23;
4163
+ getAbsolutePath = (path24, cwd) => {
4164
+ if (sysPath2.isAbsolute(path24)) {
4165
+ return path24;
4025
4166
  }
4026
- return sysPath2.join(cwd, path23);
4167
+ return sysPath2.join(cwd, path24);
4027
4168
  };
4028
4169
  EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
4029
4170
  DirEntry = class {
@@ -4078,10 +4219,10 @@ var init_esm2 = __esm({
4078
4219
  STAT_METHOD_F = "stat";
4079
4220
  STAT_METHOD_L = "lstat";
4080
4221
  WatchHelper = class {
4081
- constructor(path23, follow, fsw) {
4222
+ constructor(path24, follow, fsw) {
4082
4223
  this.fsw = fsw;
4083
- const watchPath = path23;
4084
- this.path = path23 = path23.replace(REPLACER_RE, "");
4224
+ const watchPath = path24;
4225
+ this.path = path24 = path24.replace(REPLACER_RE, "");
4085
4226
  this.watchPath = watchPath;
4086
4227
  this.fullWatchPath = sysPath2.resolve(watchPath);
4087
4228
  this.dirParts = [];
@@ -4203,20 +4344,20 @@ var init_esm2 = __esm({
4203
4344
  this._closePromise = void 0;
4204
4345
  let paths = unifyPaths(paths_);
4205
4346
  if (cwd) {
4206
- paths = paths.map((path23) => {
4207
- const absPath = getAbsolutePath(path23, cwd);
4347
+ paths = paths.map((path24) => {
4348
+ const absPath = getAbsolutePath(path24, cwd);
4208
4349
  return absPath;
4209
4350
  });
4210
4351
  }
4211
- paths.forEach((path23) => {
4212
- this._removeIgnoredPath(path23);
4352
+ paths.forEach((path24) => {
4353
+ this._removeIgnoredPath(path24);
4213
4354
  });
4214
4355
  this._userIgnored = void 0;
4215
4356
  if (!this._readyCount)
4216
4357
  this._readyCount = 0;
4217
4358
  this._readyCount += paths.length;
4218
- Promise.all(paths.map(async (path23) => {
4219
- const res = await this._nodeFsHandler._addToNodeFs(path23, !_internal, void 0, 0, _origAdd);
4359
+ Promise.all(paths.map(async (path24) => {
4360
+ const res = await this._nodeFsHandler._addToNodeFs(path24, !_internal, void 0, 0, _origAdd);
4220
4361
  if (res)
4221
4362
  this._emitReady();
4222
4363
  return res;
@@ -4238,17 +4379,17 @@ var init_esm2 = __esm({
4238
4379
  return this;
4239
4380
  const paths = unifyPaths(paths_);
4240
4381
  const { cwd } = this.options;
4241
- paths.forEach((path23) => {
4242
- if (!sysPath2.isAbsolute(path23) && !this._closers.has(path23)) {
4382
+ paths.forEach((path24) => {
4383
+ if (!sysPath2.isAbsolute(path24) && !this._closers.has(path24)) {
4243
4384
  if (cwd)
4244
- path23 = sysPath2.join(cwd, path23);
4245
- path23 = sysPath2.resolve(path23);
4385
+ path24 = sysPath2.join(cwd, path24);
4386
+ path24 = sysPath2.resolve(path24);
4246
4387
  }
4247
- this._closePath(path23);
4248
- this._addIgnoredPath(path23);
4249
- if (this._watched.has(path23)) {
4388
+ this._closePath(path24);
4389
+ this._addIgnoredPath(path24);
4390
+ if (this._watched.has(path24)) {
4250
4391
  this._addIgnoredPath({
4251
- path: path23,
4392
+ path: path24,
4252
4393
  recursive: true
4253
4394
  });
4254
4395
  }
@@ -4312,38 +4453,38 @@ var init_esm2 = __esm({
4312
4453
  * @param stats arguments to be passed with event
4313
4454
  * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
4314
4455
  */
4315
- async _emit(event, path23, stats) {
4456
+ async _emit(event, path24, stats) {
4316
4457
  if (this.closed)
4317
4458
  return;
4318
4459
  const opts = this.options;
4319
4460
  if (isWindows)
4320
- path23 = sysPath2.normalize(path23);
4461
+ path24 = sysPath2.normalize(path24);
4321
4462
  if (opts.cwd)
4322
- path23 = sysPath2.relative(opts.cwd, path23);
4323
- const args = [path23];
4463
+ path24 = sysPath2.relative(opts.cwd, path24);
4464
+ const args = [path24];
4324
4465
  if (stats != null)
4325
4466
  args.push(stats);
4326
4467
  const awf = opts.awaitWriteFinish;
4327
4468
  let pw;
4328
- if (awf && (pw = this._pendingWrites.get(path23))) {
4469
+ if (awf && (pw = this._pendingWrites.get(path24))) {
4329
4470
  pw.lastChange = /* @__PURE__ */ new Date();
4330
4471
  return this;
4331
4472
  }
4332
4473
  if (opts.atomic) {
4333
4474
  if (event === EVENTS.UNLINK) {
4334
- this._pendingUnlinks.set(path23, [event, ...args]);
4475
+ this._pendingUnlinks.set(path24, [event, ...args]);
4335
4476
  setTimeout(() => {
4336
- this._pendingUnlinks.forEach((entry, path24) => {
4477
+ this._pendingUnlinks.forEach((entry, path25) => {
4337
4478
  this.emit(...entry);
4338
4479
  this.emit(EVENTS.ALL, ...entry);
4339
- this._pendingUnlinks.delete(path24);
4480
+ this._pendingUnlinks.delete(path25);
4340
4481
  });
4341
4482
  }, typeof opts.atomic === "number" ? opts.atomic : 100);
4342
4483
  return this;
4343
4484
  }
4344
- if (event === EVENTS.ADD && this._pendingUnlinks.has(path23)) {
4485
+ if (event === EVENTS.ADD && this._pendingUnlinks.has(path24)) {
4345
4486
  event = EVENTS.CHANGE;
4346
- this._pendingUnlinks.delete(path23);
4487
+ this._pendingUnlinks.delete(path24);
4347
4488
  }
4348
4489
  }
4349
4490
  if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
@@ -4361,16 +4502,16 @@ var init_esm2 = __esm({
4361
4502
  this.emitWithAll(event, args);
4362
4503
  }
4363
4504
  };
4364
- this._awaitWriteFinish(path23, awf.stabilityThreshold, event, awfEmit);
4505
+ this._awaitWriteFinish(path24, awf.stabilityThreshold, event, awfEmit);
4365
4506
  return this;
4366
4507
  }
4367
4508
  if (event === EVENTS.CHANGE) {
4368
- const isThrottled = !this._throttle(EVENTS.CHANGE, path23, 50);
4509
+ const isThrottled = !this._throttle(EVENTS.CHANGE, path24, 50);
4369
4510
  if (isThrottled)
4370
4511
  return this;
4371
4512
  }
4372
4513
  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, path23) : path23;
4514
+ const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path24) : path24;
4374
4515
  let stats2;
4375
4516
  try {
4376
4517
  stats2 = await stat3(fullPath);
@@ -4401,23 +4542,23 @@ var init_esm2 = __esm({
4401
4542
  * @param timeout duration of time to suppress duplicate actions
4402
4543
  * @returns tracking object or false if action should be suppressed
4403
4544
  */
4404
- _throttle(actionType, path23, timeout) {
4545
+ _throttle(actionType, path24, timeout) {
4405
4546
  if (!this._throttled.has(actionType)) {
4406
4547
  this._throttled.set(actionType, /* @__PURE__ */ new Map());
4407
4548
  }
4408
4549
  const action = this._throttled.get(actionType);
4409
4550
  if (!action)
4410
4551
  throw new Error("invalid throttle");
4411
- const actionPath = action.get(path23);
4552
+ const actionPath = action.get(path24);
4412
4553
  if (actionPath) {
4413
4554
  actionPath.count++;
4414
4555
  return false;
4415
4556
  }
4416
4557
  let timeoutObject;
4417
4558
  const clear = () => {
4418
- const item = action.get(path23);
4559
+ const item = action.get(path24);
4419
4560
  const count = item ? item.count : 0;
4420
- action.delete(path23);
4561
+ action.delete(path24);
4421
4562
  clearTimeout(timeoutObject);
4422
4563
  if (item)
4423
4564
  clearTimeout(item.timeoutObject);
@@ -4425,7 +4566,7 @@ var init_esm2 = __esm({
4425
4566
  };
4426
4567
  timeoutObject = setTimeout(clear, timeout);
4427
4568
  const thr = { timeoutObject, clear, count: 0 };
4428
- action.set(path23, thr);
4569
+ action.set(path24, thr);
4429
4570
  return thr;
4430
4571
  }
4431
4572
  _incrReadyCount() {
@@ -4439,44 +4580,44 @@ var init_esm2 = __esm({
4439
4580
  * @param event
4440
4581
  * @param awfEmit Callback to be called when ready for event to be emitted.
4441
4582
  */
4442
- _awaitWriteFinish(path23, threshold, event, awfEmit) {
4583
+ _awaitWriteFinish(path24, threshold, event, awfEmit) {
4443
4584
  const awf = this.options.awaitWriteFinish;
4444
4585
  if (typeof awf !== "object")
4445
4586
  return;
4446
4587
  const pollInterval = awf.pollInterval;
4447
4588
  let timeoutHandler;
4448
- let fullPath = path23;
4449
- if (this.options.cwd && !sysPath2.isAbsolute(path23)) {
4450
- fullPath = sysPath2.join(this.options.cwd, path23);
4589
+ let fullPath = path24;
4590
+ if (this.options.cwd && !sysPath2.isAbsolute(path24)) {
4591
+ fullPath = sysPath2.join(this.options.cwd, path24);
4451
4592
  }
4452
4593
  const now = /* @__PURE__ */ new Date();
4453
4594
  const writes = this._pendingWrites;
4454
4595
  function awaitWriteFinishFn(prevStat) {
4455
4596
  statcb(fullPath, (err, curStat) => {
4456
- if (err || !writes.has(path23)) {
4597
+ if (err || !writes.has(path24)) {
4457
4598
  if (err && err.code !== "ENOENT")
4458
4599
  awfEmit(err);
4459
4600
  return;
4460
4601
  }
4461
4602
  const now2 = Number(/* @__PURE__ */ new Date());
4462
4603
  if (prevStat && curStat.size !== prevStat.size) {
4463
- writes.get(path23).lastChange = now2;
4604
+ writes.get(path24).lastChange = now2;
4464
4605
  }
4465
- const pw = writes.get(path23);
4606
+ const pw = writes.get(path24);
4466
4607
  const df = now2 - pw.lastChange;
4467
4608
  if (df >= threshold) {
4468
- writes.delete(path23);
4609
+ writes.delete(path24);
4469
4610
  awfEmit(void 0, curStat);
4470
4611
  } else {
4471
4612
  timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
4472
4613
  }
4473
4614
  });
4474
4615
  }
4475
- if (!writes.has(path23)) {
4476
- writes.set(path23, {
4616
+ if (!writes.has(path24)) {
4617
+ writes.set(path24, {
4477
4618
  lastChange: now,
4478
4619
  cancelWait: () => {
4479
- writes.delete(path23);
4620
+ writes.delete(path24);
4480
4621
  clearTimeout(timeoutHandler);
4481
4622
  return event;
4482
4623
  }
@@ -4487,8 +4628,8 @@ var init_esm2 = __esm({
4487
4628
  /**
4488
4629
  * Determines whether user has asked to ignore this path.
4489
4630
  */
4490
- _isIgnored(path23, stats) {
4491
- if (this.options.atomic && DOT_RE.test(path23))
4631
+ _isIgnored(path24, stats) {
4632
+ if (this.options.atomic && DOT_RE.test(path24))
4492
4633
  return true;
4493
4634
  if (!this._userIgnored) {
4494
4635
  const { cwd } = this.options;
@@ -4498,17 +4639,17 @@ var init_esm2 = __esm({
4498
4639
  const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
4499
4640
  this._userIgnored = anymatch(list, void 0);
4500
4641
  }
4501
- return this._userIgnored(path23, stats);
4642
+ return this._userIgnored(path24, stats);
4502
4643
  }
4503
- _isntIgnored(path23, stat4) {
4504
- return !this._isIgnored(path23, stat4);
4644
+ _isntIgnored(path24, stat4) {
4645
+ return !this._isIgnored(path24, stat4);
4505
4646
  }
4506
4647
  /**
4507
4648
  * Provides a set of common helpers and properties relating to symlink handling.
4508
4649
  * @param path file or directory pattern being watched
4509
4650
  */
4510
- _getWatchHelpers(path23) {
4511
- return new WatchHelper(path23, this.options.followSymlinks, this);
4651
+ _getWatchHelpers(path24) {
4652
+ return new WatchHelper(path24, this.options.followSymlinks, this);
4512
4653
  }
4513
4654
  // Directory helpers
4514
4655
  // -----------------
@@ -4540,63 +4681,63 @@ var init_esm2 = __esm({
4540
4681
  * @param item base path of item/directory
4541
4682
  */
4542
4683
  _remove(directory, item, isDirectory) {
4543
- const path23 = sysPath2.join(directory, item);
4544
- const fullPath = sysPath2.resolve(path23);
4545
- isDirectory = isDirectory != null ? isDirectory : this._watched.has(path23) || this._watched.has(fullPath);
4546
- if (!this._throttle("remove", path23, 100))
4684
+ const path24 = sysPath2.join(directory, item);
4685
+ const fullPath = sysPath2.resolve(path24);
4686
+ isDirectory = isDirectory != null ? isDirectory : this._watched.has(path24) || this._watched.has(fullPath);
4687
+ if (!this._throttle("remove", path24, 100))
4547
4688
  return;
4548
4689
  if (!isDirectory && this._watched.size === 1) {
4549
4690
  this.add(directory, item, true);
4550
4691
  }
4551
- const wp = this._getWatchedDir(path23);
4692
+ const wp = this._getWatchedDir(path24);
4552
4693
  const nestedDirectoryChildren = wp.getChildren();
4553
- nestedDirectoryChildren.forEach((nested) => this._remove(path23, nested));
4694
+ nestedDirectoryChildren.forEach((nested) => this._remove(path24, nested));
4554
4695
  const parent = this._getWatchedDir(directory);
4555
4696
  const wasTracked = parent.has(item);
4556
4697
  parent.remove(item);
4557
4698
  if (this._symlinkPaths.has(fullPath)) {
4558
4699
  this._symlinkPaths.delete(fullPath);
4559
4700
  }
4560
- let relPath = path23;
4701
+ let relPath = path24;
4561
4702
  if (this.options.cwd)
4562
- relPath = sysPath2.relative(this.options.cwd, path23);
4703
+ relPath = sysPath2.relative(this.options.cwd, path24);
4563
4704
  if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
4564
4705
  const event = this._pendingWrites.get(relPath).cancelWait();
4565
4706
  if (event === EVENTS.ADD)
4566
4707
  return;
4567
4708
  }
4568
- this._watched.delete(path23);
4709
+ this._watched.delete(path24);
4569
4710
  this._watched.delete(fullPath);
4570
4711
  const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
4571
- if (wasTracked && !this._isIgnored(path23))
4572
- this._emit(eventName, path23);
4573
- this._closePath(path23);
4712
+ if (wasTracked && !this._isIgnored(path24))
4713
+ this._emit(eventName, path24);
4714
+ this._closePath(path24);
4574
4715
  }
4575
4716
  /**
4576
4717
  * Closes all watchers for a path
4577
4718
  */
4578
- _closePath(path23) {
4579
- this._closeFile(path23);
4580
- const dir = sysPath2.dirname(path23);
4581
- this._getWatchedDir(dir).remove(sysPath2.basename(path23));
4719
+ _closePath(path24) {
4720
+ this._closeFile(path24);
4721
+ const dir = sysPath2.dirname(path24);
4722
+ this._getWatchedDir(dir).remove(sysPath2.basename(path24));
4582
4723
  }
4583
4724
  /**
4584
4725
  * Closes only file-specific watchers
4585
4726
  */
4586
- _closeFile(path23) {
4587
- const closers = this._closers.get(path23);
4727
+ _closeFile(path24) {
4728
+ const closers = this._closers.get(path24);
4588
4729
  if (!closers)
4589
4730
  return;
4590
4731
  closers.forEach((closer) => closer());
4591
- this._closers.delete(path23);
4732
+ this._closers.delete(path24);
4592
4733
  }
4593
- _addPathCloser(path23, closer) {
4734
+ _addPathCloser(path24, closer) {
4594
4735
  if (!closer)
4595
4736
  return;
4596
- let list = this._closers.get(path23);
4737
+ let list = this._closers.get(path24);
4597
4738
  if (!list) {
4598
4739
  list = [];
4599
- this._closers.set(path23, list);
4740
+ this._closers.set(path24, list);
4600
4741
  }
4601
4742
  list.push(closer);
4602
4743
  }
@@ -4623,8 +4764,8 @@ var init_esm2 = __esm({
4623
4764
  });
4624
4765
 
4625
4766
  // src/cli/compileDevRoutes.ts
4626
- import path14 from "path";
4627
- import fs13 from "fs";
4767
+ import path15 from "path";
4768
+ import fs14 from "fs";
4628
4769
  import fg4 from "fast-glob";
4629
4770
  async function compileDevRoutes(options) {
4630
4771
  const { rootDir, dist, files, logLevel = "silent" } = options;
@@ -4637,11 +4778,11 @@ async function compileDevRoutes(options) {
4637
4778
  if (entryPoints.length === 0) {
4638
4779
  return { compiledFiles: [] };
4639
4780
  }
4640
- const absDist = path14.resolve(rootDir, dist);
4641
- await fs13.promises.mkdir(absDist, { recursive: true });
4781
+ const absDist = path15.resolve(rootDir, dist);
4782
+ await fs14.promises.mkdir(absDist, { recursive: true });
4642
4783
  const plugins = buildAliasPlugins(rootDir);
4643
4784
  const esbuild = await import("esbuild");
4644
- const outbase = path14.resolve(rootDir, APP_DIR2);
4785
+ const outbase = path15.resolve(rootDir, APP_DIR2);
4645
4786
  const result = await esbuild.build({
4646
4787
  entryPoints,
4647
4788
  outdir: absDist,
@@ -4658,10 +4799,10 @@ async function compileDevRoutes(options) {
4658
4799
  if (result.outputFiles) {
4659
4800
  await Promise.all(
4660
4801
  result.outputFiles.map(async (file) => {
4661
- await fs13.promises.mkdir(path14.dirname(file.path), { recursive: true });
4802
+ await fs14.promises.mkdir(path15.dirname(file.path), { recursive: true });
4662
4803
  const tmp = `${file.path}.tmp-${process.pid}-${Math.random().toString(36).slice(2)}`;
4663
- await fs13.promises.writeFile(tmp, file.contents);
4664
- await fs13.promises.rename(tmp, file.path);
4804
+ await fs14.promises.writeFile(tmp, file.contents);
4805
+ await fs14.promises.rename(tmp, file.path);
4665
4806
  })
4666
4807
  );
4667
4808
  }
@@ -4677,7 +4818,7 @@ var init_compileDevRoutes = __esm({
4677
4818
  });
4678
4819
 
4679
4820
  // src/cli/watcher.ts
4680
- import path15 from "path";
4821
+ import path16 from "path";
4681
4822
  function startWatcher(options) {
4682
4823
  const { rootDir, app, devDist } = options;
4683
4824
  let rebuildTimer = null;
@@ -4727,11 +4868,11 @@ function startWatcher(options) {
4727
4868
  }
4728
4869
  });
4729
4870
  watcher.on("add", (file) => {
4730
- pendingFiles.add(path15.resolve(rootDir, file));
4871
+ pendingFiles.add(path16.resolve(rootDir, file));
4731
4872
  scheduleRebuild();
4732
4873
  });
4733
4874
  watcher.on("change", (file) => {
4734
- pendingFiles.add(path15.resolve(rootDir, file));
4875
+ pendingFiles.add(path16.resolve(rootDir, file));
4735
4876
  scheduleRebuild();
4736
4877
  });
4737
4878
  watcher.on("unlink", () => {
@@ -4788,42 +4929,42 @@ var init_detectRouteConflicts = __esm({
4788
4929
  });
4789
4930
 
4790
4931
  // src/router/matchRoute.ts
4791
- function matchRoute(routes, method, path23) {
4932
+ function matchRoute(routes, method, path24) {
4792
4933
  for (const route of routes) {
4793
4934
  if (route.method !== method) {
4794
4935
  continue;
4795
4936
  }
4796
4937
  if (!route.isDynamic) {
4797
- if (route.urlPath === path23) {
4938
+ if (route.urlPath === path24) {
4798
4939
  return { route, params: {} };
4799
4940
  }
4800
4941
  continue;
4801
4942
  }
4802
- const params = matchDynamicPath(route.urlPath, path23, route.paramNames, route.isCatchAll);
4943
+ const params = matchDynamicPath(route.urlPath, path24, route.paramNames, route.isCatchAll);
4803
4944
  if (params !== null) {
4804
4945
  return { route, params };
4805
4946
  }
4806
4947
  }
4807
4948
  return null;
4808
4949
  }
4809
- function matchWsRoute(wsRoutes, path23) {
4950
+ function matchWsRoute(wsRoutes, path24) {
4810
4951
  for (const route of wsRoutes) {
4811
4952
  if (!route.isDynamic) {
4812
- if (route.urlPath === path23) {
4953
+ if (route.urlPath === path24) {
4813
4954
  return { route, params: {} };
4814
4955
  }
4815
4956
  continue;
4816
4957
  }
4817
- const params = matchDynamicPath(route.urlPath, path23, route.paramNames, route.isCatchAll);
4958
+ const params = matchDynamicPath(route.urlPath, path24, route.paramNames, route.isCatchAll);
4818
4959
  if (params !== null) {
4819
4960
  return { route, params };
4820
4961
  }
4821
4962
  }
4822
4963
  return null;
4823
4964
  }
4824
- function matchDynamicPath(pattern, path23, paramNames, isCatchAll) {
4965
+ function matchDynamicPath(pattern, path24, paramNames, isCatchAll) {
4825
4966
  const patternSegments = pattern.split("/").filter(Boolean);
4826
- const pathSegments = path23.split("/").filter(Boolean);
4967
+ const pathSegments = path24.split("/").filter(Boolean);
4827
4968
  if (isCatchAll) {
4828
4969
  const nonCatchAllCount = patternSegments.length - 1;
4829
4970
  if (pathSegments.length <= nonCatchAllCount) {
@@ -4908,12 +5049,12 @@ var init_validateRouteModule = __esm({
4908
5049
  });
4909
5050
 
4910
5051
  // src/cli/compileOnDemand.ts
4911
- import path16 from "path";
4912
- import fs14 from "fs";
5052
+ import path17 from "path";
5053
+ import fs15 from "fs";
4913
5054
  function isProductFresh(sourceAbsPath, productAbsPath) {
4914
5055
  try {
4915
- const srcStat = fs14.statSync(sourceAbsPath);
4916
- const prodStat = fs14.statSync(productAbsPath);
5056
+ const srcStat = fs15.statSync(sourceAbsPath);
5057
+ const prodStat = fs15.statSync(productAbsPath);
4917
5058
  return prodStat.mtimeMs >= srcStat.mtimeMs;
4918
5059
  } catch {
4919
5060
  return false;
@@ -4943,7 +5084,7 @@ async function ensureCompiled(sourceAbsPath, rootDir, dist) {
4943
5084
  if (state.compiledFiles.has(sourceAbsPath)) {
4944
5085
  return false;
4945
5086
  }
4946
- if (!fs14.existsSync(sourceAbsPath)) {
5087
+ if (!fs15.existsSync(sourceAbsPath)) {
4947
5088
  return false;
4948
5089
  }
4949
5090
  const productPath = prodSourcePathToProductPath(sourceAbsPath, rootDir, dist);
@@ -4969,11 +5110,11 @@ async function ensureCompiled(sourceAbsPath, rootDir, dist) {
4969
5110
  }
4970
5111
  }
4971
5112
  function prodSourcePathToProductPath(sourceAbsPath, rootDir, dist) {
4972
- const rel = path16.relative(rootDir, sourceAbsPath).replace(/\\/g, "/");
5113
+ const rel = path17.relative(rootDir, sourceAbsPath).replace(/\\/g, "/");
4973
5114
  if (!rel.startsWith("src/")) return null;
4974
5115
  const relWithoutSrc = rel.slice(4);
4975
5116
  const jsRel = relWithoutSrc.replace(/\.ts$/, ".js");
4976
- return path16.resolve(rootDir, dist, jsRel);
5117
+ return path17.resolve(rootDir, dist, jsRel);
4977
5118
  }
4978
5119
  function clearGeneratedSchemas() {
4979
5120
  state.generatedSchemas.clear();
@@ -4989,9 +5130,9 @@ async function ensureSchemaGenerated(schemaPath, routeFilePath, routes, rootDir,
4989
5130
  if (state.generatedSchemas.has(schemaPath)) {
4990
5131
  return false;
4991
5132
  }
4992
- const prodAbsPath = path16.resolve(rootDir, routeFilePath);
5133
+ const prodAbsPath = path17.resolve(rootDir, routeFilePath);
4993
5134
  const sourceAbsPath = prodPathToSourcePath(prodAbsPath, rootDir, dist);
4994
- if (!fs14.existsSync(sourceAbsPath)) {
5135
+ if (!fs15.existsSync(sourceAbsPath)) {
4995
5136
  return false;
4996
5137
  }
4997
5138
  if (isProductFresh(sourceAbsPath, schemaPath)) {
@@ -5002,7 +5143,7 @@ async function ensureSchemaGenerated(schemaPath, routeFilePath, routes, rootDir,
5002
5143
  if (fileRoutes.length === 0) {
5003
5144
  return false;
5004
5145
  }
5005
- const sourceRelPath = path16.relative(rootDir, sourceAbsPath).replace(/\\/g, "/");
5146
+ const sourceRelPath = path17.relative(rootDir, sourceAbsPath).replace(/\\/g, "/");
5006
5147
  const sourceRoutes = fileRoutes.map((r) => ({ ...r, filePath: sourceRelPath }));
5007
5148
  const generatePromise = (async () => {
5008
5149
  await generateSchemaFiles(sourceRoutes, rootDir, dist);
@@ -5023,22 +5164,22 @@ async function deleteSchemaFiles(routes, rootDir, dist) {
5023
5164
  if (deleted.has(schemaPath)) continue;
5024
5165
  deleted.add(schemaPath);
5025
5166
  try {
5026
- await fs14.promises.unlink(schemaPath);
5167
+ await fs15.promises.unlink(schemaPath);
5027
5168
  } catch {
5028
5169
  }
5029
5170
  }
5030
5171
  }
5031
5172
  function prodPathToSourcePath(prodAbsPath, rootDir, dist) {
5032
- const rel = path16.relative(rootDir, prodAbsPath).replace(/\\/g, "/");
5173
+ const rel = path17.relative(rootDir, prodAbsPath).replace(/\\/g, "/");
5033
5174
  let relWithoutDist = rel;
5034
5175
  if (relWithoutDist.startsWith(`${dist}/`)) {
5035
5176
  relWithoutDist = relWithoutDist.slice(dist.length + 1);
5036
5177
  }
5037
5178
  const srcRel = `src/${relWithoutDist}`;
5038
5179
  const tsRel = srcRel.replace(/\.js$/, ".ts");
5039
- const tsAbs = path16.resolve(rootDir, tsRel);
5040
- if (fs14.existsSync(tsAbs)) return tsAbs;
5041
- return path16.resolve(rootDir, srcRel);
5180
+ const tsAbs = path17.resolve(rootDir, tsRel);
5181
+ if (fs15.existsSync(tsAbs)) return tsAbs;
5182
+ return path17.resolve(rootDir, srcRel);
5042
5183
  }
5043
5184
  function setDevOnDemandEnabled(enabled) {
5044
5185
  state.enabled = enabled;
@@ -5064,13 +5205,13 @@ var init_compileOnDemand = __esm({
5064
5205
  });
5065
5206
 
5066
5207
  // src/loader/loadRouteModule.ts
5067
- import fs15 from "fs";
5208
+ import fs16 from "fs";
5068
5209
  async function loadRouteModule(filePath, method, rootDir) {
5069
5210
  if (isDevOnDemandEnabled() && rootDir) {
5070
5211
  const dist = getDevDist();
5071
5212
  if (dist) {
5072
5213
  const sourcePath = prodPathToSourcePath(filePath, rootDir, dist);
5073
- if (sourcePath && fs15.existsSync(sourcePath)) {
5214
+ if (sourcePath && fs16.existsSync(sourcePath)) {
5074
5215
  try {
5075
5216
  await ensureCompiled(sourcePath, rootDir, dist);
5076
5217
  } catch (compileErr) {
@@ -5250,14 +5391,14 @@ var init_httpErrors = __esm({
5250
5391
  issues;
5251
5392
  };
5252
5393
  RouteNotFoundError = class extends FaapiError {
5253
- constructor(path23) {
5254
- super("ROUTE_NOT_FOUND", `Route not found: ${path23}`, 404);
5394
+ constructor(path24) {
5395
+ super("ROUTE_NOT_FOUND", `Route not found: ${path24}`, 404);
5255
5396
  this.name = "RouteNotFoundError";
5256
5397
  }
5257
5398
  };
5258
5399
  MethodNotAllowedError = class extends FaapiError {
5259
- constructor(method, path23, allowedMethods) {
5260
- super("METHOD_NOT_ALLOWED", `Method ${method} not allowed for ${path23}`, 405);
5400
+ constructor(method, path24, allowedMethods) {
5401
+ super("METHOD_NOT_ALLOWED", `Method ${method} not allowed for ${path24}`, 405);
5261
5402
  this.allowedMethods = allowedMethods;
5262
5403
  this.name = "MethodNotAllowedError";
5263
5404
  }
@@ -5752,44 +5893,27 @@ var init_toolRegistry = __esm({
5752
5893
  }
5753
5894
  });
5754
5895
 
5755
- // src/injection/skillRegistry.ts
5756
- function clearSkillRegistry() {
5757
- registry2 = /* @__PURE__ */ new Map();
5758
- }
5759
- function listSkills() {
5760
- return Array.from(registry2.values());
5761
- }
5762
- var registry2;
5763
- var init_skillRegistry = __esm({
5764
- "src/injection/skillRegistry.ts"() {
5765
- "use strict";
5766
- registry2 = /* @__PURE__ */ new Map();
5767
- }
5768
- });
5769
-
5770
5896
  // src/injection/agentRegistry.ts
5771
5897
  function hydrateAgentRegistry(agents) {
5772
5898
  const next = /* @__PURE__ */ new Map();
5773
5899
  for (const agent of agents) {
5774
5900
  next.set(agent.name, agent);
5775
5901
  }
5776
- registry3 = next;
5902
+ registry2 = next;
5777
5903
  }
5778
5904
  function clearAgentRegistry() {
5779
- registry3 = /* @__PURE__ */ new Map();
5905
+ registry2 = /* @__PURE__ */ new Map();
5780
5906
  }
5781
5907
  function listAgents() {
5782
5908
  const merged = /* @__PURE__ */ new Map();
5783
- for (const agent of registry3.values()) merged.set(agent.name, agent);
5784
- for (const skill of listSkills()) merged.set(skill.name, skill);
5909
+ for (const agent of registry2.values()) merged.set(agent.name, agent);
5785
5910
  return Array.from(merged.values());
5786
5911
  }
5787
- var registry3;
5912
+ var registry2;
5788
5913
  var init_agentRegistry = __esm({
5789
5914
  "src/injection/agentRegistry.ts"() {
5790
5915
  "use strict";
5791
- init_skillRegistry();
5792
- registry3 = /* @__PURE__ */ new Map();
5916
+ registry2 = /* @__PURE__ */ new Map();
5793
5917
  }
5794
5918
  });
5795
5919
 
@@ -6048,9 +6172,9 @@ async function validateInput(schemaPath, method, inputType, input) {
6048
6172
  function mapZodIssues(error) {
6049
6173
  return error.issues.map((issue) => {
6050
6174
  const code = mapZodCode(issue.code, issue.message);
6051
- const path23 = issue.path.map(String).join(".") || "";
6175
+ const path24 = issue.path.map(String).join(".") || "";
6052
6176
  return {
6053
- path: path23,
6177
+ path: path24,
6054
6178
  code,
6055
6179
  expected: issue.expected ?? mapExpectedFromMessage(issue.message),
6056
6180
  received: issue.received ?? mapReceivedFromMessage(issue.message),
@@ -6364,9 +6488,9 @@ var init_wsHandler = __esm({
6364
6488
  });
6365
6489
 
6366
6490
  // src/server/handleWsUpgrade.ts
6367
- import fs16 from "fs";
6491
+ import fs17 from "fs";
6368
6492
  import { WebSocketServer, WebSocket } from "ws";
6369
- import path17 from "path";
6493
+ import path18 from "path";
6370
6494
  function getPathname(req) {
6371
6495
  const url = req.url ?? "/";
6372
6496
  const idx = url.indexOf("?");
@@ -6377,7 +6501,7 @@ async function loadWsHandler(filePath, ctx, rootDir) {
6377
6501
  const dist = getDevDist();
6378
6502
  if (dist) {
6379
6503
  const sourcePath = prodPathToSourcePath(filePath, rootDir, dist);
6380
- if (sourcePath && fs16.existsSync(sourcePath)) {
6504
+ if (sourcePath && fs17.existsSync(sourcePath)) {
6381
6505
  await ensureCompiled(sourcePath, rootDir, dist);
6382
6506
  }
6383
6507
  }
@@ -6457,7 +6581,7 @@ function attachWebSocket(options) {
6457
6581
  const finalHandler = async () => {
6458
6582
  let handlers;
6459
6583
  try {
6460
- const absoluteFilePath = path17.resolve(rootDir, route.filePath);
6584
+ const absoluteFilePath = path18.resolve(rootDir, route.filePath);
6461
6585
  handlers = await loadWsHandler(absoluteFilePath, ctx, rootDir);
6462
6586
  } catch (err) {
6463
6587
  const reason = err instanceof Error ? err.message : String(err);
@@ -6531,7 +6655,7 @@ import {
6531
6655
  import { createSecureServer as createHttp2SecureServer } from "http2";
6532
6656
  import { readFileSync } from "fs";
6533
6657
  import { Readable as Readable3 } from "stream";
6534
- import path18 from "path";
6658
+ import path19 from "path";
6535
6659
  function toWebRequest(req, bodyLimit = DEFAULT_BODY_LIMIT) {
6536
6660
  const forwardedProto = req.headers["x-forwarded-proto"];
6537
6661
  const protocol = Array.isArray(forwardedProto) ? forwardedProto[0]?.split(",")[0]?.trim() ?? "http" : forwardedProto?.split(",")[0]?.trim() ?? "http";
@@ -6601,15 +6725,15 @@ function limitStreamSize(stream, maxSize) {
6601
6725
  }
6602
6726
  });
6603
6727
  }
6604
- function findAllowedMethods(routes, path23) {
6728
+ function findAllowedMethods(routes, path24) {
6605
6729
  const methods = /* @__PURE__ */ new Set();
6606
6730
  for (const route of routes) {
6607
- if (route.urlPath === path23) {
6731
+ if (route.urlPath === path24) {
6608
6732
  methods.add(route.method);
6609
6733
  continue;
6610
6734
  }
6611
6735
  if (route.isDynamic) {
6612
- const params = matchDynamicPath(route.urlPath, path23, route.paramNames, route.isCatchAll);
6736
+ const params = matchDynamicPath(route.urlPath, path24, route.paramNames, route.isCatchAll);
6613
6737
  if (params !== null) {
6614
6738
  methods.add(route.method);
6615
6739
  }
@@ -6701,7 +6825,7 @@ function createRoutePipeline(opts) {
6701
6825
  const match = resolveRouteOrThrow(routes, method, urlPath);
6702
6826
  ctx.params = match.params;
6703
6827
  const { route } = match;
6704
- const absoluteFilePath = path18.resolve(rootDir, route.filePath);
6828
+ const absoluteFilePath = path19.resolve(rootDir, route.filePath);
6705
6829
  const routeModule = await loadRouteModule(absoluteFilePath, route.method, rootDir);
6706
6830
  const input = await resolveInput(route.method, request);
6707
6831
  const inputType = getInputTypeForMethod(route.method);
@@ -6891,13 +7015,25 @@ var init_loadPlugins = __esm({
6891
7015
  }
6892
7016
  });
6893
7017
 
7018
+ // src/injection/skillRegistry.ts
7019
+ function clearSkillRegistry() {
7020
+ registry3 = /* @__PURE__ */ new Map();
7021
+ }
7022
+ var registry3;
7023
+ var init_skillRegistry = __esm({
7024
+ "src/injection/skillRegistry.ts"() {
7025
+ "use strict";
7026
+ registry3 = /* @__PURE__ */ new Map();
7027
+ }
7028
+ });
7029
+
6894
7030
  // src/cli/createAppCore.ts
6895
- import fs17 from "fs";
6896
- import path19 from "path";
7031
+ import fs18 from "fs";
7032
+ import path20 from "path";
6897
7033
  import { PassThrough, Readable as Readable4 } from "stream";
6898
7034
  async function loadAndHydrateTools(rootDir, dist) {
6899
- const toolsPath = path19.resolve(rootDir, dist, TOOLS_FILE2);
6900
- if (!fs17.existsSync(toolsPath)) {
7035
+ const toolsPath = path20.resolve(rootDir, dist, TOOLS_FILE2);
7036
+ if (!fs18.existsSync(toolsPath)) {
6901
7037
  return [];
6902
7038
  }
6903
7039
  const serialized = await importWithCacheBust(toolsPath);
@@ -6906,8 +7042,8 @@ async function loadAndHydrateTools(rootDir, dist) {
6906
7042
  return hydrated;
6907
7043
  }
6908
7044
  async function loadAndHydrateAgents(rootDir, dist) {
6909
- const agentsPath = path19.resolve(rootDir, dist, AGENTS_FILE2);
6910
- if (!fs17.existsSync(agentsPath)) {
7045
+ const agentsPath = path20.resolve(rootDir, dist, AGENTS_FILE2);
7046
+ if (!fs18.existsSync(agentsPath)) {
6911
7047
  return [];
6912
7048
  }
6913
7049
  const serialized = await importWithCacheBust(agentsPath);
@@ -6931,8 +7067,8 @@ function isFaapiConfigKey(key) {
6931
7067
  async function createAppBase(options) {
6932
7068
  const rootDir = options?.rootDir ?? process.cwd();
6933
7069
  const dist = options?.dist ?? process.env.FAAPI_DIST ?? DEFAULT_DIST;
6934
- const routesPath = path19.resolve(rootDir, dist, ROUTES_FILE);
6935
- if (!fs17.existsSync(routesPath)) {
7070
+ const routesPath = path20.resolve(rootDir, dist, ROUTES_FILE);
7071
+ if (!fs18.existsSync(routesPath)) {
6936
7072
  throw new Error(
6937
7073
  `[faapi] ${dist}/${ROUTES_FILE} \u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u6267\u884C \`faapi build\`\uFF08\u6216 \`faapi dev\`\uFF09\u751F\u6210\u4EA7\u7269\u3002`
6938
7074
  );
@@ -7258,7 +7394,7 @@ __export(devCommand_exports, {
7258
7394
  generateRouteArtifacts: () => generateRouteArtifacts,
7259
7395
  generateToolArtifactsForDev: () => generateToolArtifactsForDev
7260
7396
  });
7261
- import path20 from "path";
7397
+ import path21 from "path";
7262
7398
  async function devCommand(options) {
7263
7399
  const rootDir = process.cwd();
7264
7400
  if (!process.env.NODE_ENV) process.env.NODE_ENV = "development";
@@ -7285,7 +7421,7 @@ async function devCommand(options) {
7285
7421
  async function generateRouteArtifacts(rootDir, patterns, dist) {
7286
7422
  const { routes, wsRoutes } = await scanRoutes(rootDir, patterns, dist);
7287
7423
  const sorted = sortRoutes(routes);
7288
- const routesPath = path20.resolve(rootDir, dist, ROUTES_FILE2);
7424
+ const routesPath = path21.resolve(rootDir, dist, ROUTES_FILE2);
7289
7425
  const serialized = serializeRoutes(sorted, wsRoutes, rootDir, dist);
7290
7426
  await writeRoutesModule(serialized, routesPath);
7291
7427
  }
@@ -7323,8 +7459,8 @@ var init_devCommand = __esm({
7323
7459
  });
7324
7460
 
7325
7461
  // src/cli/compileBuildRoutes.ts
7326
- import path21 from "path";
7327
- import fs18 from "fs";
7462
+ import path22 from "path";
7463
+ import fs19 from "fs";
7328
7464
  import fg5 from "fast-glob";
7329
7465
  async function compileBuildRoutes(options) {
7330
7466
  const { rootDir, dist, files, logLevel = "silent" } = options;
@@ -7337,11 +7473,11 @@ async function compileBuildRoutes(options) {
7337
7473
  if (entryPoints.length === 0) {
7338
7474
  return { compiledFiles: [] };
7339
7475
  }
7340
- const absDist = path21.resolve(rootDir, dist);
7341
- await fs18.promises.mkdir(absDist, { recursive: true });
7476
+ const absDist = path22.resolve(rootDir, dist);
7477
+ await fs19.promises.mkdir(absDist, { recursive: true });
7342
7478
  const plugins = buildAliasPlugins(rootDir);
7343
7479
  const esbuild = await import("esbuild");
7344
- const outbase = path21.resolve(rootDir, APP_DIR3);
7480
+ const outbase = path22.resolve(rootDir, APP_DIR3);
7345
7481
  await esbuild.build({
7346
7482
  entryPoints,
7347
7483
  outdir: absDist,
@@ -7372,8 +7508,8 @@ var buildCommand_exports = {};
7372
7508
  __export(buildCommand_exports, {
7373
7509
  buildCommand: () => buildCommand
7374
7510
  });
7375
- import path22 from "path";
7376
- import fs19 from "fs";
7511
+ import path23 from "path";
7512
+ import fs20 from "fs";
7377
7513
  async function buildCommand(options) {
7378
7514
  const rootDir = options?.rootDir ?? process.cwd();
7379
7515
  const outdir = options?.dist ?? DEFAULT_DIST2;
@@ -7417,9 +7553,9 @@ async function buildCommand(options) {
7417
7553
  }
7418
7554
  console.log("\n[4/8] Generating schema...");
7419
7555
  await generateSchemaFiles(sorted, rootDir, outdir);
7420
- console.log(` Schema: zod.js files under ${path22.resolve(rootDir, outdir)}`);
7556
+ console.log(` Schema: zod.js files under ${path23.resolve(rootDir, outdir)}`);
7421
7557
  console.log("\n[5/8] Generating routes manifest...");
7422
- const routesPath = path22.resolve(rootDir, outdir, "faapi-routes.js");
7558
+ const routesPath = path23.resolve(rootDir, outdir, "faapi-routes.js");
7423
7559
  const serialized = serializeRoutes(sorted, wsRoutes, rootDir, outdir);
7424
7560
  await writeRoutesModule(serialized, routesPath);
7425
7561
  console.log(` Written to ${routesPath}`);
@@ -7427,14 +7563,14 @@ async function buildCommand(options) {
7427
7563
  const tools = await scanTools(rootDir, TOOL_PATTERNS);
7428
7564
  const toolMeta = await generateToolArtifacts(tools, rootDir, outdir);
7429
7565
  console.log(` Found ${toolMeta.length} tool(s)`);
7430
- console.log(` Tool manifest: ${path22.resolve(rootDir, outdir, "faapi-tools.js")}`);
7566
+ console.log(` Tool manifest: ${path23.resolve(rootDir, outdir, "faapi-tools.js")}`);
7431
7567
  console.log("\n[7/8] Generating agent manifest...");
7432
7568
  const agents = await scanAgents(rootDir, DEFAULT_AGENT_PATTERNS);
7433
7569
  const agentMeta = await generateAgentArtifacts(agents, rootDir, outdir);
7434
7570
  console.log(` Found ${agentMeta.length} agent(s)`);
7435
- console.log(` Agent manifest: ${path22.resolve(rootDir, outdir, "faapi-agents.js")}`);
7571
+ console.log(` Agent manifest: ${path23.resolve(rootDir, outdir, "faapi-agents.js")}`);
7436
7572
  console.log("\n[8/8] Generating entry file...");
7437
- const mainPath = path22.resolve(rootDir, outdir, "main.js");
7573
+ const mainPath = path23.resolve(rootDir, outdir, "main.js");
7438
7574
  const createProdAppArgs = options?.dist && options.dist !== DEFAULT_DIST2 ? `{ dist: '${outdir}' }` : "";
7439
7575
  const mainContent = `// \u7531 faapi build \u81EA\u52A8\u751F\u6210\uFF0C\u8BF7\u52FF\u624B\u52A8\u7F16\u8F91
7440
7576
  import { createProdApp, loadEnv } from '@faapi/faapi';
@@ -7446,7 +7582,7 @@ loadEnv(process.cwd());
7446
7582
  const app = await createProdApp(${createProdAppArgs});
7447
7583
  await app.listen();
7448
7584
  `;
7449
- await fs19.promises.writeFile(mainPath, mainContent, "utf-8");
7585
+ await fs20.promises.writeFile(mainPath, mainContent, "utf-8");
7450
7586
  console.log(` Written to ${mainPath}`);
7451
7587
  console.log("\nfaapi build completed");
7452
7588
  }