@faapi/faapi 6.9.1 → 6.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,10 +1,38 @@
1
- import { A as AppRegistries, R as RouteManifest, F as FaapiContext, C as CorsOptions, T as TaskClient, H as HelmetOptions, L as LoggerOptions, a as LogConfig, b as FaapiMiddleware, I as InjectorMap, c as TaskFailedHandler, d as TaskQueueDeps, e as TaskQueue, f as TaskDriver, g as TaskRegistry, h as TaskManifest, i as ToolMetadata, j as AgentCore, k as AgentMetadata, l as CreateLoggerOptions, m as Logger, W as WsRouteManifest } from './routeTypes-CuGMDCGB.js';
2
- export { n as AgentHandleFactory, o as AgentHandleStore, p as AgentPathMeta, q as AgentRegistry, r as AgentToolDescriptor, s as FaapiContextConfig, t as FaapiTaskMeta, u as FailOptions, v as Injector, w as LogEntry, x as LogLevel, y as LogSink, z as RouteInfo, B as RouteInputSchema, D as RouteOutputSchema, E as RouteParamSchema, S as SkillRegistry, G as SseEvent, J as SseWriter, K as TaskContext, M as TaskDriverJob, N as TaskDriverProcess, O as TaskDriverRecord, P as TaskFailedInfo, Q as TaskJob, U as TaskJobStatus, V as TaskMetadata, X as TaskModule, Y as TaskRegistriesSnapshot, Z as TaskRegistriesView, _ as ToolCore, $ as ToolPathMeta, a0 as ToolRegistry, a1 as cors, a2 as createAppRegistries, a3 as createTaskRegistriesView, a4 as createTaskRegistry, a5 as helmet, a6 as logger } from './routeTypes-CuGMDCGB.js';
1
+ import { F as FaapiMiddleware, A as AppRegistries, R as RouteManifest, a as FaapiContext, C as CorsOptions, T as TaskClient, H as HelmetOptions, L as LogConfig, I as InjectorMap, b as TaskFailedHandler, c as TaskQueueDeps, d as TaskQueue, e as TaskDriver, f as TaskRegistry, g as TaskManifest, h as ToolMetadata, i as AgentCore, j as AgentMetadata, k as CreateLoggerOptions, l as Logger, W as WsRouteManifest } from './routeTypes-m9wZHWyo.js';
2
+ export { m as AgentHandleFactory, n as AgentHandleStore, o as AgentPathMeta, p as AgentRegistry, q as AgentToolDescriptor, r as FaapiContextConfig, s as FaapiTaskMeta, t as FailOptions, u as Injector, v as LogEntry, w as LogLevel, x as LogSink, y as RouteInfo, z as RouteInputSchema, B as RouteOutputSchema, D as RouteParamSchema, S as SkillRegistry, E as SseEvent, G as SseWriter, J as TaskContext, K as TaskDriverJob, M as TaskDriverProcess, N as TaskDriverRecord, O as TaskFailedInfo, P as TaskJob, Q as TaskJobStatus, U as TaskMetadata, V as TaskModule, X as TaskRegistriesSnapshot, Y as TaskRegistriesView, Z as ToolCore, _ as ToolPathMeta, $ as ToolRegistry, a0 as cors, a1 as createAppRegistries, a2 as createTaskRegistriesView, a3 as createTaskRegistry, a4 as helmet } from './routeTypes-m9wZHWyo.js';
3
3
  import * as node_http from 'node:http';
4
4
  import { Server, IncomingMessage, ServerResponse } from 'node:http';
5
5
  import { Socket } from 'node:net';
6
6
  import ts from 'typescript';
7
7
 
8
+ type LoggerFn = (messageOrObj: string | Record<string, unknown>, message?: string) => void;
9
+ interface LoggerOptions {
10
+ /**
11
+ * 自定义日志函数(完全接管输出,不再走统一管道——高级用法,一般无需配置)
12
+ *
13
+ * - 传入 `console.log`:纯文本格式 `GET /api/users 200 12ms`
14
+ * - 传入 pino logger:结构化日志 `logger.info({ method, path, status, durationMs }, 'request completed')`
15
+ */
16
+ log?: LoggerFn;
17
+ }
18
+ /**
19
+ * 创建请求日志中间件(洋葱模型)
20
+ *
21
+ * 默认并入统一日志管道(egg 模型:访问日志与业务日志同管道,一份 config.log
22
+ * 管全部输出),`config.log.accessLog: false` 关闭。
23
+ *
24
+ * 日志格式(文本 message):GET /api/users 200 12ms
25
+ * 错误格式:POST /api/users 400 45ms - Error: ...
26
+ *
27
+ * before/after 一体,闭包变量共享开始时间,无需污染 ctx。
28
+ * 错误用 try/catch 捕获,记录后重新抛出(让上层处理)。
29
+ * 成功时从 next() 返回的 Response 读取状态码。
30
+ *
31
+ * log 函数每次请求时读取(options.log ?? defaultLog),运行时切换全局日志配置
32
+ * 同样生效。编程式自定义输出:`middlewares: [logger({ log: myFn })]`。
33
+ */
34
+ declare function logger(options?: LoggerOptions): FaapiMiddleware;
35
+
8
36
  /** HTTP 请求 handler 类型 */
