@faapi/faapi 6.26.0 → 6.28.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.
@@ -1,4 +1,4 @@
1
- import { F as FaapiContext } from './contextTypes-gYf84EXF.js';
1
+ import { F as FaapiContext } from './contextTypes-DhagvRH_.js';
2
2
 
3
3
  /**
4
4
  * faapi 中间件(洋葱模型)
package/dist/testing.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { F as FaapiContext } from './contextTypes-gYf84EXF.js';
2
- import { F as FaapiMiddleware, I as InjectorMap, R as RouteManifest, W as WsRouteManifest, C as CorsOptions, H as HelmetOptions } from './routeTypes-DlD6nnbT.js';
1
+ import { F as FaapiContext } from './contextTypes-DhagvRH_.js';
2
+ import { F as FaapiMiddleware, I as InjectorMap, R as RouteManifest, W as WsRouteManifest, C as CorsOptions, H as HelmetOptions } from './routeTypes-0rwuIws-.js';
3
3
  import { Server } from 'node:http';
4
4
  import { WebSocket } from 'ws';
5
5
 
@@ -30,7 +30,7 @@ interface CreateTestContextOptions {
30
30
  * 运行时资源根目录(可选)
31
31
  *
32
32
  * 传入时同时做两件事:绑定全局 readResource 读取根(handler 直调
33
- * `readResource('x.md')` 依赖)+ 挂到 ctx.resourcesDir 数据字段
33
+ * `readResource('x.md')` 依赖);ctx 上无 resourcesDir 数据字段(已删除)
34
34
  */
35
35
  resourcesDir?: string;
36
36
  /** 请求方法,默认 'GET' */
package/dist/testing.js CHANGED
@@ -312,14 +312,14 @@ var ValidationError = class extends FaapiError {
312
312
  issues;
313
313
  };