9
37
  type RequestHandler = (req: IncomingMessage, res: ServerResponse) => void;
10
38
  /** WebSocket 升级 handler 类型 */
@@ -550,21 +578,19 @@ interface FaapiConfig {
550
578
  etag?: EtagOptions | boolean;
551
579
  /** 请求体大小限制(字节),默认 10MB(10 * 1024 * 1024) */
552
580
  bodyLimit?: number;
553
- /** 日志中间件配置 */
554
- logger?: LoggerOptions | boolean;
555
581
  /**
556
- * 业务日志器全局配置(详见 logger/logger.md)
582
+ * 日志全局配置——唯一日志配置入口,业务日志与请求日志同管道(egg 模型,
583
+ * 详见 logger/logger.md;`config.logger` 独立配置已废除)
557
584
  *
558
- * - `false`:完全静默(含 error,测试降噪;不影响请求日志,关闭用 `logger: false`)
559
- * - `true` / 缺省:默认级别(显式 level > LOG_LEVEL env > 'info')+ console 文本输出
560
- * - `LogConfig`:精细配置——`sink` 自定义管道(接 pino/winston)或 `dir` egg 风格
561
- * 文件输出(app.log 全量 + error.log 仅 error,splitByLevel 按级别四文件),
562
- * 两者互斥;`dir` 模式请求日志自动并入(`accessLog` 缺省 true),未显式配置
563
- * level 时不过滤(全量落盘)
585
+ * - `false`:全部静默(含 error 与请求日志,测试降噪)
586
+ * - `true` / 缺省:console 输出(consoleLevel 默认 'info'),管道不过滤
587
+ * - `LogConfig`:`dir` egg 风格文件输出(app.log 全量 + error.log 仅 error,
588
+ * splitByLevel 按级别四文件)或 `sink` 自定义管道接管(接 pino/winston),
589
+ * 两者互斥;`level` 管道阈值(不配不过滤)、`consoleLevel` console 出口阈值
590
+ * (不配 'info',false 关 console);请求日志无条件并入(`accessLog: false` 关闭)
564
591
  *
565
- * 生效范围:`ctx.log` / 参数注入 `log` / `createLogger` / `taskCtx.log`,
566
- * `dir`/`accessLog` 模式下含请求日志中间件。
567
- * 日志全局配置是进程级资源,多 app 同进程时后启动覆盖先启动。
592
+ * 生效范围:`ctx.log` / 参数注入 `log` / `createLogger` / `taskCtx.log` /
593
+ * 请求日志中间件。日志全局配置是进程级资源,多 app 同进程时后启动覆盖先启动。
568
594
  *
569
595
  * ```ts
570
596
  * export default {
@@ -1495,14 +1521,14 @@ declare function loadEnv(rootDir: string): void;
1495
1521
  /**
1496
1522
  * 设置全局日志配置(进程级,`createAppBase` 启动时以 `config.log` 调用)
1497
1523
  *
1498
- * - `false`:完全静默(含 error,测试降噪场景)
1499
- * - `true` / `{}`:默认级别(显式 level > LOG_LEVEL env > 模式默认)+ 默认 console sink
1500
- * - `{ level, sink }`:自定义管道接管(与 dir 互斥,同时配置抛错)
1501
- * - `{ dir, splitByLevel?, stdout?, accessLog? }`:egg 风格文件输出(fileSink.md)
1524
+ * - `false`:全部静默(含 error 与请求日志,测试降噪场景)
1525
+ * - `true` / `{}`:console 出口默认 info,管道出口不过滤,无文件输出
1526
+ * - `{ level, consoleLevel, sink, dir, stdout, accessLog }`:egg 模型精细配置
1527
+ * (level 管管道出口、consoleLevel 管 console 出口;sink 与 dir 互斥)
1502
1528
  * - `undefined`:重置为默认(编程式多 app 切换全局配置用)
1503
1529
  *
1504
- * LOG_LEVEL env 仅在本函数读取——app 启动路径必经此处(env 非法在启动期报错);
1505
- * 纯编程式不调本函数时 env 不生效。
1530
+ * LOG_LEVEL env 仅作为管道 level 的环境来源(consoleLevel 无 env)——本函数是
1531
+ * env 读取点,非法值启动期报错(fail fast)。
1506
1532
  */
1507
1533
  declare function configureLogging(config?: LogConfig | boolean | undefined): void;
1508
1534
  /**
@@ -1720,4 +1746,4 @@ type ProdApp = AppBase;
1720
1746
  */
1721
1747
  declare function createProdApp(options?: CreateAppOptions): Promise<ProdApp>;
1722
1748
 
1723
- export { type AgentConfig, AgentCore, AgentMetadata, type AgentModule, type ProdApp as App, AppRegistries, CorsOptions, type CreateAppOptions, CreateLoggerOptions, type CronScheduler, type DevApp, type FaapiConfig, FaapiContext, FaapiError, FaapiMiddleware, type FaapiPlugin, type HandlerTypeInfo, HelmetOptions, type InjectOptions, type InjectResponse, InjectorMap, InternalError, type LifecycleContext, type LifecycleHooks, type LlmConfig, type LlmModelConfig, LogConfig, Logger, LoggerOptions, MethodNotAllowedError, ModuleLoadError, type PluginContext, type PluginDeclaration, type ProdApp, type PropertyType, type RequestHandler, type ResponseConfig, RouteManifest, RouteNotFoundError, type RouteSchemaSource, type RuntimeType, SchemaExtractionError, TASK_PATTERNS, type TaskBullMqOptions, TaskClient, type TaskConfig, TaskDriver, TaskFailedHandler, TaskManifest, type TaskPgBossOptions, TaskQueue, TaskRegistry, ToolMetadata, type ToolModule, type ToolSchemaModule, type TypeConstraint, type UpgradeHandler, ValidationError, type ValidationErrorCode, type ValidationIssue, type WsContext, type WsEventHandlers, type WsHandler, type WsSocket, clearAgentHandleFactory, collectRouteSchemaSources, configureLogging, createProdApp as createApp, createCronScheduler, createDevApp, createLogger, createProdApp, createProgram, createPrograms, createTaskQueue, extractTypeInfo, flushLogging, getAgent, getAgentEntry, getApp, getInputTypeForMethod, getSkill, getTool, getToolSchemaPath, hydrateSkillRegistry, invalidateProgramCache, listSkills, loadAgentModule, loadConfig, loadEnv, loadTaskDriver, loadToolModule, loadToolSchema, registerAgentHandleFactory, removeSkill, resolveAgentTools, resolveSubAgents, resolveTypeNode, scanTasks, upsertSkill };
1749
+ export { type AgentConfig, AgentCore, AgentMetadata, type AgentModule, type ProdApp as App, AppRegistries, CorsOptions, type CreateAppOptions, CreateLoggerOptions, type CronScheduler, type DevApp, type FaapiConfig, FaapiContext, FaapiError, FaapiMiddleware, type FaapiPlugin, type HandlerTypeInfo, HelmetOptions, type InjectOptions, type InjectResponse, InjectorMap, InternalError, type LifecycleContext, type LifecycleHooks, type LlmConfig, type LlmModelConfig, LogConfig, Logger, type LoggerOptions, MethodNotAllowedError, ModuleLoadError, type PluginContext, type PluginDeclaration, type ProdApp, type PropertyType, type RequestHandler, type ResponseConfig, RouteManifest, RouteNotFoundError, type RouteSchemaSource, type RuntimeType, SchemaExtractionError, TASK_PATTERNS, type TaskBullMqOptions, TaskClient, type TaskConfig, TaskDriver, TaskFailedHandler, TaskManifest, type TaskPgBossOptions, TaskQueue, TaskRegistry, ToolMetadata, type ToolModule, type ToolSchemaModule, type TypeConstraint, type UpgradeHandler, ValidationError, type ValidationErrorCode, type ValidationIssue, type WsContext, type WsEventHandlers, type WsHandler, type WsSocket, clearAgentHandleFactory, collectRouteSchemaSources, configureLogging, createProdApp as createApp, createCronScheduler, createDevApp, createLogger, createProdApp, createProgram, createPrograms, createTaskQueue, extractTypeInfo, flushLogging, getAgent, getAgentEntry, getApp, getInputTypeForMethod, getSkill, getTool, getToolSchemaPath, hydrateSkillRegistry, invalidateProgramCache, listSkills, loadAgentModule, loadConfig, loadEnv, loadTaskDriver, loadToolModule, loadToolSchema, logger, registerAgentHandleFactory, removeSkill, resolveAgentTools, resolveSubAgents, resolveTypeNode, scanTasks, upsertSkill };
package/dist/index.js CHANGED
@@ -2374,7 +2374,15 @@ function assertLogLevel(value, source) {
2374
2374
  );
2375
2375
  }