314
314
  var RouteNotFoundError = class extends FaapiError {
315
- constructor(path18) {
316
- super("ROUTE_NOT_FOUND", `Route not found: ${path18}`, 404);
315
+ constructor(path17) {
316
+ super("ROUTE_NOT_FOUND", `Route not found: ${path17}`, 404);
317
317
  this.name = "RouteNotFoundError";
318
318
  }
319
319
  };
320
320
  var MethodNotAllowedError = class extends FaapiError {
321
- constructor(method, path18, allowedMethods) {
322
- super("METHOD_NOT_ALLOWED", `Method ${method} not allowed for ${path18}`, 405);
321
+ constructor(method, path17, allowedMethods) {
322
+ super("METHOD_NOT_ALLOWED", `Method ${method} not allowed for ${path17}`, 405);
323
323
  this.allowedMethods = allowedMethods;
324
324
  this.name = "MethodNotAllowedError";
325
325
  }
@@ -628,18 +628,10 @@ function formatSetCookie(name, value, options) {
628
628
  if (options?.sameSite) cookie += `; SameSite=${options.sameSite}`;
629
629
  return cookie;
630
630
  }
631
- function createContext(request, params, config = {}, ip = "", registries, resourcesDir) {
632
- return createContextFromUrl(
633
- request,
634
- new URL(request.url),
635
- params,
636
- config,
637
- ip,
638
- registries,
639
- resourcesDir
640
- );
631
+ function createContext(request, params, config = {}, ip = "", registries) {
632
+ return createContextFromUrl(request, new URL(request.url), params, config, ip, registries);
641
633
  }
642
- function createContextFromUrl(request, url, params, config = {}, ip = "", registries, resourcesDir) {
634
+ function createContextFromUrl(request, url, params, config = {}, ip = "", registries) {
643
635
  const meta = { headers: {}, setCookies: [] };
644
636
  const parsedCookies = parseCookies(request.headers.get("cookie") ?? "");
645
637
  const cookiesObj = {};
@@ -667,9 +659,6 @@ function createContextFromUrl(request, url, params, config = {}, ip = "", regist
667
659
  ua: request.headers.get("user-agent") ?? "",
668
660
  cookies: cookiesObj,
669
661
  config,
670
- // 运行时资源根目录(HTTP/WS 链路由 createServer/handleWsUpgrade 传入;
671
- // testing 直调未传时为 undefined,见 contextTypes.resourcesDir 注释)
672
- resourcesDir,
673
662
  meta,
674
663
  setStatus(status) {
675
664
  meta.status = status;
@@ -775,7 +764,7 @@ function createContextFromUrl(request, url, params, config = {}, ip = "", regist
775
764
  function createTestContext(options) {
776
765
  const {
777
766
  method = "GET",
778
- path: path18,
767
+ path: path17,
779
768
  query,
780
769
  headers,
781
770
  params = {},
@@ -784,7 +773,7 @@ function createTestContext(options) {
784
773
  registries,
785
774
  resourcesDir
786
775
  } = options;
787
- const url = new URL(`http://localhost${path18}`);
776
+ const url = new URL(`http://localhost${path17}`);
788
777
  if (query) {
789
778
  for (const [key, value] of Object.entries(query)) {
790
779
  if (Array.isArray(value)) {
@@ -803,7 +792,7 @@ function createTestContext(options) {
803
792
  if (resourcesDir) {
804
793
  setActiveResourcesDir(resourcesDir);
805
794
  }
806
- return createContext(request, params, config, ip, registries, resourcesDir);
795
+ return createContext(request, params, config, ip, registries);
807
796
  }
808
797
 
809
798
  // src/response/pendingMeta.ts
@@ -1066,6 +1055,19 @@ function createTaskRegistry() {
1066
1055
  };
1067
1056
  }
1068
1057
 
1058
+ // src/injection/subAgentToolName.ts
1059
+ var LLM_TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]+$/;
1060
+ var SUB_AGENT_TOOL_PREFIX = "agent-";
1061
+ function subAgentToolName(agentName) {
1062
+ const toolName = SUB_AGENT_TOOL_PREFIX + agentName;
1063
+ if (!LLM_TOOL_NAME_PATTERN.test(toolName)) {
1064
+ throw new Error(
1065
+ `Sub-agent tool name "${toolName}" (from agent name "${agentName}") violates the LLM tool name pattern ${LLM_TOOL_NAME_PATTERN} \u2014 rename the agent (allowed: a-z A-Z 0-9 '-' '_'; file-based agent directory segments allow a-z A-Z 0-9 '-' only, '_' is the nesting separator)`
1066
+ );
1067
+ }
1068
+ return toolName;
1069
+ }
1070
+
1069
1071
  // src/injection/registries.ts
1070
1072
  function createToolRegistry() {
1071
1073
  let registry = /* @__PURE__ */ new Map();
@@ -1113,7 +1115,7 @@ function createAgentRegistry(tool) {
1113
1115
  if (!agent) return void 0;
1114
1116
  return {
1115
1117
  kind: "agent",
1116
- name: `agent.${agent.name}`,
1118
+ name: subAgentToolName(agent.name),
1117
1119
  agentName: agent.name,
1118
1120
  description: agent.description,
1119
1121
  metadata: agent
@@ -1386,9 +1388,9 @@ async function invokeHandler(handler, ctx, body, middlewares, injectors) {
1386
1388
  }
1387
1389
 
1388
1390
  // src/testServer.ts
1389
- import path17 from "path";
1391
+ import path16 from "path";
1390
1392
  import os from "os";
1391
- import fs14 from "fs/promises";
1393
+ import fs13 from "fs/promises";
1392
1394
 
1393
1395
  // src/router/scanRoutes.ts
1394
1396
  import fg from "fast-glob";
@@ -1400,9 +1402,9 @@ var HTTP_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"];
1400
1402
  var HTTP_METHOD_SET = new Set(HTTP_METHODS);
1401
1403
 
1402
1404
  // src/utils/normalizePath.ts
1403
- function normalizePath(path18) {
1404
- if (!path18) return "";
1405
- let result = path18.replace(/\\/g, "/");
1405
+ function normalizePath(path17) {
1406
+ if (!path17) return "";
1407
+ let result = path17.replace(/\\/g, "/");
1406
1408
  result = result.replace(/\/+/g, "/");
1407
1409
  result = result.replace(/\/+$/, "");
1408
1410
  if (result && !result.startsWith("/")) {
@@ -3851,9 +3853,9 @@ async function validateInput(schemaPath, method, inputType, input) {
3851
3853
  function mapZodIssues(error) {
3852
3854
  return error.issues.map((issue) => {
3853
3855
  const code = mapZodCode(issue);
3854
- const path18 = issue.path.map(String).join(".") || "";
3856
+ const path17 = issue.path.map(String).join(".") || "";
3855
3857
  return {
3856
- path: path18,
3858
+ path: path17,
3857
3859
  code,
3858
3860
  expected: issue.expected ?? mapExpectedFromMessage(issue.message),
3859
3861
  received: issue.received ?? mapReceivedFromMessage(issue.message),
@@ -3903,7 +3905,7 @@ import {
3903
3905
  import { createSecureServer as createHttp2SecureServer } from "http2";
3904
3906
  import { readFileSync } from "fs";
3905
3907
  import { Readable as Readable2 } from "stream";
3906
- import path16 from "path";
3908
+ import path15 from "path";
3907
3909
 
3908
3910
  // src/router/matchRoute.ts
3909
3911
  var httpIndexCache = /* @__PURE__ */ new WeakMap();
@@ -3945,25 +3947,25 @@ function getWsIndex(routes) {
3945
3947
  wsIndexCache.set(routes, index);
3946
3948
  return index;
3947
3949
  }
3948
- function matchRoute(routes, method, path18) {
3950
+ function matchRoute(routes, method, path17) {
3949
3951
  const index = getHttpIndex(routes);
3950
3952
  const upper = method.toUpperCase();
3951
- const hit = matchByMethod(index, upper, path18);
3953
+ const hit = matchByMethod(index, upper, path17);
3952
3954
  if (hit) return hit;
3953
3955
  if (upper === "HEAD") {
3954
- return matchByMethod(index, "GET", path18);
3956
+ return matchByMethod(index, "GET", path17);
3955
3957
  }
3956
3958
  return null;
3957
3959
  }
3958
- function matchByMethod(index, method, path18) {
3959
- const staticHit = index.static.get(`${method}|${path18}`);
3960
+ function matchByMethod(index, method, path17) {
3961
+ const staticHit = index.static.get(`${method}|${path17}`);
3960
3962
  if (staticHit) {
3961
3963
  return { route: staticHit, params: {} };
3962
3964
  }
3963
3965
  if (index.dynamics.length === 0) {
3964
3966
  return null;
3965
3967
  }
3966
- const pathSegments = path18.split("/").filter(Boolean);
3968
+ const pathSegments = path17.split("/").filter(Boolean);
3967
3969
  for (const entry of index.dynamics) {
3968
3970
  const route = entry.route;
3969
3971
  if (route.method !== method) {
@@ -3976,31 +3978,31 @@ function matchByMethod(index, method, path18) {
3976
3978
  }
3977
3979
  return null;
3978
3980
  }
3979
- function matchWsRoute(wsRoutes, path18) {
3981
+ function matchWsRoute(wsRoutes, path17) {
3980
3982
  const index = getWsIndex(wsRoutes);
3981
- const staticHit = index.static.get(path18);
3983
+ const staticHit = index.static.get(path17);
3982
3984
  if (staticHit) {
3983
3985
  return { route: staticHit, params: {} };
3984
3986
  }
3985
3987
  for (const route of index.dynamics) {
3986
- const params = matchDynamicPath(route.urlPath, path18, route.paramNames, route.isCatchAll);
3988
+ const params = matchDynamicPath(route.urlPath, path17, route.paramNames, route.isCatchAll);
3987
3989
  if (params !== null) {
3988
3990
  return { route, params };
3989
3991
  }
3990
3992
  }
3991
3993
  return null;
3992
3994
  }
3993
- function findAllowedMethods(routes, path18) {
3995
+ function findAllowedMethods(routes, path17) {
3994
3996
  const index = getHttpIndex(routes);
3995
3997
  const methods = /* @__PURE__ */ new Set();
3996
- const staticMethods = index.methodsByStaticPath.get(path18);
3998
+ const staticMethods = index.methodsByStaticPath.get(path17);
3997
3999
  if (staticMethods) {
3998
4000
  for (const method of staticMethods) {
3999
4001
  methods.add(method);
4000
4002
  }
4001
4003
  }
4002
4004
  if (index.dynamics.length > 0) {
4003
- const pathSegments = path18.split("/").filter(Boolean);
4005
+ const pathSegments = path17.split("/").filter(Boolean);
4004
4006
  for (const entry of index.dynamics) {
4005
4007
  const params = matchSegments(
4006
4008
  entry.segments,
@@ -4018,10 +4020,10 @@ function findAllowedMethods(routes, path18) {
4018
4020
  }
4019
4021
  return Array.from(methods);
4020
4022
  }
4021
- function matchDynamicPath(pattern, path18, paramNames, isCatchAll) {
4023
+ function matchDynamicPath(pattern, path17, paramNames, isCatchAll) {
4022
4024
  return matchSegments(
4023
4025
  pattern.split("/").filter(Boolean),
4024
- path18.split("/").filter(Boolean),
4026
+ path17.split("/").filter(Boolean),
4025
4027
  paramNames,
4026
4028
  isCatchAll
4027
4029
  );
@@ -4643,17 +4645,9 @@ function logger(options = {}) {
4643
4645
  }
4644
4646
 
4645
4647
  // src/server/handleWsUpgrade.ts
4646
- import fs13 from "fs";
4648
+ import fs12 from "fs";
4647
4649
  import { WebSocketServer, WebSocket } from "ws";
4648
- import path15 from "path";
4649
-
4650
- // src/cli/copyResources.ts
4651
4650
  import path14 from "path";
4652
- import fs12 from "fs";
4653
- var RESOURCES_OUTPUT_DIR = "resources";
4654
- function resolveResourcesDir(rootDir, dist) {
4655
- return path14.resolve(rootDir, dist, RESOURCES_OUTPUT_DIR);
4656
- }
4657
4651
 
4658
4652
  // src/server/serverUtils.ts
4659
4653
  function nodeHttpToWebHeaders(req) {
@@ -4711,7 +4705,7 @@ async function loadWsHandler(filePath, ctx, rootDir) {
4711
4705
  const dist = getDevDist();
4712
4706
  if (dist) {
4713
4707
  const sourcePath = prodPathToSourcePath(filePath, rootDir, dist);
4714
- if (sourcePath && fs13.existsSync(sourcePath)) {
4708
+ if (sourcePath && fs12.existsSync(sourcePath)) {
4715
4709
  await ensureCompiled(sourcePath, rootDir, dist);
4716
4710
  }
4717
4711
  }
@@ -4809,7 +4803,6 @@ function attachWebSocket(options) {
4809
4803
  trustedProxy = false,
4810
4804
  registries
4811
4805
  } = options;
4812
- const resourcesDir = resolveResourcesDir(rootDir, dist);
4813
4806
  const wss = new WebSocketServer({ noServer: true });
4814
4807
  server.on("upgrade", async (req, socket, head) => {
4815
4808
  try {
@@ -4841,19 +4834,12 @@ function attachWebSocket(options) {
4841
4834
  const host = req.headers.host ?? "localhost";
4842
4835
  const fullUrl = new URL(`http://${host}${req.url ?? "/"}`);
4843
4836
  const request = new Request(fullUrl.toString(), { method: "GET", headers });
4844
- const ctx = createContext(
4845
- request,
4846
- params,
4847
- config,
4848
- getClientIp(req, trustedProxy),
4849
- registries,
4850
- resourcesDir
4851
- );
4837
+ const ctx = createContext(request, params, config, getClientIp(req, trustedProxy), registries);
4852
4838
  const meta = ctx.meta;
4853
4839
  let upgraded = false;
4854
4840
  const finalHandler = async () => {
4855
4841
  const schemaPath = getRuntimeSchemaPath(route.filePath, dist, rootDir);
4856
- if (fs13.existsSync(schemaPath)) {
4842
+ if (fs12.existsSync(schemaPath)) {
4857
4843
  if (isDevOnDemandEnabled()) {
4858
4844
  const devDist = getDevDist();
4859
4845
  if (devDist) {
@@ -4892,7 +4878,7 @@ function attachWebSocket(options) {
4892
4878
  }
4893
4879
  let handlers;
4894
4880
  try {
4895
- const absoluteFilePath = path15.resolve(rootDir, route.filePath);
4881
+ const absoluteFilePath = path14.resolve(rootDir, route.filePath);
4896
4882
  handlers = await loadWsHandler(absoluteFilePath, ctx, rootDir);
4897
4883
  } catch (err) {
4898
4884
  const reason = err instanceof Error ? err.message : String(err);
@@ -5051,7 +5037,6 @@ function createServer(options) {
5051
5037
  trustedProxy = false
5052
5038
  } = options;
5053
5039
  const routesRef = { current: routes, wsCurrent: wsRoutes ?? [] };
5054
- const resourcesDir = resolveResourcesDir(rootDir, dist);
5055
5040
  const configMiddlewares = [];
5056
5041
  if (compressionOption) {
5057
5042
  const compOpts = typeof compressionOption === "object" ? compressionOption : {};
@@ -5098,8 +5083,7 @@ function createServer(options) {
5098
5083
  bodyLimit,
5099
5084
  trustedProxy,
5100
5085
  registries,
5101
- routesRef.wsCurrent,
5102
- resourcesDir
5086
+ routesRef.wsCurrent
5103
5087
  ).catch((err) => {
5104
5088
  console.error("[faapi] Request pipeline failed after error response attempt:", err);
5105
5089
  try {
@@ -5125,7 +5109,7 @@ function createServer(options) {
5125
5109
  });
5126
5110
  return { server, routesRef };
5127
5111
  }
5128
- function prepareRequest(req, request, url, config, trustedProxy, registries, preMatched, resourcesDir) {
5112
+ function prepareRequest(req, request, url, config, trustedProxy, registries, preMatched) {
5129
5113
  const method = request.method.toUpperCase();
5130
5114
  const urlPath = url.pathname;
5131
5115
  const ctx = createContextFromUrl(
@@ -5134,8 +5118,7 @@ function prepareRequest(req, request, url, config, trustedProxy, registries, pre
5134
5118
  preMatched?.params ?? {},
5135
5119
  config,
5136
5120
  getClientIp(req, trustedProxy),
5137
- registries,
5138
- resourcesDir
5121
+ registries
5139
5122
  );
5140
5123
  const meta = ctx.meta;
5141
5124
  return { request, url, ctx, meta, method, urlPath };
@@ -5154,7 +5137,7 @@ function getRoutePaths(route, rootDir, dist) {
5154
5137
  let cached = routePathCache.get(route);
5155
5138
  if (!cached) {
5156
5139
  cached = {
5157
- absFilePath: path16.resolve(rootDir, route.filePath),
5140
+ absFilePath: path15.resolve(rootDir, route.filePath),
5158
5141
  schemaPath: getRuntimeSchemaPath(route.filePath, dist, rootDir)
5159
5142
  };
5160
5143
  routePathCache.set(route, cached);
@@ -5277,7 +5260,7 @@ async function sendErrorResponse(err, meta, res, onError, ctx) {
5277
5260
  }
5278
5261
  }
5279
5262
  }
5280
- async function handleRequest(routes, rootDir, dist, req, res, outerMiddlewares, onError, config, globalInjectors, bodyLimit, trustedProxy, registries, wsRoutes, resourcesDir) {
5263
+ async function handleRequest(routes, rootDir, dist, req, res, outerMiddlewares, onError, config, globalInjectors, bodyLimit, trustedProxy, registries, wsRoutes) {
5281
5264
  let meta = { headers: {}, setCookies: [] };
5282
5265
  let ctx;
5283
5266
  let sseEarlySent = false;
@@ -5297,8 +5280,7 @@ async function handleRequest(routes, rootDir, dist, req, res, outerMiddlewares,
5297
5280
  config,
5298
5281
  trustedProxy,
5299
5282
  registries,
5300
- preMatched,
5301
- resourcesDir
5283
+ preMatched
5302
5284
  );
5303
5285
  ctx = prepared.ctx;
5304
5286
  meta = prepared.meta;
@@ -5363,7 +5345,7 @@ async function createTestServer(options) {
5363
5345
  } = options;
5364
5346
  const { routes, wsRoutes } = await scanRoutes(rootDir, patterns);
5365
5347
  const sorted = sortRoutes(routes);
5366
- const schemaDist = dist ? path17.isAbsolute(dist) ? dist : path17.resolve(rootDir, dist) : await fs14.mkdtemp(path17.join(os.tmpdir(), "faapi-test-schema-"));
5348
+ const schemaDist = dist ? path16.isAbsolute(dist) ? dist : path16.resolve(rootDir, dist) : await fs13.mkdtemp(path16.join(os.tmpdir(), "faapi-test-schema-"));
5367
5349
  await generateSchemaFiles(sorted, rootDir, schemaDist);
5368
5350
  const { server } = createServer({
5369
5351
  routes: sorted,
@@ -5395,7 +5377,7 @@ async function createTestServer(options) {
5395
5377
  await new Promise((resolve) => {
5396
5378
  server.close(() => resolve());
5397
5379
  });
5398
- await fs14.rm(schemaDist, { recursive: true, force: true }).catch(() => {
5380
+ await fs13.rm(schemaDist, { recursive: true, force: true }).catch(() => {
5399
5381
  });
5400
5382
  invalidateSchemaCache();
5401
5383
  }