2376
2376
  }
2377
- var globalState = { level: null, sink: null, fileSink: null, stdout: true, accessLog: false, disabled: false };
2377
+ var globalState = {
2378
+ level: null,
2379
+ consoleLevel: null,
2380
+ sink: null,
2381
+ fileSink: null,
2382
+ stdout: true,
2383
+ accessLog: true,
2384
+ disabled: false
2385
+ };
2378
2386
  function configureLogging(config) {
2379
2387
  const objectConfig = typeof config === "object" ? config : {};
2380
2388
  if (objectConfig.sink && objectConfig.dir) {
@@ -2385,9 +2393,17 @@ function configureLogging(config) {
2385
2393
  void globalState.fileSink?.close();
2386
2394
  globalState.disabled = config === false;
2387
2395
  globalState.sink = objectConfig.sink ?? null;
2388
- globalState.accessLog = objectConfig.accessLog ?? objectConfig.dir !== void 0;
2396
+ globalState.accessLog = objectConfig.accessLog ?? true;
2389
2397
  globalState.stdout = objectConfig.stdout ?? true;
2390
2398
  globalState.fileSink = objectConfig.dir ? createFileLogSink({ dir: objectConfig.dir, splitByLevel: objectConfig.splitByLevel }) : null;
2399
+ if (objectConfig.consoleLevel !== void 0) {
2400
+ if (objectConfig.consoleLevel !== false) {
2401
+ assertLogLevel(objectConfig.consoleLevel, "config.log.consoleLevel");
2402
+ }
2403
+ globalState.consoleLevel = objectConfig.consoleLevel;
2404
+ } else {
2405
+ globalState.consoleLevel = null;
2406
+ }
2391
2407
  if (objectConfig.level !== void 0) {
2392
2408
  assertLogLevel(objectConfig.level, "config.log.level");
2393
2409
  globalState.level = objectConfig.level;
@@ -2398,55 +2414,57 @@ function configureLogging(config) {
2398
2414
  globalState.level = null;
2399
2415
  }
2400
2416
  }
2401
- function globalThreshold() {
2402
- if (globalState.level) return globalState.level;
2403
- if (globalState.fileSink) return void 0;
2404
- return "info";
2417
+ function pipelineThreshold() {
2418
+ return globalState.level ?? void 0;
2419
+ }
2420
+ function consoleThreshold() {
2421
+ return globalState.consoleLevel ?? "info";
2405
2422
  }
2406
2423
  function belowThreshold(level, threshold) {
2407
2424
  return threshold !== void 0 && LEVEL_RANK[level] < LEVEL_RANK[threshold];
2408
2425
  }
2409
2426
  function getEffectiveLogLevel() {
2410
- return globalThreshold();
2427
+ return pipelineThreshold();
2411
2428
  }
2412
- var consoleSink = (entry) => {
2413
- console[CONSOLE_METHOD[entry.level]](formatEntry(entry));
2414
- };
2415
2429
  var CONSOLE_METHOD = {
2416
2430
  debug: "debug",
2417
2431
  info: "info",
2418
2432
  warn: "warn",
2419
2433
  error: "error"
2420
2434
  };
2435
+ function consoleDispatch(entry) {
2436
+ const threshold = consoleThreshold();
2437
+ if (threshold === false || belowThreshold(entry.level, threshold)) return;
2438
+ console[CONSOLE_METHOD[entry.level]](formatEntry(entry));
2439
+ }
2421
2440
  function globalDispatch(entry) {
2422
2441
  if (globalState.disabled) return;
2442
+ const pipeThreshold = pipelineThreshold();
2423
2443
  if (globalState.sink) {
2424
- globalState.sink(entry);
2444
+ if (!belowThreshold(entry.level, pipeThreshold)) globalState.sink(entry);
2425
2445
  return;
2426
2446
  }
2427
2447
  if (globalState.fileSink) {
2428
- globalState.fileSink.write(entry);
2429
- if (globalState.stdout) consoleSink(entry);
2448
+ if (!belowThreshold(entry.level, pipeThreshold)) globalState.fileSink.write(entry);
2449
+ if (globalState.stdout) consoleDispatch(entry);
2430
2450
  return;
2431
2451
  }
2432
- consoleSink(entry);
2452
+ consoleDispatch(entry);
2433
2453
  }
2434
2454
  function writeLogEntry(entry) {
2435
- if (belowThreshold(entry.level, globalThreshold())) return;
2436
2455
  globalDispatch(entry);
2437
2456
  }
2438
2457
  function flushLogging() {
2439
2458
  return globalState.fileSink ? globalState.fileSink.flush() : Promise.resolve();
2440
2459
  }
2441
- function isAccessLogPiped() {
2460
+ function isAccessLogEnabled() {
2442
2461
  return !globalState.disabled && globalState.accessLog;
2443
2462
  }
2444
2463
  function createLogger(scope, options) {
2445
2464
  const baseScope = scope;
2446
2465
  const baseFields = options?.fields;
2447
2466
  const write = (level, message, callFields, scopeSuffix) => {
2448
- const threshold = options?.level ?? globalThreshold();
2449
- if (belowThreshold(level, threshold)) return;
2467
+ if (belowThreshold(level, options?.level)) return;
2450
2468
  const entry = {
2451
2469
  level,
2452
2470
  message,
@@ -4017,18 +4035,14 @@ function levelForStatus(status) {
4017
4035
  return "info";
4018
4036
  }
4019
4037
  function defaultLog(entry, text) {
4020
- if (isAccessLogPiped()) {
4021
- const logEntry = {
4022
- level: levelForStatus(entry.status),
4023
- message: text,
4024
- time: (/* @__PURE__ */ new Date()).toISOString(),
4025
- scope: "access",
4026
- fields: entry
4027
- };
4028
- writeLogEntry(logEntry);
4029
- return;
4030
- }
4031
- console.log(entry);
4038
+ if (!isAccessLogEnabled()) return;
4039
+ writeLogEntry({
4040
+ level: levelForStatus(entry.status),
4041
+ message: text,
4042
+ time: (/* @__PURE__ */ new Date()).toISOString(),
4043
+ scope: "access",
4044
+ fields: entry
4045
+ });
4032
4046
  }
4033
4047
  function logger(options = {}) {
4034
4048
  return async (ctx, next) => {
@@ -5941,7 +5955,6 @@ function createServer(options) {
5941
5955
  compression: compressionOption,
5942
5956
  etag: etagOption,
5943
5957
  registries,
5944
- logger: loggerOption,
5945
5958
  bodyLimit = DEFAULT_BODY_LIMIT,
5946
5959
  http2: http2Option,
5947
5960
  trustedProxy = false
@@ -5958,8 +5971,7 @@ function createServer(options) {
5958
5971
  const helmOpts = typeof helmetOption === "object" ? helmetOption : {};
5959
5972
  configMiddlewares.push(helmet(helmOpts));
5960
5973
  }
5961
- const loggerMiddlewareInst = loggerOption === false ? null : loggerOption === true || loggerOption === void 0 ? logger() : logger(loggerOption);
5962
- if (loggerMiddlewareInst) configMiddlewares.push(loggerMiddlewareInst);
5974
+ configMiddlewares.push(logger());
5963
5975
  if (etagOption) {
5964
5976
  const etagOpts = typeof etagOption === "object" ? etagOption : {};
5965
5977
  configMiddlewares.push(etag(etagOpts));
@@ -6941,7 +6953,6 @@ var FAAPI_CONFIG_KEYS = /* @__PURE__ */ new Set([
6941
6953
  "compression",
6942
6954
  "etag",
6943
6955
  "bodyLimit",
6944
- "logger",
6945
6956
  "log",
6946
6957
  "http2",
6947
6958
  "trustedProxy",
@@ -7016,7 +7027,6 @@ async function createAppBase(options) {
7016
7027
  helmet: config?.helmet,
7017
7028
  compression: config?.compression,
7018
7029
  etag: config?.etag,
7019
- logger: config?.logger,
7020
7030
  bodyLimit: config?.bodyLimit,
7021
7031
  http2: config?.http2,
7022
7032
  trustedProxy: config?.trustedProxy,